mirror of
https://github.com/overte-org/overte.git
synced 2025-08-06 17:00:13 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into audio-noise
This commit is contained in:
commit
87a6d5921f
46 changed files with 1253 additions and 1749 deletions
|
@ -389,7 +389,7 @@ const QByteArray* OctreeQueryNode::getNextNackedPacket() {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OctreeQueryNode::parseNackPacket(QByteArray& packet) {
|
void OctreeQueryNode::parseNackPacket(const QByteArray& packet) {
|
||||||
|
|
||||||
int numBytesPacketHeader = numBytesForPacketHeader(packet);
|
int numBytesPacketHeader = numBytesForPacketHeader(packet);
|
||||||
const unsigned char* dataAt = reinterpret_cast<const unsigned char*>(packet.data()) + numBytesPacketHeader;
|
const unsigned char* dataAt = reinterpret_cast<const unsigned char*>(packet.data()) + numBytesPacketHeader;
|
||||||
|
|
|
@ -109,7 +109,7 @@ public:
|
||||||
|
|
||||||
OCTREE_PACKET_SEQUENCE getSequenceNumber() const { return _sequenceNumber; }
|
OCTREE_PACKET_SEQUENCE getSequenceNumber() const { return _sequenceNumber; }
|
||||||
|
|
||||||
void parseNackPacket(QByteArray& packet);
|
void parseNackPacket(const QByteArray& packet);
|
||||||
bool hasNextNackedPacket() const;
|
bool hasNextNackedPacket() const;
|
||||||
const QByteArray* getNextNackedPacket();
|
const QByteArray* getNextNackedPacket();
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
#include "OctreeServer.h"
|
#include "OctreeServer.h"
|
||||||
#include "OctreeServerConsts.h"
|
#include "OctreeServerConsts.h"
|
||||||
|
#include "OctreeServerDatagramProcessor.h"
|
||||||
|
|
||||||
OctreeServer* OctreeServer::_instance = NULL;
|
OctreeServer* OctreeServer::_instance = NULL;
|
||||||
int OctreeServer::_clientCount = 0;
|
int OctreeServer::_clientCount = 0;
|
||||||
|
@ -827,55 +828,83 @@ void OctreeServer::parsePayload() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OctreeServer::readPendingDatagrams() {
|
void OctreeServer::readPendingDatagram(const QByteArray& receivedPacket, const HifiSockAddr& senderSockAddr) {
|
||||||
QByteArray receivedPacket;
|
|
||||||
HifiSockAddr senderSockAddr;
|
|
||||||
|
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
NodeList* nodeList = NodeList::getInstance();
|
||||||
|
|
||||||
while (readAvailableDatagram(receivedPacket, senderSockAddr)) {
|
if (nodeList->packetVersionAndHashMatch(receivedPacket)) {
|
||||||
if (nodeList->packetVersionAndHashMatch(receivedPacket)) {
|
PacketType packetType = packetTypeForPacket(receivedPacket);
|
||||||
PacketType packetType = packetTypeForPacket(receivedPacket);
|
SharedNodePointer matchingNode = nodeList->sendingNodeForPacket(receivedPacket);
|
||||||
SharedNodePointer matchingNode = nodeList->sendingNodeForPacket(receivedPacket);
|
if (packetType == getMyQueryMessageType()) {
|
||||||
if (packetType == getMyQueryMessageType()) {
|
// If we got a query packet, then we're talking to an agent, and we
|
||||||
// If we got a query packet, then we're talking to an agent, and we
|
// need to make sure we have it in our nodeList.
|
||||||
// need to make sure we have it in our nodeList.
|
if (matchingNode) {
|
||||||
if (matchingNode) {
|
nodeList->updateNodeWithDataFromPacket(matchingNode, receivedPacket);
|
||||||
nodeList->updateNodeWithDataFromPacket(matchingNode, receivedPacket);
|
OctreeQueryNode* nodeData = (OctreeQueryNode*)matchingNode->getLinkedData();
|
||||||
OctreeQueryNode* nodeData = (OctreeQueryNode*)matchingNode->getLinkedData();
|
if (nodeData && !nodeData->isOctreeSendThreadInitalized()) {
|
||||||
if (nodeData && !nodeData->isOctreeSendThreadInitalized()) {
|
|
||||||
|
// NOTE: this is an important aspect of the proper ref counting. The send threads/node data need to
|
||||||
// NOTE: this is an important aspect of the proper ref counting. The send threads/node data need to
|
// know that the OctreeServer/Assignment will not get deleted on it while it's still active. The
|
||||||
// know that the OctreeServer/Assignment will not get deleted on it while it's still active. The
|
// solution is to get the shared pointer for the current assignment. We need to make sure this is the
|
||||||
// solution is to get the shared pointer for the current assignment. We need to make sure this is the
|
// same SharedAssignmentPointer that was ref counted by the assignment client.
|
||||||
// same SharedAssignmentPointer that was ref counted by the assignment client.
|
SharedAssignmentPointer sharedAssignment = AssignmentClient::getCurrentAssignment();
|
||||||
SharedAssignmentPointer sharedAssignment = AssignmentClient::getCurrentAssignment();
|
nodeData->initializeOctreeSendThread(sharedAssignment, matchingNode);
|
||||||
nodeData->initializeOctreeSendThread(sharedAssignment, matchingNode);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if (packetType == PacketTypeOctreeDataNack) {
|
|
||||||
// If we got a nack packet, then we're talking to an agent, and we
|
|
||||||
// need to make sure we have it in our nodeList.
|
|
||||||
if (matchingNode) {
|
|
||||||
OctreeQueryNode* nodeData = (OctreeQueryNode*)matchingNode->getLinkedData();
|
|
||||||
if (nodeData) {
|
|
||||||
nodeData->parseNackPacket(receivedPacket);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (packetType == PacketTypeJurisdictionRequest) {
|
|
||||||
_jurisdictionSender->queueReceivedPacket(matchingNode, receivedPacket);
|
|
||||||
} else if (packetType == PacketTypeSignedTransactionPayment) {
|
|
||||||
handleSignedTransactionPayment(packetType, receivedPacket);
|
|
||||||
} else if (_octreeInboundPacketProcessor && getOctree()->handlesEditPacketType(packetType)) {
|
|
||||||
_octreeInboundPacketProcessor->queueReceivedPacket(matchingNode, receivedPacket);
|
|
||||||
} else {
|
|
||||||
// let processNodeData handle it.
|
|
||||||
NodeList::getInstance()->processNodeData(senderSockAddr, receivedPacket);
|
|
||||||
}
|
}
|
||||||
|
} else if (packetType == PacketTypeOctreeDataNack) {
|
||||||
|
// If we got a nack packet, then we're talking to an agent, and we
|
||||||
|
// need to make sure we have it in our nodeList.
|
||||||
|
if (matchingNode) {
|
||||||
|
OctreeQueryNode* nodeData = (OctreeQueryNode*)matchingNode->getLinkedData();
|
||||||
|
if (nodeData) {
|
||||||
|
nodeData->parseNackPacket(receivedPacket);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (packetType == PacketTypeJurisdictionRequest) {
|
||||||
|
_jurisdictionSender->queueReceivedPacket(matchingNode, receivedPacket);
|
||||||
|
} else if (packetType == PacketTypeSignedTransactionPayment) {
|
||||||
|
handleSignedTransactionPayment(packetType, receivedPacket);
|
||||||
|
} else if (_octreeInboundPacketProcessor && getOctree()->handlesEditPacketType(packetType)) {
|
||||||
|
_octreeInboundPacketProcessor->queueReceivedPacket(matchingNode, receivedPacket);
|
||||||
|
} else {
|
||||||
|
// let processNodeData handle it.
|
||||||
|
NodeList::getInstance()->processNodeData(senderSockAddr, receivedPacket);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OctreeServer::setupDatagramProcessingThread() {
|
||||||
|
NodeList* nodeList = NodeList::getInstance();
|
||||||
|
|
||||||
|
// we do not want this event loop to be the handler for UDP datagrams, so disconnect
|
||||||
|
disconnect(&nodeList->getNodeSocket(), 0, this, 0);
|
||||||
|
|
||||||
|
// setup a QThread with us as parent that will house the AudioMixerDatagramProcessor
|
||||||
|
_datagramProcessingThread = new QThread(this);
|
||||||
|
|
||||||
|
// create an AudioMixerDatagramProcessor and move it to that thread
|
||||||
|
OctreeServerDatagramProcessor* datagramProcessor = new OctreeServerDatagramProcessor(nodeList->getNodeSocket(), thread());
|
||||||
|
datagramProcessor->moveToThread(_datagramProcessingThread);
|
||||||
|
|
||||||
|
// remove the NodeList as the parent of the node socket
|
||||||
|
nodeList->getNodeSocket().setParent(NULL);
|
||||||
|
nodeList->getNodeSocket().moveToThread(_datagramProcessingThread);
|
||||||
|
|
||||||
|
// let the datagram processor handle readyRead from node socket
|
||||||
|
connect(&nodeList->getNodeSocket(), &QUdpSocket::readyRead,
|
||||||
|
datagramProcessor, &OctreeServerDatagramProcessor::readPendingDatagrams);
|
||||||
|
|
||||||
|
// connect to the datagram processing thread signal that tells us we have to handle a packet
|
||||||
|
connect(datagramProcessor, &OctreeServerDatagramProcessor::packetRequiresProcessing, this, &OctreeServer::readPendingDatagram);
|
||||||
|
|
||||||
|
// delete the datagram processor and the associated thread when the QThread quits
|
||||||
|
connect(_datagramProcessingThread, &QThread::finished, datagramProcessor, &QObject::deleteLater);
|
||||||
|
connect(datagramProcessor, &QObject::destroyed, _datagramProcessingThread, &QThread::deleteLater);
|
||||||
|
|
||||||
|
// start the datagram processing thread
|
||||||
|
_datagramProcessingThread->start();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void OctreeServer::run() {
|
void OctreeServer::run() {
|
||||||
_safeServerName = getMyServerName();
|
_safeServerName = getMyServerName();
|
||||||
|
|
||||||
|
@ -887,6 +916,8 @@ void OctreeServer::run() {
|
||||||
// use common init to setup common timers and logging
|
// use common init to setup common timers and logging
|
||||||
commonInit(getMyLoggingServerTargetName(), getMyNodeType());
|
commonInit(getMyLoggingServerTargetName(), getMyNodeType());
|
||||||
|
|
||||||
|
setupDatagramProcessingThread();
|
||||||
|
|
||||||
// Now would be a good time to parse our arguments, if we got them as assignment
|
// Now would be a good time to parse our arguments, if we got them as assignment
|
||||||
if (getPayload().size() > 0) {
|
if (getPayload().size() > 0) {
|
||||||
parsePayload();
|
parsePayload();
|
||||||
|
|
|
@ -123,13 +123,15 @@ public:
|
||||||
public slots:
|
public slots:
|
||||||
/// runs the voxel server assignment
|
/// runs the voxel server assignment
|
||||||
void run();
|
void run();
|
||||||
void readPendingDatagrams();
|
|
||||||
void nodeAdded(SharedNodePointer node);
|
void nodeAdded(SharedNodePointer node);
|
||||||
void nodeKilled(SharedNodePointer node);
|
void nodeKilled(SharedNodePointer node);
|
||||||
void sendStatsPacket();
|
void sendStatsPacket();
|
||||||
|
|
||||||
void handleSignedTransactionPaymentResponse(const QJsonObject& jsonObject);
|
void handleSignedTransactionPaymentResponse(const QJsonObject& jsonObject);
|
||||||
|
|
||||||
|
void readPendingDatagrams() { }; // this will not be called since our datagram processing thread will handle
|
||||||
|
void readPendingDatagram(const QByteArray& receivedPacket, const HifiSockAddr& senderSockAddr);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void parsePayload();
|
void parsePayload();
|
||||||
void initHTTPManager(int port);
|
void initHTTPManager(int port);
|
||||||
|
@ -140,6 +142,7 @@ protected:
|
||||||
QString getStatusLink();
|
QString getStatusLink();
|
||||||
|
|
||||||
void handleSignedTransactionPayment(PacketType packetType, const QByteArray& datagram);
|
void handleSignedTransactionPayment(PacketType packetType, const QByteArray& datagram);
|
||||||
|
void setupDatagramProcessingThread();
|
||||||
|
|
||||||
int _argc;
|
int _argc;
|
||||||
const char** _argv;
|
const char** _argv;
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
//
|
||||||
|
// OctreeServerDatagramProcessor.cpp
|
||||||
|
// assignment-client/src
|
||||||
|
//
|
||||||
|
// Created by Brad Hefta-Gaub on 2014-09-05
|
||||||
|
// 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 <QDebug>
|
||||||
|
|
||||||
|
#include <HifiSockAddr.h>
|
||||||
|
#include <NodeList.h>
|
||||||
|
#include <PacketHeaders.h>
|
||||||
|
#include <SharedUtil.h>
|
||||||
|
|
||||||
|
#include "OctreeServerDatagramProcessor.h"
|
||||||
|
|
||||||
|
OctreeServerDatagramProcessor::OctreeServerDatagramProcessor(QUdpSocket& nodeSocket, QThread* previousNodeSocketThread) :
|
||||||
|
_nodeSocket(nodeSocket),
|
||||||
|
_previousNodeSocketThread(previousNodeSocketThread)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
OctreeServerDatagramProcessor::~OctreeServerDatagramProcessor() {
|
||||||
|
// return the node socket to its previous thread
|
||||||
|
_nodeSocket.moveToThread(_previousNodeSocketThread);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OctreeServerDatagramProcessor::readPendingDatagrams() {
|
||||||
|
|
||||||
|
HifiSockAddr senderSockAddr;
|
||||||
|
static QByteArray incomingPacket;
|
||||||
|
|
||||||
|
// read everything that is available
|
||||||
|
while (_nodeSocket.hasPendingDatagrams()) {
|
||||||
|
incomingPacket.resize(_nodeSocket.pendingDatagramSize());
|
||||||
|
|
||||||
|
// just get this packet off the stack
|
||||||
|
_nodeSocket.readDatagram(incomingPacket.data(), incomingPacket.size(),
|
||||||
|
senderSockAddr.getAddressPointer(), senderSockAddr.getPortPointer());
|
||||||
|
|
||||||
|
PacketType packetType = packetTypeForPacket(incomingPacket);
|
||||||
|
if (packetType == PacketTypePing) {
|
||||||
|
NodeList::getInstance()->processNodeData(senderSockAddr, incomingPacket);
|
||||||
|
return; // don't emit
|
||||||
|
}
|
||||||
|
|
||||||
|
// emit the signal to tell AudioMixer it needs to process a packet
|
||||||
|
emit packetRequiresProcessing(incomingPacket, senderSockAddr);
|
||||||
|
}
|
||||||
|
}
|
32
assignment-client/src/octree/OctreeServerDatagramProcessor.h
Normal file
32
assignment-client/src/octree/OctreeServerDatagramProcessor.h
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
//
|
||||||
|
// OctreeServerDatagramProcessor.h
|
||||||
|
// assignment-client/src
|
||||||
|
//
|
||||||
|
// Created by Brad Hefta-Gaub on 2014-09-05
|
||||||
|
// 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_OctreeServerDatagramProcessor_h
|
||||||
|
#define hifi_OctreeServerDatagramProcessor_h
|
||||||
|
|
||||||
|
#include <qobject.h>
|
||||||
|
#include <qudpsocket.h>
|
||||||
|
|
||||||
|
class OctreeServerDatagramProcessor : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
OctreeServerDatagramProcessor(QUdpSocket& nodeSocket, QThread* previousNodeSocketThread);
|
||||||
|
~OctreeServerDatagramProcessor();
|
||||||
|
public slots:
|
||||||
|
void readPendingDatagrams();
|
||||||
|
signals:
|
||||||
|
void packetRequiresProcessing(const QByteArray& receivedPacket, const HifiSockAddr& senderSockAddr);
|
||||||
|
private:
|
||||||
|
QUdpSocket& _nodeSocket;
|
||||||
|
QThread* _previousNodeSocketThread;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // hifi_OctreeServerDatagramProcessor_h
|
|
@ -8,9 +8,10 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
Script.include("lookWithTouch.js");
|
Script.load("lookWithTouch.js");
|
||||||
Script.include("editVoxels.js");
|
Script.load("editVoxels.js");
|
||||||
Script.include("editModels.js");
|
Script.load("editModels.js");
|
||||||
Script.include("selectAudioDevice.js");
|
Script.load("selectAudioDevice.js");
|
||||||
Script.include("hydraMove.js");
|
Script.load("hydraMove.js");
|
||||||
Script.include("inspect.js");
|
Script.load("headMove.js");
|
||||||
|
Script.load("inspect.js");
|
||||||
|
|
|
@ -1147,10 +1147,10 @@ var toolBar = (function () {
|
||||||
}, true, false);
|
}, true, false);
|
||||||
|
|
||||||
browseModelsButton = toolBar.addTool({
|
browseModelsButton = toolBar.addTool({
|
||||||
imageURL: toolIconUrl + "list-icon.png",
|
imageURL: toolIconUrl + "list-icon.svg",
|
||||||
width: toolWidth,
|
width: toolWidth,
|
||||||
height: toolHeight,
|
height: toolHeight,
|
||||||
alpha: 0.7,
|
alpha: 0.9,
|
||||||
visible: true
|
visible: true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
77
examples/headMove.js
Normal file
77
examples/headMove.js
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
//
|
||||||
|
// headMove.js
|
||||||
|
// examples
|
||||||
|
//
|
||||||
|
// Created by Philip Rosedale on September 8, 2014
|
||||||
|
// Copyright 2014 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Press the spacebar and move/turn your head to move around.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
var debug = false;
|
||||||
|
|
||||||
|
var movingWithHead = false;
|
||||||
|
var headStartPosition, headStartDeltaPitch, headStartFinalPitch, headStartRoll, headStartYaw;
|
||||||
|
|
||||||
|
var HEAD_MOVE_DEAD_ZONE = 0.0;
|
||||||
|
var HEAD_STRAFE_DEAD_ZONE = 0.0;
|
||||||
|
var HEAD_ROTATE_DEAD_ZONE = 0.0;
|
||||||
|
var HEAD_THRUST_FWD_SCALE = 12000.0;
|
||||||
|
var HEAD_THRUST_STRAFE_SCALE = 1000.0;
|
||||||
|
var HEAD_YAW_RATE = 2.0;
|
||||||
|
var HEAD_PITCH_RATE = 1.0;
|
||||||
|
var HEAD_ROLL_THRUST_SCALE = 75.0;
|
||||||
|
var HEAD_PITCH_LIFT_THRUST = 3.0;
|
||||||
|
|
||||||
|
function moveWithHead(deltaTime) {
|
||||||
|
if (movingWithHead) {
|
||||||
|
var deltaYaw = MyAvatar.getHeadFinalYaw() - headStartYaw;
|
||||||
|
var deltaPitch = MyAvatar.getHeadDeltaPitch() - headStartDeltaPitch;
|
||||||
|
|
||||||
|
var bodyLocalCurrentHeadVector = Vec3.subtract(MyAvatar.getHeadPosition(), MyAvatar.position);
|
||||||
|
bodyLocalCurrentHeadVector = Vec3.multiplyQbyV(Quat.angleAxis(-deltaYaw, {x:0, y: 1, z:0}), bodyLocalCurrentHeadVector);
|
||||||
|
var headDelta = Vec3.subtract(bodyLocalCurrentHeadVector, headStartPosition);
|
||||||
|
headDelta = Vec3.multiplyQbyV(Quat.inverse(Camera.getOrientation()), headDelta);
|
||||||
|
headDelta.y = 0.0; // Don't respond to any of the vertical component of head motion
|
||||||
|
|
||||||
|
// Thrust based on leaning forward and side-to-side
|
||||||
|
if (Math.abs(headDelta.z) > HEAD_MOVE_DEAD_ZONE) {
|
||||||
|
MyAvatar.addThrust(Vec3.multiply(Quat.getFront(Camera.getOrientation()), -headDelta.z * HEAD_THRUST_FWD_SCALE * deltaTime));
|
||||||
|
}
|
||||||
|
if (Math.abs(headDelta.x) > HEAD_STRAFE_DEAD_ZONE) {
|
||||||
|
MyAvatar.addThrust(Vec3.multiply(Quat.getRight(Camera.getOrientation()), headDelta.x * HEAD_THRUST_STRAFE_SCALE * deltaTime));
|
||||||
|
}
|
||||||
|
if (Math.abs(deltaYaw) > HEAD_ROTATE_DEAD_ZONE) {
|
||||||
|
var orientation = Quat.multiply(Quat.angleAxis(deltaYaw * HEAD_YAW_RATE * deltaTime, {x:0, y: 1, z:0}), MyAvatar.orientation);
|
||||||
|
MyAvatar.orientation = orientation;
|
||||||
|
}
|
||||||
|
// Thrust Up/Down based on head pitch
|
||||||
|
MyAvatar.addThrust(Vec3.multiply({ x:0, y:1, z:0 }, (MyAvatar.getHeadFinalPitch() - headStartFinalPitch) * HEAD_PITCH_LIFT_THRUST * deltaTime));
|
||||||
|
// For head trackers, adjust pitch by head pitch
|
||||||
|
MyAvatar.headPitch += deltaPitch * HEAD_PITCH_RATE * deltaTime;
|
||||||
|
// Thrust strafe based on roll ange
|
||||||
|
MyAvatar.addThrust(Vec3.multiply(Quat.getRight(Camera.getOrientation()), -(MyAvatar.getHeadFinalRoll() - headStartRoll) * HEAD_ROLL_THRUST_SCALE * deltaTime));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Controller.keyPressEvent.connect(function(event) {
|
||||||
|
if (event.text == "SPACE" && !movingWithHead) {
|
||||||
|
movingWithHead = true;
|
||||||
|
headStartPosition = Vec3.subtract(MyAvatar.getHeadPosition(), MyAvatar.position);
|
||||||
|
headStartDeltaPitch = MyAvatar.getHeadDeltaPitch();
|
||||||
|
headStartFinalPitch = MyAvatar.getHeadFinalPitch();
|
||||||
|
headStartRoll = MyAvatar.getHeadFinalRoll();
|
||||||
|
headStartYaw = MyAvatar.getHeadFinalYaw();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Controller.keyReleaseEvent.connect(function(event) {
|
||||||
|
if (event.text == "SPACE") {
|
||||||
|
movingWithHead = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Script.update.connect(moveWithHead);
|
||||||
|
|
|
@ -2,7 +2,9 @@
|
||||||
// hydraMove.js
|
// hydraMove.js
|
||||||
// examples
|
// examples
|
||||||
//
|
//
|
||||||
// Created by Brad Hefta-Gaub on 2/10/14.
|
// Created by Brad Hefta-Gaub on February 10, 2014
|
||||||
|
// Updated by Philip Rosedale on September 8, 2014
|
||||||
|
//
|
||||||
// Copyright 2014 High Fidelity, Inc.
|
// Copyright 2014 High Fidelity, Inc.
|
||||||
//
|
//
|
||||||
// This is an example script that demonstrates use of the Controller and MyAvatar classes to implement
|
// This is an example script that demonstrates use of the Controller and MyAvatar classes to implement
|
||||||
|
@ -34,8 +36,7 @@ var grabbingWithRightHand = false;
|
||||||
var wasGrabbingWithRightHand = false;
|
var wasGrabbingWithRightHand = false;
|
||||||
var grabbingWithLeftHand = false;
|
var grabbingWithLeftHand = false;
|
||||||
var wasGrabbingWithLeftHand = false;
|
var wasGrabbingWithLeftHand = false;
|
||||||
var movingWithHead = false;
|
|
||||||
var headStartPosition, headStartDeltaPitch, headStartFinalPitch, headStartRoll, headStartYaw;
|
|
||||||
var EPSILON = 0.000001;
|
var EPSILON = 0.000001;
|
||||||
var velocity = { x: 0, y: 0, z: 0};
|
var velocity = { x: 0, y: 0, z: 0};
|
||||||
var THRUST_MAG_UP = 100.0;
|
var THRUST_MAG_UP = 100.0;
|
||||||
|
@ -243,47 +244,6 @@ function handleGrabBehavior(deltaTime) {
|
||||||
wasGrabbingWithLeftHand = grabbingWithLeftHand;
|
wasGrabbingWithLeftHand = grabbingWithLeftHand;
|
||||||
}
|
}
|
||||||
|
|
||||||
var HEAD_MOVE_DEAD_ZONE = 0.0;
|
|
||||||
var HEAD_STRAFE_DEAD_ZONE = 0.0;
|
|
||||||
var HEAD_ROTATE_DEAD_ZONE = 0.0;
|
|
||||||
var HEAD_THRUST_FWD_SCALE = 12000.0;
|
|
||||||
var HEAD_THRUST_STRAFE_SCALE = 1000.0;
|
|
||||||
var HEAD_YAW_RATE = 2.0;
|
|
||||||
var HEAD_PITCH_RATE = 1.0;
|
|
||||||
var HEAD_ROLL_THRUST_SCALE = 75.0;
|
|
||||||
var HEAD_PITCH_LIFT_THRUST = 3.0;
|
|
||||||
|
|
||||||
function moveWithHead(deltaTime) {
|
|
||||||
if (movingWithHead) {
|
|
||||||
var deltaYaw = MyAvatar.getHeadFinalYaw() - headStartYaw;
|
|
||||||
var deltaPitch = MyAvatar.getHeadDeltaPitch() - headStartDeltaPitch;
|
|
||||||
|
|
||||||
var bodyLocalCurrentHeadVector = Vec3.subtract(MyAvatar.getHeadPosition(), MyAvatar.position);
|
|
||||||
bodyLocalCurrentHeadVector = Vec3.multiplyQbyV(Quat.angleAxis(-deltaYaw, {x:0, y: 1, z:0}), bodyLocalCurrentHeadVector);
|
|
||||||
var headDelta = Vec3.subtract(bodyLocalCurrentHeadVector, headStartPosition);
|
|
||||||
headDelta = Vec3.multiplyQbyV(Quat.inverse(Camera.getOrientation()), headDelta);
|
|
||||||
headDelta.y = 0.0; // Don't respond to any of the vertical component of head motion
|
|
||||||
|
|
||||||
// Thrust based on leaning forward and side-to-side
|
|
||||||
if (Math.abs(headDelta.z) > HEAD_MOVE_DEAD_ZONE) {
|
|
||||||
MyAvatar.addThrust(Vec3.multiply(Quat.getFront(Camera.getOrientation()), -headDelta.z * HEAD_THRUST_FWD_SCALE * deltaTime));
|
|
||||||
}
|
|
||||||
if (Math.abs(headDelta.x) > HEAD_STRAFE_DEAD_ZONE) {
|
|
||||||
MyAvatar.addThrust(Vec3.multiply(Quat.getRight(Camera.getOrientation()), headDelta.x * HEAD_THRUST_STRAFE_SCALE * deltaTime));
|
|
||||||
}
|
|
||||||
if (Math.abs(deltaYaw) > HEAD_ROTATE_DEAD_ZONE) {
|
|
||||||
var orientation = Quat.multiply(Quat.angleAxis(deltaYaw * HEAD_YAW_RATE * deltaTime, {x:0, y: 1, z:0}), MyAvatar.orientation);
|
|
||||||
MyAvatar.orientation = orientation;
|
|
||||||
}
|
|
||||||
// Thrust Up/Down based on head pitch
|
|
||||||
MyAvatar.addThrust(Vec3.multiply({ x:0, y:1, z:0 }, (MyAvatar.getHeadFinalPitch() - headStartFinalPitch) * HEAD_PITCH_LIFT_THRUST * deltaTime));
|
|
||||||
// For head trackers, adjust pitch by head pitch
|
|
||||||
MyAvatar.headPitch += deltaPitch * HEAD_PITCH_RATE * deltaTime;
|
|
||||||
// Thrust strafe based on roll ange
|
|
||||||
MyAvatar.addThrust(Vec3.multiply(Quat.getRight(Camera.getOrientation()), -(MyAvatar.getHeadFinalRoll() - headStartRoll) * HEAD_ROLL_THRUST_SCALE * deltaTime));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update for joysticks and move button
|
// Update for joysticks and move button
|
||||||
function flyWithHydra(deltaTime) {
|
function flyWithHydra(deltaTime) {
|
||||||
var thrustJoystickPosition = Controller.getJoystickPosition(THRUST_CONTROLLER);
|
var thrustJoystickPosition = Controller.getJoystickPosition(THRUST_CONTROLLER);
|
||||||
|
@ -318,12 +278,10 @@ function flyWithHydra(deltaTime) {
|
||||||
MyAvatar.orientation = Quat.multiply(orientation, deltaOrientation);
|
MyAvatar.orientation = Quat.multiply(orientation, deltaOrientation);
|
||||||
|
|
||||||
// change the headPitch based on our x controller
|
// change the headPitch based on our x controller
|
||||||
//pitch += viewJoystickPosition.y * JOYSTICK_PITCH_MAG * deltaTime;
|
|
||||||
var newPitch = MyAvatar.headPitch + (viewJoystickPosition.y * JOYSTICK_PITCH_MAG * deltaTime);
|
var newPitch = MyAvatar.headPitch + (viewJoystickPosition.y * JOYSTICK_PITCH_MAG * deltaTime);
|
||||||
MyAvatar.headPitch = newPitch;
|
MyAvatar.headPitch = newPitch;
|
||||||
}
|
}
|
||||||
handleGrabBehavior(deltaTime);
|
handleGrabBehavior(deltaTime);
|
||||||
moveWithHead(deltaTime);
|
|
||||||
displayDebug();
|
displayDebug();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -340,19 +298,4 @@ function scriptEnding() {
|
||||||
}
|
}
|
||||||
Script.scriptEnding.connect(scriptEnding);
|
Script.scriptEnding.connect(scriptEnding);
|
||||||
|
|
||||||
Controller.keyPressEvent.connect(function(event) {
|
|
||||||
if (event.text == "SPACE" && !movingWithHead) {
|
|
||||||
movingWithHead = true;
|
|
||||||
headStartPosition = Vec3.subtract(MyAvatar.getHeadPosition(), MyAvatar.position);
|
|
||||||
headStartDeltaPitch = MyAvatar.getHeadDeltaPitch();
|
|
||||||
headStartFinalPitch = MyAvatar.getHeadFinalPitch();
|
|
||||||
headStartRoll = MyAvatar.getHeadFinalRoll();
|
|
||||||
headStartYaw = MyAvatar.getHeadFinalYaw();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Controller.keyReleaseEvent.connect(function(event) {
|
|
||||||
if (event.text == "SPACE") {
|
|
||||||
movingWithHead = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
QLabel#avatarLabel {
|
|
||||||
background-image: url(styles/avatar.svg);
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: left center;
|
|
||||||
}
|
|
||||||
|
|
||||||
QLabel#advancedTuningLabel {
|
|
||||||
background-image: url(styles/wrench.svg);
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: left center;
|
|
||||||
}
|
|
||||||
|
|
||||||
QPushButton#buttonBrowseHead,
|
|
||||||
QPushButton#buttonBrowseBody,
|
|
||||||
QPushButton#buttonBrowseLocation,
|
|
||||||
QPushButton#buttonBrowseScriptsLocation {
|
|
||||||
background-image: url(styles/search.svg);
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: center center;
|
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include <QShortcut>
|
#include <QShortcut>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
|
#include <QWindow>
|
||||||
#include <QtDebug>
|
#include <QtDebug>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QDesktopServices>
|
#include <QDesktopServices>
|
||||||
|
@ -382,6 +383,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
||||||
_runningScriptsWidget->setRunningScripts(getRunningScripts());
|
_runningScriptsWidget->setRunningScripts(getRunningScripts());
|
||||||
connect(_runningScriptsWidget, &RunningScriptsWidget::stopScriptName, this, &Application::stopScript);
|
connect(_runningScriptsWidget, &RunningScriptsWidget::stopScriptName, this, &Application::stopScript);
|
||||||
|
|
||||||
|
connect(this, SIGNAL(aboutToQuit()), this, SLOT(saveScripts()));
|
||||||
|
|
||||||
// check first run...
|
// check first run...
|
||||||
QVariant firstRunValue = _settings->value("firstRun",QVariant(true));
|
QVariant firstRunValue = _settings->value("firstRun",QVariant(true));
|
||||||
if (firstRunValue.isValid() && firstRunValue.toBool()) {
|
if (firstRunValue.isValid() && firstRunValue.toBool()) {
|
||||||
|
@ -393,7 +396,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
||||||
QMutexLocker locker(&_settingsMutex);
|
QMutexLocker locker(&_settingsMutex);
|
||||||
_settings->setValue("firstRun",QVariant(false));
|
_settings->setValue("firstRun",QVariant(false));
|
||||||
} else {
|
} else {
|
||||||
// do this as late as possible so that all required subsystems are inialized
|
// do this as late as possible so that all required subsystems are initialized
|
||||||
loadScripts();
|
loadScripts();
|
||||||
|
|
||||||
QMutexLocker locker(&_settingsMutex);
|
QMutexLocker locker(&_settingsMutex);
|
||||||
|
@ -425,7 +428,6 @@ Application::~Application() {
|
||||||
|
|
||||||
saveSettings();
|
saveSettings();
|
||||||
storeSizeAndPosition();
|
storeSizeAndPosition();
|
||||||
saveScripts();
|
|
||||||
|
|
||||||
int DELAY_TIME = 1000;
|
int DELAY_TIME = 1000;
|
||||||
UserActivityLogger::getInstance().close(DELAY_TIME);
|
UserActivityLogger::getInstance().close(DELAY_TIME);
|
||||||
|
@ -1151,8 +1153,7 @@ void Application::mouseMoveEvent(QMouseEvent* event, unsigned int deviceID) {
|
||||||
showMouse = false;
|
showMouse = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QMouseEvent deviceEvent = getDeviceEvent(event, deviceID);
|
_controllerScriptingInterface.emitMouseMoveEvent(event, deviceID); // send events to any registered scripts
|
||||||
_controllerScriptingInterface.emitMouseMoveEvent(&deviceEvent, deviceID); // send events to any registered scripts
|
|
||||||
|
|
||||||
// if one of our scripts have asked to capture this event, then stop processing it
|
// if one of our scripts have asked to capture this event, then stop processing it
|
||||||
if (_controllerScriptingInterface.isMouseCaptured()) {
|
if (_controllerScriptingInterface.isMouseCaptured()) {
|
||||||
|
@ -1167,13 +1168,12 @@ void Application::mouseMoveEvent(QMouseEvent* event, unsigned int deviceID) {
|
||||||
_seenMouseMove = true;
|
_seenMouseMove = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
_mouseX = deviceEvent.x();
|
_mouseX = event->x();
|
||||||
_mouseY = deviceEvent.y();
|
_mouseY = event->y();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::mousePressEvent(QMouseEvent* event, unsigned int deviceID) {
|
void Application::mousePressEvent(QMouseEvent* event, unsigned int deviceID) {
|
||||||
QMouseEvent deviceEvent = getDeviceEvent(event, deviceID);
|
_controllerScriptingInterface.emitMousePressEvent(event); // send events to any registered scripts
|
||||||
_controllerScriptingInterface.emitMousePressEvent(&deviceEvent); // send events to any registered scripts
|
|
||||||
|
|
||||||
// if one of our scripts have asked to capture this event, then stop processing it
|
// if one of our scripts have asked to capture this event, then stop processing it
|
||||||
if (_controllerScriptingInterface.isMouseCaptured()) {
|
if (_controllerScriptingInterface.isMouseCaptured()) {
|
||||||
|
@ -1183,8 +1183,8 @@ void Application::mousePressEvent(QMouseEvent* event, unsigned int deviceID) {
|
||||||
|
|
||||||
if (activeWindow() == _window) {
|
if (activeWindow() == _window) {
|
||||||
if (event->button() == Qt::LeftButton) {
|
if (event->button() == Qt::LeftButton) {
|
||||||
_mouseX = deviceEvent.x();
|
_mouseX = event->x();
|
||||||
_mouseY = deviceEvent.y();
|
_mouseY = event->y();
|
||||||
_mouseDragStartedX = _mouseX;
|
_mouseDragStartedX = _mouseX;
|
||||||
_mouseDragStartedY = _mouseY;
|
_mouseDragStartedY = _mouseY;
|
||||||
_mousePressed = true;
|
_mousePressed = true;
|
||||||
|
@ -1206,8 +1206,7 @@ void Application::mousePressEvent(QMouseEvent* event, unsigned int deviceID) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::mouseReleaseEvent(QMouseEvent* event, unsigned int deviceID) {
|
void Application::mouseReleaseEvent(QMouseEvent* event, unsigned int deviceID) {
|
||||||
QMouseEvent deviceEvent = getDeviceEvent(event, deviceID);
|
_controllerScriptingInterface.emitMouseReleaseEvent(event); // send events to any registered scripts
|
||||||
_controllerScriptingInterface.emitMouseReleaseEvent(&deviceEvent); // send events to any registered scripts
|
|
||||||
|
|
||||||
// if one of our scripts have asked to capture this event, then stop processing it
|
// if one of our scripts have asked to capture this event, then stop processing it
|
||||||
if (_controllerScriptingInterface.isMouseCaptured()) {
|
if (_controllerScriptingInterface.isMouseCaptured()) {
|
||||||
|
@ -1216,8 +1215,8 @@ void Application::mouseReleaseEvent(QMouseEvent* event, unsigned int deviceID) {
|
||||||
|
|
||||||
if (activeWindow() == _window) {
|
if (activeWindow() == _window) {
|
||||||
if (event->button() == Qt::LeftButton) {
|
if (event->button() == Qt::LeftButton) {
|
||||||
_mouseX = deviceEvent.x();
|
_mouseX = event->x();
|
||||||
_mouseY = deviceEvent.y();
|
_mouseY = event->y();
|
||||||
_mousePressed = false;
|
_mousePressed = false;
|
||||||
checkBandwidthMeterClick();
|
checkBandwidthMeterClick();
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Stats)) {
|
if (Menu::getInstance()->isOptionChecked(MenuOption::Stats)) {
|
||||||
|
@ -1416,7 +1415,7 @@ void Application::checkBandwidthMeterClick() {
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Bandwidth) &&
|
if (Menu::getInstance()->isOptionChecked(MenuOption::Bandwidth) &&
|
||||||
glm::compMax(glm::abs(glm::ivec2(_mouseX - _mouseDragStartedX, _mouseY - _mouseDragStartedY)))
|
glm::compMax(glm::abs(glm::ivec2(_mouseX - _mouseDragStartedX, _mouseY - _mouseDragStartedY)))
|
||||||
<= BANDWIDTH_METER_CLICK_MAX_DRAG_LENGTH
|
<= BANDWIDTH_METER_CLICK_MAX_DRAG_LENGTH
|
||||||
&& _bandwidthMeter.isWithinArea(_mouseX, _mouseY, _glWidget->getDeviceWidth(), _glWidget->getDeviceHeight())) {
|
&& _bandwidthMeter.isWithinArea(_mouseX, _mouseY, _glWidget->width(), _glWidget->height())) {
|
||||||
|
|
||||||
// The bandwidth meter is visible, the click didn't get dragged too far and
|
// The bandwidth meter is visible, the click didn't get dragged too far and
|
||||||
// we actually hit the bandwidth meter
|
// we actually hit the bandwidth meter
|
||||||
|
@ -1734,8 +1733,8 @@ void Application::init() {
|
||||||
_voxelShader.init();
|
_voxelShader.init();
|
||||||
_pointShader.init();
|
_pointShader.init();
|
||||||
|
|
||||||
_mouseX = _glWidget->getDeviceWidth() / 2;
|
_mouseX = _glWidget->width() / 2;
|
||||||
_mouseY = _glWidget->getDeviceHeight() / 2;
|
_mouseY = _glWidget->height() / 2;
|
||||||
QCursor::setPos(_mouseX, _mouseY);
|
QCursor::setPos(_mouseX, _mouseY);
|
||||||
|
|
||||||
// TODO: move _myAvatar out of Application. Move relevant code to MyAvataar or AvatarManager
|
// TODO: move _myAvatar out of Application. Move relevant code to MyAvataar or AvatarManager
|
||||||
|
@ -1890,8 +1889,8 @@ void Application::updateMouseRay() {
|
||||||
// if the mouse pointer isn't visible, act like it's at the center of the screen
|
// if the mouse pointer isn't visible, act like it's at the center of the screen
|
||||||
float x = 0.5f, y = 0.5f;
|
float x = 0.5f, y = 0.5f;
|
||||||
if (!_mouseHidden) {
|
if (!_mouseHidden) {
|
||||||
x = _mouseX / (float)_glWidget->getDeviceWidth();
|
x = _mouseX / (float)_glWidget->width();
|
||||||
y = _mouseY / (float)_glWidget->getDeviceHeight();
|
y = _mouseY / (float)_glWidget->height();
|
||||||
}
|
}
|
||||||
_viewFrustum.computePickRay(x, y, _mouseRayOrigin, _mouseRayDirection);
|
_viewFrustum.computePickRay(x, y, _mouseRayOrigin, _mouseRayDirection);
|
||||||
|
|
||||||
|
@ -2331,14 +2330,6 @@ int Application::sendNackPackets() {
|
||||||
return packetsSent;
|
return packetsSent;
|
||||||
}
|
}
|
||||||
|
|
||||||
QMouseEvent Application::getDeviceEvent(QMouseEvent* event, unsigned int deviceID) {
|
|
||||||
if (deviceID > 0) {
|
|
||||||
return *event;
|
|
||||||
}
|
|
||||||
return QMouseEvent(event->type(), QPointF(_glWidget->getDeviceX(event->x()), _glWidget->getDeviceY(event->y())),
|
|
||||||
event->windowPos(), event->screenPos(), event->button(), event->buttons(), event->modifiers());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Application::queryOctree(NodeType_t serverType, PacketType packetType, NodeToJurisdictionMap& jurisdictions) {
|
void Application::queryOctree(NodeType_t serverType, PacketType packetType, NodeToJurisdictionMap& jurisdictions) {
|
||||||
|
|
||||||
//qDebug() << ">>> inside... queryOctree()... _viewFrustum.getFieldOfView()=" << _viewFrustum.getFieldOfView();
|
//qDebug() << ">>> inside... queryOctree()... _viewFrustum.getFieldOfView()=" << _viewFrustum.getFieldOfView();
|
||||||
|
@ -3040,8 +3031,16 @@ void Application::renderRearViewMirror(const QRect& region, bool billboard) {
|
||||||
_mirrorCamera.update(1.0f/_fps);
|
_mirrorCamera.update(1.0f/_fps);
|
||||||
|
|
||||||
// set the bounds of rear mirror view
|
// set the bounds of rear mirror view
|
||||||
glViewport(region.x(), _glWidget->getDeviceHeight() - region.y() - region.height(), region.width(), region.height());
|
if (billboard) {
|
||||||
glScissor(region.x(), _glWidget->getDeviceHeight() - region.y() - region.height(), region.width(), region.height());
|
glViewport(region.x(), _glWidget->getDeviceHeight() - region.y() - region.height(), region.width(), region.height());
|
||||||
|
glScissor(region.x(), _glWidget->getDeviceHeight() - region.y() - region.height(), region.width(), region.height());
|
||||||
|
} else {
|
||||||
|
// if not rendering the billboard, the region is in device independent coordinates; must convert to device
|
||||||
|
float ratio = QApplication::desktop()->windowHandle()->devicePixelRatio();
|
||||||
|
int x = region.x() * ratio, y = region.y() * ratio, width = region.width() * ratio, height = region.height() * ratio;
|
||||||
|
glViewport(x, _glWidget->getDeviceHeight() - y - height, width, height);
|
||||||
|
glScissor(x, _glWidget->getDeviceHeight() - y - height, width, height);
|
||||||
|
}
|
||||||
bool updateViewFrustum = false;
|
bool updateViewFrustum = false;
|
||||||
updateProjectionMatrix(_mirrorCamera, updateViewFrustum);
|
updateProjectionMatrix(_mirrorCamera, updateViewFrustum);
|
||||||
glEnable(GL_SCISSOR_TEST);
|
glEnable(GL_SCISSOR_TEST);
|
||||||
|
@ -3290,8 +3289,8 @@ void Application::deleteVoxelAt(const VoxelDetail& voxel) {
|
||||||
|
|
||||||
|
|
||||||
void Application::resetSensors() {
|
void Application::resetSensors() {
|
||||||
_mouseX = _glWidget->getDeviceWidth() / 2;
|
_mouseX = _glWidget->width() / 2;
|
||||||
_mouseY = _glWidget->getDeviceHeight() / 2;
|
_mouseY = _glWidget->height() / 2;
|
||||||
|
|
||||||
_faceplus.reset();
|
_faceplus.reset();
|
||||||
_faceshift.reset();
|
_faceshift.reset();
|
||||||
|
@ -3683,18 +3682,26 @@ void Application::clearScriptsBeforeRunning() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::saveScripts() {
|
void Application::saveScripts() {
|
||||||
// saves all current running scripts
|
// Saves all currently running user-loaded scripts
|
||||||
QMutexLocker locker(&_settingsMutex);
|
QMutexLocker locker(&_settingsMutex);
|
||||||
_settings->beginWriteArray("Settings");
|
_settings->beginWriteArray("Settings");
|
||||||
for (int i = 0; i < getRunningScripts().size(); ++i){
|
|
||||||
_settings->setArrayIndex(i);
|
QStringList runningScripts = getRunningScripts();
|
||||||
_settings->setValue("script", getRunningScripts().at(i));
|
int i = 0;
|
||||||
|
for (QStringList::const_iterator it = runningScripts.begin(); it != runningScripts.end(); it += 1) {
|
||||||
|
if (getScriptEngine(*it)->isUserLoaded()) {
|
||||||
|
_settings->setArrayIndex(i);
|
||||||
|
_settings->setValue("script", *it);
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_settings->endArray();
|
_settings->endArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptEngine* Application::loadScript(const QString& scriptName, bool loadScriptFromEditor, bool activateMainWindow) {
|
ScriptEngine* Application::loadScript(const QString& scriptFilename, bool isUserLoaded,
|
||||||
QUrl scriptUrl(scriptName);
|
bool loadScriptFromEditor, bool activateMainWindow) {
|
||||||
|
QUrl scriptUrl(scriptFilename);
|
||||||
const QString& scriptURLString = scriptUrl.toString();
|
const QString& scriptURLString = scriptUrl.toString();
|
||||||
if (_scriptEnginesHash.contains(scriptURLString) && loadScriptFromEditor
|
if (_scriptEnginesHash.contains(scriptURLString) && loadScriptFromEditor
|
||||||
&& !_scriptEnginesHash[scriptURLString]->isFinished()) {
|
&& !_scriptEnginesHash[scriptURLString]->isFinished()) {
|
||||||
|
@ -3703,7 +3710,7 @@ ScriptEngine* Application::loadScript(const QString& scriptName, bool loadScript
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptEngine* scriptEngine;
|
ScriptEngine* scriptEngine;
|
||||||
if (scriptName.isNull()) {
|
if (scriptFilename.isNull()) {
|
||||||
scriptEngine = new ScriptEngine(NO_SCRIPT, "", &_controllerScriptingInterface);
|
scriptEngine = new ScriptEngine(NO_SCRIPT, "", &_controllerScriptingInterface);
|
||||||
} else {
|
} else {
|
||||||
// start the script on a new thread...
|
// start the script on a new thread...
|
||||||
|
@ -3719,6 +3726,7 @@ ScriptEngine* Application::loadScript(const QString& scriptName, bool loadScript
|
||||||
_runningScriptsWidget->setRunningScripts(getRunningScripts());
|
_runningScriptsWidget->setRunningScripts(getRunningScripts());
|
||||||
UserActivityLogger::getInstance().loadedScript(scriptURLString);
|
UserActivityLogger::getInstance().loadedScript(scriptURLString);
|
||||||
}
|
}
|
||||||
|
scriptEngine->setUserLoaded(isUserLoaded);
|
||||||
|
|
||||||
// setup the packet senders and jurisdiction listeners of the script engine's scripting interfaces so
|
// setup the packet senders and jurisdiction listeners of the script engine's scripting interfaces so
|
||||||
// we can use the same ones from the application.
|
// we can use the same ones from the application.
|
||||||
|
@ -3751,7 +3759,7 @@ ScriptEngine* Application::loadScript(const QString& scriptName, bool loadScript
|
||||||
|
|
||||||
connect(scriptEngine, SIGNAL(finished(const QString&)), this, SLOT(scriptFinished(const QString&)));
|
connect(scriptEngine, SIGNAL(finished(const QString&)), this, SLOT(scriptFinished(const QString&)));
|
||||||
|
|
||||||
connect(scriptEngine, SIGNAL(loadScript(const QString&)), this, SLOT(loadScript(const QString&)));
|
connect(scriptEngine, SIGNAL(loadScript(const QString&, bool)), this, SLOT(loadScript(const QString&, bool)));
|
||||||
|
|
||||||
scriptEngine->registerGlobalObject("Overlays", &_overlays);
|
scriptEngine->registerGlobalObject("Overlays", &_overlays);
|
||||||
|
|
||||||
|
@ -3821,7 +3829,7 @@ void Application::stopAllScripts(bool restart) {
|
||||||
// stops all current running scripts
|
// stops all current running scripts
|
||||||
for (QHash<QString, ScriptEngine*>::const_iterator it = _scriptEnginesHash.constBegin();
|
for (QHash<QString, ScriptEngine*>::const_iterator it = _scriptEnginesHash.constBegin();
|
||||||
it != _scriptEnginesHash.constEnd(); it++) {
|
it != _scriptEnginesHash.constEnd(); it++) {
|
||||||
if (restart) {
|
if (restart && it.value()->isUserLoaded()) {
|
||||||
connect(it.value(), SIGNAL(finished(const QString&)), SLOT(loadScript(const QString&)));
|
connect(it.value(), SIGNAL(finished(const QString&)), SLOT(loadScript(const QString&)));
|
||||||
}
|
}
|
||||||
it.value()->stop();
|
it.value()->stop();
|
||||||
|
|
|
@ -150,7 +150,6 @@ public:
|
||||||
void setPreviousScriptLocation(const QString& previousScriptLocation);
|
void setPreviousScriptLocation(const QString& previousScriptLocation);
|
||||||
void storeSizeAndPosition();
|
void storeSizeAndPosition();
|
||||||
void clearScriptsBeforeRunning();
|
void clearScriptsBeforeRunning();
|
||||||
void saveScripts();
|
|
||||||
void initializeGL();
|
void initializeGL();
|
||||||
void paintGL();
|
void paintGL();
|
||||||
void resizeGL(int width, int height);
|
void resizeGL(int width, int height);
|
||||||
|
@ -340,13 +339,15 @@ public slots:
|
||||||
void loadScriptURLDialog();
|
void loadScriptURLDialog();
|
||||||
void toggleLogDialog();
|
void toggleLogDialog();
|
||||||
void initAvatarAndViewFrustum();
|
void initAvatarAndViewFrustum();
|
||||||
ScriptEngine* loadScript(const QString& fileNameString = QString(), bool loadScriptFromEditor = false, bool activateMainWindow = false);
|
ScriptEngine* loadScript(const QString& scriptFilename = QString(), bool isUserLoaded = true,
|
||||||
|
bool loadScriptFromEditor = false, bool activateMainWindow = false);
|
||||||
void scriptFinished(const QString& scriptName);
|
void scriptFinished(const QString& scriptName);
|
||||||
void stopAllScripts(bool restart = false);
|
void stopAllScripts(bool restart = false);
|
||||||
void stopScript(const QString& scriptName);
|
void stopScript(const QString& scriptName);
|
||||||
void reloadAllScripts();
|
void reloadAllScripts();
|
||||||
void loadDefaultScripts();
|
void loadDefaultScripts();
|
||||||
void toggleRunningScriptsWidget();
|
void toggleRunningScriptsWidget();
|
||||||
|
void saveScripts();
|
||||||
|
|
||||||
void uploadHead();
|
void uploadHead();
|
||||||
void uploadSkeleton();
|
void uploadSkeleton();
|
||||||
|
@ -435,8 +436,6 @@ private:
|
||||||
|
|
||||||
int sendNackPackets();
|
int sendNackPackets();
|
||||||
|
|
||||||
QMouseEvent getDeviceEvent(QMouseEvent* event, unsigned int deviceID);
|
|
||||||
|
|
||||||
MainWindow* _window;
|
MainWindow* _window;
|
||||||
GLCanvas* _glWidget; // our GLCanvas has a couple extra features
|
GLCanvas* _glWidget; // our GLCanvas has a couple extra features
|
||||||
|
|
||||||
|
|
|
@ -262,8 +262,8 @@ CameraScriptableObject::CameraScriptableObject(Camera* camera, ViewFrustum* view
|
||||||
}
|
}
|
||||||
|
|
||||||
PickRay CameraScriptableObject::computePickRay(float x, float y) {
|
PickRay CameraScriptableObject::computePickRay(float x, float y) {
|
||||||
float screenWidth = Application::getInstance()->getGLWidget()->getDeviceWidth();
|
float screenWidth = Application::getInstance()->getGLWidget()->width();
|
||||||
float screenHeight = Application::getInstance()->getGLWidget()->getDeviceHeight();
|
float screenHeight = Application::getInstance()->getGLWidget()->height();
|
||||||
PickRay result;
|
PickRay result;
|
||||||
if (OculusManager::isConnected()) {
|
if (OculusManager::isConnected()) {
|
||||||
result.origin = _camera->getPosition();
|
result.origin = _camera->getPosition();
|
||||||
|
|
|
@ -43,14 +43,6 @@ int GLCanvas::getDeviceHeight() const {
|
||||||
return height() * (windowHandle() ? windowHandle()->devicePixelRatio() : 1.0f);
|
return height() * (windowHandle() ? windowHandle()->devicePixelRatio() : 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
int GLCanvas::getDeviceX(int x) const {
|
|
||||||
return x * getDeviceWidth() / width();
|
|
||||||
}
|
|
||||||
|
|
||||||
int GLCanvas::getDeviceY(int y) const {
|
|
||||||
return y * getDeviceHeight() / height();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GLCanvas::initializeGL() {
|
void GLCanvas::initializeGL() {
|
||||||
Application::getInstance()->initializeGL();
|
Application::getInstance()->initializeGL();
|
||||||
setAttribute(Qt::WA_AcceptTouchEvents);
|
setAttribute(Qt::WA_AcceptTouchEvents);
|
||||||
|
|
|
@ -26,9 +26,6 @@ public:
|
||||||
int getDeviceHeight() const;
|
int getDeviceHeight() const;
|
||||||
QSize getDeviceSize() const { return QSize(getDeviceWidth(), getDeviceHeight()); }
|
QSize getDeviceSize() const { return QSize(getDeviceWidth(), getDeviceHeight()); }
|
||||||
|
|
||||||
int getDeviceX(int x) const;
|
|
||||||
int getDeviceY(int y) const;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
QTimer _frameTimer;
|
QTimer _frameTimer;
|
||||||
|
|
|
@ -1105,7 +1105,7 @@ void Menu::showLoginForCurrentDomain() {
|
||||||
|
|
||||||
void Menu::editPreferences() {
|
void Menu::editPreferences() {
|
||||||
if (!_preferencesDialog) {
|
if (!_preferencesDialog) {
|
||||||
_preferencesDialog = new PreferencesDialog(Application::getInstance()->getWindow());
|
_preferencesDialog = new PreferencesDialog();
|
||||||
_preferencesDialog->show();
|
_preferencesDialog->show();
|
||||||
} else {
|
} else {
|
||||||
_preferencesDialog->close();
|
_preferencesDialog->close();
|
||||||
|
@ -1488,7 +1488,9 @@ void Menu::showChat() {
|
||||||
if (_chatWindow->isHidden()) {
|
if (_chatWindow->isHidden()) {
|
||||||
_chatWindow->show();
|
_chatWindow->show();
|
||||||
}
|
}
|
||||||
|
_chatWindow->raise();
|
||||||
_chatWindow->activateWindow();
|
_chatWindow->activateWindow();
|
||||||
|
_chatWindow->setFocus();
|
||||||
} else {
|
} else {
|
||||||
Application::getInstance()->getTrayIcon()->showMessage("Interface", "You need to login to be able to chat with others on this domain.");
|
Application::getInstance()->getTrayIcon()->showMessage("Interface", "You need to login to be able to chat with others on this domain.");
|
||||||
}
|
}
|
||||||
|
@ -1500,6 +1502,9 @@ void Menu::toggleChat() {
|
||||||
if (!_chatAction->isEnabled() && _chatWindow && AccountManager::getInstance().isLoggedIn()) {
|
if (!_chatAction->isEnabled() && _chatWindow && AccountManager::getInstance().isLoggedIn()) {
|
||||||
if (_chatWindow->isHidden()) {
|
if (_chatWindow->isHidden()) {
|
||||||
_chatWindow->show();
|
_chatWindow->show();
|
||||||
|
_chatWindow->raise();
|
||||||
|
_chatWindow->activateWindow();
|
||||||
|
_chatWindow->setFocus();
|
||||||
} else {
|
} else {
|
||||||
_chatWindow->hide();
|
_chatWindow->hide();
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,9 @@
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include <QDesktopWidget>
|
||||||
|
#include <QWindow>
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
#include <glm/gtx/quaternion.hpp>
|
#include <glm/gtx/quaternion.hpp>
|
||||||
#include <glm/gtx/vector_angle.hpp>
|
#include <glm/gtx/vector_angle.hpp>
|
||||||
|
@ -50,7 +53,7 @@ Avatar::Avatar() :
|
||||||
AvatarData(),
|
AvatarData(),
|
||||||
_skeletonModel(this),
|
_skeletonModel(this),
|
||||||
_bodyYawDelta(0.0f),
|
_bodyYawDelta(0.0f),
|
||||||
_lastPosition(0.0f),
|
_lastPosition(_position),
|
||||||
_velocity(0.0f),
|
_velocity(0.0f),
|
||||||
_lastVelocity(0.0f),
|
_lastVelocity(0.0f),
|
||||||
_acceleration(0.0f),
|
_acceleration(0.0f),
|
||||||
|
@ -204,7 +207,9 @@ void Avatar::simulate(float deltaTime) {
|
||||||
_displayNameAlpha = abs(_displayNameAlpha - _displayNameTargetAlpha) < 0.01f ? _displayNameTargetAlpha : _displayNameAlpha;
|
_displayNameAlpha = abs(_displayNameAlpha - _displayNameTargetAlpha) < 0.01f ? _displayNameTargetAlpha : _displayNameAlpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
_position += _velocity * deltaTime;
|
// NOTE: we shouldn't extrapolate an Avatar instance forward in time...
|
||||||
|
// until velocity is in AvatarData update message.
|
||||||
|
//_position += _velocity * deltaTime;
|
||||||
measureMotionDerivatives(deltaTime);
|
measureMotionDerivatives(deltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,20 +228,6 @@ void Avatar::measureMotionDerivatives(float deltaTime) {
|
||||||
_lastOrientation = getOrientation();
|
_lastOrientation = getOrientation();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Avatar::setPosition(const glm::vec3 position, bool overideReferential) {
|
|
||||||
AvatarData::setPosition(position, overideReferential);
|
|
||||||
_lastPosition = position;
|
|
||||||
_velocity = glm::vec3(0.0f);
|
|
||||||
_lastVelocity = glm::vec3(0.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Avatar::slamPosition(const glm::vec3& newPosition) {
|
|
||||||
_position = newPosition;
|
|
||||||
_lastPosition = newPosition;
|
|
||||||
_velocity = glm::vec3(0.0f);
|
|
||||||
_lastVelocity = glm::vec3(0.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Avatar::setMouseRay(const glm::vec3 &origin, const glm::vec3 &direction) {
|
void Avatar::setMouseRay(const glm::vec3 &origin, const glm::vec3 &direction) {
|
||||||
_mouseRayOrigin = origin;
|
_mouseRayOrigin = origin;
|
||||||
_mouseRayDirection = direction;
|
_mouseRayDirection = direction;
|
||||||
|
@ -667,7 +658,8 @@ void Avatar::renderDisplayName() {
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
double textWindowHeight = abs(result1[1] - result0[1]);
|
double textWindowHeight = abs(result1[1] - result0[1]);
|
||||||
float scaleFactor = (textWindowHeight > EPSILON) ? 1.0f / textWindowHeight : 1.0f;
|
float scaleFactor = QApplication::desktop()->windowHandle()->devicePixelRatio() *
|
||||||
|
((textWindowHeight > EPSILON) ? 1.0f / textWindowHeight : 1.0f);
|
||||||
glScalef(scaleFactor, scaleFactor, 1.0);
|
glScalef(scaleFactor, scaleFactor, 1.0);
|
||||||
|
|
||||||
glScalef(1.0f, -1.0f, 1.0f); // TextRenderer::draw paints the text upside down in y axis
|
glScalef(1.0f, -1.0f, 1.0f); // TextRenderer::draw paints the text upside down in y axis
|
||||||
|
|
|
@ -161,9 +161,6 @@ public:
|
||||||
/// \param vector position to be scaled. Will store the result
|
/// \param vector position to be scaled. Will store the result
|
||||||
void scaleVectorRelativeToPosition(glm::vec3 &positionToScale) const;
|
void scaleVectorRelativeToPosition(glm::vec3 &positionToScale) const;
|
||||||
|
|
||||||
void setPosition(const glm::vec3 position, bool overideReferential = false);
|
|
||||||
void slamPosition(const glm::vec3& newPosition);
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void updateCollisionGroups();
|
void updateCollisionGroups();
|
||||||
|
|
||||||
|
|
|
@ -609,6 +609,13 @@ void MyAvatar::setGravity(const glm::vec3& gravity) {
|
||||||
// so it continues to point opposite to the previous gravity setting.
|
// so it continues to point opposite to the previous gravity setting.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MyAvatar::slamPosition(const glm::vec3& newPosition) {
|
||||||
|
AvatarData::setPosition(newPosition);
|
||||||
|
_lastPosition = _position;
|
||||||
|
_velocity = glm::vec3(0.0f);
|
||||||
|
_lastVelocity = glm::vec3(0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
AnimationHandlePointer MyAvatar::addAnimationHandle() {
|
AnimationHandlePointer MyAvatar::addAnimationHandle() {
|
||||||
AnimationHandlePointer handle = _skeletonModel.createAnimationHandle();
|
AnimationHandlePointer handle = _skeletonModel.createAnimationHandle();
|
||||||
_animationHandles.append(handle);
|
_animationHandles.append(handle);
|
||||||
|
@ -797,9 +804,11 @@ void MyAvatar::loadData(QSettings* settings) {
|
||||||
|
|
||||||
getHead()->setBasePitch(loadSetting(settings, "headPitch", 0.0f));
|
getHead()->setBasePitch(loadSetting(settings, "headPitch", 0.0f));
|
||||||
|
|
||||||
_position.x = loadSetting(settings, "position_x", START_LOCATION.x);
|
glm::vec3 newPosition;
|
||||||
_position.y = loadSetting(settings, "position_y", START_LOCATION.y);
|
newPosition.x = loadSetting(settings, "position_x", START_LOCATION.x);
|
||||||
_position.z = loadSetting(settings, "position_z", START_LOCATION.z);
|
newPosition.y = loadSetting(settings, "position_y", START_LOCATION.y);
|
||||||
|
newPosition.z = loadSetting(settings, "position_z", START_LOCATION.z);
|
||||||
|
slamPosition(newPosition);
|
||||||
|
|
||||||
getHead()->setPupilDilation(loadSetting(settings, "pupilDilation", 0.0f));
|
getHead()->setPupilDilation(loadSetting(settings, "pupilDilation", 0.0f));
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,7 @@ public:
|
||||||
void setLeanScale(float scale) { _leanScale = scale; }
|
void setLeanScale(float scale) { _leanScale = scale; }
|
||||||
void setLocalGravity(glm::vec3 gravity);
|
void setLocalGravity(glm::vec3 gravity);
|
||||||
void setShouldRenderLocally(bool shouldRender) { _shouldRender = shouldRender; }
|
void setShouldRenderLocally(bool shouldRender) { _shouldRender = shouldRender; }
|
||||||
|
void slamPosition(const glm::vec3& position);
|
||||||
|
|
||||||
// getters
|
// getters
|
||||||
float getLeanScale() const { return _leanScale; }
|
float getLeanScale() const { return _leanScale; }
|
||||||
|
|
|
@ -209,8 +209,8 @@ void PrioVR::renderCalibrationCountdown() {
|
||||||
}
|
}
|
||||||
static TextRenderer textRenderer(MONO_FONT_FAMILY, 18, QFont::Bold, false, TextRenderer::OUTLINE_EFFECT, 2);
|
static TextRenderer textRenderer(MONO_FONT_FAMILY, 18, QFont::Bold, false, TextRenderer::OUTLINE_EFFECT, 2);
|
||||||
QByteArray text = "Assume T-Pose in " + QByteArray::number(secondsRemaining) + "...";
|
QByteArray text = "Assume T-Pose in " + QByteArray::number(secondsRemaining) + "...";
|
||||||
textRenderer.draw((Application::getInstance()->getGLWidget()->getDeviceWidth() -
|
textRenderer.draw((Application::getInstance()->getGLWidget()->width() -
|
||||||
textRenderer.computeWidth(text.constData())) / 2, Application::getInstance()->getGLWidget()->getDeviceHeight() / 2,
|
textRenderer.computeWidth(text.constData())) / 2, Application::getInstance()->getGLWidget()->height() / 2,
|
||||||
text);
|
text);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -396,10 +396,10 @@ void SixenseManager::emulateMouse(PalmData* palm, int index) {
|
||||||
float yAngle = 0.5f - ((atan2(direction.z, direction.y) + M_PI_2));
|
float yAngle = 0.5f - ((atan2(direction.z, direction.y) + M_PI_2));
|
||||||
|
|
||||||
// Get the pixel range over which the xAngle and yAngle are scaled
|
// Get the pixel range over which the xAngle and yAngle are scaled
|
||||||
float cursorRange = widget->getDeviceWidth() * getCursorPixelRangeMult();
|
float cursorRange = widget->width() * getCursorPixelRangeMult();
|
||||||
|
|
||||||
pos.setX(widget->getDeviceWidth() / 2.0f + cursorRange * xAngle);
|
pos.setX(widget->width() / 2.0f + cursorRange * xAngle);
|
||||||
pos.setY(widget->getDeviceHeight() / 2.0f + cursorRange * yAngle);
|
pos.setY(widget->height() / 2.0f + cursorRange * yAngle);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -205,7 +205,7 @@ bool LocationManager::goToDestination(QString destination) {
|
||||||
MyAvatar::sendKillAvatar();
|
MyAvatar::sendKillAvatar();
|
||||||
|
|
||||||
qDebug("Going To Location: %f, %f, %f...", x, y, z);
|
qDebug("Going To Location: %f, %f, %f...", x, y, z);
|
||||||
myAvatar->setPosition(newAvatarPos);
|
myAvatar->slamPosition(newAvatarPos);
|
||||||
emit myAvatar->transformChanged();
|
emit myAvatar->transformChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -257,7 +257,7 @@ void ControllerScriptingInterface::releaseJoystick(int joystickIndex) {
|
||||||
|
|
||||||
glm::vec2 ControllerScriptingInterface::getViewportDimensions() const {
|
glm::vec2 ControllerScriptingInterface::getViewportDimensions() const {
|
||||||
GLCanvas* widget = Application::getInstance()->getGLWidget();
|
GLCanvas* widget = Application::getInstance()->getGLWidget();
|
||||||
return glm::vec2(widget->getDeviceWidth(), widget->getDeviceHeight());
|
return glm::vec2(widget->width(), widget->height());
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractInputController* ControllerScriptingInterface::createInputController(const QString& deviceName, const QString& tracker) {
|
AbstractInputController* ControllerScriptingInterface::createInputController(const QString& deviceName, const QString& tracker) {
|
||||||
|
|
|
@ -99,14 +99,14 @@ void ApplicationOverlay::renderOverlay(bool renderToTexture) {
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
|
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
gluOrtho2D(0, glWidget->getDeviceWidth(), glWidget->getDeviceHeight(), 0);
|
gluOrtho2D(0, glWidget->width(), glWidget->height(), 0);
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
glDisable(GL_LIGHTING);
|
glDisable(GL_LIGHTING);
|
||||||
|
|
||||||
renderAudioMeter();
|
renderAudioMeter();
|
||||||
|
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::HeadMouse)) {
|
if (Menu::getInstance()->isOptionChecked(MenuOption::HeadMouse)) {
|
||||||
myAvatar->renderHeadMouse(glWidget->getDeviceWidth(), glWidget->getDeviceHeight());
|
myAvatar->renderHeadMouse(glWidget->width(), glWidget->height());
|
||||||
}
|
}
|
||||||
|
|
||||||
renderStatsAndLogs();
|
renderStatsAndLogs();
|
||||||
|
@ -305,8 +305,8 @@ QPoint ApplicationOverlay::getPalmClickLocation(const PalmData *palm) const {
|
||||||
float u = asin(collisionPos.x) / (_textureFov)+0.5f;
|
float u = asin(collisionPos.x) / (_textureFov)+0.5f;
|
||||||
float v = 1.0 - (asin(collisionPos.y) / (_textureFov)+0.5f);
|
float v = 1.0 - (asin(collisionPos.y) / (_textureFov)+0.5f);
|
||||||
|
|
||||||
rv.setX(u * glWidget->getDeviceWidth());
|
rv.setX(u * glWidget->width());
|
||||||
rv.setY(v * glWidget->getDeviceHeight());
|
rv.setY(v * glWidget->height());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//if they did not click on the overlay, just set the coords to INT_MAX
|
//if they did not click on the overlay, just set the coords to INT_MAX
|
||||||
|
@ -323,8 +323,8 @@ QPoint ApplicationOverlay::getPalmClickLocation(const PalmData *palm) const {
|
||||||
ndcSpacePos = glm::vec3(clipSpacePos) / clipSpacePos.w;
|
ndcSpacePos = glm::vec3(clipSpacePos) / clipSpacePos.w;
|
||||||
}
|
}
|
||||||
|
|
||||||
rv.setX(((ndcSpacePos.x + 1.0) / 2.0) * glWidget->getDeviceWidth());
|
rv.setX(((ndcSpacePos.x + 1.0) / 2.0) * glWidget->width());
|
||||||
rv.setY((1.0 - ((ndcSpacePos.y + 1.0) / 2.0)) * glWidget->getDeviceHeight());
|
rv.setY((1.0 - ((ndcSpacePos.y + 1.0) / 2.0)) * glWidget->height());
|
||||||
}
|
}
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
@ -496,11 +496,11 @@ void ApplicationOverlay::displayOverlayTexture3DTV(Camera& whichCamera, float as
|
||||||
//draw the mouse pointer
|
//draw the mouse pointer
|
||||||
glBindTexture(GL_TEXTURE_2D, _crosshairTexture);
|
glBindTexture(GL_TEXTURE_2D, _crosshairTexture);
|
||||||
|
|
||||||
const float reticleSize = 40.0f / application->getGLWidget()->getDeviceWidth() * quadWidth;
|
const float reticleSize = 40.0f / application->getGLWidget()->width() * quadWidth;
|
||||||
x -= reticleSize / 2.0f;
|
x -= reticleSize / 2.0f;
|
||||||
y += reticleSize / 2.0f;
|
y += reticleSize / 2.0f;
|
||||||
const float mouseX = (application->getMouseX() / (float)application->getGLWidget()->getDeviceWidth()) * quadWidth;
|
const float mouseX = (application->getMouseX() / (float)application->getGLWidget()->width()) * quadWidth;
|
||||||
const float mouseY = (1.0 - (application->getMouseY() / (float)application->getGLWidget()->getDeviceHeight())) * quadHeight;
|
const float mouseY = (1.0 - (application->getMouseY() / (float)application->getGLWidget()->height())) * quadHeight;
|
||||||
|
|
||||||
glBegin(GL_QUADS);
|
glBegin(GL_QUADS);
|
||||||
|
|
||||||
|
@ -671,14 +671,14 @@ void ApplicationOverlay::renderControllerPointers() {
|
||||||
float yAngle = 0.5f - ((atan2(direction.z, direction.y) + M_PI_2));
|
float yAngle = 0.5f - ((atan2(direction.z, direction.y) + M_PI_2));
|
||||||
|
|
||||||
// Get the pixel range over which the xAngle and yAngle are scaled
|
// Get the pixel range over which the xAngle and yAngle are scaled
|
||||||
float cursorRange = glWidget->getDeviceWidth() * application->getSixenseManager()->getCursorPixelRangeMult();
|
float cursorRange = glWidget->width() * application->getSixenseManager()->getCursorPixelRangeMult();
|
||||||
|
|
||||||
mouseX = (glWidget->getDeviceWidth() / 2.0f + cursorRange * xAngle);
|
mouseX = (glWidget->width() / 2.0f + cursorRange * xAngle);
|
||||||
mouseY = (glWidget->getDeviceHeight() / 2.0f + cursorRange * yAngle);
|
mouseY = (glWidget->height() / 2.0f + cursorRange * yAngle);
|
||||||
}
|
}
|
||||||
|
|
||||||
//If the cursor is out of the screen then don't render it
|
//If the cursor is out of the screen then don't render it
|
||||||
if (mouseX < 0 || mouseX >= glWidget->getDeviceWidth() || mouseY < 0 || mouseY >= glWidget->getDeviceHeight()) {
|
if (mouseX < 0 || mouseX >= glWidget->width() || mouseY < 0 || mouseY >= glWidget->height()) {
|
||||||
_reticleActive[index] = false;
|
_reticleActive[index] = false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -709,8 +709,8 @@ void ApplicationOverlay::renderPointersOculus(const glm::vec3& eyePos) {
|
||||||
GLCanvas* glWidget = application->getGLWidget();
|
GLCanvas* glWidget = application->getGLWidget();
|
||||||
glm::vec3 cursorVerts[4];
|
glm::vec3 cursorVerts[4];
|
||||||
|
|
||||||
const int widgetWidth = glWidget->getDeviceWidth();
|
const int widgetWidth = glWidget->width();
|
||||||
const int widgetHeight = glWidget->getDeviceHeight();
|
const int widgetHeight = glWidget->height();
|
||||||
|
|
||||||
const float reticleSize = 50.0f;
|
const float reticleSize = 50.0f;
|
||||||
|
|
||||||
|
@ -850,8 +850,8 @@ void ApplicationOverlay::renderMagnifier(int mouseX, int mouseY, float sizeMult,
|
||||||
Application* application = Application::getInstance();
|
Application* application = Application::getInstance();
|
||||||
GLCanvas* glWidget = application->getGLWidget();
|
GLCanvas* glWidget = application->getGLWidget();
|
||||||
|
|
||||||
const int widgetWidth = glWidget->getDeviceWidth();
|
const int widgetWidth = glWidget->width();
|
||||||
const int widgetHeight = glWidget->getDeviceHeight();
|
const int widgetHeight = glWidget->height();
|
||||||
|
|
||||||
const float magnifyWidth = MAGNIFY_WIDTH * sizeMult;
|
const float magnifyWidth = MAGNIFY_WIDTH * sizeMult;
|
||||||
const float magnifyHeight = MAGNIFY_HEIGHT * sizeMult;
|
const float magnifyHeight = MAGNIFY_HEIGHT * sizeMult;
|
||||||
|
@ -968,7 +968,7 @@ void ApplicationOverlay::renderAudioMeter() {
|
||||||
float collisionSoundMagnitude = audio->getCollisionSoundMagnitude();
|
float collisionSoundMagnitude = audio->getCollisionSoundMagnitude();
|
||||||
const float VISIBLE_COLLISION_SOUND_MAGNITUDE = 0.5f;
|
const float VISIBLE_COLLISION_SOUND_MAGNITUDE = 0.5f;
|
||||||
if (collisionSoundMagnitude > VISIBLE_COLLISION_SOUND_MAGNITUDE) {
|
if (collisionSoundMagnitude > VISIBLE_COLLISION_SOUND_MAGNITUDE) {
|
||||||
renderCollisionOverlay(glWidget->getDeviceWidth(), glWidget->getDeviceHeight(),
|
renderCollisionOverlay(glWidget->width(), glWidget->height(),
|
||||||
audio->getCollisionSoundMagnitude());
|
audio->getCollisionSoundMagnitude());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1019,16 +1019,16 @@ void ApplicationOverlay::renderAudioMeter() {
|
||||||
if ((audio->getTimeSinceLastClip() > 0.f) && (audio->getTimeSinceLastClip() < CLIPPING_INDICATOR_TIME)) {
|
if ((audio->getTimeSinceLastClip() > 0.f) && (audio->getTimeSinceLastClip() < CLIPPING_INDICATOR_TIME)) {
|
||||||
const float MAX_MAGNITUDE = 0.7f;
|
const float MAX_MAGNITUDE = 0.7f;
|
||||||
float magnitude = MAX_MAGNITUDE * (1 - audio->getTimeSinceLastClip() / CLIPPING_INDICATOR_TIME);
|
float magnitude = MAX_MAGNITUDE * (1 - audio->getTimeSinceLastClip() / CLIPPING_INDICATOR_TIME);
|
||||||
renderCollisionOverlay(glWidget->getDeviceWidth(), glWidget->getDeviceHeight(), magnitude, 1.0f);
|
renderCollisionOverlay(glWidget->width(), glWidget->height(), magnitude, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
audio->renderToolBox(MIRROR_VIEW_LEFT_PADDING + AUDIO_METER_GAP,
|
audio->renderToolBox(MIRROR_VIEW_LEFT_PADDING + AUDIO_METER_GAP,
|
||||||
audioMeterY,
|
audioMeterY,
|
||||||
Menu::getInstance()->isOptionChecked(MenuOption::Mirror));
|
Menu::getInstance()->isOptionChecked(MenuOption::Mirror));
|
||||||
|
|
||||||
audio->renderScope(glWidget->getDeviceWidth(), glWidget->getDeviceHeight());
|
audio->renderScope(glWidget->width(), glWidget->height());
|
||||||
|
|
||||||
audio->renderStats(WHITE_TEXT, glWidget->getDeviceWidth(), glWidget->getDeviceHeight());
|
audio->renderStats(WHITE_TEXT, glWidget->width(), glWidget->height());
|
||||||
|
|
||||||
glBegin(GL_QUADS);
|
glBegin(GL_QUADS);
|
||||||
if (isClipping) {
|
if (isClipping) {
|
||||||
|
@ -1108,8 +1108,8 @@ void ApplicationOverlay::renderStatsAndLogs() {
|
||||||
application->getPacketsPerSecond(), application->getBytesPerSecond(), voxelPacketsToProcess);
|
application->getPacketsPerSecond(), application->getBytesPerSecond(), voxelPacketsToProcess);
|
||||||
// Bandwidth meter
|
// Bandwidth meter
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Bandwidth)) {
|
if (Menu::getInstance()->isOptionChecked(MenuOption::Bandwidth)) {
|
||||||
Stats::drawBackground(0x33333399, glWidget->getDeviceWidth() - 296, glWidget->getDeviceHeight() - 68, 296, 68);
|
Stats::drawBackground(0x33333399, glWidget->width() - 296, glWidget->height() - 68, 296, 68);
|
||||||
bandwidthMeter->render(glWidget->getDeviceWidth(), glWidget->getDeviceHeight());
|
bandwidthMeter->render(glWidget->width(), glWidget->height());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1122,7 +1122,7 @@ void ApplicationOverlay::renderStatsAndLogs() {
|
||||||
(Menu::getInstance()->isOptionChecked(MenuOption::Stats) &&
|
(Menu::getInstance()->isOptionChecked(MenuOption::Stats) &&
|
||||||
Menu::getInstance()->isOptionChecked(MenuOption::Bandwidth))
|
Menu::getInstance()->isOptionChecked(MenuOption::Bandwidth))
|
||||||
? 80 : 20;
|
? 80 : 20;
|
||||||
drawText(glWidget->getDeviceWidth() - 100, glWidget->getDeviceHeight() - timerBottom,
|
drawText(glWidget->width() - 100, glWidget->height() - timerBottom,
|
||||||
0.30f, 0.0f, 0, frameTimer, WHITE_TEXT);
|
0.30f, 0.0f, 0, frameTimer, WHITE_TEXT);
|
||||||
}
|
}
|
||||||
nodeBoundsDisplay.drawOverlay();
|
nodeBoundsDisplay.drawOverlay();
|
||||||
|
@ -1247,8 +1247,8 @@ void ApplicationOverlay::renderDomainConnectionStatusBorder() {
|
||||||
|
|
||||||
if (nodeList && !nodeList->getDomainHandler().isConnected()) {
|
if (nodeList && !nodeList->getDomainHandler().isConnected()) {
|
||||||
GLCanvas* glWidget = Application::getInstance()->getGLWidget();
|
GLCanvas* glWidget = Application::getInstance()->getGLWidget();
|
||||||
int right = glWidget->getDeviceWidth();
|
int right = glWidget->width();
|
||||||
int bottom = glWidget->getDeviceHeight();
|
int bottom = glWidget->height();
|
||||||
|
|
||||||
glColor3f(CONNECTION_STATUS_BORDER_COLOR[0],
|
glColor3f(CONNECTION_STATUS_BORDER_COLOR[0],
|
||||||
CONNECTION_STATUS_BORDER_COLOR[1],
|
CONNECTION_STATUS_BORDER_COLOR[1],
|
||||||
|
|
|
@ -18,28 +18,27 @@
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
|
#include "ChatMessageArea.h"
|
||||||
#include "FlowLayout.h"
|
#include "FlowLayout.h"
|
||||||
#include "qtimespan.h"
|
#include "qtimespan.h"
|
||||||
#include "ui_chatWindow.h"
|
#include "UIUtil.h"
|
||||||
#include "XmppClient.h"
|
#include "XmppClient.h"
|
||||||
#include "ChatMessageArea.h"
|
|
||||||
|
|
||||||
|
#include "ui_chatWindow.h"
|
||||||
#include "ChatWindow.h"
|
#include "ChatWindow.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const int NUM_MESSAGES_TO_TIME_STAMP = 20;
|
const int NUM_MESSAGES_TO_TIME_STAMP = 20;
|
||||||
|
|
||||||
const float OPACITY_ACTIVE = 1.0f;
|
|
||||||
const float OPACITY_INACTIVE = 0.8f;
|
|
||||||
|
|
||||||
const QRegularExpression regexLinks("((?:(?:ftp)|(?:https?)|(?:hifi))://\\S+)");
|
const QRegularExpression regexLinks("((?:(?:ftp)|(?:https?)|(?:hifi))://\\S+)");
|
||||||
const QRegularExpression regexHifiLinks("([#@]\\S+)");
|
const QRegularExpression regexHifiLinks("([#@]\\S+)");
|
||||||
const QString mentionSoundsPath("/mention-sounds/");
|
const QString mentionSoundsPath("/mention-sounds/");
|
||||||
const QString mentionRegex("@(\\b%1\\b)");
|
const QString mentionRegex("@(\\b%1\\b)");
|
||||||
|
|
||||||
ChatWindow::ChatWindow(QWidget* parent) :
|
ChatWindow::ChatWindow(QWidget* parent) :
|
||||||
FramelessDialog(parent, 0, POSITION_RIGHT),
|
QWidget(parent, Qt::Window | Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint |
|
||||||
|
Qt::WindowCloseButtonHint),
|
||||||
ui(new Ui::ChatWindow),
|
ui(new Ui::ChatWindow),
|
||||||
numMessagesAfterLastTimeStamp(0),
|
numMessagesAfterLastTimeStamp(0),
|
||||||
_mousePressed(false),
|
_mousePressed(false),
|
||||||
|
@ -82,7 +81,6 @@ ChatWindow::ChatWindow(QWidget* parent) :
|
||||||
startTimerForTimeStamps();
|
startTimerForTimeStamps();
|
||||||
} else {
|
} else {
|
||||||
ui->numOnlineLabel->hide();
|
ui->numOnlineLabel->hide();
|
||||||
ui->closeButton->hide();
|
|
||||||
ui->usersArea->hide();
|
ui->usersArea->hide();
|
||||||
ui->messagesScrollArea->hide();
|
ui->messagesScrollArea->hide();
|
||||||
ui->messagePlainTextEdit->hide();
|
ui->messagePlainTextEdit->hide();
|
||||||
|
@ -112,17 +110,25 @@ ChatWindow::~ChatWindow() {
|
||||||
void ChatWindow::keyPressEvent(QKeyEvent* event) {
|
void ChatWindow::keyPressEvent(QKeyEvent* event) {
|
||||||
if (event->key() == Qt::Key_Escape) {
|
if (event->key() == Qt::Key_Escape) {
|
||||||
Application::getInstance()->getWindow()->activateWindow();
|
Application::getInstance()->getWindow()->activateWindow();
|
||||||
|
hide();
|
||||||
} else {
|
} else {
|
||||||
FramelessDialog::keyPressEvent(event);
|
QWidget::keyPressEvent(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatWindow::showEvent(QShowEvent* event) {
|
void ChatWindow::showEvent(QShowEvent* event) {
|
||||||
FramelessDialog::showEvent(event);
|
QWidget::showEvent(event);
|
||||||
|
|
||||||
if (!event->spontaneous()) {
|
if (!event->spontaneous()) {
|
||||||
ui->messagePlainTextEdit->setFocus();
|
ui->messagePlainTextEdit->setFocus();
|
||||||
}
|
}
|
||||||
|
const QRect parentGeometry = parentWidget()->geometry();
|
||||||
|
int titleBarHeight = UIUtil::getWindowTitleBarHeight(this);
|
||||||
|
int menuBarHeight = Menu::getInstance()->geometry().height();
|
||||||
|
int topMargin = titleBarHeight + menuBarHeight;
|
||||||
|
|
||||||
|
setGeometry(parentGeometry.topRight().x() - size().width() + 1, parentGeometry.topRight().y() + topMargin,
|
||||||
|
size().width(), parentWidget()->height() - topMargin);
|
||||||
|
|
||||||
Application::processEvents();
|
Application::processEvents();
|
||||||
|
|
||||||
|
@ -167,7 +173,7 @@ bool ChatWindow::eventFilter(QObject* sender, QEvent* event) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return FramelessDialog::eventFilter(sender, event);
|
return QWidget::eventFilter(sender, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatWindow::addTimeStamp() {
|
void ChatWindow::addTimeStamp() {
|
||||||
|
@ -214,7 +220,6 @@ void ChatWindow::startTimerForTimeStamps() {
|
||||||
void ChatWindow::connected() {
|
void ChatWindow::connected() {
|
||||||
ui->connectingToXMPPLabel->hide();
|
ui->connectingToXMPPLabel->hide();
|
||||||
ui->numOnlineLabel->show();
|
ui->numOnlineLabel->show();
|
||||||
ui->closeButton->show();
|
|
||||||
ui->usersArea->show();
|
ui->usersArea->show();
|
||||||
ui->messagesScrollArea->show();
|
ui->messagesScrollArea->show();
|
||||||
ui->messagePlainTextEdit->show();
|
ui->messagePlainTextEdit->show();
|
||||||
|
@ -393,9 +398,7 @@ void ChatWindow::scrollToBottom() {
|
||||||
|
|
||||||
bool ChatWindow::event(QEvent* event) {
|
bool ChatWindow::event(QEvent* event) {
|
||||||
if (event->type() == QEvent::WindowActivate) {
|
if (event->type() == QEvent::WindowActivate) {
|
||||||
setWindowOpacity(OPACITY_ACTIVE);
|
ui->messagePlainTextEdit->setFocus();
|
||||||
} else if (event->type() == QEvent::WindowDeactivate) {
|
|
||||||
setWindowOpacity(OPACITY_INACTIVE);
|
|
||||||
}
|
}
|
||||||
return FramelessDialog::event(event);
|
return QWidget::event(event);
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@ const int AUTO_SCROLL_THRESHOLD = 20;
|
||||||
class ChatWindow;
|
class ChatWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
class ChatWindow : public FramelessDialog {
|
class ChatWindow : public QWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -52,7 +52,7 @@ JSConsole::JSConsole(QWidget* parent, ScriptEngine* scriptEngine) :
|
||||||
|
|
||||||
|
|
||||||
if (_scriptEngine == NULL) {
|
if (_scriptEngine == NULL) {
|
||||||
_scriptEngine = Application::getInstance()->loadScript();
|
_scriptEngine = Application::getInstance()->loadScript(QString(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(_scriptEngine, SIGNAL(evaluationFinished(QScriptValue, bool)),
|
connect(_scriptEngine, SIGNAL(evaluationFinished(QScriptValue, bool)),
|
||||||
|
|
|
@ -41,8 +41,8 @@ void NodeBounds::draw() {
|
||||||
// itself after the cursor disappears.
|
// itself after the cursor disappears.
|
||||||
Application* application = Application::getInstance();
|
Application* application = Application::getInstance();
|
||||||
GLCanvas* glWidget = application->getGLWidget();
|
GLCanvas* glWidget = application->getGLWidget();
|
||||||
float mouseX = application->getMouseX() / (float)glWidget->getDeviceWidth();
|
float mouseX = application->getMouseX() / (float)glWidget->width();
|
||||||
float mouseY = application->getMouseY() / (float)glWidget->getDeviceHeight();
|
float mouseY = application->getMouseY() / (float)glWidget->height();
|
||||||
glm::vec3 mouseRayOrigin;
|
glm::vec3 mouseRayOrigin;
|
||||||
glm::vec3 mouseRayDirection;
|
glm::vec3 mouseRayDirection;
|
||||||
application->getViewFrustum()->computePickRay(mouseX, mouseY, mouseRayOrigin, mouseRayDirection);
|
application->getViewFrustum()->computePickRay(mouseX, mouseY, mouseRayOrigin, mouseRayDirection);
|
||||||
|
|
|
@ -16,16 +16,15 @@
|
||||||
#include "PreferencesDialog.h"
|
#include "PreferencesDialog.h"
|
||||||
#include "UserActivityLogger.h"
|
#include "UserActivityLogger.h"
|
||||||
|
|
||||||
const int SCROLL_PANEL_BOTTOM_MARGIN = 30;
|
const int PREFERENCES_HEIGHT_PADDING = 20;
|
||||||
const int OK_BUTTON_RIGHT_MARGIN = 30;
|
|
||||||
const int BUTTONS_TOP_MARGIN = 24;
|
|
||||||
|
|
||||||
PreferencesDialog::PreferencesDialog(QWidget* parent, Qt::WindowFlags flags) : FramelessDialog(parent, flags, POSITION_LEFT) {
|
PreferencesDialog::PreferencesDialog() :
|
||||||
|
QDialog(Application::getInstance()->getWindow()) {
|
||||||
|
|
||||||
|
setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
|
||||||
ui.setupUi(this);
|
ui.setupUi(this);
|
||||||
setStyleSheetFile("styles/preferences.qss");
|
|
||||||
loadPreferences();
|
loadPreferences();
|
||||||
connect(ui.closeButton, &QPushButton::clicked, this, &QDialog::close);
|
|
||||||
|
|
||||||
connect(ui.buttonBrowseHead, &QPushButton::clicked, this, &PreferencesDialog::openHeadModelBrowser);
|
connect(ui.buttonBrowseHead, &QPushButton::clicked, this, &PreferencesDialog::openHeadModelBrowser);
|
||||||
connect(ui.buttonBrowseBody, &QPushButton::clicked, this, &PreferencesDialog::openBodyModelBrowser);
|
connect(ui.buttonBrowseBody, &QPushButton::clicked, this, &PreferencesDialog::openBodyModelBrowser);
|
||||||
|
@ -33,6 +32,9 @@ PreferencesDialog::PreferencesDialog(QWidget* parent, Qt::WindowFlags flags) : F
|
||||||
connect(ui.buttonBrowseScriptsLocation, &QPushButton::clicked, this, &PreferencesDialog::openScriptsLocationBrowser);
|
connect(ui.buttonBrowseScriptsLocation, &QPushButton::clicked, this, &PreferencesDialog::openScriptsLocationBrowser);
|
||||||
connect(ui.buttonReloadDefaultScripts, &QPushButton::clicked,
|
connect(ui.buttonReloadDefaultScripts, &QPushButton::clicked,
|
||||||
Application::getInstance(), &Application::loadDefaultScripts);
|
Application::getInstance(), &Application::loadDefaultScripts);
|
||||||
|
// move dialog to left side
|
||||||
|
move(parentWidget()->geometry().topLeft());
|
||||||
|
setFixedHeight(parentWidget()->size().height() - PREFERENCES_HEIGHT_PADDING);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PreferencesDialog::accept() {
|
void PreferencesDialog::accept() {
|
||||||
|
@ -49,78 +51,48 @@ void PreferencesDialog::setSkeletonUrl(QString modelUrl) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PreferencesDialog::openHeadModelBrowser() {
|
void PreferencesDialog::openHeadModelBrowser() {
|
||||||
setWindowFlags(windowFlags() & ~Qt::WindowStaysOnTopHint);
|
|
||||||
show();
|
|
||||||
|
|
||||||
ModelsBrowser modelBrowser(HEAD_MODEL);
|
ModelsBrowser modelBrowser(HEAD_MODEL);
|
||||||
connect(&modelBrowser, &ModelsBrowser::selected, this, &PreferencesDialog::setHeadUrl);
|
connect(&modelBrowser, &ModelsBrowser::selected, this, &PreferencesDialog::setHeadUrl);
|
||||||
modelBrowser.browse();
|
modelBrowser.browse();
|
||||||
|
|
||||||
setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
|
|
||||||
show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PreferencesDialog::openBodyModelBrowser() {
|
void PreferencesDialog::openBodyModelBrowser() {
|
||||||
setWindowFlags(windowFlags() & ~Qt::WindowStaysOnTopHint);
|
|
||||||
show();
|
|
||||||
|
|
||||||
ModelsBrowser modelBrowser(SKELETON_MODEL);
|
ModelsBrowser modelBrowser(SKELETON_MODEL);
|
||||||
connect(&modelBrowser, &ModelsBrowser::selected, this, &PreferencesDialog::setSkeletonUrl);
|
connect(&modelBrowser, &ModelsBrowser::selected, this, &PreferencesDialog::setSkeletonUrl);
|
||||||
modelBrowser.browse();
|
modelBrowser.browse();
|
||||||
|
|
||||||
setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
|
|
||||||
show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PreferencesDialog::openSnapshotLocationBrowser() {
|
void PreferencesDialog::openSnapshotLocationBrowser() {
|
||||||
setWindowFlags(windowFlags() & ~Qt::WindowStaysOnTopHint);
|
|
||||||
show();
|
|
||||||
|
|
||||||
QString dir = QFileDialog::getExistingDirectory(this, tr("Snapshots Location"),
|
QString dir = QFileDialog::getExistingDirectory(this, tr("Snapshots Location"),
|
||||||
QStandardPaths::writableLocation(QStandardPaths::DesktopLocation),
|
QStandardPaths::writableLocation(QStandardPaths::DesktopLocation),
|
||||||
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
|
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
|
||||||
if (!dir.isNull() && !dir.isEmpty()) {
|
if (!dir.isNull() && !dir.isEmpty()) {
|
||||||
ui.snapshotLocationEdit->setText(dir);
|
ui.snapshotLocationEdit->setText(dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
|
|
||||||
show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PreferencesDialog::openScriptsLocationBrowser() {
|
void PreferencesDialog::openScriptsLocationBrowser() {
|
||||||
setWindowFlags(windowFlags() & ~Qt::WindowStaysOnTopHint);
|
|
||||||
show();
|
|
||||||
|
|
||||||
QString dir = QFileDialog::getExistingDirectory(this, tr("Scripts Location"),
|
QString dir = QFileDialog::getExistingDirectory(this, tr("Scripts Location"),
|
||||||
ui.scriptsLocationEdit->text(),
|
ui.scriptsLocationEdit->text(),
|
||||||
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
|
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
|
||||||
if (!dir.isNull() && !dir.isEmpty()) {
|
if (!dir.isNull() && !dir.isEmpty()) {
|
||||||
ui.scriptsLocationEdit->setText(dir);
|
ui.scriptsLocationEdit->setText(dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
|
|
||||||
show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PreferencesDialog::resizeEvent(QResizeEvent *resizeEvent) {
|
void PreferencesDialog::resizeEvent(QResizeEvent *resizeEvent) {
|
||||||
|
|
||||||
// keep buttons panel at the bottom
|
// keep buttons panel at the bottom
|
||||||
ui.buttonsPanel->setGeometry(0, size().height() - ui.buttonsPanel->height(), size().width(), ui.buttonsPanel->height());
|
ui.buttonsPanel->setGeometry(0,
|
||||||
|
size().height() - ui.buttonsPanel->height(),
|
||||||
|
size().width(),
|
||||||
|
ui.buttonsPanel->height());
|
||||||
|
|
||||||
// set width and height of srcollarea to match bottom panel and width
|
// set width and height of srcollarea to match bottom panel and width
|
||||||
ui.scrollArea->setGeometry(ui.scrollArea->geometry().x(), ui.scrollArea->geometry().y(),
|
ui.scrollArea->setGeometry(ui.scrollArea->geometry().x(), ui.scrollArea->geometry().y(),
|
||||||
size().width(),
|
size().width(),
|
||||||
size().height() - ui.buttonsPanel->height() -
|
size().height() - ui.buttonsPanel->height() - ui.scrollArea->geometry().y());
|
||||||
SCROLL_PANEL_BOTTOM_MARGIN - ui.scrollArea->geometry().y());
|
|
||||||
|
|
||||||
// move Save button to left position
|
|
||||||
ui.defaultButton->move(size().width() - OK_BUTTON_RIGHT_MARGIN - ui.defaultButton->size().width(), BUTTONS_TOP_MARGIN);
|
|
||||||
|
|
||||||
// move Save button to left position
|
|
||||||
ui.cancelButton->move(ui.defaultButton->pos().x() - ui.cancelButton->size().width(), BUTTONS_TOP_MARGIN);
|
|
||||||
|
|
||||||
// move close button
|
|
||||||
ui.closeButton->move(size().width() - OK_BUTTON_RIGHT_MARGIN - ui.closeButton->size().width(), ui.closeButton->pos().y());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PreferencesDialog::loadPreferences() {
|
void PreferencesDialog::loadPreferences() {
|
||||||
|
|
|
@ -12,20 +12,20 @@
|
||||||
#ifndef hifi_PreferencesDialog_h
|
#ifndef hifi_PreferencesDialog_h
|
||||||
#define hifi_PreferencesDialog_h
|
#define hifi_PreferencesDialog_h
|
||||||
|
|
||||||
#include "FramelessDialog.h"
|
|
||||||
#include "ui_preferencesDialog.h"
|
#include "ui_preferencesDialog.h"
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
class PreferencesDialog : public FramelessDialog {
|
class PreferencesDialog : public QDialog {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PreferencesDialog(QWidget* parent = 0, Qt::WindowFlags flags = 0);
|
PreferencesDialog();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void resizeEvent(QResizeEvent* resizeEvent);
|
void resizeEvent(QResizeEvent* resizeEvent);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void loadPreferences();
|
void loadPreferences();
|
||||||
void savePreferences();
|
void savePreferences();
|
||||||
|
|
|
@ -69,7 +69,7 @@ void RunningScriptsWidget::updateFileFilter(const QString& filter) {
|
||||||
|
|
||||||
void RunningScriptsWidget::loadScriptFromList(const QModelIndex& index) {
|
void RunningScriptsWidget::loadScriptFromList(const QModelIndex& index) {
|
||||||
QVariant scriptFile = _proxyModel.data(index, ScriptsModel::ScriptPath);
|
QVariant scriptFile = _proxyModel.data(index, ScriptsModel::ScriptPath);
|
||||||
Application::getInstance()->loadScript(scriptFile.toString(), false, false);
|
Application::getInstance()->loadScript(scriptFile.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
void RunningScriptsWidget::loadSelectedScript() {
|
void RunningScriptsWidget::loadSelectedScript() {
|
||||||
|
|
|
@ -93,7 +93,7 @@ bool ScriptEditorWidget::setRunning(bool run) {
|
||||||
|
|
||||||
if (run) {
|
if (run) {
|
||||||
const QString& scriptURLString = QUrl(_currentScript).toString();
|
const QString& scriptURLString = QUrl(_currentScript).toString();
|
||||||
_scriptEngine = Application::getInstance()->loadScript(scriptURLString, true);
|
_scriptEngine = Application::getInstance()->loadScript(scriptURLString, true, true);
|
||||||
connect(_scriptEngine, &ScriptEngine::runningStateChanged, this, &ScriptEditorWidget::runningStateChanged);
|
connect(_scriptEngine, &ScriptEngine::runningStateChanged, this, &ScriptEditorWidget::runningStateChanged);
|
||||||
connect(_scriptEngine, &ScriptEngine::errorMessage, this, &ScriptEditorWidget::onScriptError);
|
connect(_scriptEngine, &ScriptEngine::errorMessage, this, &ScriptEditorWidget::onScriptError);
|
||||||
connect(_scriptEngine, &ScriptEngine::printedMessage, this, &ScriptEditorWidget::onScriptPrint);
|
connect(_scriptEngine, &ScriptEngine::printedMessage, this, &ScriptEditorWidget::onScriptPrint);
|
||||||
|
|
|
@ -57,7 +57,7 @@ Stats::Stats():
|
||||||
_metavoxelReceiveTotal(0)
|
_metavoxelReceiveTotal(0)
|
||||||
{
|
{
|
||||||
GLCanvas* glWidget = Application::getInstance()->getGLWidget();
|
GLCanvas* glWidget = Application::getInstance()->getGLWidget();
|
||||||
resetWidth(glWidget->getDeviceWidth(), 0);
|
resetWidth(glWidget->width(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Stats::toggleExpanded() {
|
void Stats::toggleExpanded() {
|
||||||
|
@ -114,7 +114,7 @@ void Stats::checkClick(int mouseX, int mouseY, int mouseDragStartedX, int mouseD
|
||||||
// top-right stats click
|
// top-right stats click
|
||||||
lines = _expanded ? 11 : 3;
|
lines = _expanded ? 11 : 3;
|
||||||
statsHeight = lines * STATS_PELS_PER_LINE + 10;
|
statsHeight = lines * STATS_PELS_PER_LINE + 10;
|
||||||
statsWidth = glWidget->getDeviceWidth() - statsX;
|
statsWidth = glWidget->width() - statsX;
|
||||||
if (mouseX > statsX && mouseX < statsX + statsWidth && mouseY > statsY && mouseY < statsY + statsHeight) {
|
if (mouseX > statsX && mouseX < statsX + statsWidth && mouseY > statsY && mouseY < statsY + statsHeight) {
|
||||||
toggleExpanded();
|
toggleExpanded();
|
||||||
return;
|
return;
|
||||||
|
@ -123,7 +123,7 @@ void Stats::checkClick(int mouseX, int mouseY, int mouseDragStartedX, int mouseD
|
||||||
|
|
||||||
void Stats::resetWidth(int width, int horizontalOffset) {
|
void Stats::resetWidth(int width, int horizontalOffset) {
|
||||||
GLCanvas* glWidget = Application::getInstance()->getGLWidget();
|
GLCanvas* glWidget = Application::getInstance()->getGLWidget();
|
||||||
int extraSpace = glWidget->getDeviceWidth() - horizontalOffset -2
|
int extraSpace = glWidget->width() - horizontalOffset -2
|
||||||
- STATS_GENERAL_MIN_WIDTH
|
- STATS_GENERAL_MIN_WIDTH
|
||||||
- (Menu::getInstance()->isOptionChecked(MenuOption::TestPing) ? STATS_PING_MIN_WIDTH -1 : 0)
|
- (Menu::getInstance()->isOptionChecked(MenuOption::TestPing) ? STATS_PING_MIN_WIDTH -1 : 0)
|
||||||
- STATS_GEO_MIN_WIDTH
|
- STATS_GEO_MIN_WIDTH
|
||||||
|
@ -147,7 +147,7 @@ void Stats::resetWidth(int width, int horizontalOffset) {
|
||||||
_pingStatsWidth += (int) extraSpace / panels;
|
_pingStatsWidth += (int) extraSpace / panels;
|
||||||
}
|
}
|
||||||
_geoStatsWidth += (int) extraSpace / panels;
|
_geoStatsWidth += (int) extraSpace / panels;
|
||||||
_voxelStatsWidth += glWidget->getDeviceWidth() - (_generalStatsWidth + _pingStatsWidth + _geoStatsWidth + 3);
|
_voxelStatsWidth += glWidget->width() - (_generalStatsWidth + _pingStatsWidth + _geoStatsWidth + 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,7 +210,7 @@ void Stats::display(
|
||||||
std::stringstream voxelStats;
|
std::stringstream voxelStats;
|
||||||
|
|
||||||
if (_lastHorizontalOffset != horizontalOffset) {
|
if (_lastHorizontalOffset != horizontalOffset) {
|
||||||
resetWidth(glWidget->getDeviceWidth(), horizontalOffset);
|
resetWidth(glWidget->width(), horizontalOffset);
|
||||||
_lastHorizontalOffset = horizontalOffset;
|
_lastHorizontalOffset = horizontalOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -410,7 +410,7 @@ void Stats::display(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
drawBackground(backgroundColor, horizontalOffset, 0, glWidget->getDeviceWidth() - horizontalOffset,
|
drawBackground(backgroundColor, horizontalOffset, 0, glWidget->width() - horizontalOffset,
|
||||||
lines * STATS_PELS_PER_LINE + 10);
|
lines * STATS_PELS_PER_LINE + 10);
|
||||||
horizontalOffset += 5;
|
horizontalOffset += 5;
|
||||||
|
|
||||||
|
|
|
@ -9,11 +9,14 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QDesktopWidget>
|
||||||
#include <QFont>
|
#include <QFont>
|
||||||
#include <QPaintEngine>
|
#include <QPaintEngine>
|
||||||
#include <QtDebug>
|
#include <QtDebug>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
|
#include <QWindow>
|
||||||
|
|
||||||
#include "InterfaceConfig.h"
|
#include "InterfaceConfig.h"
|
||||||
#include "TextRenderer.h"
|
#include "TextRenderer.h"
|
||||||
|
@ -25,10 +28,17 @@ Glyph::Glyph(int textureID, const QPoint& location, const QRect& bounds, int wid
|
||||||
_textureID(textureID), _location(location), _bounds(bounds), _width(width) {
|
_textureID(textureID), _location(location), _bounds(bounds), _width(width) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TextRenderer::TextRenderer(const char* family, int pointSize, int weight,
|
TextRenderer::TextRenderer(const char* family, int pointSize, int weight, bool italic,
|
||||||
bool italic, EffectType effectType, int effectThickness, QColor color)
|
EffectType effectType, int effectThickness, QColor color) :
|
||||||
: _font(family, pointSize, weight, italic), _metrics(_font), _effectType(effectType),
|
_font(family, pointSize, weight, italic),
|
||||||
_effectThickness(effectThickness), _x(IMAGE_SIZE), _y(IMAGE_SIZE), _rowHeight(0), _color(color) {
|
_metrics(_font),
|
||||||
|
_effectType(effectType),
|
||||||
|
_effectThickness(effectThickness),
|
||||||
|
_x(IMAGE_SIZE),
|
||||||
|
_y(IMAGE_SIZE),
|
||||||
|
_rowHeight(0),
|
||||||
|
_color(color) {
|
||||||
|
|
||||||
_font.setKerning(false);
|
_font.setKerning(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +83,7 @@ int TextRenderer::draw(int x, int y, const char* str) {
|
||||||
int bottom = y + glyph.bounds().y();
|
int bottom = y + glyph.bounds().y();
|
||||||
int top = y + glyph.bounds().y() + glyph.bounds().height();
|
int top = y + glyph.bounds().y() + glyph.bounds().height();
|
||||||
|
|
||||||
float scale = 1.0 / IMAGE_SIZE;
|
float scale = QApplication::desktop()->windowHandle()->devicePixelRatio() / IMAGE_SIZE;
|
||||||
float ls = glyph.location().x() * scale;
|
float ls = glyph.location().x() * scale;
|
||||||
float rs = (glyph.location().x() + glyph.bounds().width()) * scale;
|
float rs = (glyph.location().x() + glyph.bounds().width()) * scale;
|
||||||
float bt = glyph.location().y() * scale;
|
float bt = glyph.location().y() * scale;
|
||||||
|
@ -119,21 +129,25 @@ const Glyph& TextRenderer::getGlyph(char c) {
|
||||||
}
|
}
|
||||||
// we use 'J' as a representative size for the solid block character
|
// we use 'J' as a representative size for the solid block character
|
||||||
QChar ch = (c == SOLID_BLOCK_CHAR) ? QChar('J') : QChar(c);
|
QChar ch = (c == SOLID_BLOCK_CHAR) ? QChar('J') : QChar(c);
|
||||||
QRect bounds = _metrics.boundingRect(ch);
|
QRect baseBounds = _metrics.boundingRect(ch);
|
||||||
if (bounds.isEmpty()) {
|
if (baseBounds.isEmpty()) {
|
||||||
glyph = Glyph(0, QPoint(), QRect(), _metrics.width(ch));
|
glyph = Glyph(0, QPoint(), QRect(), _metrics.width(ch));
|
||||||
return glyph;
|
return glyph;
|
||||||
}
|
}
|
||||||
// grow the bounds to account for effect, if any
|
// grow the bounds to account for effect, if any
|
||||||
if (_effectType == SHADOW_EFFECT) {
|
if (_effectType == SHADOW_EFFECT) {
|
||||||
bounds.adjust(-_effectThickness, 0, 0, _effectThickness);
|
baseBounds.adjust(-_effectThickness, 0, 0, _effectThickness);
|
||||||
|
|
||||||
} else if (_effectType == OUTLINE_EFFECT) {
|
} else if (_effectType == OUTLINE_EFFECT) {
|
||||||
bounds.adjust(-_effectThickness, -_effectThickness, _effectThickness, _effectThickness);
|
baseBounds.adjust(-_effectThickness, -_effectThickness, _effectThickness, _effectThickness);
|
||||||
}
|
}
|
||||||
|
|
||||||
// grow the bounds to account for antialiasing
|
// grow the bounds to account for antialiasing
|
||||||
bounds.adjust(-1, -1, 1, 1);
|
baseBounds.adjust(-1, -1, 1, 1);
|
||||||
|
|
||||||
|
// adjust bounds for device pixel scaling
|
||||||
|
float ratio = QApplication::desktop()->windowHandle()->devicePixelRatio();
|
||||||
|
QRect bounds(baseBounds.x() * ratio, baseBounds.y() * ratio, baseBounds.width() * ratio, baseBounds.height() * ratio);
|
||||||
|
|
||||||
if (_x + bounds.width() > IMAGE_SIZE) {
|
if (_x + bounds.width() > IMAGE_SIZE) {
|
||||||
// we can't fit it on the current row; move to next
|
// we can't fit it on the current row; move to next
|
||||||
|
@ -162,9 +176,16 @@ const Glyph& TextRenderer::getGlyph(char c) {
|
||||||
} else {
|
} else {
|
||||||
image.fill(0);
|
image.fill(0);
|
||||||
QPainter painter(&image);
|
QPainter painter(&image);
|
||||||
painter.setFont(_font);
|
QFont font = _font;
|
||||||
|
if (ratio == 1.0f) {
|
||||||
|
painter.setFont(_font);
|
||||||
|
} else {
|
||||||
|
QFont enlargedFont = _font;
|
||||||
|
enlargedFont.setPointSize(_font.pointSize() * ratio);
|
||||||
|
painter.setFont(enlargedFont);
|
||||||
|
}
|
||||||
if (_effectType == SHADOW_EFFECT) {
|
if (_effectType == SHADOW_EFFECT) {
|
||||||
for (int i = 0; i < _effectThickness; i++) {
|
for (int i = 0; i < _effectThickness * ratio; i++) {
|
||||||
painter.drawText(-bounds.x() - 1 - i, -bounds.y() + 1 + i, ch);
|
painter.drawText(-bounds.x() - 1 - i, -bounds.y() + 1 + i, ch);
|
||||||
}
|
}
|
||||||
} else if (_effectType == OUTLINE_EFFECT) {
|
} else if (_effectType == OUTLINE_EFFECT) {
|
||||||
|
@ -173,7 +194,7 @@ const Glyph& TextRenderer::getGlyph(char c) {
|
||||||
font.setStyleStrategy(QFont::ForceOutline);
|
font.setStyleStrategy(QFont::ForceOutline);
|
||||||
path.addText(-bounds.x() - 0.5, -bounds.y() + 0.5, font, ch);
|
path.addText(-bounds.x() - 0.5, -bounds.y() + 0.5, font, ch);
|
||||||
QPen pen;
|
QPen pen;
|
||||||
pen.setWidth(_effectThickness);
|
pen.setWidth(_effectThickness * ratio);
|
||||||
pen.setJoinStyle(Qt::RoundJoin);
|
pen.setJoinStyle(Qt::RoundJoin);
|
||||||
pen.setCapStyle(Qt::RoundCap);
|
pen.setCapStyle(Qt::RoundCap);
|
||||||
painter.setPen(pen);
|
painter.setPen(pen);
|
||||||
|
@ -185,7 +206,7 @@ const Glyph& TextRenderer::getGlyph(char c) {
|
||||||
}
|
}
|
||||||
glTexSubImage2D(GL_TEXTURE_2D, 0, _x, _y, bounds.width(), bounds.height(), GL_RGBA, GL_UNSIGNED_BYTE, image.constBits());
|
glTexSubImage2D(GL_TEXTURE_2D, 0, _x, _y, bounds.width(), bounds.height(), GL_RGBA, GL_UNSIGNED_BYTE, image.constBits());
|
||||||
|
|
||||||
glyph = Glyph(_currentTextureID, QPoint(_x, _y), bounds, _metrics.width(ch));
|
glyph = Glyph(_currentTextureID, QPoint(_x / ratio, _y / ratio), baseBounds, _metrics.width(ch));
|
||||||
_x += bounds.width();
|
_x += bounds.width();
|
||||||
_rowHeight = qMax(_rowHeight, bounds.height());
|
_rowHeight = qMax(_rowHeight, bounds.height());
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<ui version="4.0">
|
<ui version="4.0">
|
||||||
<class>ChatWindow</class>
|
<class>ChatWindow</class>
|
||||||
<widget class="QDialog" name="ChatWindow">
|
<widget class="QWidget" name="ChatWindow">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
|
@ -86,45 +86,6 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="closeButton">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>16</width>
|
|
||||||
<height>16</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="focusPolicy">
|
|
||||||
<enum>Qt::NoFocus</enum>
|
|
||||||
</property>
|
|
||||||
<property name="styleSheet">
|
|
||||||
<string notr="true">QPushButton {
|
|
||||||
background-color: rgba( 0, 0, 0, 0% );
|
|
||||||
border: none;
|
|
||||||
image: url(../resources/images/close.svg)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QPushButton:pressed {
|
|
||||||
background-color: rgba( 0, 0, 0, 0% );
|
|
||||||
border: none;
|
|
||||||
image: url(../resources/images/close_down.svg)
|
|
||||||
}</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="flat">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
|
@ -283,7 +244,7 @@ border-color: palette(dark); border-style: solid; border-left-width: 1px; borde
|
||||||
<enum>QAbstractScrollArea::AdjustToContents</enum>
|
<enum>QAbstractScrollArea::AdjustToContents</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="tabChangesFocus">
|
<property name="tabChangesFocus">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="acceptRichText">
|
<property name="acceptRichText">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
|
@ -308,22 +269,5 @@ border-color: palette(dark); border-style: solid; border-left-width: 1px; borde
|
||||||
<tabstop>messagesScrollArea</tabstop>
|
<tabstop>messagesScrollArea</tabstop>
|
||||||
</tabstops>
|
</tabstops>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections>
|
<connections/>
|
||||||
<connection>
|
|
||||||
<sender>closeButton</sender>
|
|
||||||
<signal>clicked()</signal>
|
|
||||||
<receiver>ChatWindow</receiver>
|
|
||||||
<slot>hide()</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>390</x>
|
|
||||||
<y>42</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>550</x>
|
|
||||||
<y>42</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
</connections>
|
|
||||||
</ui>
|
</ui>
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -35,7 +35,8 @@ using namespace std;
|
||||||
|
|
||||||
AvatarData::AvatarData() :
|
AvatarData::AvatarData() :
|
||||||
_sessionUUID(),
|
_sessionUUID(),
|
||||||
_handPosition(0,0,0),
|
_position(0.0f),
|
||||||
|
_handPosition(0.0f),
|
||||||
_referential(NULL),
|
_referential(NULL),
|
||||||
_bodyYaw(-90.f),
|
_bodyYaw(-90.f),
|
||||||
_bodyPitch(0.0f),
|
_bodyPitch(0.0f),
|
||||||
|
@ -326,7 +327,7 @@ int AvatarData::parseDataAtOffset(const QByteArray& packet, int offset) {
|
||||||
}
|
}
|
||||||
return maxAvailableSize;
|
return maxAvailableSize;
|
||||||
}
|
}
|
||||||
_position = position;
|
setPosition(position);
|
||||||
|
|
||||||
// rotation (NOTE: This needs to become a quaternion to save two bytes)
|
// rotation (NOTE: This needs to become a quaternion to save two bytes)
|
||||||
float yaw, pitch, roll;
|
float yaw, pitch, roll;
|
||||||
|
|
|
@ -125,6 +125,12 @@ bool DeleteEntityOperator::postRecursion(OctreeElement* element) {
|
||||||
if ((subTreeContainsSomeEntitiesToDelete(element))) {
|
if ((subTreeContainsSomeEntitiesToDelete(element))) {
|
||||||
element->markWithChangedTime();
|
element->markWithChangedTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// It should always be ok to prune children. Because we are only in this PostRecursion function if
|
||||||
|
// we've already finished processing all of the children of this current element. If any of those
|
||||||
|
// children are the containing element for any entity in our lists of entities to delete, then they
|
||||||
|
// must have already deleted the entity, and they are safe to prune. Since this operation doesn't
|
||||||
|
// ever add any elements we don't have to worry about memory being reused within this recursion pass.
|
||||||
EntityTreeElement* entityTreeElement = static_cast<EntityTreeElement*>(element);
|
EntityTreeElement* entityTreeElement = static_cast<EntityTreeElement*>(element);
|
||||||
entityTreeElement->pruneChildren(); // take this opportunity to prune any empty leaves
|
entityTreeElement->pruneChildren(); // take this opportunity to prune any empty leaves
|
||||||
return keepSearching; // if we haven't yet found it, keep looking
|
return keepSearching; // if we haven't yet found it, keep looking
|
||||||
|
|
|
@ -39,6 +39,9 @@ void EntityTree::eraseAllOctreeElements(bool createNewRoot) {
|
||||||
}
|
}
|
||||||
_entityToElementMap.clear();
|
_entityToElementMap.clear();
|
||||||
Octree::eraseAllOctreeElements(createNewRoot);
|
Octree::eraseAllOctreeElements(createNewRoot);
|
||||||
|
_movingEntities.clear();
|
||||||
|
_changingEntities.clear();
|
||||||
|
_mortalEntities.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EntityTree::handlesEditPacketType(PacketType packetType) const {
|
bool EntityTree::handlesEditPacketType(PacketType packetType) const {
|
||||||
|
@ -859,6 +862,7 @@ void EntityTree::forgetEntitiesDeletedBefore(quint64 sinceTime) {
|
||||||
|
|
||||||
// TODO: consider consolidating processEraseMessageDetails() and processEraseMessage()
|
// TODO: consider consolidating processEraseMessageDetails() and processEraseMessage()
|
||||||
int EntityTree::processEraseMessage(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode) {
|
int EntityTree::processEraseMessage(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode) {
|
||||||
|
lockForWrite();
|
||||||
const unsigned char* packetData = (const unsigned char*)dataByteArray.constData();
|
const unsigned char* packetData = (const unsigned char*)dataByteArray.constData();
|
||||||
const unsigned char* dataAt = packetData;
|
const unsigned char* dataAt = packetData;
|
||||||
size_t packetLength = dataByteArray.size();
|
size_t packetLength = dataByteArray.size();
|
||||||
|
@ -901,10 +905,13 @@ int EntityTree::processEraseMessage(const QByteArray& dataByteArray, const Share
|
||||||
}
|
}
|
||||||
deleteEntities(entityItemIDsToDelete);
|
deleteEntities(entityItemIDsToDelete);
|
||||||
}
|
}
|
||||||
|
unlock();
|
||||||
|
|
||||||
return processedBytes;
|
return processedBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This version skips over the header
|
// This version skips over the header
|
||||||
|
// NOTE: Caller must lock the tree before calling this.
|
||||||
// TODO: consider consolidating processEraseMessageDetails() and processEraseMessage()
|
// TODO: consider consolidating processEraseMessageDetails() and processEraseMessage()
|
||||||
int EntityTree::processEraseMessageDetails(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode) {
|
int EntityTree::processEraseMessageDetails(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode) {
|
||||||
const unsigned char* packetData = (const unsigned char*)dataByteArray.constData();
|
const unsigned char* packetData = (const unsigned char*)dataByteArray.constData();
|
||||||
|
@ -938,7 +945,6 @@ int EntityTree::processEraseMessageDetails(const QByteArray& dataByteArray, cons
|
||||||
}
|
}
|
||||||
deleteEntities(entityItemIDsToDelete);
|
deleteEntities(entityItemIDsToDelete);
|
||||||
}
|
}
|
||||||
|
|
||||||
return processedBytes;
|
return processedBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@ void MovingEntitiesOperator::addEntityToMoveList(EntityItem* entity, const AACub
|
||||||
// check our tree, to determine if this entity is known
|
// check our tree, to determine if this entity is known
|
||||||
EntityToMoveDetails details;
|
EntityToMoveDetails details;
|
||||||
details.oldContainingElement = oldContainingElement;
|
details.oldContainingElement = oldContainingElement;
|
||||||
|
details.oldContainingElementCube = oldContainingElement->getAACube();
|
||||||
details.entity = entity;
|
details.entity = entity;
|
||||||
details.oldFound = false;
|
details.oldFound = false;
|
||||||
details.newFound = false;
|
details.newFound = false;
|
||||||
|
@ -123,8 +124,30 @@ bool MovingEntitiesOperator::postRecursion(OctreeElement* element) {
|
||||||
element->markWithChangedTime();
|
element->markWithChangedTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityTreeElement* entityTreeElement = static_cast<EntityTreeElement*>(element);
|
|
||||||
entityTreeElement->pruneChildren(); // take this opportunity to prune any empty leaves
|
|
||||||
|
// It's not OK to prune if we have the potential of deleting the original containig element.
|
||||||
|
// because if we prune the containing element then new might end up reallocating the same memory later
|
||||||
|
// and that will confuse our logic.
|
||||||
|
//
|
||||||
|
// it's ok to prune if:
|
||||||
|
// 2) this subtree doesn't contain any old elements
|
||||||
|
// 3) this subtree contains an old element, but this element isn't a direct parent of any old containing element
|
||||||
|
|
||||||
|
bool elementSubTreeContainsOldElements = false;
|
||||||
|
bool elementIsDirectParentOfOldElment = false;
|
||||||
|
foreach(const EntityToMoveDetails& details, _entitiesToMove) {
|
||||||
|
if (element->getAACube().contains(details.oldContainingElementCube)) {
|
||||||
|
elementSubTreeContainsOldElements = true;
|
||||||
|
}
|
||||||
|
if (element->isParentOf(details.oldContainingElement)) {
|
||||||
|
elementIsDirectParentOfOldElment = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!elementSubTreeContainsOldElements || !elementIsDirectParentOfOldElment) {
|
||||||
|
EntityTreeElement* entityTreeElement = static_cast<EntityTreeElement*>(element);
|
||||||
|
entityTreeElement->pruneChildren(); // take this opportunity to prune any empty leaves
|
||||||
|
}
|
||||||
|
|
||||||
return keepSearching; // if we haven't yet found it, keep looking
|
return keepSearching; // if we haven't yet found it, keep looking
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ public:
|
||||||
AACube newCube;
|
AACube newCube;
|
||||||
AABox newBox;
|
AABox newBox;
|
||||||
EntityTreeElement* oldContainingElement;
|
EntityTreeElement* oldContainingElement;
|
||||||
|
AACube oldContainingElementCube;
|
||||||
bool oldFound;
|
bool oldFound;
|
||||||
bool newFound;
|
bool newFound;
|
||||||
};
|
};
|
||||||
|
|
|
@ -102,6 +102,7 @@ ScriptEngine::ScriptEngine(const QString& scriptContents, const QString& fileNam
|
||||||
_vec3Library(),
|
_vec3Library(),
|
||||||
_uuidLibrary(),
|
_uuidLibrary(),
|
||||||
_animationCache(this),
|
_animationCache(this),
|
||||||
|
_isUserLoaded(false),
|
||||||
_arrayBufferClass(new ArrayBufferClass(this))
|
_arrayBufferClass(new ArrayBufferClass(this))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -127,6 +128,7 @@ ScriptEngine::ScriptEngine(const QUrl& scriptURL,
|
||||||
_vec3Library(),
|
_vec3Library(),
|
||||||
_uuidLibrary(),
|
_uuidLibrary(),
|
||||||
_animationCache(this),
|
_animationCache(this),
|
||||||
|
_isUserLoaded(false),
|
||||||
_arrayBufferClass(new ArrayBufferClass(this))
|
_arrayBufferClass(new ArrayBufferClass(this))
|
||||||
{
|
{
|
||||||
QString scriptURLString = scriptURL.toString();
|
QString scriptURLString = scriptURL.toString();
|
||||||
|
@ -708,7 +710,7 @@ void ScriptEngine::include(const QString& includeFile) {
|
||||||
|
|
||||||
void ScriptEngine::load(const QString& loadFile) {
|
void ScriptEngine::load(const QString& loadFile) {
|
||||||
QUrl url = resolveInclude(loadFile);
|
QUrl url = resolveInclude(loadFile);
|
||||||
emit loadScript(url.toString());
|
emit loadScript(url.toString(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptEngine::nodeKilled(SharedNodePointer node) {
|
void ScriptEngine::nodeKilled(SharedNodePointer node) {
|
||||||
|
|
|
@ -93,6 +93,9 @@ public:
|
||||||
bool isFinished() const { return _isFinished; }
|
bool isFinished() const { return _isFinished; }
|
||||||
bool isRunning() const { return _isRunning; }
|
bool isRunning() const { return _isRunning; }
|
||||||
|
|
||||||
|
void setUserLoaded(bool isUserLoaded) { _isUserLoaded = isUserLoaded; }
|
||||||
|
bool isUserLoaded() const { return _isUserLoaded; }
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
|
@ -116,7 +119,7 @@ signals:
|
||||||
void errorMessage(const QString& message);
|
void errorMessage(const QString& message);
|
||||||
void runningStateChanged();
|
void runningStateChanged();
|
||||||
void evaluationFinished(QScriptValue result, bool isException);
|
void evaluationFinished(QScriptValue result, bool isException);
|
||||||
void loadScript(const QString& scriptName);
|
void loadScript(const QString& scriptName, bool isUserLoaded);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QString _scriptContents;
|
QString _scriptContents;
|
||||||
|
@ -152,7 +155,8 @@ private:
|
||||||
Vec3 _vec3Library;
|
Vec3 _vec3Library;
|
||||||
ScriptUUID _uuidLibrary;
|
ScriptUUID _uuidLibrary;
|
||||||
AnimationCache _animationCache;
|
AnimationCache _animationCache;
|
||||||
|
bool _isUserLoaded;
|
||||||
|
|
||||||
ArrayBufferClass* _arrayBufferClass;
|
ArrayBufferClass* _arrayBufferClass;
|
||||||
|
|
||||||
QHash<QUuid, quint16> _outgoingScriptAudioSequenceNumbers;
|
QHash<QUuid, quint16> _outgoingScriptAudioSequenceNumbers;
|
||||||
|
|
|
@ -158,7 +158,7 @@ QScriptClass::QueryFlags TypedArray::queryProperty(const QScriptValue& object,
|
||||||
quint32 pos = name.toArrayIndex(&ok);
|
quint32 pos = name.toArrayIndex(&ok);
|
||||||
|
|
||||||
// Check that name is a valid index and arrayBuffer exists
|
// Check that name is a valid index and arrayBuffer exists
|
||||||
if (ok && pos >= 0 && pos < length) {
|
if (ok && pos < length) {
|
||||||
*id = byteOffset + pos * _bytesPerElement; // save pos to avoid recomputation
|
*id = byteOffset + pos * _bytesPerElement; // save pos to avoid recomputation
|
||||||
return HandlesReadAccess | HandlesWriteAccess; // Read/Write access
|
return HandlesReadAccess | HandlesWriteAccess; // Read/Write access
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue