mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 12:57:59 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into 20429
This commit is contained in:
commit
7b3d33c2a4
48 changed files with 463 additions and 243 deletions
|
@ -26,6 +26,7 @@ set_property(GLOBAL PROPERTY PREDEFINED_TARGETS_FOLDER "CMakeTargets")
|
||||||
|
|
||||||
project(hifi)
|
project(hifi)
|
||||||
add_definitions(-DGLM_FORCE_RADIANS)
|
add_definitions(-DGLM_FORCE_RADIANS)
|
||||||
|
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG")
|
||||||
|
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
add_definitions(-DNOMINMAX -D_CRT_SECURE_NO_WARNINGS)
|
add_definitions(-DNOMINMAX -D_CRT_SECURE_NO_WARNINGS)
|
||||||
|
|
|
@ -45,7 +45,7 @@ Agent::Agent(const QByteArray& packet) :
|
||||||
|
|
||||||
DependencyManager::get<EntityScriptingInterface>()->setPacketSender(&_entityEditSender);
|
DependencyManager::get<EntityScriptingInterface>()->setPacketSender(&_entityEditSender);
|
||||||
|
|
||||||
DependencyManager::set<ResouceCacheSharedItems>();
|
DependencyManager::set<ResourceCacheSharedItems>();
|
||||||
DependencyManager::set<SoundCache>();
|
DependencyManager::set<SoundCache>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -180,7 +180,7 @@ void AssignmentClientMonitor::readPendingDatagrams() {
|
||||||
senderSockAddr.getAddress() == QHostAddress::LocalHostIPv6) {
|
senderSockAddr.getAddress() == QHostAddress::LocalHostIPv6) {
|
||||||
if (!packetUUID.isNull()) {
|
if (!packetUUID.isNull()) {
|
||||||
matchingNode = DependencyManager::get<LimitedNodeList>()->addOrUpdateNode
|
matchingNode = DependencyManager::get<LimitedNodeList>()->addOrUpdateNode
|
||||||
(packetUUID, NodeType::Unassigned, senderSockAddr, senderSockAddr, false);
|
(packetUUID, NodeType::Unassigned, senderSockAddr, senderSockAddr, false, false);
|
||||||
AssignmentClientChildData *childData = new AssignmentClientChildData("unknown");
|
AssignmentClientChildData *childData = new AssignmentClientChildData("unknown");
|
||||||
matchingNode->setLinkedData(childData);
|
matchingNode->setLinkedData(childData);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <AccountManager.h>
|
#include <AccountManager.h>
|
||||||
#include <HTTPConnection.h>
|
#include <HTTPConnection.h>
|
||||||
#include <LogHandler.h>
|
#include <LogHandler.h>
|
||||||
|
#include <NetworkingConstants.h>
|
||||||
#include <UUID.h>
|
#include <UUID.h>
|
||||||
|
|
||||||
#include "../AssignmentClient.h"
|
#include "../AssignmentClient.h"
|
||||||
|
@ -252,7 +253,7 @@ OctreeServer::OctreeServer(const QByteArray& packet) :
|
||||||
|
|
||||||
// make sure the AccountManager has an Auth URL for payment redemptions
|
// make sure the AccountManager has an Auth URL for payment redemptions
|
||||||
|
|
||||||
AccountManager::getInstance().setAuthURL(DEFAULT_NODE_AUTH_URL);
|
AccountManager::getInstance().setAuthURL(NetworkingConstants::METAVERSE_SERVER_URL);
|
||||||
}
|
}
|
||||||
|
|
||||||
OctreeServer::~OctreeServer() {
|
OctreeServer::~OctreeServer() {
|
||||||
|
|
2
cmake/externals/bullet/CMakeLists.txt
vendored
2
cmake/externals/bullet/CMakeLists.txt
vendored
|
@ -19,7 +19,7 @@ if (WIN32)
|
||||||
${EXTERNAL_NAME}
|
${EXTERNAL_NAME}
|
||||||
URL https://bullet.googlecode.com/files/bullet-2.82-r2704.zip
|
URL https://bullet.googlecode.com/files/bullet-2.82-r2704.zip
|
||||||
URL_MD5 f5e8914fc9064ad32e0d62d19d33d977
|
URL_MD5 f5e8914fc9064ad32e0d62d19d33d977
|
||||||
CMAKE_ARGS ${PLATFORM_CMAKE_ARGS} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DBUILD_EXTRAS=0 -DINSTALL_LIBS=1 -DBUILD_DEMOS=0 -DUSE_GLUT=0
|
CMAKE_ARGS ${PLATFORM_CMAKE_ARGS} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DBUILD_EXTRAS=0 -DINSTALL_LIBS=1 -DBUILD_DEMOS=0 -DUSE_GLUT=0 -DUSE_DX11=0
|
||||||
LOG_DOWNLOAD 1
|
LOG_DOWNLOAD 1
|
||||||
LOG_CONFIGURE 1
|
LOG_CONFIGURE 1
|
||||||
LOG_BUILD 1
|
LOG_BUILD 1
|
||||||
|
|
34
cmake/externals/tbb/CMakeLists.txt
vendored
34
cmake/externals/tbb/CMakeLists.txt
vendored
|
@ -13,16 +13,28 @@ if (ANDROID)
|
||||||
BUILD_COMMAND ${NDK_BUILD_COMMAND} --directory=jni target=android tbb tbbmalloc arch=arm
|
BUILD_COMMAND ${NDK_BUILD_COMMAND} --directory=jni target=android tbb tbbmalloc arch=arm
|
||||||
BUILD_IN_SOURCE 1
|
BUILD_IN_SOURCE 1
|
||||||
CONFIGURE_COMMAND ""
|
CONFIGURE_COMMAND ""
|
||||||
INSTALL_COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/AndroidTBBLibCopy.cmake
|
INSTALL_COMMAND ${CMAKE_COMMAND} -DTBB_LIBS_SUFFIX=so -P ${CMAKE_CURRENT_SOURCE_DIR}/TBBLibCopy.cmake
|
||||||
|
LOG_DOWNLOAD 1
|
||||||
|
LOG_CONFIGURE 1
|
||||||
|
LOG_BUILD 1
|
||||||
|
)
|
||||||
|
elseif (APPLE)
|
||||||
|
find_program(MAKE_COMMAND NAMES make DOC "Path to the make command")
|
||||||
|
|
||||||
|
ExternalProject_Add(
|
||||||
|
${EXTERNAL_NAME}
|
||||||
|
URL http://hifi-public.s3.amazonaws.com/dependencies/tbb43_20150316oss_src.tgz
|
||||||
|
URL_MD5 bf090eaa86cf89ea014b7b462786a440
|
||||||
|
BUILD_COMMAND ${MAKE_COMMAND} tbb_os=macos
|
||||||
|
BUILD_IN_SOURCE 1
|
||||||
|
CONFIGURE_COMMAND ""
|
||||||
|
INSTALL_COMMAND ${CMAKE_COMMAND} -DTBB_LIBS_SUFFIX=dylib -P ${CMAKE_CURRENT_SOURCE_DIR}/TBBLibCopy.cmake
|
||||||
LOG_DOWNLOAD 1
|
LOG_DOWNLOAD 1
|
||||||
LOG_CONFIGURE 1
|
LOG_CONFIGURE 1
|
||||||
LOG_BUILD 1
|
LOG_BUILD 1
|
||||||
)
|
)
|
||||||
else ()
|
else ()
|
||||||
if (APPLE)
|
if (WIN32)
|
||||||
set(DOWNLOAD_URL http://hifi-public.s3.amazonaws.com/dependencies/tbb43_20150316oss_osx.tgz)
|
|
||||||
set(DOWNLOAD_MD5 25a36ebff070ff801760ec658079f6aa)
|
|
||||||
elseif (WIN32)
|
|
||||||
set(DOWNLOAD_URL http://s3.amazonaws.com/hifi-public/dependencies/tbb43_20150316oss_win.zip)
|
set(DOWNLOAD_URL http://s3.amazonaws.com/hifi-public/dependencies/tbb43_20150316oss_win.zip)
|
||||||
set(DOWNLOAD_MD5 d250d40bb93b255f75bcbb19e976a440)
|
set(DOWNLOAD_MD5 d250d40bb93b255f75bcbb19e976a440)
|
||||||
else ()
|
else ()
|
||||||
|
@ -46,7 +58,7 @@ ExternalProject_Get_Property(${EXTERNAL_NAME} SOURCE_DIR)
|
||||||
string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
|
string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
|
||||||
|
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
set(_TBB_LIB_DIR "${SOURCE_DIR}/lib/libc++")
|
set(_TBB_LIB_DIR "${SOURCE_DIR}/lib")
|
||||||
set(_LIB_PREFIX "lib")
|
set(_LIB_PREFIX "lib")
|
||||||
set(_LIB_EXT "dylib")
|
set(_LIB_EXT "dylib")
|
||||||
|
|
||||||
|
@ -95,14 +107,8 @@ elseif (UNIX)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
if (DEFINED _TBB_LIB_DIR)
|
if (DEFINED _TBB_LIB_DIR)
|
||||||
if (NOT APPLE)
|
set(${EXTERNAL_NAME_UPPER}_LIBRARY_DEBUG ${_TBB_LIB_DIR}/${_LIB_PREFIX}tbb_debug.${_LIB_EXT} CACHE FILEPATH "TBB debug library location")
|
||||||
set(${EXTERNAL_NAME_UPPER}_LIBRARY_DEBUG ${_TBB_LIB_DIR}/${_LIB_PREFIX}tbb_debug.${_LIB_EXT} CACHE FILEPATH "TBB debug library location")
|
set(${EXTERNAL_NAME_UPPER}_MALLOC_LIBRARY_DEBUG ${_TBB_LIB_DIR}/${_LIB_PREFIX}tbbmalloc_debug.${_LIB_EXT} CACHE FILEPATH "TBB malloc debug library location")
|
||||||
set(${EXTERNAL_NAME_UPPER}_MALLOC_LIBRARY_DEBUG ${_TBB_LIB_DIR}/${_LIB_PREFIX}tbbmalloc_debug.${_LIB_EXT} CACHE FILEPATH "TBB malloc debug library location")
|
|
||||||
else ()
|
|
||||||
set(${EXTERNAL_NAME_UPPER}_LIBRARY_DEBUG "" CACHE FILEPATH "TBB debug library location")
|
|
||||||
set(${EXTERNAL_NAME_UPPER}_MALLOC_LIBRARY_DEBUG "" CACHE FILEPATH "TBB malloc debug library location")
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${_TBB_LIB_DIR}/${_LIB_PREFIX}tbb.${_LIB_EXT} CACHE FILEPATH "TBB release library location")
|
set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${_TBB_LIB_DIR}/${_LIB_PREFIX}tbb.${_LIB_EXT} CACHE FILEPATH "TBB release library location")
|
||||||
set(${EXTERNAL_NAME_UPPER}_MALLOC_LIBRARY_RELEASE ${_TBB_LIB_DIR}/${_LIB_PREFIX}tbbmalloc.${_LIB_EXT} CACHE FILEPATH "TBB malloc release library location")
|
set(${EXTERNAL_NAME_UPPER}_MALLOC_LIBRARY_RELEASE ${_TBB_LIB_DIR}/${_LIB_PREFIX}tbbmalloc.${_LIB_EXT} CACHE FILEPATH "TBB malloc release library location")
|
||||||
endif ()
|
endif ()
|
||||||
|
|
|
@ -10,9 +10,11 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
# first find the so files in the source dir
|
# first find the so files in the source dir
|
||||||
set(_TBB_LIBRARY_DIR ${CMAKE_CURRENT_SOURCE_DIR}/lib/libc++)
|
set(_TBB_LIBRARY_DIR ${CMAKE_CURRENT_SOURCE_DIR}/lib)
|
||||||
file(GLOB_RECURSE _TBB_LIBRARIES "${_TBB_LIBRARY_DIR}/*.dylib")
|
file(GLOB_RECURSE _TBB_LIBRARIES "${_TBB_LIBRARY_DIR}/*.dylib")
|
||||||
|
|
||||||
|
message(${_TBB_LIBRARIES})
|
||||||
|
|
||||||
# raise an error if we found none
|
# raise an error if we found none
|
||||||
if (NOT _TBB_LIBRARIES)
|
if (NOT _TBB_LIBRARIES)
|
||||||
message(FATAL_ERROR "Did not find any TBB libraries")
|
message(FATAL_ERROR "Did not find any TBB libraries")
|
||||||
|
@ -28,20 +30,6 @@ find_program(LIPO_COMMAND NAMES lipo DOC "Path to the lipo command")
|
||||||
foreach(_TBB_LIBRARY ${_TBB_LIBRARIES})
|
foreach(_TBB_LIBRARY ${_TBB_LIBRARIES})
|
||||||
get_filename_component(_TBB_LIBRARY_FILENAME ${_TBB_LIBRARY} NAME)
|
get_filename_component(_TBB_LIBRARY_FILENAME ${_TBB_LIBRARY} NAME)
|
||||||
|
|
||||||
set(_LIPO_ARGS -remove i386 ${_TBB_LIBRARY_FILENAME} -output ${_TBB_LIBRARY_FILENAME})
|
|
||||||
message(STATUS "${LIPO_COMMAND} ${_LIPO_ARGS}")
|
|
||||||
|
|
||||||
# first we use lipo to remove i386 from each dylib
|
|
||||||
execute_process(
|
|
||||||
COMMAND ${LIPO_COMMAND} ${_LIPO_ARGS}
|
|
||||||
WORKING_DIRECTORY ${_TBB_LIBRARY_DIR}
|
|
||||||
ERROR_VARIABLE _LIPO_ERROR
|
|
||||||
)
|
|
||||||
|
|
||||||
if (_LIPO_ERROR)
|
|
||||||
message(FATAL_ERROR "There was an error removing i386 for ${_TBB_LIBRARY_FILENAME} - ${_LIPO_ERROR}")
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
set(_INSTALL_NAME_ARGS ${INSTALL_NAME_TOOL_COMMAND} -id ${_TBB_LIBRARY} ${_TBB_LIBRARY_FILENAME})
|
set(_INSTALL_NAME_ARGS ${INSTALL_NAME_TOOL_COMMAND} -id ${_TBB_LIBRARY} ${_TBB_LIBRARY_FILENAME})
|
||||||
|
|
||||||
message(STATUS "${INSTALL_NAME_COMMAND} ${_INSTALL_NAME_ARGS}")
|
message(STATUS "${INSTALL_NAME_COMMAND} ${_INSTALL_NAME_ARGS}")
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# AndroidTBBLibCopy.cmake
|
# TBBLibCopy.cmake
|
||||||
# cmake/externals/tbb
|
# cmake/externals/tbb
|
||||||
#
|
#
|
||||||
# Copyright 2015 High Fidelity, Inc.
|
# Copyright 2015 High Fidelity, Inc.
|
||||||
|
@ -10,7 +10,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
# first find the so files in the source dir
|
# first find the so files in the source dir
|
||||||
file(GLOB_RECURSE _TBB_LIBRARIES "${CMAKE_CURRENT_SOURCE_DIR}/build/*.so")
|
file(GLOB_RECURSE _TBB_LIBRARIES "${CMAKE_CURRENT_SOURCE_DIR}/build/*.${TBB_LIBS_SUFFIX}")
|
||||||
|
|
||||||
# raise an error if we found none
|
# raise an error if we found none
|
||||||
if (NOT _TBB_LIBRARIES)
|
if (NOT _TBB_LIBRARIES)
|
|
@ -95,6 +95,13 @@
|
||||||
"can_set": true
|
"can_set": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "editors_are_rezzers",
|
||||||
|
"type": "checkbox",
|
||||||
|
"label": "Only editors can create new entities",
|
||||||
|
"help": "When checked, only those who can edit the domain can create new entites.",
|
||||||
|
"default": false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include <HifiConfigVariantMap.h>
|
#include <HifiConfigVariantMap.h>
|
||||||
#include <HTTPConnection.h>
|
#include <HTTPConnection.h>
|
||||||
#include <LogUtils.h>
|
#include <LogUtils.h>
|
||||||
|
#include <NetworkingConstants.h>
|
||||||
#include <PacketHeaders.h>
|
#include <PacketHeaders.h>
|
||||||
#include <SettingHandle.h>
|
#include <SettingHandle.h>
|
||||||
#include <SharedUtil.h>
|
#include <SharedUtil.h>
|
||||||
|
@ -46,6 +47,7 @@ const QString ICE_SERVER_DEFAULT_HOSTNAME = "ice.highfidelity.io";
|
||||||
const QString ALLOWED_USERS_SETTINGS_KEYPATH = "security.allowed_users";
|
const QString ALLOWED_USERS_SETTINGS_KEYPATH = "security.allowed_users";
|
||||||
const QString MAXIMUM_USER_CAPACITY = "security.maximum_user_capacity";
|
const QString MAXIMUM_USER_CAPACITY = "security.maximum_user_capacity";
|
||||||
const QString ALLOWED_EDITORS_SETTINGS_KEYPATH = "security.allowed_editors";
|
const QString ALLOWED_EDITORS_SETTINGS_KEYPATH = "security.allowed_editors";
|
||||||
|
const QString EDITORS_ARE_REZZERS_KEYPATH = "security.editors_are_rezzers";
|
||||||
|
|
||||||
|
|
||||||
DomainServer::DomainServer(int argc, char* argv[]) :
|
DomainServer::DomainServer(int argc, char* argv[]) :
|
||||||
|
@ -181,7 +183,7 @@ bool DomainServer::optionallySetupOAuth() {
|
||||||
|
|
||||||
// if we don't have an oauth provider URL then we default to the default node auth url
|
// if we don't have an oauth provider URL then we default to the default node auth url
|
||||||
if (_oauthProviderURL.isEmpty()) {
|
if (_oauthProviderURL.isEmpty()) {
|
||||||
_oauthProviderURL = DEFAULT_NODE_AUTH_URL;
|
_oauthProviderURL = NetworkingConstants::METAVERSE_SERVER_URL;
|
||||||
}
|
}
|
||||||
|
|
||||||
AccountManager& accountManager = AccountManager::getInstance();
|
AccountManager& accountManager = AccountManager::getInstance();
|
||||||
|
@ -645,9 +647,23 @@ void DomainServer::handleConnectRequest(const QByteArray& packet, const HifiSock
|
||||||
QStringList allowedEditors = allowedEditorsVariant ? allowedEditorsVariant->toStringList() : QStringList();
|
QStringList allowedEditors = allowedEditorsVariant ? allowedEditorsVariant->toStringList() : QStringList();
|
||||||
bool canAdjustLocks = allowedEditors.isEmpty() || allowedEditors.contains(username);
|
bool canAdjustLocks = allowedEditors.isEmpty() || allowedEditors.contains(username);
|
||||||
|
|
||||||
|
const QVariant* editorsAreRezzersVariant =
|
||||||
|
valueForKeyPath(_settingsManager.getSettingsMap(), EDITORS_ARE_REZZERS_KEYPATH);
|
||||||
|
|
||||||
|
bool onlyEditorsAreRezzers = false;
|
||||||
|
if (editorsAreRezzersVariant) {
|
||||||
|
onlyEditorsAreRezzers = editorsAreRezzersVariant->toBool();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool canRez = true;
|
||||||
|
if (onlyEditorsAreRezzers) {
|
||||||
|
canRez = canAdjustLocks;
|
||||||
|
}
|
||||||
|
|
||||||
SharedNodePointer newNode =
|
SharedNodePointer newNode =
|
||||||
DependencyManager::get<LimitedNodeList>()->addOrUpdateNode(nodeUUID, nodeType,
|
DependencyManager::get<LimitedNodeList>()->addOrUpdateNode(nodeUUID, nodeType,
|
||||||
publicSockAddr, localSockAddr, canAdjustLocks);
|
publicSockAddr, localSockAddr,
|
||||||
|
canAdjustLocks, canRez);
|
||||||
// when the newNode is created the linked data is also created
|
// when the newNode is created the linked data is also created
|
||||||
// if this was a static assignment set the UUID, set the sendingSockAddr
|
// if this was a static assignment set the UUID, set the sendingSockAddr
|
||||||
DomainServerNodeData* nodeData = reinterpret_cast<DomainServerNodeData*>(newNode->getLinkedData());
|
DomainServerNodeData* nodeData = reinterpret_cast<DomainServerNodeData*>(newNode->getLinkedData());
|
||||||
|
@ -902,6 +918,7 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif
|
||||||
QDataStream broadcastDataStream(&broadcastPacket, QIODevice::Append);
|
QDataStream broadcastDataStream(&broadcastPacket, QIODevice::Append);
|
||||||
broadcastDataStream << node->getUUID();
|
broadcastDataStream << node->getUUID();
|
||||||
broadcastDataStream << node->getCanAdjustLocks();
|
broadcastDataStream << node->getCanAdjustLocks();
|
||||||
|
broadcastDataStream << node->getCanRez();
|
||||||
|
|
||||||
int numBroadcastPacketLeadBytes = broadcastDataStream.device()->pos();
|
int numBroadcastPacketLeadBytes = broadcastDataStream.device()->pos();
|
||||||
|
|
||||||
|
|
|
@ -43,8 +43,8 @@ var floor = Entities.addEntity(
|
||||||
var edge1 = Entities.addEntity(
|
var edge1 = Entities.addEntity(
|
||||||
{ type: "Box",
|
{ type: "Box",
|
||||||
position: Vec3.sum(center, { x: FLOOR_SIZE / 2.0, y: FLOOR_THICKNESS / 2.0, z: 0 }),
|
position: Vec3.sum(center, { x: FLOOR_SIZE / 2.0, y: FLOOR_THICKNESS / 2.0, z: 0 }),
|
||||||
dimensions: { x: EDGE_THICKESS, y: EDGE_THICKESS, z: FLOOR_SIZE },
|
dimensions: { x: EDGE_THICKESS, y: EDGE_THICKESS, z: FLOOR_SIZE + EDGE_THICKESS },
|
||||||
color: { red: 128, green: 128, blue: 128 },
|
color: { red: 100, green: 100, blue: 100 },
|
||||||
gravity: { x: 0, y: 0, z: 0 },
|
gravity: { x: 0, y: 0, z: 0 },
|
||||||
ignoreCollisions: false,
|
ignoreCollisions: false,
|
||||||
visible: true,
|
visible: true,
|
||||||
|
@ -54,8 +54,8 @@ var edge1 = Entities.addEntity(
|
||||||
var edge2 = Entities.addEntity(
|
var edge2 = Entities.addEntity(
|
||||||
{ type: "Box",
|
{ type: "Box",
|
||||||
position: Vec3.sum(center, { x: -FLOOR_SIZE / 2.0, y: FLOOR_THICKNESS / 2.0, z: 0 }),
|
position: Vec3.sum(center, { x: -FLOOR_SIZE / 2.0, y: FLOOR_THICKNESS / 2.0, z: 0 }),
|
||||||
dimensions: { x: EDGE_THICKESS, y: EDGE_THICKESS, z: FLOOR_SIZE },
|
dimensions: { x: EDGE_THICKESS, y: EDGE_THICKESS, z: FLOOR_SIZE + EDGE_THICKESS },
|
||||||
color: { red: 128, green: 128, blue: 128 },
|
color: { red: 100, green: 100, blue: 100 },
|
||||||
gravity: { x: 0, y: 0, z: 0 },
|
gravity: { x: 0, y: 0, z: 0 },
|
||||||
ignoreCollisions: false,
|
ignoreCollisions: false,
|
||||||
visible: true,
|
visible: true,
|
||||||
|
@ -65,8 +65,8 @@ var edge2 = Entities.addEntity(
|
||||||
var edge3 = Entities.addEntity(
|
var edge3 = Entities.addEntity(
|
||||||
{ type: "Box",
|
{ type: "Box",
|
||||||
position: Vec3.sum(center, { x: 0, y: FLOOR_THICKNESS / 2.0, z: -FLOOR_SIZE / 2.0 }),
|
position: Vec3.sum(center, { x: 0, y: FLOOR_THICKNESS / 2.0, z: -FLOOR_SIZE / 2.0 }),
|
||||||
dimensions: { x: FLOOR_SIZE, y: EDGE_THICKESS, z: EDGE_THICKESS },
|
dimensions: { x: FLOOR_SIZE + EDGE_THICKESS, y: EDGE_THICKESS, z: EDGE_THICKESS },
|
||||||
color: { red: 128, green: 128, blue: 128 },
|
color: { red: 100, green: 100, blue: 100 },
|
||||||
gravity: { x: 0, y: 0, z: 0 },
|
gravity: { x: 0, y: 0, z: 0 },
|
||||||
ignoreCollisions: false,
|
ignoreCollisions: false,
|
||||||
visible: true,
|
visible: true,
|
||||||
|
@ -76,8 +76,8 @@ var edge3 = Entities.addEntity(
|
||||||
var edge4 = Entities.addEntity(
|
var edge4 = Entities.addEntity(
|
||||||
{ type: "Box",
|
{ type: "Box",
|
||||||
position: Vec3.sum(center, { x: 0, y: FLOOR_THICKNESS / 2.0, z: FLOOR_SIZE / 2.0 }),
|
position: Vec3.sum(center, { x: 0, y: FLOOR_THICKNESS / 2.0, z: FLOOR_SIZE / 2.0 }),
|
||||||
dimensions: { x: FLOOR_SIZE, y: EDGE_THICKESS, z: EDGE_THICKESS },
|
dimensions: { x: FLOOR_SIZE + EDGE_THICKESS, y: EDGE_THICKESS, z: EDGE_THICKESS },
|
||||||
color: { red: 128, green: 128, blue: 128 },
|
color: { red: 100, green: 100, blue: 100 },
|
||||||
gravity: { x: 0, y: 0, z: 0 },
|
gravity: { x: 0, y: 0, z: 0 },
|
||||||
ignoreCollisions: false,
|
ignoreCollisions: false,
|
||||||
visible: true,
|
visible: true,
|
||||||
|
@ -97,6 +97,7 @@ for (var i = 0; i < NUM_BLOCKS; i++) {
|
||||||
dimensions: { x: type.x * SCALE, y: type.y * SCALE, z: type.z * SCALE },
|
dimensions: { x: type.x * SCALE, y: type.y * SCALE, z: type.z * SCALE },
|
||||||
color: { red: type.red, green: type.green, blue: type.blue },
|
color: { red: type.red, green: type.green, blue: type.blue },
|
||||||
gravity: { x: 0, y: GRAVITY, z: 0 },
|
gravity: { x: 0, y: GRAVITY, z: 0 },
|
||||||
|
velocity: { x: 0, y: 0.05, z: 0 },
|
||||||
ignoreCollisions: false,
|
ignoreCollisions: false,
|
||||||
damping: DAMPING,
|
damping: DAMPING,
|
||||||
lifetime: LIFETIME,
|
lifetime: LIFETIME,
|
||||||
|
@ -104,6 +105,11 @@ for (var i = 0; i < NUM_BLOCKS; i++) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function scriptEnding() {
|
function scriptEnding() {
|
||||||
|
Entities.editEntity(edge1, { locked: false });
|
||||||
|
Entities.editEntity(edge2, { locked: false });
|
||||||
|
Entities.editEntity(edge3, { locked: false });
|
||||||
|
Entities.editEntity(edge4, { locked: false });
|
||||||
|
Entities.editEntity(floor, { locked: false });
|
||||||
Entities.deleteEntity(edge1);
|
Entities.deleteEntity(edge1);
|
||||||
Entities.deleteEntity(edge2);
|
Entities.deleteEntity(edge2);
|
||||||
Entities.deleteEntity(edge3);
|
Entities.deleteEntity(edge3);
|
||||||
|
|
|
@ -23,6 +23,8 @@ HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/";
|
||||||
|
|
||||||
var rollSound = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/dice/diceRoll.wav");
|
var rollSound = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/dice/diceRoll.wav");
|
||||||
|
|
||||||
|
var INSUFFICIENT_PERMISSIONS_ERROR_MSG = "You do not have the necessary permissions to create new objects."
|
||||||
|
|
||||||
var screenSize = Controller.getViewportDimensions();
|
var screenSize = Controller.getViewportDimensions();
|
||||||
var offButton = Overlays.addOverlay("image", {
|
var offButton = Overlays.addOverlay("image", {
|
||||||
x: screenSize.x - 48,
|
x: screenSize.x - 48,
|
||||||
|
@ -49,20 +51,26 @@ var LIFETIME = 300;
|
||||||
var MAX_ANGULAR_SPEED = Math.PI;
|
var MAX_ANGULAR_SPEED = Math.PI;
|
||||||
|
|
||||||
function shootDice(position, velocity) {
|
function shootDice(position, velocity) {
|
||||||
for (var i = 0; i < NUMBER_OF_DICE; i++) {
|
if (!Entities.canRez()) {
|
||||||
dice.push(Entities.addEntity(
|
Window.alert(INSUFFICIENT_PERMISSIONS_ERROR_MSG);
|
||||||
{ type: "Model",
|
} else {
|
||||||
modelURL: HIFI_PUBLIC_BUCKET + "models/props/Dice/goldDie.fbx",
|
for (var i = 0; i < NUMBER_OF_DICE; i++) {
|
||||||
position: position,
|
dice.push(Entities.addEntity(
|
||||||
velocity: velocity,
|
{ type: "Model",
|
||||||
rotation: Quat.fromPitchYawRollDegrees(Math.random() * 360, Math.random() * 360, Math.random() * 360),
|
modelURL: HIFI_PUBLIC_BUCKET + "models/props/Dice/goldDie.fbx",
|
||||||
angularVelocity: { x: Math.random() * MAX_ANGULAR_SPEED, y: Math.random() * MAX_ANGULAR_SPEED, z: Math.random() * MAX_ANGULAR_SPEED },
|
position: position,
|
||||||
lifetime: LIFETIME,
|
velocity: velocity,
|
||||||
gravity: { x: 0, y: GRAVITY, z: 0 },
|
rotation: Quat.fromPitchYawRollDegrees(Math.random() * 360, Math.random() * 360, Math.random() * 360),
|
||||||
shapeType: "box",
|
angularVelocity: { x: Math.random() * MAX_ANGULAR_SPEED,
|
||||||
collisionsWillMove: true
|
y: Math.random() * MAX_ANGULAR_SPEED,
|
||||||
}));
|
z: Math.random() * MAX_ANGULAR_SPEED },
|
||||||
position = Vec3.sum(position, Vec3.multiply(DIE_SIZE, Vec3.normalize(Quat.getRight(Camera.getOrientation()))));
|
lifetime: LIFETIME,
|
||||||
|
gravity: { x: 0, y: GRAVITY, z: 0 },
|
||||||
|
shapeType: "box",
|
||||||
|
collisionsWillMove: true
|
||||||
|
}));
|
||||||
|
position = Vec3.sum(position, Vec3.multiply(DIE_SIZE, Vec3.normalize(Quat.getRight(Camera.getOrientation()))));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -132,7 +132,7 @@
|
||||||
this.updateLightIDInUserData();
|
this.updateLightIDInUserData();
|
||||||
} else {
|
} else {
|
||||||
var that = this;
|
var that = this;
|
||||||
Script.setTimeout(function() { that.maybeUpdateLightIDInUserData() }, 500);
|
Script.setTimeout(function() { that.maybeUpdateLightIDInUserData() }, 500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,6 +213,10 @@
|
||||||
this.preload = function(entityID) {
|
this.preload = function(entityID) {
|
||||||
this.preOperation(entityID);
|
this.preOperation(entityID);
|
||||||
};
|
};
|
||||||
|
this.unload = function(){
|
||||||
|
Entities.deleteEntity(this.lightID);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
this.clickReleaseOnEntity = function(entityID, mouseEvent) {
|
this.clickReleaseOnEntity = function(entityID, mouseEvent) {
|
||||||
this.preOperation(entityID);
|
this.preOperation(entityID);
|
||||||
|
|
|
@ -11,8 +11,11 @@
|
||||||
|
|
||||||
var usersWindow = (function () {
|
var usersWindow = (function () {
|
||||||
|
|
||||||
var WINDOW_WIDTH_2D = 160,
|
var HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/",
|
||||||
|
|
||||||
|
WINDOW_WIDTH_2D = 160,
|
||||||
WINDOW_MARGIN_2D = 12,
|
WINDOW_MARGIN_2D = 12,
|
||||||
|
WINDOW_BASE_MARGIN_2D = 6, // A little less is needed in order look correct
|
||||||
WINDOW_FONT_2D = { size: 12 },
|
WINDOW_FONT_2D = { size: 12 },
|
||||||
WINDOW_FOREGROUND_COLOR_2D = { red: 240, green: 240, blue: 240 },
|
WINDOW_FOREGROUND_COLOR_2D = { red: 240, green: 240, blue: 240 },
|
||||||
WINDOW_FOREGROUND_ALPHA_2D = 0.9,
|
WINDOW_FOREGROUND_ALPHA_2D = 0.9,
|
||||||
|
@ -22,6 +25,14 @@ var usersWindow = (function () {
|
||||||
WINDOW_BACKGROUND_ALPHA_2D = 0.7,
|
WINDOW_BACKGROUND_ALPHA_2D = 0.7,
|
||||||
windowPane2D,
|
windowPane2D,
|
||||||
windowHeading2D,
|
windowHeading2D,
|
||||||
|
MINIMIZE_BUTTON_SVG = HIFI_PUBLIC_BUCKET + "images/tools/min-max-toggle.svg",
|
||||||
|
MINIMIZE_BUTTON_SVG_WIDTH = 17.1,
|
||||||
|
MINIMIZE_BUTTON_SVG_HEIGHT = 32.5,
|
||||||
|
MINIMIZE_BUTTON_WIDTH_2D = 14,
|
||||||
|
MINIMIZE_BUTTON_HEIGHT_2D = MINIMIZE_BUTTON_WIDTH_2D,
|
||||||
|
MINIMIZE_BUTTON_COLOR_2D = { red: 255, green: 255, blue: 255 },
|
||||||
|
MINIMIZE_BUTTON_ALPHA_2D = 0.9,
|
||||||
|
minimizeButton2D,
|
||||||
SCROLLBAR_BACKGROUND_WIDTH_2D = 12,
|
SCROLLBAR_BACKGROUND_WIDTH_2D = 12,
|
||||||
SCROLLBAR_BACKGROUND_COLOR_2D = { red: 80, green: 80, blue: 80 },
|
SCROLLBAR_BACKGROUND_COLOR_2D = { red: 80, green: 80, blue: 80 },
|
||||||
SCROLLBAR_BACKGROUND_ALPHA_2D = 0.8,
|
SCROLLBAR_BACKGROUND_ALPHA_2D = 0.8,
|
||||||
|
@ -65,6 +76,7 @@ var usersWindow = (function () {
|
||||||
MENU_ITEM_AFTER = "Chat...",
|
MENU_ITEM_AFTER = "Chat...",
|
||||||
|
|
||||||
isVisible = true,
|
isVisible = true,
|
||||||
|
isMinimized = false,
|
||||||
|
|
||||||
viewportHeight,
|
viewportHeight,
|
||||||
isMirrorDisplay = false,
|
isMirrorDisplay = false,
|
||||||
|
@ -77,7 +89,6 @@ var usersWindow = (function () {
|
||||||
scrollbarBarClickedAt, // 0.0 .. 1.0
|
scrollbarBarClickedAt, // 0.0 .. 1.0
|
||||||
scrollbarValue = 0.0, // 0.0 .. 1.0
|
scrollbarValue = 0.0, // 0.0 .. 1.0
|
||||||
|
|
||||||
HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/",
|
|
||||||
RADIO_BUTTON_SVG = HIFI_PUBLIC_BUCKET + "images/radio-button.svg",
|
RADIO_BUTTON_SVG = HIFI_PUBLIC_BUCKET + "images/radio-button.svg",
|
||||||
RADIO_BUTTON_SVG_DIAMETER = 14,
|
RADIO_BUTTON_SVG_DIAMETER = 14,
|
||||||
RADIO_BUTTON_DISPLAY_SCALE = 0.7, // 1.0 = windowTextHeight
|
RADIO_BUTTON_DISPLAY_SCALE = 0.7, // 1.0 = windowTextHeight
|
||||||
|
@ -89,9 +100,15 @@ var usersWindow = (function () {
|
||||||
nonUsersHeight,
|
nonUsersHeight,
|
||||||
maxWindowHeight;
|
maxWindowHeight;
|
||||||
|
|
||||||
|
if (isMinimized) {
|
||||||
|
windowHeight = windowTextHeight + WINDOW_MARGIN_2D + WINDOW_BASE_MARGIN_2D;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Reserve 5 lines for window heading plus visibility heading and controls
|
// Reserve 5 lines for window heading plus visibility heading and controls
|
||||||
// Subtract windowLineSpacing for both end of user list and end of controls
|
// Subtract windowLineSpacing for both end of user list and end of controls
|
||||||
nonUsersHeight = 5 * windowLineHeight - 2 * windowLineSpacing + VISIBILITY_SPACER_2D + 2 * WINDOW_MARGIN_2D;
|
nonUsersHeight = 5 * windowLineHeight - 2 * windowLineSpacing + VISIBILITY_SPACER_2D + WINDOW_MARGIN_2D
|
||||||
|
+ WINDOW_BASE_MARGIN_2D;
|
||||||
|
|
||||||
// Limit window to height of viewport minus VU meter and mirror if displayed
|
// Limit window to height of viewport minus VU meter and mirror if displayed
|
||||||
windowHeight = linesOfUsers.length * windowLineHeight + nonUsersHeight;
|
windowHeight = linesOfUsers.length * windowLineHeight + nonUsersHeight;
|
||||||
|
@ -102,7 +119,7 @@ var usersWindow = (function () {
|
||||||
windowHeight = Math.max(Math.min(windowHeight, maxWindowHeight), nonUsersHeight);
|
windowHeight = Math.max(Math.min(windowHeight, maxWindowHeight), nonUsersHeight);
|
||||||
|
|
||||||
// Corresponding number of users to actually display
|
// Corresponding number of users to actually display
|
||||||
numUsersToDisplay = Math.max(Math.round((windowHeight - nonUsersHeight) / windowLineHeight), 0);
|
numUsersToDisplay = Math.max(Math.floor((windowHeight - nonUsersHeight) / windowLineHeight), 0);
|
||||||
isUsingScrollbars = 0 < numUsersToDisplay && numUsersToDisplay < linesOfUsers.length;
|
isUsingScrollbars = 0 < numUsersToDisplay && numUsersToDisplay < linesOfUsers.length;
|
||||||
if (isUsingScrollbars) {
|
if (isUsingScrollbars) {
|
||||||
firstUserToDisplay = Math.floor(scrollbarValue * (linesOfUsers.length - numUsersToDisplay));
|
firstUserToDisplay = Math.floor(scrollbarValue * (linesOfUsers.length - numUsersToDisplay));
|
||||||
|
@ -123,6 +140,10 @@ var usersWindow = (function () {
|
||||||
y: viewportHeight - windowHeight + WINDOW_MARGIN_2D
|
y: viewportHeight - windowHeight + WINDOW_MARGIN_2D
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Overlays.editOverlay(minimizeButton2D, {
|
||||||
|
y: viewportHeight - windowHeight + WINDOW_MARGIN_2D / 2
|
||||||
|
});
|
||||||
|
|
||||||
scrollbarBackgroundPosition.y = viewportHeight - windowHeight + WINDOW_MARGIN_2D + windowTextHeight;
|
scrollbarBackgroundPosition.y = viewportHeight - windowHeight + WINDOW_MARGIN_2D + windowTextHeight;
|
||||||
Overlays.editOverlay(scrollbarBackground2D, {
|
Overlays.editOverlay(scrollbarBackground2D, {
|
||||||
y: scrollbarBackgroundPosition.y
|
y: scrollbarBackgroundPosition.y
|
||||||
|
@ -133,10 +154,10 @@ var usersWindow = (function () {
|
||||||
y: scrollbarBarPosition.y
|
y: scrollbarBarPosition.y
|
||||||
});
|
});
|
||||||
Overlays.editOverlay(visibilityHeading2D, {
|
Overlays.editOverlay(visibilityHeading2D, {
|
||||||
y: viewportHeight - 4 * windowLineHeight + windowLineSpacing - WINDOW_MARGIN_2D
|
y: viewportHeight - 4 * windowLineHeight + windowLineSpacing - WINDOW_BASE_MARGIN_2D
|
||||||
});
|
});
|
||||||
for (i = 0; i < visibilityControls2D.length; i += 1) {
|
for (i = 0; i < visibilityControls2D.length; i += 1) {
|
||||||
y = viewportHeight - (3 - i) * windowLineHeight + windowLineSpacing - WINDOW_MARGIN_2D;
|
y = viewportHeight - (3 - i) * windowLineHeight + windowLineSpacing - WINDOW_BASE_MARGIN_2D;
|
||||||
Overlays.editOverlay(visibilityControls2D[i].radioOverlay, { y: y });
|
Overlays.editOverlay(visibilityControls2D[i].radioOverlay, { y: y });
|
||||||
Overlays.editOverlay(visibilityControls2D[i].textOverlay, { y: y });
|
Overlays.editOverlay(visibilityControls2D[i].textOverlay, { y: y });
|
||||||
}
|
}
|
||||||
|
@ -166,29 +187,43 @@ var usersWindow = (function () {
|
||||||
reducedTextWidth,
|
reducedTextWidth,
|
||||||
i;
|
i;
|
||||||
|
|
||||||
maxTextWidth = WINDOW_WIDTH_2D - (isUsingScrollbars ? SCROLLBAR_BACKGROUND_WIDTH_2D : 0) - 2 * WINDOW_MARGIN_2D;
|
if (!isMinimized) {
|
||||||
ellipsisWidth = Overlays.textSize(windowPane2D, "...").width;
|
maxTextWidth = WINDOW_WIDTH_2D - (isUsingScrollbars ? SCROLLBAR_BACKGROUND_WIDTH_2D : 0) - 2 * WINDOW_MARGIN_2D;
|
||||||
reducedTextWidth = maxTextWidth - ellipsisWidth;
|
ellipsisWidth = Overlays.textSize(windowPane2D, "...").width;
|
||||||
|
reducedTextWidth = maxTextWidth - ellipsisWidth;
|
||||||
|
|
||||||
for (i = 0; i < numUsersToDisplay; i += 1) {
|
for (i = 0; i < numUsersToDisplay; i += 1) {
|
||||||
user = usersOnline[linesOfUsers[firstUserToDisplay + i]];
|
user = usersOnline[linesOfUsers[firstUserToDisplay + i]];
|
||||||
userText = user.text;
|
userText = user.text;
|
||||||
textWidth = user.textWidth;
|
textWidth = user.textWidth;
|
||||||
|
|
||||||
if (textWidth > maxTextWidth) {
|
if (textWidth > maxTextWidth) {
|
||||||
// Trim and append "..." to fit window width
|
// Trim and append "..." to fit window width
|
||||||
maxTextWidth = maxTextWidth - Overlays.textSize(windowPane2D, "...").width;
|
maxTextWidth = maxTextWidth - Overlays.textSize(windowPane2D, "...").width;
|
||||||
while (textWidth > reducedTextWidth) {
|
while (textWidth > reducedTextWidth) {
|
||||||
userText = userText.slice(0, -1);
|
userText = userText.slice(0, -1);
|
||||||
textWidth = Overlays.textSize(windowPane2D, userText).width;
|
textWidth = Overlays.textSize(windowPane2D, userText).width;
|
||||||
|
}
|
||||||
|
userText += "...";
|
||||||
}
|
}
|
||||||
userText += "...";
|
|
||||||
|
displayText += "\n" + userText;
|
||||||
}
|
}
|
||||||
|
|
||||||
displayText += "\n" + userText;
|
displayText = displayText.slice(1); // Remove leading "\n".
|
||||||
}
|
|
||||||
|
|
||||||
displayText = displayText.slice(1); // Remove leading "\n".
|
scrollbarBackgroundHeight = numUsersToDisplay * windowLineHeight - windowLineSpacing / 2;
|
||||||
|
Overlays.editOverlay(scrollbarBackground2D, {
|
||||||
|
height: scrollbarBackgroundHeight,
|
||||||
|
visible: isUsingScrollbars
|
||||||
|
});
|
||||||
|
scrollbarBarHeight = Math.max(numUsersToDisplay / linesOfUsers.length * scrollbarBackgroundHeight,
|
||||||
|
SCROLLBAR_BAR_MIN_HEIGHT);
|
||||||
|
Overlays.editOverlay(scrollbarBar2D, {
|
||||||
|
height: scrollbarBarHeight,
|
||||||
|
visible: isUsingScrollbars
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Overlays.editOverlay(windowPane2D, {
|
Overlays.editOverlay(windowPane2D, {
|
||||||
height: windowHeight,
|
height: windowHeight,
|
||||||
|
@ -198,20 +233,6 @@ var usersWindow = (function () {
|
||||||
Overlays.editOverlay(windowHeading2D, {
|
Overlays.editOverlay(windowHeading2D, {
|
||||||
text: linesOfUsers.length > 0 ? "Users online" : "No users online"
|
text: linesOfUsers.length > 0 ? "Users online" : "No users online"
|
||||||
});
|
});
|
||||||
|
|
||||||
scrollbarBackgroundHeight = numUsersToDisplay * windowLineHeight - windowLineSpacing / 2;
|
|
||||||
Overlays.editOverlay(scrollbarBackground2D, {
|
|
||||||
height: scrollbarBackgroundHeight,
|
|
||||||
visible: isUsingScrollbars
|
|
||||||
});
|
|
||||||
scrollbarBarHeight = Math.max(numUsersToDisplay / linesOfUsers.length * scrollbarBackgroundHeight,
|
|
||||||
SCROLLBAR_BAR_MIN_HEIGHT);
|
|
||||||
Overlays.editOverlay(scrollbarBar2D, {
|
|
||||||
height: scrollbarBarHeight,
|
|
||||||
visible: isUsingScrollbars
|
|
||||||
});
|
|
||||||
|
|
||||||
updateOverlayPositions();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function pollUsers() {
|
function pollUsers() {
|
||||||
|
@ -264,6 +285,7 @@ var usersWindow = (function () {
|
||||||
|
|
||||||
calculateWindowHeight();
|
calculateWindowHeight();
|
||||||
updateUsersDisplay();
|
updateUsersDisplay();
|
||||||
|
updateOverlayPositions();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
print("Error: Request for users status returned " + usersRequest.status + " " + usersRequest.statusText);
|
print("Error: Request for users status returned " + usersRequest.status + " " + usersRequest.statusText);
|
||||||
|
@ -289,9 +311,22 @@ var usersWindow = (function () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function setVisible(visible) {
|
function updateOverlayVisibility() {
|
||||||
var i;
|
var i;
|
||||||
|
|
||||||
|
Overlays.editOverlay(windowPane2D, { visible: isVisible });
|
||||||
|
Overlays.editOverlay(windowHeading2D, { visible: isVisible });
|
||||||
|
Overlays.editOverlay(minimizeButton2D, { visible: isVisible });
|
||||||
|
Overlays.editOverlay(scrollbarBackground2D, { visible: isVisible && isUsingScrollbars && !isMinimized });
|
||||||
|
Overlays.editOverlay(scrollbarBar2D, { visible: isVisible && isUsingScrollbars && !isMinimized });
|
||||||
|
Overlays.editOverlay(visibilityHeading2D, { visible: isVisible && !isMinimized });
|
||||||
|
for (i = 0; i < visibilityControls2D.length; i += 1) {
|
||||||
|
Overlays.editOverlay(visibilityControls2D[i].radioOverlay, { visible: isVisible && !isMinimized });
|
||||||
|
Overlays.editOverlay(visibilityControls2D[i].textOverlay, { visible: isVisible && !isMinimized });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setVisible(visible) {
|
||||||
isVisible = visible;
|
isVisible = visible;
|
||||||
|
|
||||||
if (isVisible) {
|
if (isVisible) {
|
||||||
|
@ -303,15 +338,15 @@ var usersWindow = (function () {
|
||||||
usersTimer = null;
|
usersTimer = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Overlays.editOverlay(windowPane2D, { visible: isVisible });
|
updateOverlayVisibility();
|
||||||
Overlays.editOverlay(windowHeading2D, { visible: isVisible });
|
}
|
||||||
Overlays.editOverlay(scrollbarBackground2D, { visible: isVisible && isUsingScrollbars });
|
|
||||||
Overlays.editOverlay(scrollbarBar2D, { visible: isVisible && isUsingScrollbars });
|
function setMinimized(minimized) {
|
||||||
Overlays.editOverlay(visibilityHeading2D, { visible: isVisible });
|
isMinimized = minimized;
|
||||||
for (i = 0; i < visibilityControls2D.length; i += 1) {
|
Overlays.editOverlay(minimizeButton2D, {
|
||||||
Overlays.editOverlay(visibilityControls2D[i].radioOverlay, { visible: isVisible });
|
subImage: { y: isMinimized ? MINIMIZE_BUTTON_SVG_HEIGHT / 2 : 0 }
|
||||||
Overlays.editOverlay(visibilityControls2D[i].textOverlay, { visible: isVisible });
|
});
|
||||||
}
|
updateOverlayVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
function onMenuItemEvent(event) {
|
function onMenuItemEvent(event) {
|
||||||
|
@ -360,6 +395,8 @@ var usersWindow = (function () {
|
||||||
//print("Go to " + usersOnline[linesOfUsers[userClicked]].username);
|
//print("Go to " + usersOnline[linesOfUsers[userClicked]].username);
|
||||||
location.goToUser(usersOnline[linesOfUsers[userClicked]].username);
|
location.goToUser(usersOnline[linesOfUsers[userClicked]].username);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
visibilityChanged = false;
|
visibilityChanged = false;
|
||||||
|
@ -376,6 +413,15 @@ var usersWindow = (function () {
|
||||||
visibilityControls2D[i].selected = clickedOverlay === visibilityControls2D[i].textOverlay;
|
visibilityControls2D[i].selected = clickedOverlay === visibilityControls2D[i].textOverlay;
|
||||||
}
|
}
|
||||||
updateVisibilityControls();
|
updateVisibilityControls();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clickedOverlay === minimizeButton2D) {
|
||||||
|
setMinimized(!isMinimized);
|
||||||
|
calculateWindowHeight();
|
||||||
|
updateOverlayPositions();
|
||||||
|
updateUsersDisplay();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clickedOverlay === scrollbarBar2D) {
|
if (clickedOverlay === scrollbarBar2D) {
|
||||||
|
@ -384,6 +430,7 @@ var usersWindow = (function () {
|
||||||
backgroundAlpha: SCROLLBAR_BAR_SELECTED_ALPHA_2D
|
backgroundAlpha: SCROLLBAR_BAR_SELECTED_ALPHA_2D
|
||||||
});
|
});
|
||||||
isMovingScrollbar = true;
|
isMovingScrollbar = true;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clickedOverlay === scrollbarBackground2D) {
|
if (clickedOverlay === scrollbarBackground2D) {
|
||||||
|
@ -398,6 +445,7 @@ var usersWindow = (function () {
|
||||||
firstUserToDisplay = Math.floor(scrollbarValue * (linesOfUsers.length - numUsersToDisplay));
|
firstUserToDisplay = Math.floor(scrollbarValue * (linesOfUsers.length - numUsersToDisplay));
|
||||||
updateOverlayPositions();
|
updateOverlayPositions();
|
||||||
updateUsersDisplay();
|
updateUsersDisplay();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -492,7 +540,19 @@ var usersWindow = (function () {
|
||||||
backgroundAlpha: 0.0,
|
backgroundAlpha: 0.0,
|
||||||
text: "No users online",
|
text: "No users online",
|
||||||
font: WINDOW_FONT_2D,
|
font: WINDOW_FONT_2D,
|
||||||
visible: isVisible
|
visible: isVisible && !isMinimized
|
||||||
|
});
|
||||||
|
|
||||||
|
minimizeButton2D = Overlays.addOverlay("image", {
|
||||||
|
x: WINDOW_WIDTH_2D - WINDOW_MARGIN_2D / 2 - MINIMIZE_BUTTON_WIDTH_2D,
|
||||||
|
y: viewportHeight,
|
||||||
|
width: MINIMIZE_BUTTON_WIDTH_2D,
|
||||||
|
height: MINIMIZE_BUTTON_HEIGHT_2D,
|
||||||
|
imageURL: MINIMIZE_BUTTON_SVG,
|
||||||
|
subImage: { x: 0, y: 0, width: MINIMIZE_BUTTON_SVG_WIDTH, height: MINIMIZE_BUTTON_SVG_HEIGHT / 2 },
|
||||||
|
color: MINIMIZE_BUTTON_COLOR_2D,
|
||||||
|
alpha: MINIMIZE_BUTTON_ALPHA_2D,
|
||||||
|
visible: isVisible && !isMinimized
|
||||||
});
|
});
|
||||||
|
|
||||||
scrollbarBackgroundPosition = {
|
scrollbarBackgroundPosition = {
|
||||||
|
@ -507,7 +567,7 @@ var usersWindow = (function () {
|
||||||
backgroundColor: SCROLLBAR_BACKGROUND_COLOR_2D,
|
backgroundColor: SCROLLBAR_BACKGROUND_COLOR_2D,
|
||||||
backgroundAlpha: SCROLLBAR_BACKGROUND_ALPHA_2D,
|
backgroundAlpha: SCROLLBAR_BACKGROUND_ALPHA_2D,
|
||||||
text: "",
|
text: "",
|
||||||
visible: isVisible && isUsingScrollbars
|
visible: isVisible && isUsingScrollbars && !isMinimized
|
||||||
});
|
});
|
||||||
|
|
||||||
scrollbarBarPosition = {
|
scrollbarBarPosition = {
|
||||||
|
@ -522,7 +582,7 @@ var usersWindow = (function () {
|
||||||
backgroundColor: SCROLLBAR_BAR_COLOR_2D,
|
backgroundColor: SCROLLBAR_BAR_COLOR_2D,
|
||||||
backgroundAlpha: SCROLLBAR_BAR_ALPHA_2D,
|
backgroundAlpha: SCROLLBAR_BAR_ALPHA_2D,
|
||||||
text: "",
|
text: "",
|
||||||
visible: isVisible && isUsingScrollbars
|
visible: isVisible && isUsingScrollbars && !isMinimized
|
||||||
});
|
});
|
||||||
|
|
||||||
visibilityHeading2D = Overlays.addOverlay("text", {
|
visibilityHeading2D = Overlays.addOverlay("text", {
|
||||||
|
@ -537,7 +597,7 @@ var usersWindow = (function () {
|
||||||
backgroundAlpha: 0.0,
|
backgroundAlpha: 0.0,
|
||||||
text: "I am visible to:",
|
text: "I am visible to:",
|
||||||
font: WINDOW_FONT_2D,
|
font: WINDOW_FONT_2D,
|
||||||
visible: isVisible
|
visible: isVisible && !isMinimized
|
||||||
});
|
});
|
||||||
|
|
||||||
myVisibility = GlobalServices.findableBy;
|
myVisibility = GlobalServices.findableBy;
|
||||||
|
@ -561,7 +621,8 @@ var usersWindow = (function () {
|
||||||
height: RADIO_BUTTON_SVG_DIAMETER
|
height: RADIO_BUTTON_SVG_DIAMETER
|
||||||
},
|
},
|
||||||
color: WINDOW_HEADING_COLOR_2D,
|
color: WINDOW_HEADING_COLOR_2D,
|
||||||
alpha: WINDOW_FOREGROUND_ALPHA_2D
|
alpha: WINDOW_FOREGROUND_ALPHA_2D,
|
||||||
|
visible: isVisible && !isMinimized
|
||||||
}),
|
}),
|
||||||
textOverlay: Overlays.addOverlay("text", {
|
textOverlay: Overlays.addOverlay("text", {
|
||||||
x: WINDOW_MARGIN_2D,
|
x: WINDOW_MARGIN_2D,
|
||||||
|
@ -575,7 +636,7 @@ var usersWindow = (function () {
|
||||||
backgroundAlpha: 0.0,
|
backgroundAlpha: 0.0,
|
||||||
text: optionText,
|
text: optionText,
|
||||||
font: WINDOW_FONT_2D,
|
font: WINDOW_FONT_2D,
|
||||||
visible: isVisible
|
visible: isVisible && !isMinimized
|
||||||
}),
|
}),
|
||||||
selected: myVisibility === VISIBILITY_VALUES[0]
|
selected: myVisibility === VISIBILITY_VALUES[0]
|
||||||
}];
|
}];
|
||||||
|
@ -634,6 +695,7 @@ var usersWindow = (function () {
|
||||||
Script.clearTimeout(usersTimer);
|
Script.clearTimeout(usersTimer);
|
||||||
Overlays.deleteOverlay(windowPane2D);
|
Overlays.deleteOverlay(windowPane2D);
|
||||||
Overlays.deleteOverlay(windowHeading2D);
|
Overlays.deleteOverlay(windowHeading2D);
|
||||||
|
Overlays.deleteOverlay(minimizeButton2D);
|
||||||
Overlays.deleteOverlay(scrollbarBackground2D);
|
Overlays.deleteOverlay(scrollbarBackground2D);
|
||||||
Overlays.deleteOverlay(scrollbarBar2D);
|
Overlays.deleteOverlay(scrollbarBar2D);
|
||||||
Overlays.deleteOverlay(visibilityHeading2D);
|
Overlays.deleteOverlay(visibilityHeading2D);
|
||||||
|
|
|
@ -68,6 +68,7 @@
|
||||||
#include <MainWindow.h>
|
#include <MainWindow.h>
|
||||||
#include <ModelEntityItem.h>
|
#include <ModelEntityItem.h>
|
||||||
#include <NetworkAccessManager.h>
|
#include <NetworkAccessManager.h>
|
||||||
|
#include <NetworkingConstants.h>
|
||||||
#include <OctalCode.h>
|
#include <OctalCode.h>
|
||||||
#include <OctreeSceneStats.h>
|
#include <OctreeSceneStats.h>
|
||||||
#include <PacketHeaders.h>
|
#include <PacketHeaders.h>
|
||||||
|
@ -136,6 +137,13 @@
|
||||||
#include "ui/StandAloneJSConsole.h"
|
#include "ui/StandAloneJSConsole.h"
|
||||||
#include "ui/Stats.h"
|
#include "ui/Stats.h"
|
||||||
|
|
||||||
|
// ON WIndows PC, NVidia Optimus laptop, we want to enable NVIDIA GPU
|
||||||
|
#if defined(Q_OS_WIN)
|
||||||
|
extern "C" {
|
||||||
|
_declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
// Starfield information
|
// Starfield information
|
||||||
|
@ -241,7 +249,7 @@ bool setupEssentials(int& argc, char** argv) {
|
||||||
auto jsConsole = DependencyManager::set<StandAloneJSConsole>();
|
auto jsConsole = DependencyManager::set<StandAloneJSConsole>();
|
||||||
auto dialogsManager = DependencyManager::set<DialogsManager>();
|
auto dialogsManager = DependencyManager::set<DialogsManager>();
|
||||||
auto bandwidthRecorder = DependencyManager::set<BandwidthRecorder>();
|
auto bandwidthRecorder = DependencyManager::set<BandwidthRecorder>();
|
||||||
auto resouceCacheSharedItems = DependencyManager::set<ResouceCacheSharedItems>();
|
auto resourceCacheSharedItems = DependencyManager::set<ResourceCacheSharedItems>();
|
||||||
auto entityScriptingInterface = DependencyManager::set<EntityScriptingInterface>();
|
auto entityScriptingInterface = DependencyManager::set<EntityScriptingInterface>();
|
||||||
auto windowScriptingInterface = DependencyManager::set<WindowScriptingInterface>();
|
auto windowScriptingInterface = DependencyManager::set<WindowScriptingInterface>();
|
||||||
#if defined(Q_OS_MAC) || defined(Q_OS_WIN)
|
#if defined(Q_OS_MAC) || defined(Q_OS_WIN)
|
||||||
|
@ -418,7 +426,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
||||||
connect(&accountManager, &AccountManager::usernameChanged, this, &Application::updateWindowTitle);
|
connect(&accountManager, &AccountManager::usernameChanged, this, &Application::updateWindowTitle);
|
||||||
|
|
||||||
// set the account manager's root URL and trigger a login request if we don't have the access token
|
// set the account manager's root URL and trigger a login request if we don't have the access token
|
||||||
accountManager.setAuthURL(DEFAULT_NODE_AUTH_URL);
|
accountManager.setAuthURL(NetworkingConstants::METAVERSE_SERVER_URL);
|
||||||
UserActivityLogger::getInstance().launch(applicationVersion());
|
UserActivityLogger::getInstance().launch(applicationVersion());
|
||||||
|
|
||||||
// once the event loop has started, check and signal for an access token
|
// once the event loop has started, check and signal for an access token
|
||||||
|
@ -646,6 +654,11 @@ void Application::initializeGL() {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
qDebug() << "GL Version: " << QString((const char*) glGetString(GL_VERSION));
|
||||||
|
qDebug() << "GL Shader Language Version: " << QString((const char*) glGetString(GL_SHADING_LANGUAGE_VERSION));
|
||||||
|
qDebug() << "GL Vendor: " << QString((const char*) glGetString(GL_VENDOR));
|
||||||
|
qDebug() << "GL Renderer: " << QString((const char*) glGetString(GL_RENDERER));
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
GLenum err = glewInit();
|
GLenum err = glewInit();
|
||||||
if (GLEW_OK != err) {
|
if (GLEW_OK != err) {
|
||||||
|
|
|
@ -685,6 +685,10 @@ void SkeletonModel::computeBoundingShape(const FBXGeometry& geometry) {
|
||||||
* joint.preTransform * glm::mat4_cast(modifiedRotation) * joint.postTransform;
|
* joint.preTransform * glm::mat4_cast(modifiedRotation) * joint.postTransform;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Each joint contributes its point to the bounding box
|
||||||
|
glm::vec3 jointPosition = extractTranslation(transforms[i]);
|
||||||
|
totalExtents.addPoint(jointPosition);
|
||||||
|
|
||||||
Shape* shape = _shapes[i];
|
Shape* shape = _shapes[i];
|
||||||
if (!shape) {
|
if (!shape) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -694,8 +698,6 @@ void SkeletonModel::computeBoundingShape(const FBXGeometry& geometry) {
|
||||||
// that contains the sphere centered at the end of the joint with radius of the bone.
|
// that contains the sphere centered at the end of the joint with radius of the bone.
|
||||||
|
|
||||||
// TODO: skip hand and arm shapes for bounding box calculation
|
// TODO: skip hand and arm shapes for bounding box calculation
|
||||||
glm::vec3 jointPosition = extractTranslation(transforms[i]);
|
|
||||||
|
|
||||||
int type = shape->getType();
|
int type = shape->getType();
|
||||||
if (type == CAPSULE_SHAPE) {
|
if (type == CAPSULE_SHAPE) {
|
||||||
// add the two furthest surface points of the capsule
|
// add the two furthest surface points of the capsule
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
#include <qwebview.h>
|
#include <qwebview.h>
|
||||||
|
|
||||||
#include <AccountManager.h>
|
#include <AccountManager.h>
|
||||||
#include <LimitedNodeList.h>
|
#include <NetworkingConstants.h>
|
||||||
|
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
#include "DataWebPage.h"
|
#include "DataWebPage.h"
|
||||||
|
@ -39,7 +39,7 @@ DataWebDialog* DataWebDialog::dialogForPath(const QString& path,
|
||||||
connect(dialogWebView->page()->mainFrame(), &QWebFrame::javaScriptWindowObjectCleared,
|
connect(dialogWebView->page()->mainFrame(), &QWebFrame::javaScriptWindowObjectCleared,
|
||||||
dialogWebView, &DataWebDialog::addJavascriptObjectsToWindow);
|
dialogWebView, &DataWebDialog::addJavascriptObjectsToWindow);
|
||||||
|
|
||||||
QUrl dataWebUrl(DEFAULT_NODE_AUTH_URL);
|
QUrl dataWebUrl(NetworkingConstants::METAVERSE_SERVER_URL);
|
||||||
dataWebUrl.setPath(path);
|
dataWebUrl.setPath(path);
|
||||||
|
|
||||||
qDebug() << "Opening a data web dialog for" << dataWebUrl.toString();
|
qDebug() << "Opening a data web dialog for" << dataWebUrl.toString();
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QPixmap>
|
#include <QPixmap>
|
||||||
|
|
||||||
|
#include <NetworkingConstants.h>
|
||||||
#include <PathUtils.h>
|
#include <PathUtils.h>
|
||||||
|
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
|
@ -23,7 +24,7 @@
|
||||||
#include "LoginDialog.h"
|
#include "LoginDialog.h"
|
||||||
#include "UIUtil.h"
|
#include "UIUtil.h"
|
||||||
|
|
||||||
const QString FORGOT_PASSWORD_URL = "https://metaverse.highfidelity.com/users/password/new";
|
const QString FORGOT_PASSWORD_URL = NetworkingConstants::METAVERSE_SERVER_URL.toString() + "/users/password/new";
|
||||||
|
|
||||||
LoginDialog::LoginDialog(QWidget* parent) :
|
LoginDialog::LoginDialog(QWidget* parent) :
|
||||||
FramelessDialog(parent, 0, FramelessDialog::POSITION_TOP),
|
FramelessDialog(parent, 0, FramelessDialog::POSITION_TOP),
|
||||||
|
|
|
@ -101,7 +101,7 @@ void EntityTreeRenderer::init() {
|
||||||
_lastAvatarPosition = _viewState->getAvatarPosition() + glm::vec3((float)TREE_SCALE);
|
_lastAvatarPosition = _viewState->getAvatarPosition() + glm::vec3((float)TREE_SCALE);
|
||||||
|
|
||||||
connect(entityTree, &EntityTree::deletingEntity, this, &EntityTreeRenderer::deletingEntity);
|
connect(entityTree, &EntityTree::deletingEntity, this, &EntityTreeRenderer::deletingEntity);
|
||||||
connect(entityTree, &EntityTree::addingEntity, this, &EntityTreeRenderer::checkAndCallPreload);
|
connect(entityTree, &EntityTree::addingEntity, this, &EntityTreeRenderer::addingEntity);
|
||||||
connect(entityTree, &EntityTree::entityScriptChanging, this, &EntityTreeRenderer::entitySciptChanging);
|
connect(entityTree, &EntityTree::entityScriptChanging, this, &EntityTreeRenderer::entitySciptChanging);
|
||||||
connect(entityTree, &EntityTree::changingEntityID, this, &EntityTreeRenderer::changingEntityID);
|
connect(entityTree, &EntityTree::changingEntityID, this, &EntityTreeRenderer::changingEntityID);
|
||||||
}
|
}
|
||||||
|
@ -193,7 +193,7 @@ QScriptValue EntityTreeRenderer::loadEntityScript(EntityItem* entity, bool isPre
|
||||||
// can accomplish all we need to here with just the script "text" and the ID.
|
// can accomplish all we need to here with just the script "text" and the ID.
|
||||||
EntityItemID entityID = entity->getEntityItemID();
|
EntityItemID entityID = entity->getEntityItemID();
|
||||||
QString entityScript = entity->getScript();
|
QString entityScript = entity->getScript();
|
||||||
|
|
||||||
if (_entityScripts.contains(entityID)) {
|
if (_entityScripts.contains(entityID)) {
|
||||||
EntityScriptDetails details = _entityScripts[entityID];
|
EntityScriptDetails details = _entityScripts[entityID];
|
||||||
|
|
||||||
|
@ -217,7 +217,6 @@ QScriptValue EntityTreeRenderer::loadEntityScript(EntityItem* entity, bool isPre
|
||||||
|
|
||||||
if (isPending && isPreload && isURL) {
|
if (isPending && isPreload && isURL) {
|
||||||
_waitingOnPreload.insert(url, entityID);
|
_waitingOnPreload.insert(url, entityID);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto scriptCache = DependencyManager::get<ScriptCache>();
|
auto scriptCache = DependencyManager::get<ScriptCache>();
|
||||||
|
@ -941,6 +940,10 @@ void EntityTreeRenderer::deletingEntity(const EntityItemID& entityID) {
|
||||||
_entityScripts.remove(entityID);
|
_entityScripts.remove(entityID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EntityTreeRenderer::addingEntity(const EntityItemID& entityID) {
|
||||||
|
checkAndCallPreload(entityID);
|
||||||
|
}
|
||||||
|
|
||||||
void EntityTreeRenderer::entitySciptChanging(const EntityItemID& entityID) {
|
void EntityTreeRenderer::entitySciptChanging(const EntityItemID& entityID) {
|
||||||
if (_tree && !_shuttingDown) {
|
if (_tree && !_shuttingDown) {
|
||||||
checkAndCallUnload(entityID);
|
checkAndCallUnload(entityID);
|
||||||
|
|
|
@ -105,6 +105,7 @@ signals:
|
||||||
void leaveEntity(const EntityItemID& entityItemID);
|
void leaveEntity(const EntityItemID& entityItemID);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
void addingEntity(const EntityItemID& entityID);
|
||||||
void deletingEntity(const EntityItemID& entityID);
|
void deletingEntity(const EntityItemID& entityID);
|
||||||
void changingEntityID(const EntityItemID& oldEntityID, const EntityItemID& newEntityID);
|
void changingEntityID(const EntityItemID& oldEntityID, const EntityItemID& newEntityID);
|
||||||
void entitySciptChanging(const EntityItemID& entityID);
|
void entitySciptChanging(const EntityItemID& entityID);
|
||||||
|
|
|
@ -61,7 +61,7 @@ void RenderableModelEntityItem::remapTextures() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_model->isLoadedWithTextures()) {
|
if (!_model->isLoadedWithTextures()) {
|
||||||
return; // nothing to do if the model has not yet loaded it's default textures
|
return; // nothing to do if the model has not yet loaded its default textures
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_originalTexturesRead && _model->isLoadedWithTextures()) {
|
if (!_originalTexturesRead && _model->isLoadedWithTextures()) {
|
||||||
|
@ -220,7 +220,7 @@ Model* RenderableModelEntityItem::getModel(EntityTreeRenderer* renderer) {
|
||||||
// if we have a URL, then we will want to end up returning a model...
|
// if we have a URL, then we will want to end up returning a model...
|
||||||
if (!getModelURL().isEmpty()) {
|
if (!getModelURL().isEmpty()) {
|
||||||
|
|
||||||
// if we have a previously allocated model, but it's URL doesn't match
|
// if we have a previously allocated model, but its URL doesn't match
|
||||||
// then we need to let our renderer update our model for us.
|
// then we need to let our renderer update our model for us.
|
||||||
if (_model && QUrl(getModelURL()) != _model->getURL()) {
|
if (_model && QUrl(getModelURL()) != _model->getURL()) {
|
||||||
result = _model = _myRenderer->updateModel(_model, getModelURL(), getCollisionModelURL());
|
result = _model = _myRenderer->updateModel(_model, getModelURL(), getCollisionModelURL());
|
||||||
|
@ -293,7 +293,7 @@ bool RenderableModelEntityItem::isReadyToComputeShape() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_model->getCollisionURL().isEmpty()) {
|
if (_model->getCollisionURL().isEmpty()) {
|
||||||
// no model url, so we're ready to compute a shape.
|
// no collision-model url, so we're ready to compute a shape (of type None).
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -312,35 +312,30 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) {
|
||||||
info.setParams(getShapeType(), 0.5f * getDimensions());
|
info.setParams(getShapeType(), 0.5f * getDimensions());
|
||||||
} else {
|
} else {
|
||||||
const QSharedPointer<NetworkGeometry> collisionNetworkGeometry = _model->getCollisionGeometry();
|
const QSharedPointer<NetworkGeometry> collisionNetworkGeometry = _model->getCollisionGeometry();
|
||||||
const FBXGeometry& fbxGeometry = collisionNetworkGeometry->getFBXGeometry();
|
const FBXGeometry& collisionGeometry = collisionNetworkGeometry->getFBXGeometry();
|
||||||
|
|
||||||
|
const QSharedPointer<NetworkGeometry> renderNetworkGeometry = _model->getGeometry();
|
||||||
|
const FBXGeometry& renderGeometry = renderNetworkGeometry->getFBXGeometry();
|
||||||
|
|
||||||
AABox aaBox;
|
|
||||||
_points.clear();
|
_points.clear();
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
|
|
||||||
// the way OBJ files get read, each section under a "g" line is its own meshPart. We only expect
|
// the way OBJ files get read, each section under a "g" line is its own meshPart. We only expect
|
||||||
// to find one actual "mesh" (with one or more meshParts in it), but we loop over the meshes, just in case.
|
// to find one actual "mesh" (with one or more meshParts in it), but we loop over the meshes, just in case.
|
||||||
foreach (const FBXMesh& mesh, fbxGeometry.meshes) {
|
foreach (const FBXMesh& mesh, collisionGeometry.meshes) {
|
||||||
// each meshPart is a convex hull
|
// each meshPart is a convex hull
|
||||||
foreach (const FBXMeshPart &meshPart, mesh.parts) {
|
foreach (const FBXMeshPart &meshPart, mesh.parts) {
|
||||||
QVector<glm::vec3> pointsInPart;
|
QVector<glm::vec3> pointsInPart;
|
||||||
|
|
||||||
// run through all the triangles and (uniquely) add each point to the hull
|
// run through all the triangles and (uniquely) add each point to the hull
|
||||||
unsigned int triangleCount = meshPart.triangleIndices.size() / 3;
|
unsigned int triangleCount = meshPart.triangleIndices.size() / 3;
|
||||||
assert((unsigned int)meshPart.triangleIndices.size() == triangleCount*3);
|
|
||||||
for (unsigned int j = 0; j < triangleCount; j++) {
|
for (unsigned int j = 0; j < triangleCount; j++) {
|
||||||
unsigned int p0Index = meshPart.triangleIndices[j*3];
|
unsigned int p0Index = meshPart.triangleIndices[j*3];
|
||||||
unsigned int p1Index = meshPart.triangleIndices[j*3+1];
|
unsigned int p1Index = meshPart.triangleIndices[j*3+1];
|
||||||
unsigned int p2Index = meshPart.triangleIndices[j*3+2];
|
unsigned int p2Index = meshPart.triangleIndices[j*3+2];
|
||||||
assert(p0Index < (unsigned int)mesh.vertices.size());
|
|
||||||
assert(p1Index < (unsigned int)mesh.vertices.size());
|
|
||||||
assert(p2Index < (unsigned int)mesh.vertices.size());
|
|
||||||
glm::vec3 p0 = mesh.vertices[p0Index];
|
glm::vec3 p0 = mesh.vertices[p0Index];
|
||||||
glm::vec3 p1 = mesh.vertices[p1Index];
|
glm::vec3 p1 = mesh.vertices[p1Index];
|
||||||
glm::vec3 p2 = mesh.vertices[p2Index];
|
glm::vec3 p2 = mesh.vertices[p2Index];
|
||||||
aaBox += p0;
|
|
||||||
aaBox += p1;
|
|
||||||
aaBox += p2;
|
|
||||||
if (!pointsInPart.contains(p0)) {
|
if (!pointsInPart.contains(p0)) {
|
||||||
pointsInPart << p0;
|
pointsInPart << p0;
|
||||||
}
|
}
|
||||||
|
@ -360,18 +355,10 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) {
|
||||||
unsigned int p1Index = meshPart.quadIndices[j*4+1];
|
unsigned int p1Index = meshPart.quadIndices[j*4+1];
|
||||||
unsigned int p2Index = meshPart.quadIndices[j*4+2];
|
unsigned int p2Index = meshPart.quadIndices[j*4+2];
|
||||||
unsigned int p3Index = meshPart.quadIndices[j*4+3];
|
unsigned int p3Index = meshPart.quadIndices[j*4+3];
|
||||||
assert(p0Index < (unsigned int)mesh.vertices.size());
|
|
||||||
assert(p1Index < (unsigned int)mesh.vertices.size());
|
|
||||||
assert(p2Index < (unsigned int)mesh.vertices.size());
|
|
||||||
assert(p3Index < (unsigned int)mesh.vertices.size());
|
|
||||||
glm::vec3 p0 = mesh.vertices[p0Index];
|
glm::vec3 p0 = mesh.vertices[p0Index];
|
||||||
glm::vec3 p1 = mesh.vertices[p1Index];
|
glm::vec3 p1 = mesh.vertices[p1Index];
|
||||||
glm::vec3 p2 = mesh.vertices[p2Index];
|
glm::vec3 p2 = mesh.vertices[p2Index];
|
||||||
glm::vec3 p3 = mesh.vertices[p3Index];
|
glm::vec3 p3 = mesh.vertices[p3Index];
|
||||||
aaBox += p0;
|
|
||||||
aaBox += p1;
|
|
||||||
aaBox += p2;
|
|
||||||
aaBox += p3;
|
|
||||||
if (!pointsInPart.contains(p0)) {
|
if (!pointsInPart.contains(p0)) {
|
||||||
pointsInPart << p0;
|
pointsInPart << p0;
|
||||||
}
|
}
|
||||||
|
@ -386,6 +373,11 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pointsInPart.size() == 0) {
|
||||||
|
qDebug() << "Warning -- meshPart has no faces";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// add next convex hull
|
// add next convex hull
|
||||||
QVector<glm::vec3> newMeshPoints;
|
QVector<glm::vec3> newMeshPoints;
|
||||||
_points << newMeshPoints;
|
_points << newMeshPoints;
|
||||||
|
@ -394,11 +386,14 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure we aren't about to divide by zero
|
// We expect that the collision model will have the same units and will be displaced
|
||||||
glm::vec3 aaBoxDim = aaBox.getDimensions();
|
// from its origin in the same way the visual model is. The visual model has
|
||||||
aaBoxDim = glm::clamp(aaBoxDim, glm::vec3(FLT_EPSILON), aaBoxDim);
|
// been centered and probably scaled. We take the scaling and offset which were applied
|
||||||
|
// to the visual model and apply them to the collision model (without regard for the
|
||||||
|
// collision model's extents).
|
||||||
|
|
||||||
|
glm::vec3 scale = _dimensions / renderGeometry.getUnscaledMeshExtents().size();
|
||||||
|
|
||||||
glm::vec3 scale = _dimensions / aaBoxDim;
|
|
||||||
// multiply each point by scale before handing the point-set off to the physics engine
|
// multiply each point by scale before handing the point-set off to the physics engine
|
||||||
for (int i = 0; i < _points.size(); i++) {
|
for (int i = 0; i < _points.size(); i++) {
|
||||||
for (int j = 0; j < _points[i].size(); j++) {
|
for (int j = 0; j < _points[i].size(); j++) {
|
||||||
|
|
|
@ -23,6 +23,7 @@ EntityScriptingInterface::EntityScriptingInterface() :
|
||||||
{
|
{
|
||||||
auto nodeList = DependencyManager::get<NodeList>();
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
connect(nodeList.data(), &NodeList::canAdjustLocksChanged, this, &EntityScriptingInterface::canAdjustLocksChanged);
|
connect(nodeList.data(), &NodeList::canAdjustLocksChanged, this, &EntityScriptingInterface::canAdjustLocksChanged);
|
||||||
|
connect(nodeList.data(), &NodeList::canRezChanged, this, &EntityScriptingInterface::canRezChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityScriptingInterface::queueEntityMessage(PacketType packetType,
|
void EntityScriptingInterface::queueEntityMessage(PacketType packetType,
|
||||||
|
@ -30,12 +31,15 @@ void EntityScriptingInterface::queueEntityMessage(PacketType packetType,
|
||||||
getEntityPacketSender()->queueEditEntityMessage(packetType, entityID, properties);
|
getEntityPacketSender()->queueEditEntityMessage(packetType, entityID, properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool EntityScriptingInterface::canAdjustLocks() {
|
bool EntityScriptingInterface::canAdjustLocks() {
|
||||||
auto nodeList = DependencyManager::get<NodeList>();
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
return nodeList->getThisNodeCanAdjustLocks();
|
return nodeList->getThisNodeCanAdjustLocks();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool EntityScriptingInterface::canRez() {
|
||||||
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
return nodeList->getThisNodeCanRez();
|
||||||
|
}
|
||||||
|
|
||||||
void EntityScriptingInterface::setEntityTree(EntityTree* modelTree) {
|
void EntityScriptingInterface::setEntityTree(EntityTree* modelTree) {
|
||||||
if (_entityTree) {
|
if (_entityTree) {
|
||||||
|
|
|
@ -66,6 +66,9 @@ public slots:
|
||||||
// returns true if the DomainServer will allow this Node/Avatar to make changes
|
// returns true if the DomainServer will allow this Node/Avatar to make changes
|
||||||
Q_INVOKABLE bool canAdjustLocks();
|
Q_INVOKABLE bool canAdjustLocks();
|
||||||
|
|
||||||
|
// returns true if the DomainServer will allow this Node/Avatar to rez new entities
|
||||||
|
Q_INVOKABLE bool canRez();
|
||||||
|
|
||||||
/// adds a model with the specific properties
|
/// adds a model with the specific properties
|
||||||
Q_INVOKABLE EntityItemID addEntity(const EntityItemProperties& properties);
|
Q_INVOKABLE EntityItemID addEntity(const EntityItemProperties& properties);
|
||||||
|
|
||||||
|
@ -117,6 +120,7 @@ signals:
|
||||||
void entityCollisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision);
|
void entityCollisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision);
|
||||||
|
|
||||||
void canAdjustLocksChanged(bool canAdjustLocks);
|
void canAdjustLocksChanged(bool canAdjustLocks);
|
||||||
|
void canRezChanged(bool canRez);
|
||||||
|
|
||||||
void mousePressOnEntity(const EntityItemID& entityItemID, const MouseEvent& event);
|
void mousePressOnEntity(const EntityItemID& entityItemID, const MouseEvent& event);
|
||||||
void mouseMoveOnEntity(const EntityItemID& entityItemID, const MouseEvent& event);
|
void mouseMoveOnEntity(const EntityItemID& entityItemID, const MouseEvent& event);
|
||||||
|
|
|
@ -404,7 +404,8 @@ void EntityTree::handleAddEntityResponse(const QByteArray& packet) {
|
||||||
EntityItem* foundEntity = NULL;
|
EntityItem* foundEntity = NULL;
|
||||||
EntityItemID creatorTokenVersion = searchEntityID.convertToCreatorTokenVersion();
|
EntityItemID creatorTokenVersion = searchEntityID.convertToCreatorTokenVersion();
|
||||||
EntityItemID knownIDVersion = searchEntityID.convertToKnownIDVersion();
|
EntityItemID knownIDVersion = searchEntityID.convertToKnownIDVersion();
|
||||||
|
|
||||||
|
_changedEntityIDs[creatorTokenVersion] = knownIDVersion;
|
||||||
|
|
||||||
// First look for and find the "viewed version" of this entity... it's possible we got
|
// First look for and find the "viewed version" of this entity... it's possible we got
|
||||||
// the known ID version sent to us between us creating our local version, and getting this
|
// the known ID version sent to us between us creating our local version, and getting this
|
||||||
|
@ -592,6 +593,9 @@ EntityItem* EntityTree::findEntityByEntityItemID(const EntityItemID& entityID) /
|
||||||
EntityTreeElement* containingElement = getContainingElement(entityID);
|
EntityTreeElement* containingElement = getContainingElement(entityID);
|
||||||
if (containingElement) {
|
if (containingElement) {
|
||||||
foundEntity = containingElement->getEntityWithEntityItemID(entityID);
|
foundEntity = containingElement->getEntityWithEntityItemID(entityID);
|
||||||
|
if (!foundEntity && _changedEntityIDs.contains(entityID)) {
|
||||||
|
foundEntity = containingElement->getEntityWithEntityItemID(_changedEntityIDs[entityID]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return foundEntity;
|
return foundEntity;
|
||||||
}
|
}
|
||||||
|
@ -655,12 +659,14 @@ int EntityTree::processEditPacketData(PacketType packetType, const unsigned char
|
||||||
qDebug() << "User attempted to edit an unknown entity. ID:" << entityItemID;
|
qDebug() << "User attempted to edit an unknown entity. ID:" << entityItemID;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// this is a new entity... assign a new entityID
|
if (senderNode->getCanRez()) {
|
||||||
entityItemID = assignEntityID(entityItemID);
|
// this is a new entity... assign a new entityID
|
||||||
EntityItem* newEntity = addEntity(entityItemID, properties);
|
entityItemID = assignEntityID(entityItemID);
|
||||||
if (newEntity) {
|
EntityItem* newEntity = addEntity(entityItemID, properties);
|
||||||
newEntity->markAsChangedOnServer();
|
if (newEntity) {
|
||||||
notifyNewlyCreatedEntity(*newEntity, senderNode);
|
newEntity->markAsChangedOnServer();
|
||||||
|
notifyNewlyCreatedEntity(*newEntity, senderNode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -958,6 +964,12 @@ EntityTreeElement* EntityTree::getContainingElement(const EntityItemID& entityIt
|
||||||
creatorTokenOnly.isKnownID = false;
|
creatorTokenOnly.isKnownID = false;
|
||||||
element = _entityToElementMap.value(creatorTokenOnly);
|
element = _entityToElementMap.value(creatorTokenOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we still didn't find the entity, but the ID was in our changed entityIDs, search for the new ID version
|
||||||
|
if (!element && _changedEntityIDs.contains(entityItemID)) {
|
||||||
|
element = getContainingElement(_changedEntityIDs[entityItemID]);
|
||||||
|
}
|
||||||
|
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -195,6 +195,7 @@ private:
|
||||||
EntityItemFBXService* _fbxService;
|
EntityItemFBXService* _fbxService;
|
||||||
|
|
||||||
QHash<EntityItemID, EntityTreeElement*> _entityToElementMap;
|
QHash<EntityItemID, EntityTreeElement*> _entityToElementMap;
|
||||||
|
QHash<EntityItemID, EntityItemID> _changedEntityIDs;
|
||||||
|
|
||||||
EntitySimulation* _simulation;
|
EntitySimulation* _simulation;
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,8 @@ public:
|
||||||
enum SpecialToken {
|
enum SpecialToken {
|
||||||
NO_TOKEN = -1,
|
NO_TOKEN = -1,
|
||||||
NO_PUSHBACKED_TOKEN = -1,
|
NO_PUSHBACKED_TOKEN = -1,
|
||||||
DATUM_TOKEN = 0x100
|
DATUM_TOKEN = 0x100,
|
||||||
|
COMMENT_TOKEN = 0x101
|
||||||
};
|
};
|
||||||
int nextToken();
|
int nextToken();
|
||||||
const QByteArray& getDatum() const { return _datum; }
|
const QByteArray& getDatum() const { return _datum; }
|
||||||
|
@ -35,11 +36,13 @@ public:
|
||||||
void skipLine() { _device->readLine(); }
|
void skipLine() { _device->readLine(); }
|
||||||
void pushBackToken(int token) { _pushedBackToken = token; }
|
void pushBackToken(int token) { _pushedBackToken = token; }
|
||||||
void ungetChar(char ch) { _device->ungetChar(ch); }
|
void ungetChar(char ch) { _device->ungetChar(ch); }
|
||||||
|
const QString getComment() const { return _comment; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QIODevice* _device;
|
QIODevice* _device;
|
||||||
QByteArray _datum;
|
QByteArray _datum;
|
||||||
int _pushedBackToken;
|
int _pushedBackToken;
|
||||||
|
QString _comment;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -56,9 +59,11 @@ int OBJTokenizer::nextToken() {
|
||||||
continue; // skip whitespace
|
continue; // skip whitespace
|
||||||
}
|
}
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case '#':
|
case '#': {
|
||||||
_device->readLine(); // skip the comment
|
_comment = _device->readLine(); // skip the comment
|
||||||
break;
|
qDebug() << "COMMENT:" << _comment;
|
||||||
|
return COMMENT_TOKEN;
|
||||||
|
}
|
||||||
|
|
||||||
case '\"':
|
case '\"':
|
||||||
_datum = "";
|
_datum = "";
|
||||||
|
@ -104,7 +109,8 @@ bool OBJTokenizer::isNextTokenFloat() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool parseOBJGroup(OBJTokenizer &tokenizer, const QVariantHash& mapping,
|
bool parseOBJGroup(OBJTokenizer &tokenizer, const QVariantHash& mapping,
|
||||||
FBXGeometry &geometry, QVector<glm::vec3>& faceNormals, QVector<int>& faceNormalIndexes) {
|
FBXGeometry &geometry, QVector<glm::vec3>& faceNormals, QVector<int>& faceNormalIndexes,
|
||||||
|
float& scaleGuess) {
|
||||||
FBXMesh &mesh = geometry.meshes[0];
|
FBXMesh &mesh = geometry.meshes[0];
|
||||||
mesh.parts.append(FBXMeshPart());
|
mesh.parts.append(FBXMeshPart());
|
||||||
FBXMeshPart &meshPart = mesh.parts.last();
|
FBXMeshPart &meshPart = mesh.parts.last();
|
||||||
|
@ -128,7 +134,17 @@ bool parseOBJGroup(OBJTokenizer &tokenizer, const QVariantHash& mapping,
|
||||||
meshPart._material->setEmissive(glm::vec3(0.0, 0.0, 0.0));
|
meshPart._material->setEmissive(glm::vec3(0.0, 0.0, 0.0));
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if (tokenizer.nextToken() != OBJTokenizer::DATUM_TOKEN) {
|
int tokenType = tokenizer.nextToken();
|
||||||
|
if (tokenType == OBJTokenizer::COMMENT_TOKEN) {
|
||||||
|
if (tokenizer.getComment().contains("This file uses centimeters as units")) {
|
||||||
|
scaleGuess = 1.0f / 100.0f;
|
||||||
|
}
|
||||||
|
if (tokenizer.getComment().contains("This file uses millimeters as units")) {
|
||||||
|
scaleGuess = 1.0f / 1000.0f;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (tokenType != OBJTokenizer::DATUM_TOKEN) {
|
||||||
result = false;
|
result = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -192,6 +208,7 @@ bool parseOBJGroup(OBJTokenizer &tokenizer, const QVariantHash& mapping,
|
||||||
while (true) {
|
while (true) {
|
||||||
if (tokenizer.nextToken() != OBJTokenizer::DATUM_TOKEN) {
|
if (tokenizer.nextToken() != OBJTokenizer::DATUM_TOKEN) {
|
||||||
if (indices.count() == 0) {
|
if (indices.count() == 0) {
|
||||||
|
// nonsense, bail out.
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -266,22 +283,22 @@ bool parseOBJGroup(OBJTokenizer &tokenizer, const QVariantHash& mapping,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// something we don't (yet) care about
|
// something we don't (yet) care about
|
||||||
qDebug() << "OBJ parser is skipping a line with" << token;
|
// qDebug() << "OBJ parser is skipping a line with" << token;
|
||||||
tokenizer.skipLine();
|
tokenizer.skipLine();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
|
||||||
|
if (meshPart.triangleIndices.size() == 0 && meshPart.quadIndices.size() == 0) {
|
||||||
|
// empty mesh?
|
||||||
|
mesh.parts.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
FBXGeometry extractOBJGeometry(const FBXNode& node, const QVariantHash& mapping) {
|
|
||||||
FBXGeometry geometry;
|
|
||||||
return geometry;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
FBXGeometry readOBJ(const QByteArray& model, const QVariantHash& mapping) {
|
FBXGeometry readOBJ(const QByteArray& model, const QVariantHash& mapping) {
|
||||||
QBuffer buffer(const_cast<QByteArray*>(&model));
|
QBuffer buffer(const_cast<QByteArray*>(&model));
|
||||||
buffer.open(QIODevice::ReadOnly);
|
buffer.open(QIODevice::ReadOnly);
|
||||||
|
@ -294,24 +311,30 @@ FBXGeometry readOBJ(QIODevice* device, const QVariantHash& mapping) {
|
||||||
OBJTokenizer tokenizer(device);
|
OBJTokenizer tokenizer(device);
|
||||||
QVector<int> faceNormalIndexes;
|
QVector<int> faceNormalIndexes;
|
||||||
QVector<glm::vec3> faceNormals;
|
QVector<glm::vec3> faceNormals;
|
||||||
|
float scaleGuess = 1.0f;
|
||||||
|
|
||||||
faceNormalIndexes.clear();
|
faceNormalIndexes.clear();
|
||||||
|
|
||||||
geometry.meshExtents.reset();
|
geometry.meshExtents.reset();
|
||||||
geometry.meshes.append(FBXMesh());
|
geometry.meshes.append(FBXMesh());
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// call parseOBJGroup as long as it's returning true. Each successful call will
|
// call parseOBJGroup as long as it's returning true. Each successful call will
|
||||||
// add a new meshPart to the geometry's single mesh.
|
// add a new meshPart to the geometry's single mesh.
|
||||||
bool success = true;
|
bool success = true;
|
||||||
while (success) {
|
while (success) {
|
||||||
success = parseOBJGroup(tokenizer, mapping, geometry, faceNormals, faceNormalIndexes);
|
success = parseOBJGroup(tokenizer, mapping, geometry, faceNormals, faceNormalIndexes, scaleGuess);
|
||||||
}
|
}
|
||||||
|
|
||||||
FBXMesh &mesh = geometry.meshes[0];
|
FBXMesh &mesh = geometry.meshes[0];
|
||||||
|
|
||||||
|
// if we got a hint about units, scale all the points
|
||||||
|
if (scaleGuess != 1.0f) {
|
||||||
|
for (int i = 0; i < mesh.vertices.size(); i++) {
|
||||||
|
mesh.vertices[i] *= scaleGuess;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mesh.meshExtents.reset();
|
mesh.meshExtents.reset();
|
||||||
foreach (const glm::vec3& vertex, mesh.vertices) {
|
foreach (const glm::vec3& vertex, mesh.vertices) {
|
||||||
mesh.meshExtents.addPoint(vertex);
|
mesh.meshExtents.addPoint(vertex);
|
||||||
|
|
|
@ -33,8 +33,7 @@ AddressManager::AddressManager() :
|
||||||
_rootPlaceName(),
|
_rootPlaceName(),
|
||||||
_rootPlaceID(),
|
_rootPlaceID(),
|
||||||
_positionGetter(NULL),
|
_positionGetter(NULL),
|
||||||
_orientationGetter(NULL),
|
_orientationGetter(NULL)
|
||||||
_localDSPortSharedMem(NULL)
|
|
||||||
{
|
{
|
||||||
connect(qApp, &QCoreApplication::aboutToQuit, this, &AddressManager::storeCurrentAddress);
|
connect(qApp, &QCoreApplication::aboutToQuit, this, &AddressManager::storeCurrentAddress);
|
||||||
}
|
}
|
||||||
|
@ -331,13 +330,6 @@ bool AddressManager::handleNetworkAddress(const QString& lookupString) {
|
||||||
|
|
||||||
quint16 domainPort = DEFAULT_DOMAIN_SERVER_PORT;
|
quint16 domainPort = DEFAULT_DOMAIN_SERVER_PORT;
|
||||||
|
|
||||||
if (domainHostname == "localhost") {
|
|
||||||
auto nodeList = DependencyManager::get<NodeList>();
|
|
||||||
nodeList->getLocalServerPortFromSharedMemory(DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY,
|
|
||||||
_localDSPortSharedMem,
|
|
||||||
domainPort);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hostnameRegex.cap(2).isEmpty()) {
|
if (!hostnameRegex.cap(2).isEmpty()) {
|
||||||
domainPort = (qint16) hostnameRegex.cap(2).toInt();
|
domainPort = (qint16) hostnameRegex.cap(2).toInt();
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,8 +95,6 @@ private:
|
||||||
QUuid _rootPlaceID;
|
QUuid _rootPlaceID;
|
||||||
PositionGetter _positionGetter;
|
PositionGetter _positionGetter;
|
||||||
OrientationGetter _orientationGetter;
|
OrientationGetter _orientationGetter;
|
||||||
|
|
||||||
QSharedMemory* _localDSPortSharedMem; // memory shared with domain server
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_AddressManager_h
|
#endif // hifi_AddressManager_h
|
||||||
|
|
|
@ -47,6 +47,7 @@ public:
|
||||||
void setSockAddr(const HifiSockAddr& sockAddr, const QString& hostname);
|
void setSockAddr(const HifiSockAddr& sockAddr, const QString& hostname);
|
||||||
|
|
||||||
unsigned short getPort() const { return _sockAddr.getPort(); }
|
unsigned short getPort() const { return _sockAddr.getPort(); }
|
||||||
|
void setPort(quint16 port) { _sockAddr.setPort(port); }
|
||||||
|
|
||||||
const QUuid& getAssignmentUUID() const { return _assignmentUUID; }
|
const QUuid& getAssignmentUUID() const { return _assignmentUUID; }
|
||||||
void setAssignmentUUID(const QUuid& assignmentUUID) { _assignmentUUID = assignmentUUID; }
|
void setAssignmentUUID(const QUuid& assignmentUUID) { _assignmentUUID = assignmentUUID; }
|
||||||
|
|
|
@ -36,8 +36,6 @@ const char SOLO_NODE_TYPES[2] = {
|
||||||
NodeType::AudioMixer
|
NodeType::AudioMixer
|
||||||
};
|
};
|
||||||
|
|
||||||
const QUrl DEFAULT_NODE_AUTH_URL = QUrl("https://metaverse.highfidelity.com");
|
|
||||||
|
|
||||||
LimitedNodeList::LimitedNodeList(unsigned short socketListenPort, unsigned short dtlsListenPort) :
|
LimitedNodeList::LimitedNodeList(unsigned short socketListenPort, unsigned short dtlsListenPort) :
|
||||||
linkedDataCreateCallback(NULL),
|
linkedDataCreateCallback(NULL),
|
||||||
_sessionUUID(),
|
_sessionUUID(),
|
||||||
|
@ -49,7 +47,8 @@ LimitedNodeList::LimitedNodeList(unsigned short socketListenPort, unsigned short
|
||||||
_publicSockAddr(),
|
_publicSockAddr(),
|
||||||
_stunSockAddr(STUN_SERVER_HOSTNAME, STUN_SERVER_PORT),
|
_stunSockAddr(STUN_SERVER_HOSTNAME, STUN_SERVER_PORT),
|
||||||
_packetStatTimer(),
|
_packetStatTimer(),
|
||||||
_thisNodeCanAdjustLocks(false)
|
_thisNodeCanAdjustLocks(false),
|
||||||
|
_thisNodeCanRez(true)
|
||||||
{
|
{
|
||||||
static bool firstCall = true;
|
static bool firstCall = true;
|
||||||
if (firstCall) {
|
if (firstCall) {
|
||||||
|
@ -108,6 +107,13 @@ void LimitedNodeList::setThisNodeCanAdjustLocks(bool canAdjustLocks) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LimitedNodeList::setThisNodeCanRez(bool canRez) {
|
||||||
|
if (_thisNodeCanRez != canRez) {
|
||||||
|
_thisNodeCanRez = canRez;
|
||||||
|
emit canRezChanged(canRez);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QUdpSocket& LimitedNodeList::getDTLSSocket() {
|
QUdpSocket& LimitedNodeList::getDTLSSocket() {
|
||||||
if (!_dtlsSocket) {
|
if (!_dtlsSocket) {
|
||||||
// DTLS socket getter called but no DTLS socket exists, create it now
|
// DTLS socket getter called but no DTLS socket exists, create it now
|
||||||
|
@ -392,8 +398,9 @@ void LimitedNodeList::killNodeWithUUID(const QUuid& nodeUUID) {
|
||||||
|
|
||||||
_nodeMutex.unlock();
|
_nodeMutex.unlock();
|
||||||
|
|
||||||
QWriteLocker writeLocker(&_nodeMutex);
|
_nodeMutex.lockForWrite();
|
||||||
_nodeHash.unsafe_erase(it);
|
_nodeHash.unsafe_erase(it);
|
||||||
|
_nodeMutex.unlock();
|
||||||
|
|
||||||
handleNodeKill(matchingNode);
|
handleNodeKill(matchingNode);
|
||||||
} else {
|
} else {
|
||||||
|
@ -416,7 +423,7 @@ void LimitedNodeList::handleNodeKill(const SharedNodePointer& node) {
|
||||||
|
|
||||||
SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, NodeType_t nodeType,
|
SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, NodeType_t nodeType,
|
||||||
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket,
|
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket,
|
||||||
bool canAdjustLocks) {
|
bool canAdjustLocks, bool canRez) {
|
||||||
NodeHash::const_iterator it = _nodeHash.find(uuid);
|
NodeHash::const_iterator it = _nodeHash.find(uuid);
|
||||||
|
|
||||||
if (it != _nodeHash.end()) {
|
if (it != _nodeHash.end()) {
|
||||||
|
@ -425,11 +432,12 @@ SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, NodeType_t
|
||||||
matchingNode->setPublicSocket(publicSocket);
|
matchingNode->setPublicSocket(publicSocket);
|
||||||
matchingNode->setLocalSocket(localSocket);
|
matchingNode->setLocalSocket(localSocket);
|
||||||
matchingNode->setCanAdjustLocks(canAdjustLocks);
|
matchingNode->setCanAdjustLocks(canAdjustLocks);
|
||||||
|
matchingNode->setCanRez(canRez);
|
||||||
|
|
||||||
return matchingNode;
|
return matchingNode;
|
||||||
} else {
|
} else {
|
||||||
// we didn't have this node, so add them
|
// we didn't have this node, so add them
|
||||||
Node* newNode = new Node(uuid, nodeType, publicSocket, localSocket, canAdjustLocks);
|
Node* newNode = new Node(uuid, nodeType, publicSocket, localSocket, canAdjustLocks, canRez);
|
||||||
SharedNodePointer newNodePointer(newNode);
|
SharedNodePointer newNodePointer(newNode);
|
||||||
|
|
||||||
_nodeHash.insert(UUIDNodePair(newNode->getUUID(), newNodePointer));
|
_nodeHash.insert(UUIDNodePair(newNode->getUUID(), newNodePointer));
|
||||||
|
|
|
@ -42,8 +42,6 @@ const quint64 NODE_SILENCE_THRESHOLD_MSECS = 2 * 1000;
|
||||||
|
|
||||||
extern const char SOLO_NODE_TYPES[2];
|
extern const char SOLO_NODE_TYPES[2];
|
||||||
|
|
||||||
extern const QUrl DEFAULT_NODE_AUTH_URL;
|
|
||||||
|
|
||||||
const char DEFAULT_ASSIGNMENT_SERVER_HOSTNAME[] = "localhost";
|
const char DEFAULT_ASSIGNMENT_SERVER_HOSTNAME[] = "localhost";
|
||||||
|
|
||||||
const char STUN_SERVER_HOSTNAME[] = "stun.highfidelity.io";
|
const char STUN_SERVER_HOSTNAME[] = "stun.highfidelity.io";
|
||||||
|
@ -86,6 +84,9 @@ public:
|
||||||
|
|
||||||
bool getThisNodeCanAdjustLocks() const { return _thisNodeCanAdjustLocks; }
|
bool getThisNodeCanAdjustLocks() const { return _thisNodeCanAdjustLocks; }
|
||||||
void setThisNodeCanAdjustLocks(bool canAdjustLocks);
|
void setThisNodeCanAdjustLocks(bool canAdjustLocks);
|
||||||
|
|
||||||
|
bool getThisNodeCanRez() const { return _thisNodeCanRez; }
|
||||||
|
void setThisNodeCanRez(bool canRez);
|
||||||
|
|
||||||
void rebindNodeSocket();
|
void rebindNodeSocket();
|
||||||
QUdpSocket& getNodeSocket() { return _nodeSocket; }
|
QUdpSocket& getNodeSocket() { return _nodeSocket; }
|
||||||
|
@ -116,7 +117,8 @@ public:
|
||||||
SharedNodePointer sendingNodeForPacket(const QByteArray& packet);
|
SharedNodePointer sendingNodeForPacket(const QByteArray& packet);
|
||||||
|
|
||||||
SharedNodePointer addOrUpdateNode(const QUuid& uuid, NodeType_t nodeType,
|
SharedNodePointer addOrUpdateNode(const QUuid& uuid, NodeType_t nodeType,
|
||||||
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket, bool canAdjustLocks);
|
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket,
|
||||||
|
bool canAdjustLocks, bool canRez);
|
||||||
|
|
||||||
const HifiSockAddr& getLocalSockAddr() const { return _localSockAddr; }
|
const HifiSockAddr& getLocalSockAddr() const { return _localSockAddr; }
|
||||||
const HifiSockAddr& getSTUNSockAddr() const { return _stunSockAddr; }
|
const HifiSockAddr& getSTUNSockAddr() const { return _stunSockAddr; }
|
||||||
|
@ -208,6 +210,7 @@ signals:
|
||||||
void publicSockAddrChanged(const HifiSockAddr& publicSockAddr);
|
void publicSockAddrChanged(const HifiSockAddr& publicSockAddr);
|
||||||
|
|
||||||
void canAdjustLocksChanged(bool canAdjustLocks);
|
void canAdjustLocksChanged(bool canAdjustLocks);
|
||||||
|
void canRezChanged(bool canRez);
|
||||||
|
|
||||||
void dataSent(const quint8 channel_type, const int bytes);
|
void dataSent(const quint8 channel_type, const int bytes);
|
||||||
void dataReceived(const quint8 channel_type, const int bytes);
|
void dataReceived(const quint8 channel_type, const int bytes);
|
||||||
|
@ -243,6 +246,7 @@ protected:
|
||||||
|
|
||||||
QElapsedTimer _packetStatTimer;
|
QElapsedTimer _packetStatTimer;
|
||||||
bool _thisNodeCanAdjustLocks;
|
bool _thisNodeCanAdjustLocks;
|
||||||
|
bool _thisNodeCanRez;
|
||||||
|
|
||||||
template<typename IteratorLambda>
|
template<typename IteratorLambda>
|
||||||
void eachNodeHashIterator(IteratorLambda functor) {
|
void eachNodeHashIterator(IteratorLambda functor) {
|
||||||
|
|
21
libraries/networking/src/NetworkingConstants.h
Normal file
21
libraries/networking/src/NetworkingConstants.h
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
//
|
||||||
|
// NetworkingConstants.h
|
||||||
|
// libraries/networking/src
|
||||||
|
//
|
||||||
|
// Created by Stephen Birarda on 2015-03-31.
|
||||||
|
// 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
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef hifi_NetworkingConstants_h
|
||||||
|
#define hifi_NetworkingConstants_h
|
||||||
|
|
||||||
|
#include <QtCore/QUrl>
|
||||||
|
|
||||||
|
namespace NetworkingConstants {
|
||||||
|
const QUrl METAVERSE_SERVER_URL = QUrl("https://metaverse.highfidelity.com");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // hifi_NetworkingConstants_h
|
|
@ -41,7 +41,7 @@ const QString& NodeType::getNodeTypeName(NodeType_t nodeType) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Node::Node(const QUuid& uuid, NodeType_t type, const HifiSockAddr& publicSocket,
|
Node::Node(const QUuid& uuid, NodeType_t type, const HifiSockAddr& publicSocket,
|
||||||
const HifiSockAddr& localSocket, bool canAdjustLocks) :
|
const HifiSockAddr& localSocket, bool canAdjustLocks, bool canRez) :
|
||||||
NetworkPeer(uuid, publicSocket, localSocket),
|
NetworkPeer(uuid, publicSocket, localSocket),
|
||||||
_type(type),
|
_type(type),
|
||||||
_activeSocket(NULL),
|
_activeSocket(NULL),
|
||||||
|
@ -53,7 +53,8 @@ Node::Node(const QUuid& uuid, NodeType_t type, const HifiSockAddr& publicSocket,
|
||||||
_clockSkewUsec(0),
|
_clockSkewUsec(0),
|
||||||
_mutex(),
|
_mutex(),
|
||||||
_clockSkewMovingPercentile(30, 0.8f), // moving 80th percentile of 30 samples
|
_clockSkewMovingPercentile(30, 0.8f), // moving 80th percentile of 30 samples
|
||||||
_canAdjustLocks(canAdjustLocks)
|
_canAdjustLocks(canAdjustLocks),
|
||||||
|
_canRez(canRez)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -133,6 +134,7 @@ QDataStream& operator<<(QDataStream& out, const Node& node) {
|
||||||
out << node._publicSocket;
|
out << node._publicSocket;
|
||||||
out << node._localSocket;
|
out << node._localSocket;
|
||||||
out << node._canAdjustLocks;
|
out << node._canAdjustLocks;
|
||||||
|
out << node._canRez;
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
@ -143,6 +145,7 @@ QDataStream& operator>>(QDataStream& in, Node& node) {
|
||||||
in >> node._publicSocket;
|
in >> node._publicSocket;
|
||||||
in >> node._localSocket;
|
in >> node._localSocket;
|
||||||
in >> node._canAdjustLocks;
|
in >> node._canAdjustLocks;
|
||||||
|
in >> node._canRez;
|
||||||
|
|
||||||
return in;
|
return in;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ class Node : public NetworkPeer {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
Node(const QUuid& uuid, NodeType_t type,
|
Node(const QUuid& uuid, NodeType_t type,
|
||||||
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket, bool canAdjustLocks);
|
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket, bool canAdjustLocks, bool canRez);
|
||||||
~Node();
|
~Node();
|
||||||
|
|
||||||
bool operator==(const Node& otherNode) const { return _uuid == otherNode._uuid; }
|
bool operator==(const Node& otherNode) const { return _uuid == otherNode._uuid; }
|
||||||
|
@ -79,6 +79,9 @@ public:
|
||||||
|
|
||||||
void setCanAdjustLocks(bool canAdjustLocks) { _canAdjustLocks = canAdjustLocks; }
|
void setCanAdjustLocks(bool canAdjustLocks) { _canAdjustLocks = canAdjustLocks; }
|
||||||
bool getCanAdjustLocks() { return _canAdjustLocks; }
|
bool getCanAdjustLocks() { return _canAdjustLocks; }
|
||||||
|
|
||||||
|
void setCanRez(bool canRez) { _canRez = canRez; }
|
||||||
|
bool getCanRez() { return _canRez; }
|
||||||
|
|
||||||
void activatePublicSocket();
|
void activatePublicSocket();
|
||||||
void activateLocalSocket();
|
void activateLocalSocket();
|
||||||
|
@ -105,6 +108,7 @@ private:
|
||||||
QMutex _mutex;
|
QMutex _mutex;
|
||||||
MovingPercentile _clockSkewMovingPercentile;
|
MovingPercentile _clockSkewMovingPercentile;
|
||||||
bool _canAdjustLocks;
|
bool _canAdjustLocks;
|
||||||
|
bool _canRez;
|
||||||
};
|
};
|
||||||
|
|
||||||
QDebug operator<<(QDebug debug, const Node &message);
|
QDebug operator<<(QDebug debug, const Node &message);
|
||||||
|
|
|
@ -277,6 +277,23 @@ void NodeList::sendDomainServerCheckIn() {
|
||||||
|
|
||||||
if (!_domainHandler.isConnected()) {
|
if (!_domainHandler.isConnected()) {
|
||||||
qDebug() << "Sending connect request to domain-server at" << _domainHandler.getHostname();
|
qDebug() << "Sending connect request to domain-server at" << _domainHandler.getHostname();
|
||||||
|
|
||||||
|
// is this our localhost domain-server?
|
||||||
|
// if so we need to make sure we have an up-to-date local port in case it restarted
|
||||||
|
|
||||||
|
if (_domainHandler.getSockAddr().getAddress() == QHostAddress::LocalHost
|
||||||
|
|| _domainHandler.getHostname() == "localhost") {
|
||||||
|
|
||||||
|
static QSharedMemory* localDSPortSharedMem = NULL;
|
||||||
|
|
||||||
|
quint16 domainPort = DEFAULT_DOMAIN_SERVER_PORT;
|
||||||
|
getLocalServerPortFromSharedMemory(DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY,
|
||||||
|
localDSPortSharedMem,
|
||||||
|
domainPort);
|
||||||
|
qDebug() << "Local domain-server port read from shared memory (or default) is" << domainPort;
|
||||||
|
_domainHandler.setPort(domainPort);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// construct the DS check in packet
|
// construct the DS check in packet
|
||||||
|
@ -386,6 +403,10 @@ int NodeList::processDomainServerList(const QByteArray& packet) {
|
||||||
bool thisNodeCanAdjustLocks;
|
bool thisNodeCanAdjustLocks;
|
||||||
packetStream >> thisNodeCanAdjustLocks;
|
packetStream >> thisNodeCanAdjustLocks;
|
||||||
setThisNodeCanAdjustLocks(thisNodeCanAdjustLocks);
|
setThisNodeCanAdjustLocks(thisNodeCanAdjustLocks);
|
||||||
|
|
||||||
|
bool thisNodeCanRez;
|
||||||
|
packetStream >> thisNodeCanRez;
|
||||||
|
setThisNodeCanRez(thisNodeCanRez);
|
||||||
|
|
||||||
// pull each node in the packet
|
// pull each node in the packet
|
||||||
while(packetStream.device()->pos() < packet.size()) {
|
while(packetStream.device()->pos() < packet.size()) {
|
||||||
|
@ -394,8 +415,9 @@ int NodeList::processDomainServerList(const QByteArray& packet) {
|
||||||
QUuid nodeUUID, connectionUUID;
|
QUuid nodeUUID, connectionUUID;
|
||||||
HifiSockAddr nodePublicSocket, nodeLocalSocket;
|
HifiSockAddr nodePublicSocket, nodeLocalSocket;
|
||||||
bool canAdjustLocks;
|
bool canAdjustLocks;
|
||||||
|
bool canRez;
|
||||||
|
|
||||||
packetStream >> nodeType >> nodeUUID >> nodePublicSocket >> nodeLocalSocket >> canAdjustLocks;
|
packetStream >> nodeType >> nodeUUID >> nodePublicSocket >> nodeLocalSocket >> canAdjustLocks >> canRez;
|
||||||
|
|
||||||
// if the public socket address is 0 then it's reachable at the same IP
|
// if the public socket address is 0 then it's reachable at the same IP
|
||||||
// as the domain server
|
// as the domain server
|
||||||
|
@ -403,7 +425,8 @@ int NodeList::processDomainServerList(const QByteArray& packet) {
|
||||||
nodePublicSocket.setAddress(_domainHandler.getIP());
|
nodePublicSocket.setAddress(_domainHandler.getIP());
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedNodePointer node = addOrUpdateNode(nodeUUID, nodeType, nodePublicSocket, nodeLocalSocket, canAdjustLocks);
|
SharedNodePointer node = addOrUpdateNode(nodeUUID, nodeType, nodePublicSocket,
|
||||||
|
nodeLocalSocket, canAdjustLocks, canRez);
|
||||||
|
|
||||||
packetStream >> connectionUUID;
|
packetStream >> connectionUUID;
|
||||||
node->setConnectionSecret(connectionUUID);
|
node->setConnectionSecret(connectionUUID);
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
|
|
||||||
#include "AccountManager.h"
|
#include "AccountManager.h"
|
||||||
#include "LimitedNodeList.h"
|
#include "LimitedNodeList.h"
|
||||||
|
#include "NetworkingConstants.h"
|
||||||
#include "SharedUtil.h"
|
#include "SharedUtil.h"
|
||||||
|
|
||||||
#include "OAuthNetworkAccessManager.h"
|
#include "OAuthNetworkAccessManager.h"
|
||||||
|
@ -33,7 +34,8 @@ QNetworkReply* OAuthNetworkAccessManager::createRequest(QNetworkAccessManager::O
|
||||||
QIODevice* outgoingData) {
|
QIODevice* outgoingData) {
|
||||||
AccountManager& accountManager = AccountManager::getInstance();
|
AccountManager& accountManager = AccountManager::getInstance();
|
||||||
|
|
||||||
if (accountManager.hasValidAccessToken() && req.url().host() == DEFAULT_NODE_AUTH_URL.host()) {
|
if (accountManager.hasValidAccessToken()
|
||||||
|
&& req.url().host() == NetworkingConstants::METAVERSE_SERVER_URL.host()) {
|
||||||
QNetworkRequest authenticatedRequest(req);
|
QNetworkRequest authenticatedRequest(req);
|
||||||
authenticatedRequest.setHeader(QNetworkRequest::UserAgentHeader, HIGH_FIDELITY_USER_AGENT);
|
authenticatedRequest.setHeader(QNetworkRequest::UserAgentHeader, HIGH_FIDELITY_USER_AGENT);
|
||||||
authenticatedRequest.setRawHeader(ACCESS_TOKEN_AUTHORIZATION_HEADER,
|
authenticatedRequest.setRawHeader(ACCESS_TOKEN_AUTHORIZATION_HEADER,
|
||||||
|
|
|
@ -64,7 +64,7 @@ PacketVersion versionForPacketType(PacketType type) {
|
||||||
return 2;
|
return 2;
|
||||||
case PacketTypeDomainList:
|
case PacketTypeDomainList:
|
||||||
case PacketTypeDomainListRequest:
|
case PacketTypeDomainListRequest:
|
||||||
return 4;
|
return 5;
|
||||||
case PacketTypeCreateAssignment:
|
case PacketTypeCreateAssignment:
|
||||||
case PacketTypeRequestAssignment:
|
case PacketTypeRequestAssignment:
|
||||||
return 2;
|
return 2;
|
||||||
|
|
|
@ -70,6 +70,7 @@ QSharedPointer<Resource> ResourceCache::getResource(const QUrl& url, const QUrl&
|
||||||
bool delayLoad, void* extra) {
|
bool delayLoad, void* extra) {
|
||||||
QSharedPointer<Resource> resource = _resources.value(url);
|
QSharedPointer<Resource> resource = _resources.value(url);
|
||||||
if (!resource.isNull()) {
|
if (!resource.isNull()) {
|
||||||
|
removeUnusedResource(resource);
|
||||||
return resource;
|
return resource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,16 +84,14 @@ QSharedPointer<Resource> ResourceCache::getResource(const QUrl& url, const QUrl&
|
||||||
return getResource(fallback, QUrl(), delayLoad);
|
return getResource(fallback, QUrl(), delayLoad);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resource.isNull()) {
|
resource = createResource(url, fallback.isValid() ?
|
||||||
resource = createResource(url, fallback.isValid() ?
|
getResource(fallback, QUrl(), true) : QSharedPointer<Resource>(), delayLoad, extra);
|
||||||
getResource(fallback, QUrl(), true) : QSharedPointer<Resource>(), delayLoad, extra);
|
resource->setSelf(resource);
|
||||||
resource->setSelf(resource);
|
resource->setCache(this);
|
||||||
resource->setCache(this);
|
_resources.insert(url, resource);
|
||||||
_resources.insert(url, resource);
|
removeUnusedResource(resource);
|
||||||
|
resource->ensureLoading();
|
||||||
} else {
|
|
||||||
removeUnusedResource(resource);
|
|
||||||
}
|
|
||||||
return resource;
|
return resource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,7 +133,7 @@ void ResourceCache::reserveUnusedResource(qint64 resourceSize) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceCache::attemptRequest(Resource* resource) {
|
void ResourceCache::attemptRequest(Resource* resource) {
|
||||||
auto sharedItems = DependencyManager::get<ResouceCacheSharedItems>();
|
auto sharedItems = DependencyManager::get<ResourceCacheSharedItems>();
|
||||||
if (_requestLimit <= 0) {
|
if (_requestLimit <= 0) {
|
||||||
// wait until a slot becomes available
|
// wait until a slot becomes available
|
||||||
sharedItems->_pendingRequests.append(resource);
|
sharedItems->_pendingRequests.append(resource);
|
||||||
|
@ -147,7 +146,7 @@ void ResourceCache::attemptRequest(Resource* resource) {
|
||||||
|
|
||||||
void ResourceCache::requestCompleted(Resource* resource) {
|
void ResourceCache::requestCompleted(Resource* resource) {
|
||||||
|
|
||||||
auto sharedItems = DependencyManager::get<ResouceCacheSharedItems>();
|
auto sharedItems = DependencyManager::get<ResourceCacheSharedItems>();
|
||||||
sharedItems->_loadingRequests.removeOne(resource);
|
sharedItems->_loadingRequests.removeOne(resource);
|
||||||
_requestLimit++;
|
_requestLimit++;
|
||||||
|
|
||||||
|
|
|
@ -48,14 +48,14 @@ static const qint64 MAX_UNUSED_MAX_SIZE = 10 * BYTES_PER_GIGABYTES;
|
||||||
// ResourceCache derived classes. Since we can't count on the ordering of
|
// ResourceCache derived classes. Since we can't count on the ordering of
|
||||||
// static members destruction, we need to use this Dependency manager implemented
|
// static members destruction, we need to use this Dependency manager implemented
|
||||||
// object instead
|
// object instead
|
||||||
class ResouceCacheSharedItems : public Dependency {
|
class ResourceCacheSharedItems : public Dependency {
|
||||||
SINGLETON_DEPENDENCY
|
SINGLETON_DEPENDENCY
|
||||||
public:
|
public:
|
||||||
QList<QPointer<Resource> > _pendingRequests;
|
QList<QPointer<Resource> > _pendingRequests;
|
||||||
QList<Resource*> _loadingRequests;
|
QList<Resource*> _loadingRequests;
|
||||||
private:
|
private:
|
||||||
ResouceCacheSharedItems() { }
|
ResourceCacheSharedItems() { }
|
||||||
virtual ~ResouceCacheSharedItems() { }
|
virtual ~ResourceCacheSharedItems() { }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -71,10 +71,10 @@ public:
|
||||||
qint64 getUnusedResourceCacheSize() const { return _unusedResourcesMaxSize; }
|
qint64 getUnusedResourceCacheSize() const { return _unusedResourcesMaxSize; }
|
||||||
|
|
||||||
static const QList<Resource*>& getLoadingRequests()
|
static const QList<Resource*>& getLoadingRequests()
|
||||||
{ return DependencyManager::get<ResouceCacheSharedItems>()->_loadingRequests; }
|
{ return DependencyManager::get<ResourceCacheSharedItems>()->_loadingRequests; }
|
||||||
|
|
||||||
static int getPendingRequestCount()
|
static int getPendingRequestCount()
|
||||||
{ return DependencyManager::get<ResouceCacheSharedItems>()->_pendingRequests.size(); }
|
{ return DependencyManager::get<ResourceCacheSharedItems>()->_pendingRequests.size(); }
|
||||||
|
|
||||||
ResourceCache(QObject* parent = NULL);
|
ResourceCache(QObject* parent = NULL);
|
||||||
virtual ~ResourceCache();
|
virtual ~ResourceCache();
|
||||||
|
|
|
@ -864,7 +864,7 @@ void CharacterController::updateShapeIfNecessary() {
|
||||||
void CharacterController::preSimulation(btScalar timeStep) {
|
void CharacterController::preSimulation(btScalar timeStep) {
|
||||||
if (_enabled && _dynamicsWorld) {
|
if (_enabled && _dynamicsWorld) {
|
||||||
glm::quat rotation = _avatarData->getOrientation();
|
glm::quat rotation = _avatarData->getOrientation();
|
||||||
btVector3 _currentUp = quatRotate(glmToBullet(rotation), LOCAL_UP_AXIS);
|
_currentUp = quatRotate(glmToBullet(rotation), LOCAL_UP_AXIS);
|
||||||
glm::vec3 position = _avatarData->getPosition() + rotation * _shapeLocalOffset;
|
glm::vec3 position = _avatarData->getPosition() + rotation * _shapeLocalOffset;
|
||||||
btVector3 walkVelocity = glmToBullet(_avatarData->getVelocity());
|
btVector3 walkVelocity = glmToBullet(_avatarData->getVelocity());
|
||||||
|
|
||||||
|
|
|
@ -535,10 +535,13 @@ void DeferredLightingEffect::loadLightProgram(const char* fragSource, bool limit
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeferredLightingEffect::setAmbientLightMode(int preset) {
|
void DeferredLightingEffect::setAmbientLightMode(int preset) {
|
||||||
if ((preset >= -1) && (preset < model::SphericalHarmonics::NUM_PRESET)) {
|
if ((preset >= 0) && (preset < model::SphericalHarmonics::NUM_PRESET)) {
|
||||||
_ambientLightMode = preset;
|
_ambientLightMode = preset;
|
||||||
auto light = _allocatedLights.front();
|
auto light = _allocatedLights.front();
|
||||||
light->setAmbientSpherePreset(model::SphericalHarmonics::Preset(preset % model::SphericalHarmonics::NUM_PRESET));
|
light->setAmbientSpherePreset(model::SphericalHarmonics::Preset(preset % model::SphericalHarmonics::NUM_PRESET));
|
||||||
|
} else {
|
||||||
|
// force to preset 0
|
||||||
|
setAmbientLightMode(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1775,10 +1775,10 @@ QSharedPointer<NetworkGeometry> GeometryCache::getGeometry(const QUrl& url, cons
|
||||||
return getResource(url, fallback, delayLoad, NULL).staticCast<NetworkGeometry>();
|
return getResource(url, fallback, delayLoad, NULL).staticCast<NetworkGeometry>();
|
||||||
}
|
}
|
||||||
|
|
||||||
QSharedPointer<Resource> GeometryCache::createResource(const QUrl& url,
|
QSharedPointer<Resource> GeometryCache::createResource(const QUrl& url, const QSharedPointer<Resource>& fallback,
|
||||||
const QSharedPointer<Resource>& fallback, bool delayLoad, const void* extra) {
|
bool delayLoad, const void* extra) {
|
||||||
QSharedPointer<NetworkGeometry> geometry(new NetworkGeometry(url, fallback.staticCast<NetworkGeometry>(), delayLoad),
|
QSharedPointer<NetworkGeometry> geometry(new NetworkGeometry(url, fallback.staticCast<NetworkGeometry>(), delayLoad),
|
||||||
&Resource::allReferencesCleared);
|
&Resource::allReferencesCleared);
|
||||||
geometry->setLODParent(geometry);
|
geometry->setLODParent(geometry);
|
||||||
return geometry.staticCast<Resource>();
|
return geometry.staticCast<Resource>();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2372,7 +2372,7 @@ int Model::renderMeshesForModelsInScene(gpu::Batch& batch, RenderMode mode, bool
|
||||||
|
|
||||||
int Model::renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold,
|
int Model::renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold,
|
||||||
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args,
|
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args,
|
||||||
bool forceRenderSomeMeshes) {
|
bool forceRenderMeshes) {
|
||||||
|
|
||||||
PROFILE_RANGE(__FUNCTION__);
|
PROFILE_RANGE(__FUNCTION__);
|
||||||
int meshPartsRendered = 0;
|
int meshPartsRendered = 0;
|
||||||
|
@ -2395,7 +2395,7 @@ int Model::renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, fl
|
||||||
pickPrograms(batch, mode, translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned,
|
pickPrograms(batch, mode, translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned,
|
||||||
args, locations, skinLocations);
|
args, locations, skinLocations);
|
||||||
meshPartsRendered = renderMeshesFromList(list, batch, mode, translucent, alphaThreshold,
|
meshPartsRendered = renderMeshesFromList(list, batch, mode, translucent, alphaThreshold,
|
||||||
args, locations, skinLocations, forceRenderSomeMeshes);
|
args, locations, skinLocations, forceRenderMeshes);
|
||||||
GLBATCH(glUseProgram)(0);
|
GLBATCH(glUseProgram)(0);
|
||||||
|
|
||||||
return meshPartsRendered;
|
return meshPartsRendered;
|
||||||
|
@ -2403,7 +2403,7 @@ int Model::renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, fl
|
||||||
|
|
||||||
|
|
||||||
int Model::renderMeshesFromList(QVector<int>& list, gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold, RenderArgs* args,
|
int Model::renderMeshesFromList(QVector<int>& list, gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold, RenderArgs* args,
|
||||||
Locations* locations, SkinLocations* skinLocations, bool forceRenderSomeMeshes) {
|
Locations* locations, SkinLocations* skinLocations, bool forceRenderMeshes) {
|
||||||
PROFILE_RANGE(__FUNCTION__);
|
PROFILE_RANGE(__FUNCTION__);
|
||||||
|
|
||||||
auto textureCache = DependencyManager::get<TextureCache>();
|
auto textureCache = DependencyManager::get<TextureCache>();
|
||||||
|
@ -2439,21 +2439,14 @@ int Model::renderMeshesFromList(QVector<int>& list, gpu::Batch& batch, RenderMod
|
||||||
// if we got here, then check to see if this mesh is in view
|
// if we got here, then check to see if this mesh is in view
|
||||||
if (args) {
|
if (args) {
|
||||||
bool shouldRender = true;
|
bool shouldRender = true;
|
||||||
bool forceRender = false;
|
|
||||||
args->_meshesConsidered++;
|
args->_meshesConsidered++;
|
||||||
|
|
||||||
if (args->_viewFrustum) {
|
if (args->_viewFrustum) {
|
||||||
|
|
||||||
// NOTE: This is a hack to address the fact that for avatar meshes, the _calculatedMeshBoxes can be wrong
|
shouldRender = forceRenderMeshes ||
|
||||||
// for some meshes. Those meshes where the mesh's modelTransform is the identity matrix, and will have
|
args->_viewFrustum->boxInFrustum(_calculatedMeshBoxes.at(i)) != ViewFrustum::OUTSIDE;
|
||||||
// incorrectly calculated mesh boxes. In this case, we will ignore the box and assume it's visible.
|
|
||||||
if (forceRenderSomeMeshes && (geometry.meshes.at(i).modelTransform == glm::mat4())) {
|
|
||||||
forceRender = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
shouldRender = forceRender || args->_viewFrustum->boxInFrustum(_calculatedMeshBoxes.at(i)) != ViewFrustum::OUTSIDE;
|
|
||||||
|
|
||||||
if (shouldRender && !forceRender) {
|
if (shouldRender && !forceRenderMeshes) {
|
||||||
float distance = args->_viewFrustum->distanceToCamera(_calculatedMeshBoxes.at(i).calcCenter());
|
float distance = args->_viewFrustum->distanceToCamera(_calculatedMeshBoxes.at(i).calcCenter());
|
||||||
shouldRender = !_viewState ? false : _viewState->shouldRenderMesh(_calculatedMeshBoxes.at(i).getLargestDimension(),
|
shouldRender = !_viewState ? false : _viewState->shouldRenderMesh(_calculatedMeshBoxes.at(i).getLargestDimension(),
|
||||||
distance);
|
distance);
|
||||||
|
|
|
@ -460,14 +460,14 @@ private:
|
||||||
bool renderCore(float alpha, RenderMode mode, RenderArgs* args);
|
bool renderCore(float alpha, RenderMode mode, RenderArgs* args);
|
||||||
int renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold,
|
int renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold,
|
||||||
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args = NULL,
|
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args = NULL,
|
||||||
bool forceRenderSomeMeshes = false);
|
bool forceRenderMeshes = false);
|
||||||
|
|
||||||
void setupBatchTransform(gpu::Batch& batch);
|
void setupBatchTransform(gpu::Batch& batch);
|
||||||
QVector<int>* pickMeshList(bool translucent, float alphaThreshold, bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned);
|
QVector<int>* pickMeshList(bool translucent, float alphaThreshold, bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned);
|
||||||
|
|
||||||
int renderMeshesFromList(QVector<int>& list, gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold,
|
int renderMeshesFromList(QVector<int>& list, gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold,
|
||||||
RenderArgs* args, Locations* locations, SkinLocations* skinLocations,
|
RenderArgs* args, Locations* locations, SkinLocations* skinLocations,
|
||||||
bool forceRenderSomeMeshes = false);
|
bool forceRenderMeshes = false);
|
||||||
|
|
||||||
static void pickPrograms(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold,
|
static void pickPrograms(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold,
|
||||||
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args,
|
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args,
|
||||||
|
|
|
@ -17,12 +17,13 @@
|
||||||
#include <qurlquery.h>
|
#include <qurlquery.h>
|
||||||
|
|
||||||
#include <NetworkAccessManager.h>
|
#include <NetworkAccessManager.h>
|
||||||
|
#include <NetworkingConstants.h>
|
||||||
|
|
||||||
#include <AccountManager.h>
|
#include <AccountManager.h>
|
||||||
#include "XMLHttpRequestClass.h"
|
#include "XMLHttpRequestClass.h"
|
||||||
#include "ScriptEngine.h"
|
#include "ScriptEngine.h"
|
||||||
|
|
||||||
const QString METAVERSE_API_URL = "https://metaverse.highfidelity.com/api/";
|
const QString METAVERSE_API_URL = NetworkingConstants::METAVERSE_SERVER_URL.toString() + "/api/";
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(QByteArray*)
|
Q_DECLARE_METATYPE(QByteArray*)
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ public:
|
||||||
void rotate(const glm::quat& rotation);
|
void rotate(const glm::quat& rotation);
|
||||||
|
|
||||||
glm::vec3 size() const { return maximum - minimum; }
|
glm::vec3 size() const { return maximum - minimum; }
|
||||||
float largestDimension () const {glm::vec3 s = size(); return glm::max(s[0], s[1], s[2]); }
|
float largestDimension() const {glm::vec3 s = size(); return glm::max(s[0], s[1], s[2]); }
|
||||||
|
|
||||||
/// \return new Extents which is original rotated around orign by rotation
|
/// \return new Extents which is original rotated around orign by rotation
|
||||||
Extents getRotated(const glm::quat& rotation) const {
|
Extents getRotated(const glm::quat& rotation) const {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// SettingInterface.cpp
|
// SettingInterface.cpp
|
||||||
//
|
// libraries/shared/src
|
||||||
//
|
//
|
||||||
// Created by Clement on 2/2/15.
|
// Created by Clement on 2/2/15.
|
||||||
// Copyright 2015 High Fidelity, Inc.
|
// Copyright 2015 High Fidelity, Inc.
|
||||||
|
@ -9,7 +9,6 @@
|
||||||
// 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 <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
|
@ -23,8 +22,16 @@ namespace Setting {
|
||||||
|
|
||||||
// cleans up the settings private instance. Should only be run once at closing down.
|
// cleans up the settings private instance. Should only be run once at closing down.
|
||||||
void cleanupPrivateInstance() {
|
void cleanupPrivateInstance() {
|
||||||
delete privateInstance;
|
// grab the thread before we nuke the instance
|
||||||
privateInstance = nullptr;
|
QThread* settingsManagerThread = privateInstance->thread();
|
||||||
|
|
||||||
|
// tell the private instance to clean itself up on its thread
|
||||||
|
privateInstance->deleteLater();
|
||||||
|
privateInstance = NULL;
|
||||||
|
|
||||||
|
// quit the settings manager thread and wait on it to make sure it's gone
|
||||||
|
settingsManagerThread->quit();
|
||||||
|
settingsManagerThread->wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sets up the settings private instance. Should only be run once at startup
|
// Sets up the settings private instance. Should only be run once at startup
|
||||||
|
|
|
@ -66,7 +66,9 @@ QDataStream& operator>>(QDataStream& in, glm::quat& quaternion) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// less common utils can be enabled with DEBUG
|
// less common utils can be enabled with DEBUG
|
||||||
#ifdef DEBUG
|
// FIXME, remove the second defined clause once these compile, or remove the
|
||||||
|
// functions.
|
||||||
|
#if defined(DEBUG) && defined(FIXED_STREAMS)
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& s, const CollisionInfo& c) {
|
std::ostream& operator<<(std::ostream& s, const CollisionInfo& c) {
|
||||||
s << "{penetration=" << c._penetration
|
s << "{penetration=" << c._penetration
|
||||||
|
|
Loading…
Reference in a new issue