Merge branch 'master' of https://github.com/worklist/hifi into 20638

This commit is contained in:
Thijs Wenker 2015-08-20 21:09:22 +02:00
commit 7f5fc64f6c
48 changed files with 244 additions and 167 deletions

View file

@ -17,4 +17,5 @@ if (UNIX)
target_link_libraries(${TARGET_NAME} ${CMAKE_DL_LIBS}) target_link_libraries(${TARGET_NAME} ${CMAKE_DL_LIBS})
endif (UNIX) endif (UNIX)
include_application_version()
copy_dlls_beside_windows_executable() copy_dlls_beside_windows_executable()

View file

@ -129,6 +129,7 @@ AssignmentClient::AssignmentClient(Assignment::Type requestAssignmentType, QStri
packetReceiver.registerListener(PacketType::CreateAssignment, this, "handleCreateAssignmentPacket"); packetReceiver.registerListener(PacketType::CreateAssignment, this, "handleCreateAssignmentPacket");
packetReceiver.registerListener(PacketType::StopNode, this, "handleStopNodePacket"); packetReceiver.registerListener(PacketType::StopNode, this, "handleStopNodePacket");
} }
void AssignmentClient::stopAssignmentClient() { void AssignmentClient::stopAssignmentClient() {
qDebug() << "Forced stop of assignment-client."; qDebug() << "Forced stop of assignment-client.";
@ -172,7 +173,6 @@ void AssignmentClient::aboutToQuit() {
qInstallMessageHandler(0); qInstallMessageHandler(0);
} }
void AssignmentClient::setUpStatusToMonitor() { void AssignmentClient::setUpStatusToMonitor() {
// send a stats packet every 1 seconds // send a stats packet every 1 seconds
connect(&_statsTimerACM, &QTimer::timeout, this, &AssignmentClient::sendStatusPacketToACM); connect(&_statsTimerACM, &QTimer::timeout, this, &AssignmentClient::sendStatusPacketToACM);
@ -217,7 +217,6 @@ void AssignmentClient::sendAssignmentRequest() {
qDebug() << "Failed to read local assignment server port from shared memory" qDebug() << "Failed to read local assignment server port from shared memory"
<< "- will send assignment request to previous assignment server socket."; << "- will send assignment request to previous assignment server socket.";
} }
} }
nodeList->sendAssignment(_requestAssignment); nodeList->sendAssignment(_requestAssignment);

View file

@ -12,6 +12,7 @@
#include <QCommandLineParser> #include <QCommandLineParser>
#include <QThread> #include <QThread>
#include <ApplicationVersion.h>
#include <LogHandler.h> #include <LogHandler.h>
#include <SharedUtil.h> #include <SharedUtil.h>
#include <HifiConfigVariantMap.h> #include <HifiConfigVariantMap.h>
@ -40,6 +41,7 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) :
setOrganizationName("High Fidelity"); setOrganizationName("High Fidelity");
setOrganizationDomain("highfidelity.io"); setOrganizationDomain("highfidelity.io");
setApplicationName("assignment-client"); setApplicationName("assignment-client");
setApplicationName(BUILD_VERSION);
// use the verbose message handler in Logging // use the verbose message handler in Logging
qInstallMessageHandler(LogHandler::verboseMessageHandler); qInstallMessageHandler(LogHandler::verboseMessageHandler);
@ -93,10 +95,8 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) :
Q_UNREACHABLE(); Q_UNREACHABLE();
} }
const QVariantMap argumentVariantMap = HifiConfigVariantMap::mergeCLParametersWithJSONConfig(arguments()); const QVariantMap argumentVariantMap = HifiConfigVariantMap::mergeCLParametersWithJSONConfig(arguments());
unsigned int numForks = 0; unsigned int numForks = 0;
if (parser.isSet(numChildsOption)) { if (parser.isSet(numChildsOption)) {
numForks = parser.value(numChildsOption).toInt(); numForks = parser.value(numChildsOption).toInt();
@ -139,7 +139,6 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) :
assignmentPool = parser.value(poolOption); assignmentPool = parser.value(poolOption);
} }
QUuid walletUUID; QUuid walletUUID;
if (argumentVariantMap.contains(ASSIGNMENT_WALLET_DESTINATION_ID_OPTION)) { if (argumentVariantMap.contains(ASSIGNMENT_WALLET_DESTINATION_ID_OPTION)) {
walletUUID = argumentVariantMap.value(ASSIGNMENT_WALLET_DESTINATION_ID_OPTION).toString(); walletUUID = argumentVariantMap.value(ASSIGNMENT_WALLET_DESTINATION_ID_OPTION).toString();

View file

@ -203,7 +203,7 @@ void AssignmentClientMonitor::checkSpares() {
void AssignmentClientMonitor::handleChildStatusPacket(QSharedPointer<NLPacket> packet) { void AssignmentClientMonitor::handleChildStatusPacket(QSharedPointer<NLPacket> packet) {
// read out the sender ID // read out the sender ID
QUuid senderID = QUuid::fromRfc4122(packet->read(NUM_BYTES_RFC4122_UUID)); QUuid senderID = QUuid::fromRfc4122(packet->readWithoutCopy(NUM_BYTES_RFC4122_UUID));
auto nodeList = DependencyManager::get<NodeList>(); auto nodeList = DependencyManager::get<NodeList>();

View file

@ -90,7 +90,7 @@ int AudioMixerClientData::parseData(NLPacket& packet) {
// grab the stream identifier for this injected audio // grab the stream identifier for this injected audio
packet.seek(sizeof(quint16)); packet.seek(sizeof(quint16));
QUuid streamIdentifier = QUuid::fromRfc4122(packet.read(NUM_BYTES_RFC4122_UUID)); QUuid streamIdentifier = QUuid::fromRfc4122(packet.readWithoutCopy(NUM_BYTES_RFC4122_UUID));
bool isStereo; bool isStereo;
packet.readPrimitive(&isStereo); packet.readPrimitive(&isStereo);

View file

@ -15,7 +15,7 @@
int AvatarMixerClientData::parseData(NLPacket& packet) { int AvatarMixerClientData::parseData(NLPacket& packet) {
// compute the offset to the data payload // compute the offset to the data payload
return _avatar.parseDataFromBuffer(packet.read(packet.bytesLeftToRead())); return _avatar.parseDataFromBuffer(packet.readWithoutCopy(packet.bytesLeftToRead()));
} }
bool AvatarMixerClientData::checkAndSetHasReceivedFirstPackets() { bool AvatarMixerClientData::checkAndSetHasReceivedFirstPackets() {

View file

@ -1,11 +1,9 @@
// //
// InterfaceVersion.h // ApplicationVersion.h.in
// interface/src // cmake/macros
// //
// Created by Leonardo Murillo on 12/16/13. // Created by Leonardo Murillo on 8/13/15.
// Copyright 2013 High Fidelity, Inc. // Copyright 2015 High Fidelity, Inc.
//
// Declaration of version and build data
// //
// Distributed under the Apache License, Version 2.0. // Distributed under the Apache License, Version 2.0.
// 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

View file

@ -0,0 +1,22 @@
#
# IncludeApplicationVersion.cmake
# cmake/macros
#
# Created by Leonardo Murillo on 07/14/2015.
# Copyright 2015 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
#
macro(INCLUDE_APPLICATION_VERSION)
if (DEFINED ENV{JOB_ID})
set (BUILD_SEQ $ENV{JOB_ID})
elseif (DEFINED ENV{ghprbPullId})
set (BUILD_SEQ "PR: $ENV{ghprbPullId} - Commit: $ENV{ghprbActualCommit}")
else ()
set(BUILD_SEQ "dev")
endif ()
configure_file("${MACRO_DIR}/ApplicationVersion.h.in" "${PROJECT_BINARY_DIR}/includes/ApplicationVersion.h")
include_directories("${PROJECT_BINARY_DIR}/includes")
endmacro(INCLUDE_APPLICATION_VERSION)

View file

@ -31,4 +31,5 @@ include_directories(SYSTEM "${OPENSSL_INCLUDE_DIR}")
# append OpenSSL to our list of libraries to link # append OpenSSL to our list of libraries to link
target_link_libraries(${TARGET_NAME} ${OPENSSL_LIBRARIES}) target_link_libraries(${TARGET_NAME} ${OPENSSL_LIBRARIES})
include_application_version()
copy_dlls_beside_windows_executable() copy_dlls_beside_windows_executable()

View file

@ -9,6 +9,7 @@
<thead> <thead>
<tr> <tr>
<th>Type</th> <th>Type</th>
<th>Version</th>
<th>UUID</th> <th>UUID</th>
<th>Pool</th> <th>Pool</th>
<th>Username</th> <th>Username</th>
@ -24,6 +25,7 @@
<% _.each(nodes, function(node, node_index){ %> <% _.each(nodes, function(node, node_index){ %>
<tr> <tr>
<td><%- node.type %></td> <td><%- node.type %></td>
<td><%- node.version %></td>
<td><a href="stats/?uuid=<%- node.uuid %>"><%- node.uuid %></a></td> <td><a href="stats/?uuid=<%- node.uuid %>"><%- node.uuid %></a></td>
<td><%- node.pool %></td> <td><%- node.pool %></td>
<td><%- node.username %></td> <td><%- node.username %></td>
@ -75,4 +77,4 @@
<!--#include file="footer.html"--> <!--#include file="footer.html"-->
<script src='js/underscore-min.js'></script> <script src='js/underscore-min.js'></script>
<script src='js/tables.js'></script> <script src='js/tables.js'></script>
<!--#include file="page-end.html"--> <!--#include file="page-end.html"-->

View file

@ -24,6 +24,7 @@
#include <QUrlQuery> #include <QUrlQuery>
#include <AccountManager.h> #include <AccountManager.h>
#include <ApplicationVersion.h>
#include <HifiConfigVariantMap.h> #include <HifiConfigVariantMap.h>
#include <HTTPConnection.h> #include <HTTPConnection.h>
#include <JSONBreakableMarshal.h> #include <JSONBreakableMarshal.h>
@ -75,6 +76,7 @@ DomainServer::DomainServer(int argc, char* argv[]) :
setOrganizationName("High Fidelity"); setOrganizationName("High Fidelity");
setOrganizationDomain("highfidelity.io"); setOrganizationDomain("highfidelity.io");
setApplicationName("domain-server"); setApplicationName("domain-server");
setApplicationVersion(BUILD_VERSION);
QSettings::setDefaultFormat(QSettings::IniFormat); QSettings::setDefaultFormat(QSettings::IniFormat);
// make sure we have a fresh AccountManager instance // make sure we have a fresh AccountManager instance
@ -738,6 +740,7 @@ void DomainServer::processConnectRequestPacket(QSharedPointer<NLPacket> packet)
if (isAssignment) { if (isAssignment) {
nodeData->setAssignmentUUID(matchingQueuedAssignment->getUUID()); nodeData->setAssignmentUUID(matchingQueuedAssignment->getUUID());
nodeData->setWalletUUID(pendingAssigneeData->getWalletUUID()); nodeData->setWalletUUID(pendingAssigneeData->getWalletUUID());
nodeData->setNodeVersion(pendingAssigneeData->getNodeVersion());
// always allow assignment clients to create and destroy entities // always allow assignment clients to create and destroy entities
newNode->setCanAdjustLocks(true); newNode->setCanAdjustLocks(true);
@ -1168,7 +1171,8 @@ void DomainServer::processRequestAssignmentPacket(QSharedPointer<NLPacket> packe
// add the information for that deployed assignment to the hash of pending assigned nodes // add the information for that deployed assignment to the hash of pending assigned nodes
PendingAssignedNodeData* pendingNodeData = new PendingAssignedNodeData(assignmentToDeploy->getUUID(), PendingAssignedNodeData* pendingNodeData = new PendingAssignedNodeData(assignmentToDeploy->getUUID(),
requestAssignment.getWalletUUID()); requestAssignment.getWalletUUID(),
requestAssignment.getNodeVersion());
_pendingAssignedNodes.insert(uniqueAssignment.getUUID(), pendingNodeData); _pendingAssignedNodes.insert(uniqueAssignment.getUUID(), pendingNodeData);
} else { } else {
if (requestAssignment.getType() != Assignment::AgentType if (requestAssignment.getType() != Assignment::AgentType
@ -1478,7 +1482,7 @@ const char JSON_KEY_POOL[] = "pool";
const char JSON_KEY_PENDING_CREDITS[] = "pending_credits"; const char JSON_KEY_PENDING_CREDITS[] = "pending_credits";
const char JSON_KEY_WAKE_TIMESTAMP[] = "wake_timestamp"; const char JSON_KEY_WAKE_TIMESTAMP[] = "wake_timestamp";
const char JSON_KEY_USERNAME[] = "username"; const char JSON_KEY_USERNAME[] = "username";
const char JSON_KEY_VERSION[] = "version";
QJsonObject DomainServer::jsonObjectForNode(const SharedNodePointer& node) { QJsonObject DomainServer::jsonObjectForNode(const SharedNodePointer& node) {
QJsonObject nodeJson; QJsonObject nodeJson;
@ -1505,6 +1509,7 @@ QJsonObject DomainServer::jsonObjectForNode(const SharedNodePointer& node) {
// add the node username, if it exists // add the node username, if it exists
nodeJson[JSON_KEY_USERNAME] = nodeData->getUsername(); nodeJson[JSON_KEY_USERNAME] = nodeData->getUsername();
nodeJson[JSON_KEY_VERSION] = nodeData->getNodeVersion();
SharedAssignmentPointer matchingAssignment = _allAssignments.value(nodeData->getAssignmentUUID()); SharedAssignmentPointer matchingAssignment = _allAssignments.value(nodeData->getAssignmentUUID());
if (matchingAssignment) { if (matchingAssignment) {
@ -1527,7 +1532,6 @@ QJsonObject DomainServer::jsonObjectForNode(const SharedNodePointer& node) {
} }
const char ASSIGNMENT_SCRIPT_HOST_LOCATION[] = "resources/web/assignment"; const char ASSIGNMENT_SCRIPT_HOST_LOCATION[] = "resources/web/assignment";
QString pathForAssignmentScript(const QUuid& assignmentUUID) { QString pathForAssignmentScript(const QUuid& assignmentUUID) {
QString newPath(ASSIGNMENT_SCRIPT_HOST_LOCATION); QString newPath(ASSIGNMENT_SCRIPT_HOST_LOCATION);
newPath += "/scripts/"; newPath += "/scripts/";
@ -1537,7 +1541,6 @@ QString pathForAssignmentScript(const QUuid& assignmentUUID) {
} }
const QString URI_OAUTH = "/oauth"; const QString URI_OAUTH = "/oauth";
bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url, bool skipSubHandler) { bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url, bool skipSubHandler) {
const QString JSON_MIME_TYPE = "application/json"; const QString JSON_MIME_TYPE = "application/json";
@ -2024,8 +2027,6 @@ bool DomainServer::isAuthenticatedRequest(HTTPConnection* connection, const QUrl
} }
const QString OAUTH_JSON_ACCESS_TOKEN_KEY = "access_token"; const QString OAUTH_JSON_ACCESS_TOKEN_KEY = "access_token";
QNetworkReply* DomainServer::profileRequestGivenTokenReply(QNetworkReply* tokenReply) { QNetworkReply* DomainServer::profileRequestGivenTokenReply(QNetworkReply* tokenReply) {
// pull the access token from the returned JSON and store it with the matching session UUID // pull the access token from the returned JSON and store it with the matching session UUID
QJsonDocument returnedJSON = QJsonDocument::fromJson(tokenReply->readAll()); QJsonDocument returnedJSON = QJsonDocument::fromJson(tokenReply->readAll());
@ -2042,7 +2043,6 @@ QNetworkReply* DomainServer::profileRequestGivenTokenReply(QNetworkReply* tokenR
} }
const QString DS_SETTINGS_SESSIONS_GROUP = "web-sessions"; const QString DS_SETTINGS_SESSIONS_GROUP = "web-sessions";
Headers DomainServer::setupCookieHeadersFromProfileReply(QNetworkReply* profileReply) { Headers DomainServer::setupCookieHeadersFromProfileReply(QNetworkReply* profileReply) {
Headers cookieHeaders; Headers cookieHeaders;

View file

@ -50,6 +50,10 @@ public:
const NodeSet& getNodeInterestSet() const { return _nodeInterestSet; } const NodeSet& getNodeInterestSet() const { return _nodeInterestSet; }
void setNodeInterestSet(const NodeSet& nodeInterestSet) { _nodeInterestSet = nodeInterestSet; } void setNodeInterestSet(const NodeSet& nodeInterestSet) { _nodeInterestSet = nodeInterestSet; }
void setNodeVersion(const QString& nodeVersion) { _nodeVersion = nodeVersion; }
const QString& getNodeVersion() { return _nodeVersion; }
private: private:
QJsonObject mergeJSONStatsFromNewObject(const QJsonObject& newObject, QJsonObject destinationObject); QJsonObject mergeJSONStatsFromNewObject(const QJsonObject& newObject, QJsonObject destinationObject);
@ -62,6 +66,7 @@ private:
HifiSockAddr _sendingSockAddr; HifiSockAddr _sendingSockAddr;
bool _isAuthenticated; bool _isAuthenticated;
NodeSet _nodeInterestSet; NodeSet _nodeInterestSet;
QString _nodeVersion;
}; };
#endif // hifi_DomainServerNodeData_h #endif // hifi_DomainServerNodeData_h

View file

@ -11,9 +11,10 @@
#include "PendingAssignedNodeData.h" #include "PendingAssignedNodeData.h"
PendingAssignedNodeData::PendingAssignedNodeData(const QUuid& assignmentUUID, const QUuid& walletUUID) : PendingAssignedNodeData::PendingAssignedNodeData(const QUuid& assignmentUUID, const QUuid& walletUUID, const QString& nodeVersion) :
_assignmentUUID(assignmentUUID), _assignmentUUID(assignmentUUID),
_walletUUID(walletUUID) _walletUUID(walletUUID),
_nodeVersion(nodeVersion)
{ {
} }

View file

@ -18,16 +18,20 @@
class PendingAssignedNodeData : public QObject { class PendingAssignedNodeData : public QObject {
Q_OBJECT Q_OBJECT
public: public:
PendingAssignedNodeData(const QUuid& assignmentUUID, const QUuid& walletUUID); PendingAssignedNodeData(const QUuid& assignmentUUID, const QUuid& walletUUID, const QString& nodeVersion);
void setAssignmentUUID(const QUuid& assignmentUUID) { _assignmentUUID = assignmentUUID; } void setAssignmentUUID(const QUuid& assignmentUUID) { _assignmentUUID = assignmentUUID; }
const QUuid& getAssignmentUUID() const { return _assignmentUUID; } const QUuid& getAssignmentUUID() const { return _assignmentUUID; }
void setWalletUUID(const QUuid& walletUUID) { _walletUUID = walletUUID; } void setWalletUUID(const QUuid& walletUUID) { _walletUUID = walletUUID; }
const QUuid& getWalletUUID() const { return _walletUUID; } const QUuid& getWalletUUID() const { return _walletUUID; }
const QString& getNodeVersion() const { return _nodeVersion; }
private: private:
QUuid _assignmentUUID; QUuid _assignmentUUID;
QUuid _walletUUID; QUuid _walletUUID;
QString _nodeVersion;
}; };
#endif // hifi_PendingAssignedNodeData_h #endif // hifi_PendingAssignedNodeData_h

View file

@ -16,6 +16,4 @@ Script.load("notifications.js");
Script.load("users.js"); Script.load("users.js");
Script.load("grab.js"); Script.load("grab.js");
Script.load("directory.js"); Script.load("directory.js");
Script.load("mouseLook.js");
Script.load("hmdControls.js");
Script.load("dialTone.js"); Script.load("dialTone.js");

View file

@ -1043,17 +1043,23 @@ function getPositionToCreateEntity() {
var placementPosition = Vec3.sum(Camera.position, offset); var placementPosition = Vec3.sum(Camera.position, offset);
var cameraPosition = Camera.position; var cameraPosition = Camera.position;
var HALF_TREE_SCALE = 16384;
var cameraOutOfBounds = cameraPosition.x < 0 || cameraPosition.y < 0 || cameraPosition.z < 0; var cameraOutOfBounds = Math.abs(cameraPosition.x) > HALF_TREE_SCALE
var placementOutOfBounds = placementPosition.x < 0 || placementPosition.y < 0 || placementPosition.z < 0; || Math.abs(cameraPosition.y) > HALF_TREE_SCALE
|| Math.abs(cameraPosition.z) > HALF_TREE_SCALE;
var placementOutOfBounds = Math.abs(placementPosition.x) > HALF_TREE_SCALE
|| Math.abs(placementPosition.y) > HALF_TREE_SCALE
|| Math.abs(placementPosition.z) > HALF_TREE_SCALE;
if (cameraOutOfBounds && placementOutOfBounds) { if (cameraOutOfBounds && placementOutOfBounds) {
return null; return null;
} }
placementPosition.x = Math.max(0, placementPosition.x); placementPosition.x = Math.min(HALF_TREE_SCALE, Math.max(-HALF_TREE_SCALE, placementPosition.x));
placementPosition.y = Math.max(0, placementPosition.y); placementPosition.y = Math.min(HALF_TREE_SCALE, Math.max(-HALF_TREE_SCALE, placementPosition.y));
placementPosition.z = Math.max(0, placementPosition.z); placementPosition.z = Math.min(HALF_TREE_SCALE, Math.max(-HALF_TREE_SCALE, placementPosition.z));
return placementPosition; return placementPosition;
} }

View file

@ -14,20 +14,12 @@ endforeach()
find_package(Qt5LinguistTools REQUIRED) find_package(Qt5LinguistTools REQUIRED)
find_package(Qt5LinguistToolsMacros) find_package(Qt5LinguistToolsMacros)
if (DEFINED ENV{JOB_ID})
set(BUILD_SEQ $ENV{JOB_ID})
elseif (DEFINED ENV{ghprbPullId})
set(BUILD_SEQ "PR: $ENV{ghprbPullId} - Commit: $ENV{ghprbActualCommit}")
else ()
set(BUILD_SEQ "dev")
endif ()
if (WIN32) if (WIN32)
add_definitions(-D_USE_MATH_DEFINES) # apparently needed to get M_PI and other defines from cmath/math.h add_definitions(-D_USE_MATH_DEFINES) # apparently needed to get M_PI and other defines from cmath/math.h
add_definitions(-DWINDOWS_LEAN_AND_MEAN) # needed to make sure windows doesn't go to crazy with its defines add_definitions(-DWINDOWS_LEAN_AND_MEAN) # needed to make sure windows doesn't go to crazy with its defines
endif() endif()
configure_file(InterfaceVersion.h.in "${PROJECT_BINARY_DIR}/includes/InterfaceVersion.h") include_application_version()
# grab the implementation and header files from src dirs # grab the implementation and header files from src dirs
file(GLOB_RECURSE INTERFACE_SRCS "src/*.cpp" "src/*.h") file(GLOB_RECURSE INTERFACE_SRCS "src/*.cpp" "src/*.h")
@ -174,7 +166,7 @@ if (RTMIDI_FOUND AND NOT DISABLE_RTMIDI AND APPLE)
endif () endif ()
# include headers for interface and InterfaceConfig. # include headers for interface and InterfaceConfig.
include_directories("${PROJECT_SOURCE_DIR}/src" "${PROJECT_BINARY_DIR}/includes") include_directories("${PROJECT_SOURCE_DIR}/src")
target_link_libraries( target_link_libraries(
${TARGET_NAME} ${TARGET_NAME}

View file

@ -52,6 +52,7 @@
#include <AccountManager.h> #include <AccountManager.h>
#include <AddressManager.h> #include <AddressManager.h>
#include <ApplicationVersion.h>
#include <CursorManager.h> #include <CursorManager.h>
#include <AudioInjector.h> #include <AudioInjector.h>
#include <AutoUpdater.h> #include <AutoUpdater.h>
@ -103,7 +104,6 @@
#include "AudioClient.h" #include "AudioClient.h"
#include "DiscoverabilityManager.h" #include "DiscoverabilityManager.h"
#include "GLCanvas.h" #include "GLCanvas.h"
#include "InterfaceVersion.h"
#include "LODManager.h" #include "LODManager.h"
#include "Menu.h" #include "Menu.h"
#include "ModelPackager.h" #include "ModelPackager.h"
@ -175,8 +175,6 @@ public:
using namespace std; using namespace std;
// Starfield information // Starfield information
static uint8_t THROTTLED_IDLE_TIMER_DELAY = 10;
const qint64 MAXIMUM_CACHE_SIZE = 10 * BYTES_PER_GIGABYTES; // 10GB const qint64 MAXIMUM_CACHE_SIZE = 10 * BYTES_PER_GIGABYTES; // 10GB
static QTimer* locationUpdateTimer = NULL; static QTimer* locationUpdateTimer = NULL;
@ -737,6 +735,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
_keyboardFocusHighlight->setVisible(false); _keyboardFocusHighlight->setVisible(false);
} }
}); });
connect(this, &Application::applicationStateChanged, this, &Application::activeChanged);
} }
void Application::aboutToQuit() { void Application::aboutToQuit() {
@ -2108,8 +2108,11 @@ void Application::idle() {
// Once rendering is off on another thread we should be able to have Application::idle run at start(0) in // Once rendering is off on another thread we should be able to have Application::idle run at start(0) in
// perpetuity and not expect events to get backed up. // perpetuity and not expect events to get backed up.
bool isThrottled = getActiveDisplayPlugin()->isThrottled();
static const int THROTTLED_IDLE_TIMER_DELAY = MSECS_PER_SECOND / 15;
static const int IDLE_TIMER_DELAY_MS = 2; static const int IDLE_TIMER_DELAY_MS = 2;
int desiredInterval = getActiveDisplayPlugin()->isThrottled() ? THROTTLED_IDLE_TIMER_DELAY : IDLE_TIMER_DELAY_MS; int desiredInterval = isThrottled ? THROTTLED_IDLE_TIMER_DELAY : IDLE_TIMER_DELAY_MS;
//qDebug() << "isThrottled:" << isThrottled << "desiredInterval:" << desiredInterval;
if (idleTimer->interval() != desiredInterval) { if (idleTimer->interval() != desiredInterval) {
idleTimer->start(desiredInterval); idleTimer->start(desiredInterval);
@ -4612,6 +4615,24 @@ void Application::checkSkeleton() {
} }
} }
bool Application::isForeground() {
return _isForeground && !getWindow()->isMinimized();
}
void Application::activeChanged(Qt::ApplicationState state) {
switch (state) {
case Qt::ApplicationActive:
_isForeground = true;
break;
case Qt::ApplicationSuspended:
case Qt::ApplicationHidden:
case Qt::ApplicationInactive:
default:
_isForeground = false;
break;
}
}
void Application::showFriendsWindow() { void Application::showFriendsWindow() {
const QString FRIENDS_WINDOW_TITLE = "Add/Remove Friends"; const QString FRIENDS_WINDOW_TITLE = "Add/Remove Friends";
const QString FRIENDS_WINDOW_URL = "https://metaverse.highfidelity.com/user/friends"; const QString FRIENDS_WINDOW_URL = "https://metaverse.highfidelity.com/user/friends";
@ -4725,6 +4746,7 @@ static void addDisplayPluginToMenu(DisplayPluginPointer displayPlugin, bool acti
} }
static QVector<QPair<QString, QString>> _currentDisplayPluginActions; static QVector<QPair<QString, QString>> _currentDisplayPluginActions;
static bool _activatingDisplayPlugin{false};
void Application::updateDisplayMode() { void Application::updateDisplayMode() {
auto menu = Menu::getInstance(); auto menu = Menu::getInstance();
@ -4771,7 +4793,9 @@ void Application::updateDisplayMode() {
if (newDisplayPlugin) { if (newDisplayPlugin) {
_offscreenContext->makeCurrent(); _offscreenContext->makeCurrent();
_activatingDisplayPlugin = true;
newDisplayPlugin->activate(); newDisplayPlugin->activate();
_activatingDisplayPlugin = false;
_offscreenContext->makeCurrent(); _offscreenContext->makeCurrent();
offscreenUi->resize(fromGlm(newDisplayPlugin->getRecommendedUiSize())); offscreenUi->resize(fromGlm(newDisplayPlugin->getRecommendedUiSize()));
_offscreenContext->makeCurrent(); _offscreenContext->makeCurrent();
@ -4779,10 +4803,17 @@ void Application::updateDisplayMode() {
oldDisplayPlugin = _displayPlugin; oldDisplayPlugin = _displayPlugin;
_displayPlugin = newDisplayPlugin; _displayPlugin = newDisplayPlugin;
// If the displayPlugin is a screen based HMD, then it will want the HMDTools displayed
// Direct Mode HMDs (like windows Oculus) will be isHmd() but will have a screen of -1
bool newPluginWantsHMDTools = newDisplayPlugin ?
(newDisplayPlugin->isHmd() && (newDisplayPlugin->getHmdScreen() >= 0)) : false;
bool oldPluginWantedHMDTools = oldDisplayPlugin ?
(oldDisplayPlugin->isHmd() && (oldDisplayPlugin->getHmdScreen() >= 0)) : false;
// Only show the hmd tools after the correct plugin has // Only show the hmd tools after the correct plugin has
// been activated so that it's UI is setup correctly // been activated so that it's UI is setup correctly
if (newDisplayPlugin->isHmd()) { if (newPluginWantsHMDTools) {
showDisplayPluginsTools(); showDisplayPluginsTools();
} }
@ -4791,7 +4822,7 @@ void Application::updateDisplayMode() {
_offscreenContext->makeCurrent(); _offscreenContext->makeCurrent();
// if the old plugin was HMD and the new plugin is not HMD, then hide our hmdtools // if the old plugin was HMD and the new plugin is not HMD, then hide our hmdtools
if (oldDisplayPlugin->isHmd() && !newDisplayPlugin->isHmd()) { if (oldPluginWantedHMDTools && !newPluginWantsHMDTools) {
DependencyManager::get<DialogsManager>()->hmdTools(false); DependencyManager::get<DialogsManager>()->hmdTools(false);
} }
} }
@ -4888,14 +4919,17 @@ void Application::removeMenu(const QString& menuName) {
void Application::addMenuItem(const QString& path, const QString& name, std::function<void(bool)> onClicked, bool checkable, bool checked, const QString& groupName) { void Application::addMenuItem(const QString& path, const QString& name, std::function<void(bool)> onClicked, bool checkable, bool checked, const QString& groupName) {
auto menu = Menu::getInstance(); auto menu = Menu::getInstance();
MenuWrapper* parentItem = menu->getMenu(path); MenuWrapper* parentItem = menu->getMenu(path);
QAction* action = parentItem->addAction(name); QAction* action = menu->addActionToQMenuAndActionHash(parentItem, name);
connect(action, &QAction::triggered, [=] { connect(action, &QAction::triggered, [=] {
onClicked(action->isChecked()); onClicked(action->isChecked());
}); });
action->setCheckable(checkable); action->setCheckable(checkable);
action->setChecked(checked); action->setChecked(checked);
_currentDisplayPluginActions.push_back({ path, name }); if (_activatingDisplayPlugin) {
_currentInputPluginActions.push_back({ path, name }); _currentDisplayPluginActions.push_back({ path, name });
} else {
_currentInputPluginActions.push_back({ path, name });
}
} }
void Application::removeMenuItem(const QString& menuName, const QString& menuItem) { void Application::removeMenuItem(const QString& menuName, const QString& menuItem) {

View file

@ -291,6 +291,7 @@ public:
virtual void unsetFullscreen(const QScreen* avoid) override; virtual void unsetFullscreen(const QScreen* avoid) override;
virtual void showDisplayPluginsTools() override; virtual void showDisplayPluginsTools() override;
virtual QGLWidget* getPrimarySurface() override; virtual QGLWidget* getPrimarySurface() override;
virtual bool isForeground() override;
void setActiveDisplayPlugin(const QString& pluginName); void setActiveDisplayPlugin(const QString& pluginName);
@ -476,6 +477,7 @@ private slots:
void faceTrackerMuteToggled(); void faceTrackerMuteToggled();
void setCursorVisible(bool visible); void setCursorVisible(bool visible);
void activeChanged(Qt::ApplicationState state);
private: private:
void resetCameras(Camera& camera, const glm::uvec2& size); void resetCameras(Camera& camera, const glm::uvec2& size);
@ -688,6 +690,7 @@ private:
SimpleMovingAverage _simsPerSecond{10}; SimpleMovingAverage _simsPerSecond{10};
int _simsPerSecondReport = 0; int _simsPerSecondReport = 0;
quint64 _lastSimsPerSecondUpdate = 0; quint64 _lastSimsPerSecondUpdate = 0;
bool _isForeground = true; // starts out assumed to be in foreground
}; };
#endif // hifi_Application_h #endif // hifi_Application_h

View file

@ -18,8 +18,6 @@
#include "MainWindow.h" #include "MainWindow.h"
const int MSECS_PER_FRAME_WHEN_THROTTLED = 66;
static QGLFormat& getDesiredGLFormat() { static QGLFormat& getDesiredGLFormat() {
// Specify an OpenGL 3.3 format using the Core profile. // Specify an OpenGL 3.3 format using the Core profile.
// That is, no old-school fixed pipeline functionality // That is, no old-school fixed pipeline functionality
@ -35,10 +33,7 @@ static QGLFormat& getDesiredGLFormat() {
return glFormat; return glFormat;
} }
GLCanvas::GLCanvas() : QGLWidget(getDesiredGLFormat()), GLCanvas::GLCanvas() : QGLWidget(getDesiredGLFormat()) {
_throttleRendering(false),
_idleRenderInterval(MSECS_PER_FRAME_WHEN_THROTTLED)
{
#ifdef Q_OS_LINUX #ifdef Q_OS_LINUX
// Cause GLCanvas::eventFilter to be called. // Cause GLCanvas::eventFilter to be called.
// It wouldn't hurt to do this on Mac and PC too; but apparently it's only needed on linux. // It wouldn't hurt to do this on Mac and PC too; but apparently it's only needed on linux.
@ -46,15 +41,6 @@ GLCanvas::GLCanvas() : QGLWidget(getDesiredGLFormat()),
#endif #endif
} }
void GLCanvas::stopFrameTimer() {
_frameTimer.stop();
}
bool GLCanvas::isThrottleRendering() const {
return (_throttleRendering
|| (Application::getInstance()->getWindow()->isMinimized() && Application::getInstance()->isThrottleFPSEnabled()));
}
int GLCanvas::getDeviceWidth() const { int GLCanvas::getDeviceWidth() const {
return width() * (windowHandle() ? (float)windowHandle()->devicePixelRatio() : 1.0f); return width() * (windowHandle() ? (float)windowHandle()->devicePixelRatio() : 1.0f);
} }
@ -66,17 +52,17 @@ int GLCanvas::getDeviceHeight() const {
void GLCanvas::initializeGL() { void GLCanvas::initializeGL() {
setAttribute(Qt::WA_AcceptTouchEvents); setAttribute(Qt::WA_AcceptTouchEvents);
setAcceptDrops(true); setAcceptDrops(true);
connect(Application::getInstance(), SIGNAL(applicationStateChanged(Qt::ApplicationState)), this, SLOT(activeChanged(Qt::ApplicationState)));
connect(&_frameTimer, SIGNAL(timeout()), this, SLOT(throttleRender()));
// Note, we *DO NOT* want Qt to automatically swap buffers for us. This results in the "ringing" bug mentioned in WL#19514 when we're throttling the framerate. // Note, we *DO NOT* want Qt to automatically swap buffers for us. This results in the "ringing" bug mentioned in WL#19514 when we're throttling the framerate.
setAutoBufferSwap(false); setAutoBufferSwap(false);
} }
void GLCanvas::paintGL() { void GLCanvas::paintGL() {
PROFILE_RANGE(__FUNCTION__); PROFILE_RANGE(__FUNCTION__);
if (!_throttleRendering &&
(!Application::getInstance()->getWindow()->isMinimized() || !Application::getInstance()->isThrottleFPSEnabled())) { // FIXME - I'm not sure why this still remains, it appears as if this GLCanvas gets a single paintGL call near
// the beginning of the application starting up. I'm not sure if we really need to call Application::paintGL()
// in this case, since the display plugins eventually handle all the painting
if ((!Application::getInstance()->getWindow()->isMinimized() || !Application::getInstance()->isThrottleFPSEnabled())) {
Application::getInstance()->paintGL(); Application::getInstance()->paintGL();
} }
} }
@ -85,39 +71,6 @@ void GLCanvas::resizeGL(int width, int height) {
Application::getInstance()->resizeGL(); Application::getInstance()->resizeGL();
} }
void GLCanvas::activeChanged(Qt::ApplicationState state) {
switch (state) {
case Qt::ApplicationActive:
// If we're active, stop the frame timer and the throttle.
_frameTimer.stop();
_throttleRendering = false;
break;
case Qt::ApplicationSuspended:
case Qt::ApplicationHidden:
// If we're hidden or are about to suspend, don't render anything.
_throttleRendering = false;
_frameTimer.stop();
break;
default:
// Otherwise, throttle.
if (!_throttleRendering && !Application::getInstance()->isAboutToQuit()
&& Application::getInstance()->isThrottleFPSEnabled()) {
_frameTimer.start(_idleRenderInterval);
_throttleRendering = true;
}
break;
}
}
void GLCanvas::throttleRender() {
_frameTimer.start(_idleRenderInterval);
if (!Application::getInstance()->getWindow()->isMinimized()) {
Application::getInstance()->paintGL();
}
}
int updateTime = 0; int updateTime = 0;
bool GLCanvas::event(QEvent* event) { bool GLCanvas::event(QEvent* event) {
switch (event->type()) { switch (event->type()) {

View file

@ -23,28 +23,18 @@ class GLCanvas : public QGLWidget {
public: public:
GLCanvas(); GLCanvas();
void stopFrameTimer();
bool isThrottleRendering() const;
int getDeviceWidth() const; int getDeviceWidth() const;
int getDeviceHeight() const; int getDeviceHeight() const;
QSize getDeviceSize() const { return QSize(getDeviceWidth(), getDeviceHeight()); } QSize getDeviceSize() const { return QSize(getDeviceWidth(), getDeviceHeight()); }
protected: protected:
QTimer _frameTimer;
bool _throttleRendering;
int _idleRenderInterval;
virtual void initializeGL(); virtual void initializeGL();
virtual void paintGL(); virtual void paintGL();
virtual void resizeGL(int width, int height); virtual void resizeGL(int width, int height);
virtual bool event(QEvent* event); virtual bool event(QEvent* event);
private slots: private slots:
void activeChanged(Qt::ApplicationState state);
void throttleRender();
bool eventFilter(QObject*, QEvent* event); bool eventFilter(QObject*, QEvent* event);
}; };

View file

@ -283,7 +283,7 @@ namespace MenuOption {
const QString TestPing = "Test Ping"; const QString TestPing = "Test Ping";
const QString ThirdPerson = "Third Person"; const QString ThirdPerson = "Third Person";
const QString ThreePointCalibration = "3 Point Calibration"; const QString ThreePointCalibration = "3 Point Calibration";
const QString ThrottleFPSIfNotFocus = "Throttle FPS If Not Focus"; const QString ThrottleFPSIfNotFocus = "Throttle FPS If Not Focus"; // FIXME - this value duplicated in Basic2DWindowOpenGLDisplayPlugin.cpp
const QString ToolWindow = "Tool Window"; const QString ToolWindow = "Tool Window";
const QString TransmitterDrive = "Transmitter Drive"; const QString TransmitterDrive = "Transmitter Drive";
const QString TurnWithHead = "Turn using Head"; const QString TurnWithHead = "Turn using Head";

View file

@ -43,11 +43,13 @@ void renderWorldBox(gpu::Batch& batch) {
auto transform = Transform{}; auto transform = Transform{};
batch.setModelTransform(transform); batch.setModelTransform(transform);
geometryCache->renderLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(TREE_SCALE, 0.0f, 0.0f), red);
geometryCache->renderLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, TREE_SCALE, 0.0f), green); // TODO - consider alternate rendering for negative build-able space in the domain
geometryCache->renderLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, TREE_SCALE), blue); geometryCache->renderLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(HALF_TREE_SCALE, 0.0f, 0.0f), red);
geometryCache->renderLine(batch, glm::vec3(0.0f, 0.0f, TREE_SCALE), glm::vec3(TREE_SCALE, 0.0f, TREE_SCALE), grey); geometryCache->renderLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, HALF_TREE_SCALE, 0.0f), green);
geometryCache->renderLine(batch, glm::vec3(TREE_SCALE, 0.0f, TREE_SCALE), glm::vec3(TREE_SCALE, 0.0f, 0.0f), grey); geometryCache->renderLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, HALF_TREE_SCALE), blue);
geometryCache->renderLine(batch, glm::vec3(0.0f, 0.0f, HALF_TREE_SCALE), glm::vec3(HALF_TREE_SCALE, 0.0f, HALF_TREE_SCALE), grey);
geometryCache->renderLine(batch, glm::vec3(HALF_TREE_SCALE, 0.0f, HALF_TREE_SCALE), glm::vec3(HALF_TREE_SCALE, 0.0f, 0.0f), grey);
// Draw meter markers along the 3 axis to help with measuring things // Draw meter markers along the 3 axis to help with measuring things
const float MARKER_DISTANCE = 1.0f; const float MARKER_DISTANCE = 1.0f;

View file

@ -112,7 +112,7 @@ int InboundAudioStream::parseData(NLPacket& packet) {
// parse the info after the seq number and before the audio data (the stream properties) // parse the info after the seq number and before the audio data (the stream properties)
int prePropertyPosition = packet.pos(); int prePropertyPosition = packet.pos();
int propertyBytes = parseStreamProperties(packet.getType(), packet.read(packet.bytesLeftToRead()), networkSamples); int propertyBytes = parseStreamProperties(packet.getType(), packet.readWithoutCopy(packet.bytesLeftToRead()), networkSamples);
packet.seek(prePropertyPosition + propertyBytes); packet.seek(prePropertyPosition + propertyBytes);
// handle this packet based on its arrival status. // handle this packet based on its arrival status.
@ -131,7 +131,7 @@ int InboundAudioStream::parseData(NLPacket& packet) {
if (packet.getType() == PacketType::SilentAudioFrame) { if (packet.getType() == PacketType::SilentAudioFrame) {
writeDroppableSilentSamples(networkSamples); writeDroppableSilentSamples(networkSamples);
} else { } else {
parseAudioData(packet.getType(), packet.read(packet.bytesLeftToRead()), networkSamples); parseAudioData(packet.getType(), packet.readWithoutCopy(packet.bytesLeftToRead()), networkSamples);
} }
break; break;
} }

View file

@ -53,11 +53,11 @@ void AvatarHashMap::processAvatarDataPacket(QSharedPointer<NLPacket> packet, Sha
// enumerate over all of the avatars in this packet // enumerate over all of the avatars in this packet
// only add them if mixerWeakPointer points to something (meaning that mixer is still around) // only add them if mixerWeakPointer points to something (meaning that mixer is still around)
while (packet->bytesLeftToRead()) { while (packet->bytesLeftToRead()) {
QUuid sessionUUID = QUuid::fromRfc4122(packet->read(NUM_BYTES_RFC4122_UUID)); QUuid sessionUUID = QUuid::fromRfc4122(packet->readWithoutCopy(NUM_BYTES_RFC4122_UUID));
int positionBeforeRead = packet->pos(); int positionBeforeRead = packet->pos();
QByteArray byteArray = packet->read(packet->bytesLeftToRead()); QByteArray byteArray = packet->readWithoutCopy(packet->bytesLeftToRead());
if (sessionUUID != _lastOwnerSessionUUID) { if (sessionUUID != _lastOwnerSessionUUID) {
AvatarSharedPointer avatar = _avatarHash.value(sessionUUID); AvatarSharedPointer avatar = _avatarHash.value(sessionUUID);
@ -114,7 +114,7 @@ void AvatarHashMap::processAvatarIdentityPacket(QSharedPointer<NLPacket> packet,
} }
void AvatarHashMap::processAvatarBillboardPacket(QSharedPointer<NLPacket> packet, SharedNodePointer sendingNode) { void AvatarHashMap::processAvatarBillboardPacket(QSharedPointer<NLPacket> packet, SharedNodePointer sendingNode) {
QUuid sessionUUID = QUuid::fromRfc4122(packet->read(NUM_BYTES_RFC4122_UUID)); QUuid sessionUUID = QUuid::fromRfc4122(packet->readWithoutCopy(NUM_BYTES_RFC4122_UUID));
AvatarSharedPointer avatar = _avatarHash.value(sessionUUID); AvatarSharedPointer avatar = _avatarHash.value(sessionUUID);
if (!avatar) { if (!avatar) {
@ -129,7 +129,7 @@ void AvatarHashMap::processAvatarBillboardPacket(QSharedPointer<NLPacket> packet
void AvatarHashMap::processKillAvatar(QSharedPointer<NLPacket> packet, SharedNodePointer sendingNode) { void AvatarHashMap::processKillAvatar(QSharedPointer<NLPacket> packet, SharedNodePointer sendingNode) {
// read the node id // read the node id
QUuid sessionUUID = QUuid::fromRfc4122(packet->read(NUM_BYTES_RFC4122_UUID)); QUuid sessionUUID = QUuid::fromRfc4122(packet->readWithoutCopy(NUM_BYTES_RFC4122_UUID));
removeAvatar(sessionUUID); removeAvatar(sessionUUID);
} }

View file

@ -9,12 +9,11 @@
#include <plugins/PluginContainer.h> #include <plugins/PluginContainer.h>
#include <QWindow> #include <QWindow>
#include <QGuiApplication>
const QString Basic2DWindowOpenGLDisplayPlugin::NAME("2D Display"); const QString Basic2DWindowOpenGLDisplayPlugin::NAME("2D Display");
const QString MENU_PARENT = "View"; const QString MENU_PATH = "Display";
const QString MENU_NAME = "Display Options";
const QString MENU_PATH = MENU_PARENT + ">" + MENU_NAME;
const QString FULLSCREEN = "Fullscreen"; const QString FULLSCREEN = "Fullscreen";
const QString& Basic2DWindowOpenGLDisplayPlugin::getName() const { const QString& Basic2DWindowOpenGLDisplayPlugin::getName() const {
@ -22,15 +21,44 @@ const QString& Basic2DWindowOpenGLDisplayPlugin::getName() const {
} }
void Basic2DWindowOpenGLDisplayPlugin::activate() { void Basic2DWindowOpenGLDisplayPlugin::activate() {
// container->addMenu(MENU_PATH); CONTAINER->addMenu(MENU_PATH);
// container->addMenuItem(MENU_PATH, FULLSCREEN, CONTAINER->addMenuItem(MENU_PATH, FULLSCREEN,
// [this] (bool clicked) { this->setFullscreen(clicked); }, [this](bool clicked) {
// true, false); if (clicked) {
CONTAINER->setFullscreen(getFullscreenTarget());
} else {
CONTAINER->unsetFullscreen();
}
}, true, false);
MainWindowOpenGLDisplayPlugin::activate(); MainWindowOpenGLDisplayPlugin::activate();
} }
void Basic2DWindowOpenGLDisplayPlugin::deactivate() { void Basic2DWindowOpenGLDisplayPlugin::deactivate() {
// container->removeMenuItem(MENU_NAME, FULLSCREEN);
// container->removeMenu(MENU_PATH);
MainWindowOpenGLDisplayPlugin::deactivate(); MainWindowOpenGLDisplayPlugin::deactivate();
} }
int Basic2DWindowOpenGLDisplayPlugin::getDesiredInterval(bool isThrottled) const {
static const int THROTTLED_PAINT_TIMER_DELAY = MSECS_PER_SECOND / 15;
static const int PAINT_TIMER_DELAY_MS = 1;
return isThrottled ? THROTTLED_PAINT_TIMER_DELAY : PAINT_TIMER_DELAY_MS;
}
bool Basic2DWindowOpenGLDisplayPlugin::isThrottled() const {
static const QString ThrottleFPSIfNotFocus = "Throttle FPS If Not Focus"; // FIXME - this value duplicated in Menu.h
bool shouldThrottle = (!CONTAINER->isForeground() && CONTAINER->isOptionChecked(ThrottleFPSIfNotFocus));
if (_isThrottled != shouldThrottle) {
int desiredInterval = getDesiredInterval(shouldThrottle);
_timer.start(desiredInterval);
_isThrottled = shouldThrottle;
}
return shouldThrottle;
}
// FIXME target the screen the window is currently on
QScreen* Basic2DWindowOpenGLDisplayPlugin::getFullscreenTarget() {
return qApp->primaryScreen();
}

View file

@ -9,6 +9,7 @@
#include "MainWindowOpenGLDisplayPlugin.h" #include "MainWindowOpenGLDisplayPlugin.h"
class QScreen;
class Basic2DWindowOpenGLDisplayPlugin : public MainWindowOpenGLDisplayPlugin { class Basic2DWindowOpenGLDisplayPlugin : public MainWindowOpenGLDisplayPlugin {
Q_OBJECT Q_OBJECT
@ -18,6 +19,14 @@ public:
virtual const QString & getName() const override; virtual const QString & getName() const override;
virtual bool isThrottled() const override;
protected:
int getDesiredInterval(bool isThrottled) const;
mutable bool _isThrottled = false;
private: private:
static const QString NAME; static const QString NAME;
QScreen* getFullscreenTarget();
int _fullscreenTarget{ -1 };
}; };

View file

@ -37,8 +37,8 @@ protected:
virtual void doneCurrent() = 0; virtual void doneCurrent() = 0;
virtual void swapBuffers() = 0; virtual void swapBuffers() = 0;
QTimer _timer; mutable QTimer _timer;
ProgramPtr _program; ProgramPtr _program;
ShapeWrapperPtr _plane; ShapeWrapperPtr _plane;
}; };

View file

@ -25,7 +25,8 @@ AddEntityOperator::AddEntityOperator(EntityTree* tree,
{ {
// caller must have verified existence of newEntity // caller must have verified existence of newEntity
assert(_newEntity); assert(_newEntity);
_newEntityBox = _newEntity->getMaximumAACube().clamp(0.0f, (float)TREE_SCALE);
_newEntityBox = _newEntity->getMaximumAACube().clamp((float)(-HALF_TREE_SCALE), (float)HALF_TREE_SCALE);
} }
bool AddEntityOperator::preRecursion(OctreeElement* element) { bool AddEntityOperator::preRecursion(OctreeElement* element) {

View file

@ -253,7 +253,7 @@ void EntityItemPropertiesFromScriptValueHonorReadOnly(const QScriptValue &object
// define these inline here so the macros work // define these inline here so the macros work
inline void EntityItemProperties::setPosition(const glm::vec3& value) inline void EntityItemProperties::setPosition(const glm::vec3& value)
{ _position = glm::clamp(value, 0.0f, (float)TREE_SCALE); _positionChanged = true; } { _position = glm::clamp(value, (float)-HALF_TREE_SCALE, (float)HALF_TREE_SCALE); _positionChanged = true; }
inline QDebug operator<<(QDebug debug, const EntityItemProperties& properties) { inline QDebug operator<<(QDebug debug, const EntityItemProperties& properties) {
debug << "EntityItemProperties[" << "\n"; debug << "EntityItemProperties[" << "\n";

View file

@ -113,7 +113,7 @@ void EntitySimulation::sortEntitiesThatMoved() {
// External changes to entity position/shape are expected to be sorted outside of the EntitySimulation. // External changes to entity position/shape are expected to be sorted outside of the EntitySimulation.
PerformanceTimer perfTimer("sortingEntities"); PerformanceTimer perfTimer("sortingEntities");
MovingEntitiesOperator moveOperator(_entityTree); MovingEntitiesOperator moveOperator(_entityTree);
AACube domainBounds(glm::vec3(0.0f,0.0f,0.0f), (float)TREE_SCALE); AACube domainBounds(glm::vec3((float)-HALF_TREE_SCALE), (float)TREE_SCALE);
SetOfEntities::iterator itemItr = _entitiesToSort.begin(); SetOfEntities::iterator itemItr = _entitiesToSort.begin();
while (itemItr != _entitiesToSort.end()) { while (itemItr != _entitiesToSort.end()) {
EntityItemPointer entity = *itemItr; EntityItemPointer entity = *itemItr;
@ -195,7 +195,7 @@ void EntitySimulation::changeEntity(EntityItemPointer entity) {
bool wasRemoved = false; bool wasRemoved = false;
uint32_t dirtyFlags = entity->getDirtyFlags(); uint32_t dirtyFlags = entity->getDirtyFlags();
if (dirtyFlags & EntityItem::DIRTY_POSITION) { if (dirtyFlags & EntityItem::DIRTY_POSITION) {
AACube domainBounds(glm::vec3(0.0f,0.0f,0.0f), (float)TREE_SCALE); AACube domainBounds(glm::vec3((float)-HALF_TREE_SCALE), (float)TREE_SCALE);
AACube newCube = entity->getMaximumAACube(); AACube newCube = entity->getMaximumAACube();
if (!domainBounds.touches(newCube)) { if (!domainBounds.touches(newCube)) {
qCDebug(entities) << "Entity " << entity->getEntityItemID() << " moved out of domain bounds."; qCDebug(entities) << "Entity " << entity->getEntityItemID() << " moved out of domain bounds.";

View file

@ -873,7 +873,7 @@ int EntityTree::processEraseMessage(NLPacket& packet, const SharedNodePointer& s
break; // bail to prevent buffer overflow break; // bail to prevent buffer overflow
} }
QUuid entityID = QUuid::fromRfc4122(packet.read(NUM_BYTES_RFC4122_UUID)); QUuid entityID = QUuid::fromRfc4122(packet.readWithoutCopy(NUM_BYTES_RFC4122_UUID));
EntityItemID entityItemID(entityID); EntityItemID entityItemID(entityID);
entityItemIDsToDelete << entityItemID; entityItemIDsToDelete << entityItemID;

View file

@ -444,14 +444,14 @@ bool EntityTreeElement::bestFitBounds(const AABox& bounds) const {
} }
bool EntityTreeElement::containsBounds(const glm::vec3& minPoint, const glm::vec3& maxPoint) const { bool EntityTreeElement::containsBounds(const glm::vec3& minPoint, const glm::vec3& maxPoint) const {
glm::vec3 clampedMin = glm::clamp(minPoint, 0.0f, (float)TREE_SCALE); glm::vec3 clampedMin = glm::clamp(minPoint, (float)-HALF_TREE_SCALE, (float)HALF_TREE_SCALE);
glm::vec3 clampedMax = glm::clamp(maxPoint, 0.0f, (float)TREE_SCALE); glm::vec3 clampedMax = glm::clamp(maxPoint, (float)-HALF_TREE_SCALE, (float)HALF_TREE_SCALE);
return _cube.contains(clampedMin) && _cube.contains(clampedMax); return _cube.contains(clampedMin) && _cube.contains(clampedMax);
} }
bool EntityTreeElement::bestFitBounds(const glm::vec3& minPoint, const glm::vec3& maxPoint) const { bool EntityTreeElement::bestFitBounds(const glm::vec3& minPoint, const glm::vec3& maxPoint) const {
glm::vec3 clampedMin = glm::clamp(minPoint, 0.0f, (float)TREE_SCALE); glm::vec3 clampedMin = glm::clamp(minPoint, (float)-HALF_TREE_SCALE, (float)HALF_TREE_SCALE);
glm::vec3 clampedMax = glm::clamp(maxPoint, 0.0f, (float)TREE_SCALE); glm::vec3 clampedMax = glm::clamp(maxPoint, (float)-HALF_TREE_SCALE, (float)HALF_TREE_SCALE);
if (_cube.contains(clampedMin) && _cube.contains(clampedMax)) { if (_cube.contains(clampedMin) && _cube.contains(clampedMax)) {

View file

@ -52,7 +52,7 @@ MovingEntitiesOperator::~MovingEntitiesOperator() {
void MovingEntitiesOperator::addEntityToMoveList(EntityItemPointer entity, const AACube& newCube) { void MovingEntitiesOperator::addEntityToMoveList(EntityItemPointer entity, const AACube& newCube) {
EntityTreeElement* oldContainingElement = _tree->getContainingElement(entity->getEntityItemID()); EntityTreeElement* oldContainingElement = _tree->getContainingElement(entity->getEntityItemID());
AABox newCubeClamped = newCube.clamp(0.0f, (float)TREE_SCALE); AABox newCubeClamped = newCube.clamp((float)-HALF_TREE_SCALE, (float)HALF_TREE_SCALE);
if (_wantDebug) { if (_wantDebug) {
qCDebug(entities) << "MovingEntitiesOperator::addEntityToMoveList() -----------------------------"; qCDebug(entities) << "MovingEntitiesOperator::addEntityToMoveList() -----------------------------";

View file

@ -47,7 +47,7 @@ UpdateEntityOperator::UpdateEntityOperator(EntityTree* tree,
// which can handle all potential rotations? // which can handle all potential rotations?
// the getMaximumAACube is the relaxed form. // the getMaximumAACube is the relaxed form.
_oldEntityCube = _existingEntity->getMaximumAACube(); _oldEntityCube = _existingEntity->getMaximumAACube();
_oldEntityBox = _oldEntityCube.clamp(0.0f, (float)TREE_SCALE); // clamp to domain bounds _oldEntityBox = _oldEntityCube.clamp((float)-HALF_TREE_SCALE, (float)HALF_TREE_SCALE); // clamp to domain bounds
// If the old properties doesn't contain the properties required to calculate a bounding box, // If the old properties doesn't contain the properties required to calculate a bounding box,
// get them from the existing entity. Registration point is required to correctly calculate // get them from the existing entity. Registration point is required to correctly calculate
@ -123,7 +123,7 @@ UpdateEntityOperator::UpdateEntityOperator(EntityTree* tree,
} }
} }
_newEntityBox = _newEntityCube.clamp(0.0f, (float)TREE_SCALE); // clamp to domain bounds _newEntityBox = _newEntityCube.clamp((float)-HALF_TREE_SCALE, (float)HALF_TREE_SCALE); // clamp to domain bounds
if (_wantDebug) { if (_wantDebug) {

View file

@ -28,4 +28,5 @@ include_directories(SYSTEM "${OPENSSL_INCLUDE_DIR}")
target_link_libraries(${TARGET_NAME} ${OPENSSL_LIBRARIES} ${TBB_LIBRARIES}) target_link_libraries(${TARGET_NAME} ${OPENSSL_LIBRARIES} ${TBB_LIBRARIES})
# append tbb includes to our list of includes to bubble # append tbb includes to our list of includes to bubble
target_include_directories(${TARGET_NAME} SYSTEM PUBLIC ${TBB_INCLUDE_DIRS}) target_include_directories(${TARGET_NAME} SYSTEM PUBLIC ${TBB_INCLUDE_DIRS})
include_application_version()

View file

@ -15,6 +15,7 @@
#include <QtCore/QDataStream> #include <QtCore/QDataStream>
#include <ApplicationVersion.h>
#include "Assignment.h" #include "Assignment.h"
Assignment::Type Assignment::typeForNodeType(NodeType_t nodeType) { Assignment::Type Assignment::typeForNodeType(NodeType_t nodeType) {
@ -52,11 +53,14 @@ Assignment::Assignment(Assignment::Command command, Assignment::Type type, const
_location(location), _location(location),
_payload(), _payload(),
_isStatic(false), _isStatic(false),
_walletUUID() _walletUUID(),
_nodeVersion()
{ {
if (_command == Assignment::CreateCommand) { if (_command == Assignment::CreateCommand) {
// this is a newly created assignment, generate a random UUID // this is a newly created assignment, generate a random UUID
_uuid = QUuid::createUuid(); _uuid = QUuid::createUuid();
} else if (_command == Assignment::RequestCommand) {
_nodeVersion = BUILD_VERSION;
} }
} }
@ -64,7 +68,8 @@ Assignment::Assignment(NLPacket& packet) :
_pool(), _pool(),
_location(GlobalLocation), _location(GlobalLocation),
_payload(), _payload(),
_walletUUID() _walletUUID(),
_nodeVersion()
{ {
if (packet.getType() == PacketType::RequestAssignment) { if (packet.getType() == PacketType::RequestAssignment) {
_command = Assignment::RequestCommand; _command = Assignment::RequestCommand;
@ -83,15 +88,14 @@ Assignment::Assignment(NLPacket& packet) :
Assignment::Assignment(const Assignment& otherAssignment) { Assignment::Assignment(const Assignment& otherAssignment) {
_uuid = otherAssignment._uuid; _uuid = otherAssignment._uuid;
_command = otherAssignment._command; _command = otherAssignment._command;
_type = otherAssignment._type; _type = otherAssignment._type;
_location = otherAssignment._location; _location = otherAssignment._location;
_pool = otherAssignment._pool; _pool = otherAssignment._pool;
_payload = otherAssignment._payload; _payload = otherAssignment._payload;
_walletUUID = otherAssignment._walletUUID; _walletUUID = otherAssignment._walletUUID;
_nodeVersion = otherAssignment._nodeVersion;
} }
Assignment& Assignment::operator=(const Assignment& rhsAssignment) { Assignment& Assignment::operator=(const Assignment& rhsAssignment) {
@ -110,6 +114,7 @@ void Assignment::swap(Assignment& otherAssignment) {
swap(_pool, otherAssignment._pool); swap(_pool, otherAssignment._pool);
swap(_payload, otherAssignment._payload); swap(_payload, otherAssignment._payload);
swap(_walletUUID, otherAssignment._walletUUID); swap(_walletUUID, otherAssignment._walletUUID);
swap(_nodeVersion, otherAssignment._nodeVersion);
} }
const char* Assignment::getTypeName() const { const char* Assignment::getTypeName() const {
@ -139,7 +144,13 @@ QDebug operator<<(QDebug debug, const Assignment &assignment) {
} }
QDataStream& operator<<(QDataStream &out, const Assignment& assignment) { QDataStream& operator<<(QDataStream &out, const Assignment& assignment) {
out << (quint8) assignment._type << assignment._uuid << assignment._pool << assignment._payload; out << (quint8) assignment._type;
if (assignment._command == Assignment::RequestCommand) {
out << assignment._nodeVersion;
}
out << assignment._uuid << assignment._pool << assignment._payload;
if (assignment._command == Assignment::RequestCommand) { if (assignment._command == Assignment::RequestCommand) {
out << assignment._walletUUID; out << assignment._walletUUID;
@ -151,6 +162,9 @@ QDataStream& operator<<(QDataStream &out, const Assignment& assignment) {
QDataStream& operator>>(QDataStream &in, Assignment& assignment) { QDataStream& operator>>(QDataStream &in, Assignment& assignment) {
quint8 packedType; quint8 packedType;
in >> packedType; in >> packedType;
if (assignment._command == Assignment::RequestCommand) {
in >> assignment._nodeVersion;
}
assignment._type = (Assignment::Type) packedType; assignment._type = (Assignment::Type) packedType;
in >> assignment._uuid >> assignment._pool >> assignment._payload; in >> assignment._uuid >> assignment._pool >> assignment._payload;

View file

@ -83,6 +83,8 @@ public:
void setWalletUUID(const QUuid& walletUUID) { _walletUUID = walletUUID; } void setWalletUUID(const QUuid& walletUUID) { _walletUUID = walletUUID; }
const QUuid& getWalletUUID() const { return _walletUUID; } const QUuid& getWalletUUID() const { return _walletUUID; }
const QString& getNodeVersion() const { return _nodeVersion; }
const char* getTypeName() const; const char* getTypeName() const;
friend QDebug operator<<(QDebug debug, const Assignment& assignment); friend QDebug operator<<(QDebug debug, const Assignment& assignment);
@ -98,6 +100,7 @@ protected:
QByteArray _payload; /// an optional payload attached to this assignment, a maximum for 1024 bytes will be packed QByteArray _payload; /// an optional payload attached to this assignment, a maximum for 1024 bytes will be packed
bool _isStatic; /// defines if this assignment needs to be re-queued in the domain-server if it stops being fulfilled bool _isStatic; /// defines if this assignment needs to be re-queued in the domain-server if it stops being fulfilled
QUuid _walletUUID; /// the UUID for the wallet that should be paid for this assignment QUuid _walletUUID; /// the UUID for the wallet that should be paid for this assignment
QString _nodeVersion;
}; };
#endif // hifi_Assignment_h #endif // hifi_Assignment_h

View file

@ -397,7 +397,7 @@ void LimitedNodeList::killNodeWithUUID(const QUuid& nodeUUID) {
void LimitedNodeList::processKillNode(NLPacket& packet) { void LimitedNodeList::processKillNode(NLPacket& packet) {
// read the node id // read the node id
QUuid nodeUUID = QUuid::fromRfc4122(packet.read(NUM_BYTES_RFC4122_UUID)); QUuid nodeUUID = QUuid::fromRfc4122(packet.readWithoutCopy(NUM_BYTES_RFC4122_UUID));
// kill the node with this UUID, if it exists // kill the node with this UUID, if it exists
killNodeWithUUID(nodeUUID); killNodeWithUUID(nodeUUID);

View file

@ -17,6 +17,7 @@
#include <QtCore/QThread> #include <QtCore/QThread>
#include <QtNetwork/QHostInfo> #include <QtNetwork/QHostInfo>
#include <ApplicationVersion.h>
#include <LogHandler.h> #include <LogHandler.h>
#include "AccountManager.h" #include "AccountManager.h"
@ -367,7 +368,6 @@ void NodeList::sendDSPathQuery(const QString& newPath) {
} }
} }
void NodeList::processDomainServerPathResponse(QSharedPointer<NLPacket> packet) { void NodeList::processDomainServerPathResponse(QSharedPointer<NLPacket> packet) {
// This is a response to a path query we theoretically made. // This is a response to a path query we theoretically made.
// In the future we may want to check that this was actually from our DS and for a query we actually made. // In the future we may want to check that this was actually from our DS and for a query we actually made.
@ -457,14 +457,13 @@ void NodeList::pingPunchForDomainServer() {
} }
} }
void NodeList::processDomainServerConnectionTokenPacket(QSharedPointer<NLPacket> packet) { void NodeList::processDomainServerConnectionTokenPacket(QSharedPointer<NLPacket> packet) {
if (_domainHandler.getSockAddr().isNull()) { if (_domainHandler.getSockAddr().isNull()) {
// refuse to process this packet if we aren't currently connected to the DS // refuse to process this packet if we aren't currently connected to the DS
return; return;
} }
// read in the connection token from the packet, then send domain-server checkin // read in the connection token from the packet, then send domain-server checkin
_domainHandler.setConnectionToken(QUuid::fromRfc4122(packet->read(NUM_BYTES_RFC4122_UUID))); _domainHandler.setConnectionToken(QUuid::fromRfc4122(packet->readWithoutCopy(NUM_BYTES_RFC4122_UUID)));
sendDomainServerCheckIn(); sendDomainServerCheckIn();
} }
@ -548,7 +547,7 @@ void NodeList::sendAssignment(Assignment& assignment) {
: PacketType::RequestAssignment; : PacketType::RequestAssignment;
auto assignmentPacket = NLPacket::create(assignmentPacketType); auto assignmentPacket = NLPacket::create(assignmentPacketType);
QDataStream packetStream(assignmentPacket.get()); QDataStream packetStream(assignmentPacket.get());
packetStream << assignment; packetStream << assignment;

View file

@ -213,6 +213,13 @@ void Packet::writeSequenceNumber(SequenceNumber seqNum) {
} }
QByteArray Packet::read(qint64 maxSize) { QByteArray Packet::read(qint64 maxSize) {
qint64 sizeToRead = std::min(size() - pos(), maxSize);
QByteArray data { getPayload() + pos(), (int) sizeToRead };
seek(pos() + sizeToRead);
return data;
}
QByteArray Packet::readWithoutCopy(qint64 maxSize) {
qint64 sizeToRead = std::min(size() - pos(), maxSize); qint64 sizeToRead = std::min(size() - pos(), maxSize);
QByteArray data { QByteArray::fromRawData(getPayload() + pos(), sizeToRead) }; QByteArray data { QByteArray::fromRawData(getPayload() + pos(), sizeToRead) };
seek(pos() + sizeToRead); seek(pos() + sizeToRead);

View file

@ -81,7 +81,8 @@ public:
using QIODevice::read; using QIODevice::read;
QByteArray read(qint64 maxSize); QByteArray read(qint64 maxSize);
QByteArray readWithoutCopy(qint64 maxSize); // this can only be used if packet will stay in scope
template<typename T> qint64 peekPrimitive(T* data); template<typename T> qint64 peekPrimitive(T* data);
template<typename T> qint64 readPrimitive(T* data); template<typename T> qint64 readPrimitive(T* data);
template<typename T> qint64 writePrimitive(const T& data); template<typename T> qint64 writePrimitive(const T& data);

View file

@ -67,7 +67,7 @@ PacketVersion versionForPacketType(PacketType::Value packetType) {
case EntityAdd: case EntityAdd:
case EntityEdit: case EntityEdit:
case EntityData: case EntityData:
return VERSION_ENTITIES_POLYLINE; return VERSION_OCTREE_CENTERED_ORIGIN;
case AvatarData: case AvatarData:
return 12; return 12;
default: default:

View file

@ -142,5 +142,6 @@ const PacketVersion VERSION_ENTITIES_HAVE_SIMULATION_OWNER_AND_ACTIONS_OVER_WIRE
const PacketVersion VERSION_ENTITIES_NEW_PROTOCOL_LAYER = 35; const PacketVersion VERSION_ENTITIES_NEW_PROTOCOL_LAYER = 35;
const PacketVersion VERSION_POLYVOX_TEXTURES = 36; const PacketVersion VERSION_POLYVOX_TEXTURES = 36;
const PacketVersion VERSION_ENTITIES_POLYLINE = 37; const PacketVersion VERSION_ENTITIES_POLYLINE = 37;
const PacketVersion VERSION_OCTREE_CENTERED_ORIGIN = 38;
#endif // hifi_PacketHeaders_h #endif // hifi_PacketHeaders_h

View file

@ -17,7 +17,8 @@
const quint64 CHANGE_FUDGE = 1000 * 200; // useconds of fudge in determining if we want to resend changed voxels const quint64 CHANGE_FUDGE = 1000 * 200; // useconds of fudge in determining if we want to resend changed voxels
const int TREE_SCALE = 16384; // ~10 miles.. This is the number of meters of the 0.0 to 1.0 voxel universe const int TREE_SCALE = 32768; // ~20 miles.. This is the number of meters of the 0.0 to 1.0 voxel universe
const int HALF_TREE_SCALE = TREE_SCALE / 2;
// This controls the LOD. Larger number will make smaller voxels visible at greater distance. // This controls the LOD. Larger number will make smaller voxels visible at greater distance.
const float DEFAULT_OCTREE_SIZE_SCALE = TREE_SCALE * 400.0f; const float DEFAULT_OCTREE_SIZE_SCALE = TREE_SCALE * 400.0f;

View file

@ -191,6 +191,7 @@ void OctreeElement::calculateAACube() {
// this tells you the "size" of the voxel // this tells you the "size" of the voxel
float voxelScale = (float)TREE_SCALE / powf(2.0f, numberOfThreeBitSectionsInCode(getOctalCode())); float voxelScale = (float)TREE_SCALE / powf(2.0f, numberOfThreeBitSectionsInCode(getOctalCode()));
corner *= (float)TREE_SCALE; corner *= (float)TREE_SCALE;
corner -= (float)HALF_TREE_SCALE;
_cube.setBox(corner, voxelScale); _cube.setBox(corner, voxelScale);
} }
@ -717,8 +718,8 @@ int OctreeElement::getMyChildContaining(const AACube& cube) const {
} }
// Determine which of our children the minimum and maximum corners of the cube live in... // Determine which of our children the minimum and maximum corners of the cube live in...
glm::vec3 cubeCornerMinimum = glm::clamp(cube.getCorner(), 0.0f, (float)TREE_SCALE); glm::vec3 cubeCornerMinimum = glm::clamp(cube.getCorner(), (float)-HALF_TREE_SCALE, (float)HALF_TREE_SCALE);
glm::vec3 cubeCornerMaximum = glm::clamp(cube.calcTopFarLeft(), 0.0f, (float)TREE_SCALE); glm::vec3 cubeCornerMaximum = glm::clamp(cube.calcTopFarLeft(), (float)-HALF_TREE_SCALE, (float)HALF_TREE_SCALE);
if (_cube.contains(cubeCornerMinimum) && _cube.contains(cubeCornerMaximum)) { if (_cube.contains(cubeCornerMinimum) && _cube.contains(cubeCornerMaximum)) {
int childIndexCubeMinimum = getMyChildContainingPoint(cubeCornerMinimum); int childIndexCubeMinimum = getMyChildContainingPoint(cubeCornerMinimum);

View file

@ -31,7 +31,7 @@ const float DEFAULT_KEYHOLE_RADIUS = 3.0f;
const float DEFAULT_FIELD_OF_VIEW_DEGREES = 45.0f; const float DEFAULT_FIELD_OF_VIEW_DEGREES = 45.0f;
const float DEFAULT_ASPECT_RATIO = 16.0f/9.0f; const float DEFAULT_ASPECT_RATIO = 16.0f/9.0f;
const float DEFAULT_NEAR_CLIP = 0.08f; const float DEFAULT_NEAR_CLIP = 0.08f;
const float DEFAULT_FAR_CLIP = (float)TREE_SCALE; const float DEFAULT_FAR_CLIP = (float)HALF_TREE_SCALE;
class ViewFrustum { class ViewFrustum {
public: public:

View file

@ -26,4 +26,5 @@ public:
virtual void unsetFullscreen(const QScreen* avoidScreen = nullptr) = 0; virtual void unsetFullscreen(const QScreen* avoidScreen = nullptr) = 0;
virtual void showDisplayPluginsTools() = 0; virtual void showDisplayPluginsTools() = 0;
virtual QGLWidget* getPrimarySurface() = 0; virtual QGLWidget* getPrimarySurface() = 0;
virtual bool isForeground() = 0;
}; };