This commit is contained in:
Philip Rosedale 2014-02-06 07:46:26 -08:00
commit a9b330baff
38 changed files with 118 additions and 287 deletions

View file

@ -18,9 +18,18 @@ send your resume to hiring@highfidelity.io
Building Interface & other High Fidelity Components Building Interface & other High Fidelity Components
========= =========
Interface is our OS X and Linux build-able client for accessing our virtual Interface is our Windows, OS X, and Linux build-able client for accessing our virtual
world. world.
For detailed notes on building for Windows, please refer to the following wiki page:
https://github.com/highfidelity/hifi/wiki/Building-on-Windows
For detailed notes on building for Ubuntu, please refer to the following wiki page:
https://github.com/highfidelity/hifi/wiki/Building-on-Ubuntu-13.04
Building on Mac OS X and Linux:
--------------------------------
CMake CMake
----- -----
Hifi uses CMake to generate build files and project files Hifi uses CMake to generate build files and project files
@ -45,9 +54,9 @@ If Cmake throws you an error related to Qt5 it likely cannot find your Qt5 cmake
You can solve this by setting an environment variable, QT_CMAKE_PREFIX_PATH, to the location of the folder distributed You can solve this by setting an environment variable, QT_CMAKE_PREFIX_PATH, to the location of the folder distributed
with Qt5 that contains them. with Qt5 that contains them.
For example, a Qt5 5.1.1 installation to /usr/local/qt5 would require that QT_CMAKE_PREFIX_PATH be set with the following command. This can either be entered directly into your shell session before you build or in your shell profile (e.g.: ~/.bash_profile, ~/.bashrc, ~/.zshrc - this depends on your shell and environment). For example, a Qt5 5.2.0 installation to /usr/local/qt5 would require that QT_CMAKE_PREFIX_PATH be set with the following command. This can either be entered directly into your shell session before you build or in your shell profile (e.g.: ~/.bash_profile, ~/.bashrc, ~/.zshrc - this depends on your shell and environment).
export QT_CMAKE_PREFIX_PATH=/usr/local/qt/5.1.1/clang_64/lib/cmake/ export QT_CMAKE_PREFIX_PATH=/usr/local/qt/5.2.0/clang_64/lib/cmake/
The path it needs to be set to will depend on where and how Qt5 was installed. The path it needs to be set to will depend on where and how Qt5 was installed.
@ -64,7 +73,7 @@ components located in the build/target_name/Debug directories.
Other dependencies & information Other dependencies & information
---- ----
In addition to CMake, Qt 5.1 is required to build all components. In addition to CMake, Qt 5.2 is required to build all components.
What can I build on? What can I build on?
We have successfully built on OS X 10.8, Ubuntu and a few other modern Linux We have successfully built on OS X 10.8, Ubuntu and a few other modern Linux

View file

@ -30,9 +30,6 @@ link_hifi_library(octree ${TARGET_NAME} ${ROOT_DIR})
link_hifi_library(voxels ${TARGET_NAME} ${ROOT_DIR}) link_hifi_library(voxels ${TARGET_NAME} ${ROOT_DIR})
link_hifi_library(particles ${TARGET_NAME} ${ROOT_DIR}) link_hifi_library(particles ${TARGET_NAME} ${ROOT_DIR})
link_hifi_library(metavoxels ${TARGET_NAME} ${ROOT_DIR}) link_hifi_library(metavoxels ${TARGET_NAME} ${ROOT_DIR})
link_hifi_library(octree-server ${TARGET_NAME} ${ROOT_DIR})
link_hifi_library(particle-server ${TARGET_NAME} ${ROOT_DIR})
link_hifi_library(voxel-server ${TARGET_NAME} ${ROOT_DIR})
link_hifi_library(script-engine ${TARGET_NAME} ${ROOT_DIR}) link_hifi_library(script-engine ${TARGET_NAME} ${ROOT_DIR})
link_hifi_library(embedded-webserver ${TARGET_NAME} ${ROOT_DIR}) link_hifi_library(embedded-webserver ${TARGET_NAME} ${ROOT_DIR})

View file

@ -8,15 +8,13 @@
#include <PacketHeaders.h> #include <PacketHeaders.h>
#include <ParticleServer.h>
#include <VoxelServer.h>
#include "Agent.h" #include "Agent.h"
#include "AssignmentFactory.h" #include "AssignmentFactory.h"
#include "audio/AudioMixer.h" #include "audio/AudioMixer.h"
#include "avatars/AvatarMixer.h" #include "avatars/AvatarMixer.h"
#include "metavoxels/MetavoxelServer.h" #include "metavoxels/MetavoxelServer.h"
#include "particles/ParticleServer.h"
#include "voxels/VoxelServer.h"
ThreadedAssignment* AssignmentFactory::unpackAssignment(const QByteArray& packet) { ThreadedAssignment* AssignmentFactory::unpackAssignment(const QByteArray& packet) {
QDataStream packetStream(packet); QDataStream packetStream(packet);

View file

@ -10,9 +10,10 @@
#ifndef __hifi__ParticleNodeData__ #ifndef __hifi__ParticleNodeData__
#define __hifi__ParticleNodeData__ #define __hifi__ParticleNodeData__
#include <OctreeQueryNode.h>
#include <PacketHeaders.h> #include <PacketHeaders.h>
#include "../octree/OctreeQueryNode.h"
class ParticleNodeData : public OctreeQueryNode { class ParticleNodeData : public OctreeQueryNode {
public: public:
ParticleNodeData() : ParticleNodeData() :

View file

@ -10,7 +10,7 @@
#ifndef __particle_server__ParticleServer__ #ifndef __particle_server__ParticleServer__
#define __particle_server__ParticleServer__ #define __particle_server__ParticleServer__
#include <OctreeServer.h> #include "../octree/OctreeServer.h"
#include "Particle.h" #include "Particle.h"
#include "ParticleServerConsts.h" #include "ParticleServerConsts.h"

View file

@ -3,15 +3,16 @@
// hifi // hifi
// //
// Created by Stephen Birarda on 3/21/13. // Created by Stephen Birarda on 3/21/13.
// // Copyright (c) 2014 HighFidelity, Inc. All rights reserved.
// //
#ifndef __hifi__VoxelNodeData__ #ifndef __hifi__VoxelNodeData__
#define __hifi__VoxelNodeData__ #define __hifi__VoxelNodeData__
#include <OctreeQueryNode.h>
#include <PacketHeaders.h> #include <PacketHeaders.h>
#include "../octree/OctreeQueryNode.h"
class VoxelNodeData : public OctreeQueryNode { class VoxelNodeData : public OctreeQueryNode {
public: public:
VoxelNodeData() : OctreeQueryNode() { }; VoxelNodeData() : OctreeQueryNode() { };

View file

@ -17,8 +17,7 @@
#include <ThreadedAssignment.h> #include <ThreadedAssignment.h>
#include <EnvironmentData.h> #include <EnvironmentData.h>
#include <OctreeServer.h> #include "../octree/OctreeServer.h"
#include "VoxelServerConsts.h" #include "VoxelServerConsts.h"

View file

@ -275,6 +275,9 @@ function cleanupGame() {
if (missileFired) { if (missileFired) {
Particles.deleteParticle(myMissile); Particles.deleteParticle(myMissile);
} }
Controller.releaseKeyEvents({text: " "});
Script.stop(); Script.stop();
} }
Script.scriptEnding.connect(cleanupGame); Script.scriptEnding.connect(cleanupGame);

View file

@ -154,8 +154,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
_resetRecentMaxPacketsSoon(true), _resetRecentMaxPacketsSoon(true),
_swatch(NULL), _swatch(NULL),
_pasteMode(false), _pasteMode(false),
_logger(new FileLogger(this)), _logger(new FileLogger(this))
_persistThread(NULL)
{ {
_myAvatar = _avatarManager.getMyAvatar(); _myAvatar = _avatarManager.getMyAvatar();
@ -316,12 +315,7 @@ Application::~Application() {
_voxelHideShowThread.terminate(); _voxelHideShowThread.terminate();
_voxelEditSender.terminate(); _voxelEditSender.terminate();
_particleEditSender.terminate(); _particleEditSender.terminate();
if (_persistThread) {
_persistThread->terminate();
_persistThread->deleteLater();
_persistThread = NULL;
}
storeSizeAndPosition(); storeSizeAndPosition();
saveScripts(); saveScripts();
_sharedVoxelSystem.changeTree(new VoxelTree); _sharedVoxelSystem.changeTree(new VoxelTree);
@ -1907,9 +1901,6 @@ void Application::init() {
connect(_rearMirrorTools, SIGNAL(restoreView()), SLOT(restoreMirrorView())); connect(_rearMirrorTools, SIGNAL(restoreView()), SLOT(restoreMirrorView()));
connect(_rearMirrorTools, SIGNAL(shrinkView()), SLOT(shrinkMirrorView())); connect(_rearMirrorTools, SIGNAL(shrinkView()), SLOT(shrinkMirrorView()));
connect(_rearMirrorTools, SIGNAL(resetView()), SLOT(resetSensors())); connect(_rearMirrorTools, SIGNAL(resetView()), SLOT(resetSensors()));
updateLocalOctreeCache(true);
} }
void Application::closeMirrorView() { void Application::closeMirrorView() {
@ -2062,7 +2053,7 @@ void Application::updateHoverVoxels(float deltaTime, float& distance, BoxFace& f
glm::vec4 oldVoxel(_hoverVoxel.x, _hoverVoxel.y, _hoverVoxel.z, _hoverVoxel.s); glm::vec4 oldVoxel(_hoverVoxel.x, _hoverVoxel.y, _hoverVoxel.z, _hoverVoxel.s);
// only do this work if MAKE_SOUND_ON_VOXEL_HOVER or MAKE_SOUND_ON_VOXEL_CLICK is enabled, // only do this work if MAKE_SOUND_ON_VOXEL_HOVER or MAKE_SOUND_ON_VOXEL_CLICK is enabled,
// and make sure the tree is not already busy... because otherwise you'll have to wait. // and make sure the tree is not already busy... because otherwise you'll have to wait.
if (!(_voxels.treeIsBusy() || _mousePressed)) { if (!_mousePressed) {
{ {
PerformanceWarning warn(showWarnings, "Application::updateHoverVoxels() _voxels.findRayIntersection()"); PerformanceWarning warn(showWarnings, "Application::updateHoverVoxels() _voxels.findRayIntersection()");
_isHoverVoxel = _voxels.findRayIntersection(_mouseRayOrigin, _mouseRayDirection, _hoverVoxel, distance, face); _isHoverVoxel = _voxels.findRayIntersection(_mouseRayOrigin, _mouseRayDirection, _hoverVoxel, distance, face);
@ -2207,9 +2198,6 @@ void Application::updateThreads(float deltaTime) {
_voxelHideShowThread.threadRoutine(); _voxelHideShowThread.threadRoutine();
_voxelEditSender.threadRoutine(); _voxelEditSender.threadRoutine();
_particleEditSender.threadRoutine(); _particleEditSender.threadRoutine();
if (_persistThread) {
_persistThread->threadRoutine();
}
} }
} }
@ -2884,7 +2872,8 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
} }
} }
_avatarManager.renderAvatars(whichCamera.getMode() == CAMERA_MODE_MIRROR, selfAvatarOnly); bool renderMyHead = (whichCamera.getInterpolatedMode() != CAMERA_MODE_FIRST_PERSON);
_avatarManager.renderAvatars(renderMyHead, selfAvatarOnly);
if (!selfAvatarOnly) { if (!selfAvatarOnly) {
// Render the world box // Render the world box
@ -3882,10 +3871,6 @@ void Application::domainChanged(const QString& domainHostname) {
// reset the particle renderer // reset the particle renderer
_particles.clear(); _particles.clear();
// reset our persist thread
qDebug() << "Domain changed to" << domainHostname << ". Swapping persist cache.";
updateLocalOctreeCache();
} }
void Application::nodeKilled(SharedNodePointer node) { void Application::nodeKilled(SharedNodePointer node) {
@ -4155,49 +4140,6 @@ void Application::initAvatarAndViewFrustum() {
updateMyAvatar(0.f); updateMyAvatar(0.f);
} }
QString Application::getLocalVoxelCacheFileName() {
QString fileName = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
QDir logDir(fileName);
if (!logDir.exists(fileName)) {
logDir.mkdir(fileName);
}
fileName.append(QString("/hifi.voxelscache."));
fileName.append(_profile.getLastDomain());
fileName.append(QString(".svo"));
return fileName;
}
void Application::updateLocalOctreeCache(bool firstTime) {
// only do this if we've already got a persistThread or we're told this is the first time
if (firstTime || _persistThread) {
if (_persistThread) {
_persistThread->terminate();
_persistThread->deleteLater();
_persistThread = NULL;
}
QString localVoxelCacheFileName = getLocalVoxelCacheFileName();
const int LOCAL_CACHE_PERSIST_INTERVAL = 1000 * 10; // every 10 seconds
if (!Menu::getInstance()->isOptionChecked(MenuOption::DisableLocalVoxelCache)) {
_persistThread = new OctreePersistThread(_voxels.getTree(),
localVoxelCacheFileName.toLocal8Bit().constData(),LOCAL_CACHE_PERSIST_INTERVAL);
qDebug() << "updateLocalOctreeCache()... localVoxelCacheFileName=" << localVoxelCacheFileName;
}
if (_persistThread) {
_voxels.beginLoadingLocalVoxelCache(); // while local voxels are importing, don't do individual node VBO updates
connect(_persistThread, SIGNAL(loadCompleted()), &_voxels, SLOT(localVoxelCacheLoaded()));
_persistThread->initialize(true);
}
}
}
void Application::checkVersion() { void Application::checkVersion() {
QNetworkRequest latestVersionRequest((QUrl(CHECK_VERSION_URL))); QNetworkRequest latestVersionRequest((QUrl(CHECK_VERSION_URL)));
latestVersionRequest.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache); latestVersionRequest.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache);

View file

@ -484,11 +484,6 @@ private:
FileLogger* _logger; FileLogger* _logger;
OctreePersistThread* _persistThread;
QString getLocalVoxelCacheFileName();
void updateLocalOctreeCache(bool firstTime = false);
void checkVersion(); void checkVersion();
void displayUpdateDialog(); void displayUpdateDialog();
bool shouldSkipVersion(QString latestVersion); bool shouldSkipVersion(QString latestVersion);

View file

@ -417,7 +417,7 @@ void Audio::handleAudioInput() {
Application::getInstance()->getBandwidthMeter()->outputStream(BandwidthMeter::AUDIO) Application::getInstance()->getBandwidthMeter()->outputStream(BandwidthMeter::AUDIO)
.updateValue(NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL + leadingBytes); .updateValue(NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL + leadingBytes);
} }
delete[] inputAudioSamples; delete[] inputAudioSamples;
} }
} }
@ -481,7 +481,7 @@ void Audio::addReceivedAudioToBuffer(const QByteArray& audioByteArray) {
// copy the samples we'll resample from the ring buffer - this also // copy the samples we'll resample from the ring buffer - this also
// pushes the read pointer of the ring buffer forwards // pushes the read pointer of the ring buffer forwards
int16_t ringBufferSamples[numNetworkOutputSamples]; int16_t* ringBufferSamples= new int16_t[numNetworkOutputSamples];
_ringBuffer.readSamples(ringBufferSamples, numNetworkOutputSamples); _ringBuffer.readSamples(ringBufferSamples, numNetworkOutputSamples);
// add the next numNetworkOutputSamples from each QByteArray // add the next numNetworkOutputSamples from each QByteArray
@ -502,6 +502,7 @@ void Audio::addReceivedAudioToBuffer(const QByteArray& audioByteArray) {
Q_ARG(QByteArray, QByteArray((char*) ringBufferSamples, numNetworkOutputSamples)), Q_ARG(QByteArray, QByteArray((char*) ringBufferSamples, numNetworkOutputSamples)),
Q_ARG(bool, true), Q_ARG(bool, false)); Q_ARG(bool, true), Q_ARG(bool, false));
} }
delete[] ringBufferSamples;
} }
} }

View file

@ -36,6 +36,7 @@ Camera::Camera() {
_modeShiftRate = 1.0f; _modeShiftRate = 1.0f;
_linearModeShift = 0.0f; _linearModeShift = 0.0f;
_mode = CAMERA_MODE_THIRD_PERSON; _mode = CAMERA_MODE_THIRD_PERSON;
_prevMode = CAMERA_MODE_THIRD_PERSON;
_tightness = 10.0f; // default _tightness = 10.0f; // default
_fieldOfView = DEFAULT_FIELD_OF_VIEW_DEGREES; _fieldOfView = DEFAULT_FIELD_OF_VIEW_DEGREES;
_aspectRatio = 16.f/9.f; _aspectRatio = 16.f/9.f;
@ -123,6 +124,7 @@ void Camera::setModeShiftRate ( float rate ) {
void Camera::setMode(CameraMode m) { void Camera::setMode(CameraMode m) {
_prevMode = _mode;
_mode = m; _mode = m;
_modeShift = 0.0; _modeShift = 0.0;
_linearModeShift = 0.0; _linearModeShift = 0.0;
@ -199,6 +201,17 @@ bool Camera::getFrustumNeedsReshape() const {
return _frustumNeedsReshape; return _frustumNeedsReshape;
} }
// call this when deciding whether to render the head or not
CameraMode Camera::getInterpolatedMode() const {
const float SHIFT_THRESHOLD_INTO_FIRST_PERSON = 0.7f;
const float SHIFT_THRESHOLD_OUT_OF_FIRST_PERSON = 0.6f;
if ((_mode == CAMERA_MODE_FIRST_PERSON && _linearModeShift < SHIFT_THRESHOLD_INTO_FIRST_PERSON) ||
(_prevMode == CAMERA_MODE_FIRST_PERSON && _linearModeShift < SHIFT_THRESHOLD_OUT_OF_FIRST_PERSON)) {
return _prevMode;
}
return _mode;
}
// call this after reshaping the view frustum // call this after reshaping the view frustum
void Camera::setFrustumWasReshaped() { void Camera::setFrustumWasReshaped() {
_frustumNeedsReshape = false; _frustumNeedsReshape = false;

View file

@ -61,6 +61,8 @@ public:
const glm::quat& getEyeOffsetOrientation () const { return _eyeOffsetOrientation; } const glm::quat& getEyeOffsetOrientation () const { return _eyeOffsetOrientation; }
float getScale () const { return _scale; } float getScale () const { return _scale; }
CameraMode getInterpolatedMode() const;
bool getFrustumNeedsReshape() const; // call to find out if the view frustum needs to be reshaped bool getFrustumNeedsReshape() const; // call to find out if the view frustum needs to be reshaped
void setFrustumWasReshaped(); // call this after reshaping the view frustum. void setFrustumWasReshaped(); // call this after reshaping the view frustum.
@ -68,6 +70,7 @@ private:
bool _needsToInitialize; bool _needsToInitialize;
CameraMode _mode; CameraMode _mode;
CameraMode _prevMode;
bool _frustumNeedsReshape; bool _frustumNeedsReshape;
glm::vec3 _position; glm::vec3 _position;
glm::vec3 _idealPosition; glm::vec3 _idealPosition;

View file

@ -317,7 +317,6 @@ Menu::Menu() :
addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::AmbientOcclusion); addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::AmbientOcclusion);
addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::DontFadeOnVoxelServerChanges); addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::DontFadeOnVoxelServerChanges);
addActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::LodTools, Qt::SHIFT | Qt::Key_L, this, SLOT(lodTools())); addActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::LodTools, Qt::SHIFT | Qt::Key_L, this, SLOT(lodTools()));
addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::DisableLocalVoxelCache);
QMenu* voxelProtoOptionsMenu = voxelOptionsMenu->addMenu("Voxel Server Protocol Options"); QMenu* voxelProtoOptionsMenu = voxelOptionsMenu->addMenu("Voxel Server Protocol Options");

View file

@ -176,7 +176,6 @@ namespace MenuOption {
const QString DestructiveAddVoxel = "Create Voxel is Destructive"; const QString DestructiveAddVoxel = "Create Voxel is Destructive";
const QString DisableColorVoxels = "Disable Colored Voxels"; const QString DisableColorVoxels = "Disable Colored Voxels";
const QString DisableDeltaSending = "Disable Delta Sending"; const QString DisableDeltaSending = "Disable Delta Sending";
const QString DisableLocalVoxelCache = "Disable Local Voxel Cache";
const QString DisableLowRes = "Disable Lower Resolution While Moving"; const QString DisableLowRes = "Disable Lower Resolution While Moving";
const QString DisplayFrustum = "Display Frustum"; const QString DisplayFrustum = "Display Frustum";
const QString DisplayLeapHands = "Display Leap Hands"; const QString DisplayLeapHands = "Display Leap Hands";

View file

@ -99,8 +99,6 @@ VoxelSystem::VoxelSystem(float treeScale, int maxVoxels)
_culledOnce = false; _culledOnce = false;
_inhideOutOfView = false; _inhideOutOfView = false;
_treeIsBusy = false;
} }
void VoxelSystem::elementDeleted(OctreeElement* element) { void VoxelSystem::elementDeleted(OctreeElement* element) {
@ -594,9 +592,10 @@ int VoxelSystem::parseData(const QByteArray& packet) {
} }
if (sectionLength) { if (sectionLength) {
PerformanceWarning warn(showTimingDetails, "VoxelSystem::parseData() section");
// ask the VoxelTree to read the bitstream into the tree // ask the VoxelTree to read the bitstream into the tree
ReadBitstreamToTreeParams args(packetIsColored ? WANT_COLOR : NO_COLOR, WANT_EXISTS_BITS, NULL, getDataSourceUUID()); ReadBitstreamToTreeParams args(packetIsColored ? WANT_COLOR : NO_COLOR, WANT_EXISTS_BITS, NULL, getDataSourceUUID());
lockTree(); _tree->lockForWrite();
VoxelPacketData packetData(packetIsCompressed); VoxelPacketData packetData(packetIsCompressed);
packetData.loadFinalizedContent(dataAt, sectionLength); packetData.loadFinalizedContent(dataAt, sectionLength);
if (Application::getInstance()->getLogger()->extraDebugging()) { if (Application::getInstance()->getLogger()->extraDebugging()) {
@ -608,7 +607,7 @@ int VoxelSystem::parseData(const QByteArray& packet) {
packetData.getUncompressedSize()); packetData.getUncompressedSize());
} }
_tree->readBitstreamToTree(packetData.getUncompressedData(), packetData.getUncompressedSize(), args); _tree->readBitstreamToTree(packetData.getUncompressedData(), packetData.getUncompressedSize(), args);
unlockTree(); _tree->unlock();
dataBytes -= sectionLength; dataBytes -= sectionLength;
dataAt += sectionLength; dataAt += sectionLength;
@ -1395,9 +1394,11 @@ void VoxelSystem::removeScaleAndReleaseProgram(bool texture) {
int VoxelSystem::_nodeCount = 0; int VoxelSystem::_nodeCount = 0;
void VoxelSystem::killLocalVoxels() { void VoxelSystem::killLocalVoxels() {
lockTree(); PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
"VoxelSystem::killLocalVoxels()");
_tree->lockForWrite();
_tree->eraseAllOctreeElements(); _tree->eraseAllOctreeElements();
unlockTree(); _tree->unlock();
clearFreeBufferIndexes(); clearFreeBufferIndexes();
_voxelsInReadArrays = 0; // do we need to do this? _voxelsInReadArrays = 0; // do we need to do this?
setupNewVoxelsForDrawing(); setupNewVoxelsForDrawing();
@ -1416,10 +1417,12 @@ bool VoxelSystem::clearAllNodesBufferIndexOperation(OctreeElement* element, void
} }
void VoxelSystem::clearAllNodesBufferIndex() { void VoxelSystem::clearAllNodesBufferIndex() {
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
"VoxelSystem::clearAllNodesBufferIndex()");
_nodeCount = 0; _nodeCount = 0;
lockTree(); _tree->lockForRead(); // we won't change the tree so it's ok to treat this as a read
_tree->recurseTreeWithOperation(clearAllNodesBufferIndexOperation); _tree->recurseTreeWithOperation(clearAllNodesBufferIndexOperation);
unlockTree(); _tree->unlock();
if (Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings)) { if (Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings)) {
qDebug("clearing buffer index of %d nodes", _nodeCount); qDebug("clearing buffer index of %d nodes", _nodeCount);
} }
@ -1481,7 +1484,8 @@ bool VoxelSystem::trueColorizeOperation(OctreeElement* element, void* extraData)
} }
void VoxelSystem::trueColorize() { void VoxelSystem::trueColorize() {
PerformanceWarning warn(true, "trueColorize()",true); PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
"trueColorize()",true);
_nodeCount = 0; _nodeCount = 0;
_tree->recurseTreeWithOperation(trueColorizeOperation); _tree->recurseTreeWithOperation(trueColorizeOperation);
qDebug("setting true color for %d nodes", _nodeCount); qDebug("setting true color for %d nodes", _nodeCount);
@ -1951,9 +1955,13 @@ void VoxelSystem::hideOutOfView(bool forceFullFrustum) {
return; return;
} }
lockTree(); {
_tree->recurseTreeWithOperation(hideOutOfViewOperation,(void*)&args); PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
unlockTree(); "VoxelSystem::... recurseTreeWithOperation(hideOutOfViewOperation)");
_tree->lockForRead();
_tree->recurseTreeWithOperation(hideOutOfViewOperation,(void*)&args);
_tree->unlock();
}
_lastCulledViewFrustum = args.thisViewFrustum; // save last stable _lastCulledViewFrustum = args.thisViewFrustum; // save last stable
_culledOnce = true; _culledOnce = true;
@ -2150,35 +2158,47 @@ bool VoxelSystem::hideOutOfViewOperation(OctreeElement* element, void* extraData
bool VoxelSystem::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, bool VoxelSystem::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
VoxelDetail& detail, float& distance, BoxFace& face) { VoxelDetail& detail, float& distance, BoxFace& face) {
lockTree();
OctreeElement* element; PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
if (!_tree->findRayIntersection(origin, direction, element, distance, face)) { "VoxelSystem::findRayIntersection()");
unlockTree(); bool result = false; // assume no intersection
return false; if (_tree->tryLockForRead()) {
OctreeElement* element;
result = _tree->findRayIntersection(origin, direction, element, distance, face);
if (result) {
VoxelTreeElement* voxel = (VoxelTreeElement*)element;
detail.x = voxel->getCorner().x;
detail.y = voxel->getCorner().y;
detail.z = voxel->getCorner().z;
detail.s = voxel->getScale();
detail.red = voxel->getColor()[0];
detail.green = voxel->getColor()[1];
detail.blue = voxel->getColor()[2];
}
_tree->unlock();
} }
VoxelTreeElement* voxel = (VoxelTreeElement*)element; return result;
detail.x = voxel->getCorner().x;
detail.y = voxel->getCorner().y;
detail.z = voxel->getCorner().z;
detail.s = voxel->getScale();
detail.red = voxel->getColor()[0];
detail.green = voxel->getColor()[1];
detail.blue = voxel->getColor()[2];
unlockTree();
return true;
} }
bool VoxelSystem::findSpherePenetration(const glm::vec3& center, float radius, glm::vec3& penetration) { bool VoxelSystem::findSpherePenetration(const glm::vec3& center, float radius, glm::vec3& penetration) {
lockTree(); PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
bool result = _tree->findSpherePenetration(center, radius, penetration); "VoxelSystem::findSpherePenetration()");
unlockTree(); bool result = false; // assume no penetration
if (_tree->tryLockForRead()) {
result = _tree->findSpherePenetration(center, radius, penetration);
_tree->unlock();
}
return result; return result;
} }
bool VoxelSystem::findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, float radius, glm::vec3& penetration) { bool VoxelSystem::findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, float radius, glm::vec3& penetration) {
lockTree(); PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
bool result = _tree->findCapsulePenetration(start, end, radius, penetration); "VoxelSystem::findCapsulePenetration()");
unlockTree(); bool result = false; // assume no penetration
if (_tree->tryLockForRead()) {
result = _tree->findCapsulePenetration(start, end, radius, penetration);
_tree->unlock();
}
return result; return result;
} }
@ -2354,13 +2374,14 @@ void VoxelSystem::collectStatsForTreesAndVBOs() {
void VoxelSystem::deleteVoxelAt(float x, float y, float z, float s) { void VoxelSystem::deleteVoxelAt(float x, float y, float z, float s) {
lockTree(); PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
"VoxelSystem::deleteVoxelAt()");
_tree->lockForWrite();
_tree->deleteVoxelAt(x, y, z, s); _tree->deleteVoxelAt(x, y, z, s);
unlockTree(); _tree->unlock();
// redraw! // redraw!
setupNewVoxelsForDrawing(); // do we even need to do this? Or will the next network receive kick in? setupNewVoxelsForDrawing(); // do we even need to do this? Or will the next network receive kick in?
}; };
VoxelTreeElement* VoxelSystem::getVoxelAt(float x, float y, float z, float s) const { VoxelTreeElement* VoxelSystem::getVoxelAt(float x, float y, float z, float s) const {
@ -2370,10 +2391,12 @@ VoxelTreeElement* VoxelSystem::getVoxelAt(float x, float y, float z, float s) co
void VoxelSystem::createVoxel(float x, float y, float z, float s, void VoxelSystem::createVoxel(float x, float y, float z, float s,
unsigned char red, unsigned char green, unsigned char blue, bool destructive) { unsigned char red, unsigned char green, unsigned char blue, bool destructive) {
//qDebug("VoxelSystem::createVoxel(%f,%f,%f,%f)\n",x,y,z,s); PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
lockTree(); "VoxelSystem::createVoxel()");
_tree->lockForWrite();
_tree->createVoxel(x, y, z, s, red, green, blue, destructive); _tree->createVoxel(x, y, z, s, red, green, blue, destructive);
unlockTree(); _tree->unlock();
setupNewVoxelsForDrawing(); setupNewVoxelsForDrawing();
}; };
@ -2744,37 +2767,3 @@ unsigned long VoxelSystem::getVoxelMemoryUsageGPU() {
return (_initialMemoryUsageGPU - currentFreeMemory); return (_initialMemoryUsageGPU - currentFreeMemory);
} }
void VoxelSystem::lockTree() {
_treeLock.lock();
_treeIsBusy = true;
}
void VoxelSystem::unlockTree() {
_treeIsBusy = false;
_treeLock.unlock();
}
void VoxelSystem::localVoxelCacheLoaded() {
qDebug() << "localVoxelCacheLoaded()";
// Make sure that the application has properly set up the view frustum for our loaded state
Application::getInstance()->initAvatarAndViewFrustum();
_tree->setDirtyBit(); // make sure the tree thinks it's dirty
_setupNewVoxelsForDrawingLastFinished = 0; // don't allow the setupNewVoxelsForDrawing() shortcuts
_writeRenderFullVBO = true; // this will disable individual node updates, was reset by killLocalVoxels()
setupNewVoxelsForDrawing();
_inhideOutOfView = false; // reenable hideOutOfView behavior
}
void VoxelSystem::beginLoadingLocalVoxelCache() {
qDebug() << "beginLoadingLocalVoxelCache()";
_writeRenderFullVBO = true; // this will disable individual node updates
_inhideOutOfView = true; // this will disable hidOutOfView which we want to do until local cache is loaded
killLocalVoxels();
qDebug() << "DONE beginLoadingLocalVoxelCache()";
}

View file

@ -110,8 +110,6 @@ public:
virtual void elementDeleted(OctreeElement* element); virtual void elementDeleted(OctreeElement* element);
virtual void elementUpdated(OctreeElement* element); virtual void elementUpdated(OctreeElement* element);
bool treeIsBusy() const { return _treeIsBusy; }
VoxelTreeElement* getVoxelEnclosing(const glm::vec3& point); VoxelTreeElement* getVoxelEnclosing(const glm::vec3& point);
signals: signals:
@ -144,9 +142,6 @@ public slots:
void setUseVoxelShader(bool useVoxelShader); void setUseVoxelShader(bool useVoxelShader);
void setVoxelsAsPoints(bool voxelsAsPoints); void setVoxelsAsPoints(bool voxelsAsPoints);
void localVoxelCacheLoaded();
void beginLoadingLocalVoxelCache();
protected: protected:
float _treeScale; float _treeScale;
unsigned long _maxVoxels; unsigned long _maxVoxels;
@ -304,10 +299,6 @@ private:
bool _useFastVoxelPipeline; bool _useFastVoxelPipeline;
bool _inhideOutOfView; bool _inhideOutOfView;
bool _treeIsBusy; // is the tree mutex locked? if so, it's busy, and if you can avoid it, don't access the tree
void lockTree();
void unlockTree();
}; };
#endif #endif

View file

@ -242,7 +242,9 @@ void Avatar::renderBody(bool forceRenderHead) {
glm::vec3 pos = getPosition(); glm::vec3 pos = getPosition();
//printf("Render other at %.3f, %.2f, %.2f\n", pos.x, pos.y, pos.z); //printf("Render other at %.3f, %.2f, %.2f\n", pos.x, pos.y, pos.z);
_skeletonModel.render(1.0f); _skeletonModel.render(1.0f);
_head.render(1.0f); if (forceRenderHead) {
_head.render(1.0f);
}
_hand.render(false); _hand.render(false);
} }

View file

@ -75,7 +75,6 @@ void AvatarManager::renderAvatars(bool forceRenderHead, bool selfAvatarOnly) {
bool renderLookAtVectors = Menu::getInstance()->isOptionChecked(MenuOption::LookAtVectors); bool renderLookAtVectors = Menu::getInstance()->isOptionChecked(MenuOption::LookAtVectors);
if (!selfAvatarOnly) { if (!selfAvatarOnly) {
// Render avatars of other nodes
foreach (const AvatarSharedPointer& avatarPointer, _avatarHash) { foreach (const AvatarSharedPointer& avatarPointer, _avatarHash) {
Avatar* avatar = static_cast<Avatar*>(avatarPointer.data()); Avatar* avatar = static_cast<Avatar*>(avatarPointer.data());
if (!avatar->isInitialized()) { if (!avatar->isInitialized()) {
@ -84,7 +83,7 @@ void AvatarManager::renderAvatars(bool forceRenderHead, bool selfAvatarOnly) {
if (avatar == static_cast<Avatar*>(_myAvatar.data())) { if (avatar == static_cast<Avatar*>(_myAvatar.data())) {
avatar->render(forceRenderHead); avatar->render(forceRenderHead);
} else { } else {
avatar->render(false); avatar->render(true);
} }
avatar->setDisplayingLookatVectors(renderLookAtVectors); avatar->setDisplayingLookatVectors(renderLookAtVectors);
} }

View file

@ -138,7 +138,7 @@ void DatagramSequencer::receivedDatagram(const QByteArray& datagram) {
} }
// read and dispatch the high-priority messages // read and dispatch the high-priority messages
quint32 highPriorityMessageCount; int highPriorityMessageCount;
_incomingPacketStream >> highPriorityMessageCount; _incomingPacketStream >> highPriorityMessageCount;
int newHighPriorityMessages = highPriorityMessageCount - _receivedHighPriorityMessages; int newHighPriorityMessages = highPriorityMessageCount - _receivedHighPriorityMessages;
for (int i = 0; i < highPriorityMessageCount; i++) { for (int i = 0; i < highPriorityMessageCount; i++) {

View file

@ -1,36 +0,0 @@
cmake_minimum_required(VERSION 2.8)
set(ROOT_DIR ../..)
set(MACRO_DIR ${ROOT_DIR}/cmake/macros)
# setup for find modules
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/../../cmake/modules/")
set(TARGET_NAME octree-server)
find_package(Qt5Network REQUIRED)
find_package(Qt5Widgets REQUIRED)
include(${MACRO_DIR}/SetupHifiLibrary.cmake)
setup_hifi_library(${TARGET_NAME} ${OPTIONAL_SRCS})
qt5_use_modules(${TARGET_NAME} Network Widgets)
include(${MACRO_DIR}/IncludeGLM.cmake)
include_glm(${TARGET_NAME} ${ROOT_DIR})
# link ZLIB
find_package(ZLIB)
include_directories(${ZLIB_INCLUDE_DIRS})
target_link_libraries(${TARGET_NAME} ${ZLIB_LIBRARIES})
# link in the shared library
include(${MACRO_DIR}/LinkHifiLibrary.cmake)
link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR})
# link in the hifi octree library
link_hifi_library(octree ${TARGET_NAME} ${ROOT_DIR})
# link the embedded webserver
link_hifi_library(embedded-webserver ${TARGET_NAME} ${ROOT_DIR})

View file

@ -1,37 +0,0 @@
cmake_minimum_required(VERSION 2.8)
set(ROOT_DIR ../..)
set(MACRO_DIR ${ROOT_DIR}/cmake/macros)
# setup for find modules
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/../../cmake/modules/")
set(TARGET_NAME particle-server)
find_package(Qt5Widgets REQUIRED)
include(${MACRO_DIR}/SetupHifiLibrary.cmake)
setup_hifi_library(${TARGET_NAME} ${OPTIONAL_SRCS})
qt5_use_modules(${TARGET_NAME} Widgets)
# inluce GLM
include(${MACRO_DIR}/IncludeGLM.cmake)
include_glm(${TARGET_NAME} ${ROOT_DIR})
# link in the shared library
include(${MACRO_DIR}/LinkHifiLibrary.cmake)
link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR})
# link ZLIB
find_package(ZLIB)
include_directories(${ZLIB_INCLUDE_DIRS})
target_link_libraries(${TARGET_NAME} ${ZLIB_LIBRARIES})
link_hifi_library(octree ${TARGET_NAME} ${ROOT_DIR})
link_hifi_library(octree-server ${TARGET_NAME} ${ROOT_DIR})
link_hifi_library(particles ${TARGET_NAME} ${ROOT_DIR})
# link in the embedded webserver
link_hifi_library(embedded-webserver ${TARGET_NAME} ${ROOT_DIR})

View file

@ -337,7 +337,7 @@ void NodeList::processSTUNResponse(const QByteArray& packet) {
const uint32_t RFC_5389_MAGIC_COOKIE_NETWORK_ORDER = htonl(RFC_5389_MAGIC_COOKIE); const uint32_t RFC_5389_MAGIC_COOKIE_NETWORK_ORDER = htonl(RFC_5389_MAGIC_COOKIE);
size_t attributeStartIndex = NUM_BYTES_STUN_HEADER; int attributeStartIndex = NUM_BYTES_STUN_HEADER;
if (memcmp(packet.data() + NUM_BYTES_MESSAGE_TYPE_AND_LENGTH, if (memcmp(packet.data() + NUM_BYTES_MESSAGE_TYPE_AND_LENGTH,
&RFC_5389_MAGIC_COOKIE_NETWORK_ORDER, &RFC_5389_MAGIC_COOKIE_NETWORK_ORDER,

View file

@ -37,7 +37,7 @@ int packArithmeticallyCodedValue(int value, char* destination) {
return 1; return 1;
} else { } else {
// pack 255 and then recursively pack on // pack 255 and then recursively pack on
destination[0] = 255; ((unsigned char*)destination)[0] = 255;
return 1 + packArithmeticallyCodedValue(value - 255, destination + 1); return 1 + packArithmeticallyCodedValue(value - 255, destination + 1);
} }
} }

View file

@ -1,37 +0,0 @@
cmake_minimum_required(VERSION 2.8)
set(ROOT_DIR ../..)
set(MACRO_DIR ${ROOT_DIR}/cmake/macros)
# setup for find modules
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/../../cmake/modules/")
set(TARGET_NAME voxel-server)
find_package(Qt5Widgets REQUIRED)
include(${MACRO_DIR}/SetupHifiLibrary.cmake)
setup_hifi_library(${TARGET_NAME} ${OPTIONAL_SRCS})
qt5_use_modules(${TARGET_NAME} Widgets)
include(${MACRO_DIR}/IncludeGLM.cmake)
include_glm(${TARGET_NAME} ${ROOT_DIR})
# link ZLIB
find_package(ZLIB)
include_directories(${ZLIB_INCLUDE_DIRS})
target_link_libraries(${TARGET_NAME} ${ZLIB_LIBRARIES})
# link in the shared library
include(${MACRO_DIR}/LinkHifiLibrary.cmake)
link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR})
# link in the embedded webserver
link_hifi_library(embedded-webserver ${TARGET_NAME} ${ROOT_DIR})
# link in the hifi octree library
link_hifi_library(octree ${TARGET_NAME} ${ROOT_DIR})
link_hifi_library(octree-server ${TARGET_NAME} ${ROOT_DIR})
link_hifi_library(voxels ${TARGET_NAME} ${ROOT_DIR})