Merge remote-tracking branch 'origin/master'

This commit is contained in:
Ryan 2013-10-31 08:59:09 -07:00
commit 8b781bf9cd
25 changed files with 567 additions and 159 deletions

View file

@ -326,6 +326,7 @@ DomainServer::DomainServer(int argc, char* argv[]) :
struct mg_callbacks callbacks = {};
QString documentRoot = QString("%1/resources/web").arg(QCoreApplication::applicationDirPath());
qDebug("The document root is %s\n", documentRoot.toLocal8Bit().constData());
// list of options. Last element must be NULL.
const char* options[] = {"listening_ports", "8080",

View file

@ -620,7 +620,13 @@ void Application::keyPressEvent(QKeyEvent* event) {
_audioScope.inputPaused = !_audioScope.inputPaused;
break;
case Qt::Key_L:
_displayLevels = !_displayLevels;
if (!isShifted && !isMeta) {
_displayLevels = !_displayLevels;
} else if (isShifted) {
Menu::getInstance()->triggerOption(MenuOption::LodTools);
} else if (isMeta) {
Menu::getInstance()->triggerOption(MenuOption::Log);
}
break;
case Qt::Key_E:
@ -2365,6 +2371,11 @@ void Application::queryVoxels() {
}
// These will be the same for all servers, so we can set them up once and then reuse for each server we send to.
_voxelQuery.setWantLowResMoving(Menu::getInstance()->isOptionChecked(MenuOption::LowRes));
_voxelQuery.setWantColor(Menu::getInstance()->isOptionChecked(MenuOption::SendVoxelColors));
_voxelQuery.setWantDelta(Menu::getInstance()->isOptionChecked(MenuOption::DeltaSending));
_voxelQuery.setWantOcclusionCulling(Menu::getInstance()->isOptionChecked(MenuOption::OcclusionCulling));
_voxelQuery.setCameraPosition(_viewFrustum.getPosition());
_voxelQuery.setCameraOrientation(_viewFrustum.getOrientation());
_voxelQuery.setCameraFov(_viewFrustum.getFieldOfView());
@ -2372,6 +2383,8 @@ void Application::queryVoxels() {
_voxelQuery.setCameraNearClip(_viewFrustum.getNearClip());
_voxelQuery.setCameraFarClip(_viewFrustum.getFarClip());
_voxelQuery.setCameraEyeOffsetPosition(_viewFrustum.getEyeOffsetPosition());
_voxelQuery.setVoxelSizeScale(Menu::getInstance()->getVoxelSizeScale());
_voxelQuery.setBoundaryLevelAdjust(Menu::getInstance()->getBoundaryLevelAdjust());
unsigned char voxelQueryPacket[MAX_PACKET_SIZE];
@ -3173,10 +3186,12 @@ void Application::displayStats() {
std::stringstream voxelStats;
voxelStats.precision(4);
voxelStats << "Voxels Rendered: " << _voxels.getVoxelsRendered() / 1000.f << "K " <<
"Written: " << _voxels.getVoxelsWritten()/1000.f << "K " <<
"Updated: " << _voxels.getVoxelsUpdated()/1000.f << "K " <<
"Max: " << _voxels.getMaxVoxels()/1000.f << "K ";
voxelStats << "Voxels " <<
"Max: " << _voxels.getMaxVoxels() / 1000.f << "K " <<
"Rendered: " << _voxels.getVoxelsRendered() / 1000.f << "K " <<
"Written: " << _voxels.getVoxelsWritten() / 1000.f << "K " <<
"Abandoned: " << _voxels.getAbandonedVoxels() / 1000.f << "K " <<
"Updated: " << _voxels.getVoxelsUpdated() / 1000.f << "K ";
statsVerticalOffset += PELS_PER_LINE;
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, (char*)voxelStats.str().c_str());

View file

@ -60,6 +60,7 @@
#include "ui/ChatEntry.h"
#include "ui/VoxelStatsDialog.h"
#include "ui/RearMirrorTools.h"
#include "ui/LodToolsDialog.h"
class QAction;
class QActionGroup;

View file

@ -53,7 +53,10 @@ Menu::Menu() :
_viewFrustumOffset(DEFAULT_FRUSTUM_OFFSET),
_voxelModeActionsGroup(NULL),
_voxelStatsDialog(NULL),
_maxVoxels(DEFAULT_MAX_VOXELS_PER_SYSTEM)
_lodToolsDialog(NULL),
_maxVoxels(DEFAULT_MAX_VOXELS_PER_SYSTEM),
_voxelSizeScale(DEFAULT_VOXEL_SIZE_SCALE),
_boundaryLevelAdjust(0)
{
Application *appInstance = Application::getInstance();
@ -277,6 +280,7 @@ Menu::Menu() :
addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::VoxelTextures);
addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::AmbientOcclusion);
addActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::LodTools, Qt::SHIFT | Qt::Key_L, this, SLOT(lodTools()));
QMenu* cullingOptionsMenu = voxelOptionsMenu->addMenu("Culling Options");
addDisabledActionAndSeparator(cullingOptionsMenu, "Standard Settings");
@ -466,34 +470,10 @@ Menu::Menu() :
QMenu* voxelProtoOptionsMenu = developerMenu->addMenu("Voxel Server Protocol Options");
addCheckableActionToQMenuAndActionHash(voxelProtoOptionsMenu,
MenuOption::SendVoxelColors,
0,
true,
appInstance->getAvatar(),
SLOT(setWantColor(bool)));
addCheckableActionToQMenuAndActionHash(voxelProtoOptionsMenu,
MenuOption::LowRes,
0,
true,
appInstance->getAvatar(),
SLOT(setWantLowResMoving(bool)));
addCheckableActionToQMenuAndActionHash(voxelProtoOptionsMenu,
MenuOption::DeltaSending,
0,
true,
appInstance->getAvatar(),
SLOT(setWantDelta(bool)));
addCheckableActionToQMenuAndActionHash(voxelProtoOptionsMenu,
MenuOption::OcclusionCulling,
Qt::SHIFT | Qt::Key_C,
true,
appInstance->getAvatar(),
SLOT(setWantOcclusionCulling(bool)));
addCheckableActionToQMenuAndActionHash(voxelProtoOptionsMenu, MenuOption::SendVoxelColors);
addCheckableActionToQMenuAndActionHash(voxelProtoOptionsMenu, MenuOption::LowRes);
addCheckableActionToQMenuAndActionHash(voxelProtoOptionsMenu, MenuOption::DeltaSending);
addCheckableActionToQMenuAndActionHash(voxelProtoOptionsMenu, MenuOption::OcclusionCulling);
addCheckableActionToQMenuAndActionHash(voxelProtoOptionsMenu, MenuOption::DestructiveAddVoxel);
#ifndef Q_OS_MAC
@ -517,6 +497,8 @@ void Menu::loadSettings(QSettings* settings) {
_audioJitterBufferSamples = loadSetting(settings, "audioJitterBufferSamples", 0);
_fieldOfView = loadSetting(settings, "fieldOfView", DEFAULT_FIELD_OF_VIEW_DEGREES);
_maxVoxels = loadSetting(settings, "maxVoxels", DEFAULT_MAX_VOXELS_PER_SYSTEM);
_voxelSizeScale = loadSetting(settings, "voxelSizeScale", DEFAULT_VOXEL_SIZE_SCALE);
_boundaryLevelAdjust = loadSetting(settings, "boundaryLevelAdjust", 0);
settings->beginGroup("View Frustum Offset Camera");
// in case settings is corrupt or missing loadSetting() will check for NaN
@ -543,6 +525,8 @@ void Menu::saveSettings(QSettings* settings) {
settings->setValue("audioJitterBufferSamples", _audioJitterBufferSamples);
settings->setValue("fieldOfView", _fieldOfView);
settings->setValue("maxVoxels", _maxVoxels);
settings->setValue("voxelSizeScale", _voxelSizeScale);
settings->setValue("boundaryLevelAdjust", _boundaryLevelAdjust);
settings->beginGroup("View Frustum Offset Camera");
settings->setValue("viewFrustumOffsetYaw", _viewFrustumOffset.yaw);
settings->setValue("viewFrustumOffsetPitch", _viewFrustumOffset.pitch);
@ -1022,7 +1006,6 @@ void Menu::goToUser() {
}
void Menu::bandwidthDetails() {
if (! _bandwidthDialog) {
_bandwidthDialog = new BandwidthDialog(Application::getInstance()->getGLWidget(),
Application::getInstance()->getBandwidthMeter());
@ -1057,6 +1040,32 @@ void Menu::voxelStatsDetailsClosed() {
}
}
void Menu::setVoxelSizeScale(float sizeScale) {
_voxelSizeScale = sizeScale;
Application::getInstance()->getVoxels()->redrawInViewVoxels();
}
void Menu::setBoundaryLevelAdjust(int boundaryLevelAdjust) {
_boundaryLevelAdjust = boundaryLevelAdjust;
Application::getInstance()->getVoxels()->redrawInViewVoxels();
}
void Menu::lodTools() {
if (!_lodToolsDialog) {
_lodToolsDialog = new LodToolsDialog(Application::getInstance()->getGLWidget());
connect(_lodToolsDialog, SIGNAL(closed()), SLOT(lodToolsClosed()));
_lodToolsDialog->show();
}
_lodToolsDialog->raise();
}
void Menu::lodToolsClosed() {
if (_lodToolsDialog) {
delete _lodToolsDialog;
_lodToolsDialog = NULL;
}
}
void Menu::cycleFrustumRenderMode() {
_frustumDrawMode = (FrustumDrawMode)((_frustumDrawMode + 1) % FRUSTUM_DRAW_MODE_COUNT);
updateFrustumRenderModeAction();

View file

@ -35,6 +35,7 @@ class QSettings;
class BandwidthDialog;
class VoxelStatsDialog;
class LodToolsDialog;
class Menu : public QMenuBar {
Q_OBJECT
@ -53,15 +54,23 @@ public:
FrustumDrawMode getFrustumDrawMode() const { return _frustumDrawMode; }
ViewFrustumOffset getViewFrustumOffset() const { return _viewFrustumOffset; }
VoxelStatsDialog* getVoxelStatsDialog() const { return _voxelStatsDialog; }
LodToolsDialog* getLodToolsDialog() const { return _lodToolsDialog; }
int getMaxVoxels() const { return _maxVoxels; }
QAction* getUseVoxelShader() const { return _useVoxelShader; }
void handleViewFrustumOffsetKeyModifier(int key);
// User Tweakable LOD Items
void setVoxelSizeScale(float sizeScale);
float getVoxelSizeScale() const { return _voxelSizeScale; }
void setBoundaryLevelAdjust(int boundaryLevelAdjust);
int getBoundaryLevelAdjust() const { return _boundaryLevelAdjust; }
public slots:
void bandwidthDetails();
void voxelStatsDetails();
void lodTools();
void loadSettings(QSettings* settings = NULL);
void saveSettings(QSettings* settings = NULL);
void importSettings();
@ -76,6 +85,7 @@ private slots:
void goToLocation();
void bandwidthDetailsClosed();
void voxelStatsDetailsClosed();
void lodToolsClosed();
void cycleFrustumRenderMode();
void updateVoxelModeActions();
void chooseVoxelPaintColor();
@ -120,7 +130,10 @@ private:
ViewFrustumOffset _viewFrustumOffset;
QActionGroup* _voxelModeActionsGroup;
VoxelStatsDialog* _voxelStatsDialog;
LodToolsDialog* _lodToolsDialog;
int _maxVoxels;
float _voxelSizeScale;
int _boundaryLevelAdjust;
QAction* _useVoxelShader;
};
@ -178,6 +191,7 @@ namespace MenuOption {
const QString GoHome = "Go Home";
const QString Gravity = "Use Gravity";
const QString ParticleCloud = "Particle Cloud";
const QString LodTools = "LOD Tools";
const QString Log = "Log";
const QString Login = "Login";
const QString LookAtIndicator = "Look-at Indicator";

View file

@ -109,6 +109,7 @@ VoxelSystem::VoxelSystem(float treeScale, int maxVoxels)
_useFastVoxelPipeline = false;
_culledOnce = false;
_inhideOutOfView = false;
}
void VoxelSystem::voxelDeleted(VoxelNode* node) {
@ -139,7 +140,9 @@ void VoxelSystem::voxelUpdated(VoxelNode* node) {
if (node->getVoxelSystem() == this) {
bool shouldRender = false; // assume we don't need to render it
// if it's colored, we might need to render it!
shouldRender = node->calculateShouldRender(_viewFrustum);
float voxelSizeScale = Menu::getInstance()->getVoxelSizeScale();
int boundaryLevelAdjust = Menu::getInstance()->getBoundaryLevelAdjust();
shouldRender = node->calculateShouldRender(_viewFrustum, voxelSizeScale, boundaryLevelAdjust);
if (node->getShouldRender() != shouldRender) {
node->setShouldRender(shouldRender);
@ -155,7 +158,7 @@ void VoxelSystem::voxelUpdated(VoxelNode* node) {
VoxelNode* childNode = node->getChildAtIndex(i);
if (childNode) {
bool wasShouldRender = childNode->getShouldRender();
bool isShouldRender = childNode->calculateShouldRender(_viewFrustum);
bool isShouldRender = childNode->calculateShouldRender(_viewFrustum, voxelSizeScale, boundaryLevelAdjust);
if (wasShouldRender && !isShouldRender) {
childrenGotHiddenCount++;
}
@ -416,6 +419,12 @@ void VoxelSystem::initVoxelMemory() {
_memoryUsageRAM = 0;
_memoryUsageVBO = 0; // our VBO allocations as we know them
// if _voxelsAsPoints then we must have _useVoxelShader
if (_voxelsAsPoints && !_useVoxelShader) {
_useVoxelShader = true;
}
if (_useVoxelShader) {
GLuint* indicesArray = new GLuint[_maxVoxels];
@ -923,7 +932,9 @@ int VoxelSystem::newTreeToArrays(VoxelNode* node) {
int voxelsUpdated = 0;
bool shouldRender = false; // assume we don't need to render it
// if it's colored, we might need to render it!
shouldRender = node->calculateShouldRender(_viewFrustum);
float voxelSizeScale = Menu::getInstance()->getVoxelSizeScale();;
int boundaryLevelAdjust = Menu::getInstance()->getBoundaryLevelAdjust();
shouldRender = node->calculateShouldRender(_viewFrustum, voxelSizeScale, boundaryLevelAdjust);
node->setShouldRender(shouldRender);
// let children figure out their renderness
@ -985,7 +996,7 @@ int VoxelSystem::forceRemoveNodeFromArrays(VoxelNode* node) {
int VoxelSystem::updateNodeInArrays(VoxelNode* node, bool reuseIndex, bool forceDraw) {
// If we've run out of room, then just bail...
if (_voxelsInWriteArrays >= _maxVoxels) {
if (_voxelsInWriteArrays >= _maxVoxels && (_freeIndexes.size() == 0)) {
// We need to think about what else we can do in this case. This basically means that all of our available
// VBO slots are used up, but we're trying to render more voxels. At this point, if this happens we'll just
// not render these Voxels. We need to think about ways to keep the entire scene intact but maybe lower quality
@ -1384,6 +1395,10 @@ void VoxelSystem::killLocalVoxels() {
setupNewVoxelsForDrawing();
}
void VoxelSystem::redrawInViewVoxels() {
hideOutOfView(true);
}
bool VoxelSystem::clearAllNodesBufferIndexOperation(VoxelNode* node, void* extraData) {
_nodeCount++;
@ -1771,7 +1786,9 @@ bool VoxelSystem::showAllLocalVoxelsOperation(VoxelNode* node, void* extraData)
args->nodesScanned++;
bool shouldRender = true; // node->calculateShouldRender(&args->thisViewFrustum);
float voxelSizeScale = Menu::getInstance()->getVoxelSizeScale();;
int boundaryLevelAdjust = Menu::getInstance()->getBoundaryLevelAdjust();
bool shouldRender = node->calculateShouldRender(&args->thisViewFrustum, voxelSizeScale, boundaryLevelAdjust);
node->setShouldRender(shouldRender);
if (shouldRender) {
@ -1838,6 +1855,14 @@ public:
};
void VoxelSystem::hideOutOfView(bool forceFullFrustum) {
// don't re-enter...
if (_inhideOutOfView) {
return;
}
_inhideOutOfView = true;
bool showDebugDetails = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
PerformanceWarning warn(showDebugDetails, "hideOutOfView()", showDebugDetails);
bool widenFrustum = true;
@ -1869,10 +1894,13 @@ void VoxelSystem::hideOutOfView(bool forceFullFrustum) {
if (!forceFullFrustum && _culledOnce && args.lastViewFrustum.isVerySimilar(args.thisViewFrustum)) {
//printf("view frustum hasn't changed BAIL!!!\n");
_inhideOutOfView = false;
return;
}
pthread_mutex_lock(&_treeLock);
_tree->recurseTreeWithOperation(hideOutOfViewOperation,(void*)&args);
pthread_mutex_unlock(&_treeLock);
_lastCulledViewFrustum = args.thisViewFrustum; // save last stable
_culledOnce = true;
@ -1890,6 +1918,7 @@ void VoxelSystem::hideOutOfView(bool forceFullFrustum) {
args.nodesInsideInside, args.nodesIntersectInside, args.nodesOutsideOutside
);
}
_inhideOutOfView = false;
}
bool VoxelSystem::hideAllSubTreeOperation(VoxelNode* node, void* extraData) {
@ -1947,7 +1976,9 @@ bool VoxelSystem::showAllSubTreeOperation(VoxelNode* node, void* extraData) {
args->nodesInside++;
bool shouldRender = node->calculateShouldRender(&args->thisViewFrustum);
float voxelSizeScale = Menu::getInstance()->getVoxelSizeScale();
int boundaryLevelAdjust = Menu::getInstance()->getBoundaryLevelAdjust();
bool shouldRender = node->calculateShouldRender(&args->thisViewFrustum, voxelSizeScale, boundaryLevelAdjust);
node->setShouldRender(shouldRender);
if (shouldRender && !node->isKnownBufferIndex()) {

View file

@ -60,6 +60,7 @@ public:
unsigned long getVoxelsUpdated() const { return _voxelsUpdated; }
unsigned long getVoxelsRendered() const { return _voxelsInReadArrays; }
unsigned long getVoxelsWritten() const { return _voxelsInWriteArrays; }
unsigned long getAbandonedVoxels() const { return _freeIndexes.size(); }
ViewFrustum* getLastCulledViewFrustum() { return &_lastCulledViewFrustum; }
@ -83,6 +84,7 @@ public:
float getVoxelsBytesReadPerSecondAverage();
void killLocalVoxels();
void redrawInViewVoxels();
virtual void removeOutOfView();
virtual void hideOutOfView(bool forceFullFrustum = false);
@ -298,6 +300,8 @@ private:
bool _inSetupNewVoxelsForDrawing;
bool _useFastVoxelPipeline;
bool _inhideOutOfView;
};
#endif

View file

@ -35,22 +35,12 @@ bool SkeletonModel::render(float alpha) {
return false;
}
const FBXGeometry& geometry = _geometry->getFBXGeometry();
glm::vec3 skinColor, darkSkinColor;
_owningAvatar->getSkinColors(skinColor, darkSkinColor);
for (int i = 0; i < _jointStates.size(); i++) {
glPushMatrix();
// only render the balls and sticks if the skeleton has no meshes
if (_meshStates.isEmpty()) {
const FBXGeometry& geometry = _geometry->getFBXGeometry();
glm::vec3 position;
getJointPosition(i, position);
glTranslatef(position.x, position.y, position.z);
glm::quat rotation;
getJointRotation(i, rotation);
glm::vec3 axis = glm::axis(rotation);
glRotatef(glm::angle(rotation), axis.x, axis.y, axis.z);
glm::vec3 skinColor, darkSkinColor;
_owningAvatar->getSkinColors(skinColor, darkSkinColor);
glColor4f(skinColor.r, skinColor.g, skinColor.b, alpha);
const float BALL_RADIUS = 0.005f;

View file

@ -107,6 +107,16 @@ protected:
QVector<JointState> _jointStates;
class MeshState {
public:
QVector<glm::mat4> clusterMatrices;
QVector<glm::vec3> worldSpaceVertices;
QVector<glm::vec3> vertexVelocities;
QVector<glm::vec3> worldSpaceNormals;
};
QVector<MeshState> _meshStates;
/// Updates the state of the joint at the specified index.
virtual void updateJointState(int index);
@ -129,15 +139,6 @@ private:
QUrl _url;
class MeshState {
public:
QVector<glm::mat4> clusterMatrices;
QVector<glm::vec3> worldSpaceVertices;
QVector<glm::vec3> vertexVelocities;
QVector<glm::vec3> worldSpaceNormals;
};
QVector<MeshState> _meshStates;
QVector<GLuint> _blendedVertexBufferIDs;
QVector<QVector<QSharedPointer<Texture> > > _dilatedTextures;
bool _resetStates;

View file

@ -15,26 +15,51 @@ const float Generator::STAR_COLORIZATION = 0.1;
void Generator::computeStarPositions(InputVertices& destination, unsigned limit, unsigned seed) {
InputVertices* vertices = & destination;
//_limit = limit;
timeval startTime;
gettimeofday(&startTime, NULL);
srand(seed);
vertices->clear();
vertices->reserve(limit);
const unsigned MILKY_WAY_WIDTH = 16.0; // width in degrees of one half of the Milky Way
const float MILKY_WAY_INCLINATION = 30.0f; // angle of Milky Way from horizontal in degrees
const float MILKY_WAY_RATIO = 0.6;
const unsigned NUM_DEGREES = 360;
for(int star = 0; star < limit; ++star) {
for(int star = 0; star < floor(limit * (1 - MILKY_WAY_RATIO)); ++star) {
float azimuth, altitude;
azimuth = ((float)rand() / (float) RAND_MAX) * NUM_DEGREES;
altitude = (((float)rand() / (float) RAND_MAX) * NUM_DEGREES / 2) - NUM_DEGREES / 4;
azimuth = (((float)rand() / (float) RAND_MAX) * NUM_DEGREES) - (NUM_DEGREES / 2);
altitude = (acos((2.0f * ((float)rand() / (float)RAND_MAX)) - 1.0f) / PI_OVER_180) + 90;
vertices->push_back(InputVertex(azimuth, altitude, computeStarColor(STAR_COLORIZATION)));
}
for(int star = 0; star < ceil(limit * MILKY_WAY_RATIO); ++star) {
float azimuth = ((float)rand() / (float) RAND_MAX) * NUM_DEGREES;
float altitude = asin((float)rand() / (float) RAND_MAX * 2 - 1) * MILKY_WAY_WIDTH;
// we need to rotate the Milky Way band to the correct orientation in the sky
// convert from spherical coordinates to cartesian, rotate the point and then convert back.
// An improvement would be to convert all stars to cartesian at this point and not have to convert back.
float tempX = sin(azimuth * PI_OVER_180) * cos(altitude * PI_OVER_180);
float tempY = sin(altitude * PI_OVER_180);
float tempZ = -cos(azimuth * PI_OVER_180) * cos(altitude * PI_OVER_180);
float xangle = MILKY_WAY_INCLINATION * PI_OVER_180;
float newX = (tempX * cos(xangle)) - (tempY * sin(xangle));
float newY = (tempX * sin(xangle)) + (tempY * cos(xangle));
float newZ = tempZ;
azimuth = (atan2(newX,-newZ) + Radians::pi()) / PI_OVER_180;
altitude = atan2(-newY, hypotf(newX, newZ)) / PI_OVER_180;
vertices->push_back(InputVertex(azimuth, altitude, computeStarColor(STAR_COLORIZATION)));
}
qDebug("Took %llu msec to generate stars.\n", (usecTimestampNow() - usecTimestamp(&startTime)) / 1000);
}

View file

@ -7,7 +7,6 @@
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
#include "starfield/data/GpuVertex.h"
#include "starfield/data/InputVertex.h"
using namespace starfield;

View file

@ -0,0 +1,153 @@
//
// LodToolsDialog.cpp
// interface
//
// Created by Brad Hefta-Gaub on 7/19/13.
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
#include <QFormLayout>
#include <QDialogButtonBox>
#include <QPalette>
#include <QColor>
#include <QSlider>
#include <QPushButton>
#include <QString>
#include <VoxelConstants.h>
#include "Menu.h"
#include "ui/LodToolsDialog.h"
LodToolsDialog::LodToolsDialog(QWidget* parent) :
QDialog(parent, Qt::Window | Qt::WindowCloseButtonHint | Qt::WindowStaysOnTopHint)
{
this->setWindowTitle("LOD Tools");
// Create layouter
QFormLayout* form = new QFormLayout();
_lodSize = new QSlider(Qt::Horizontal);
const int MAX_LOD_SIZE = MAX_LOD_SIZE_MULTIPLIER;
const int MIN_LOD_SIZE = 0;
const int STEP_LOD_SIZE = 1;
const int PAGE_STEP_LOD_SIZE = 100;
const int SLIDER_WIDTH = 300;
_lodSize->setMaximum(MAX_LOD_SIZE);
_lodSize->setMinimum(MIN_LOD_SIZE);
_lodSize->setSingleStep(STEP_LOD_SIZE);
_lodSize->setTickInterval(PAGE_STEP_LOD_SIZE);
_lodSize->setTickPosition(QSlider::TicksBelow);
_lodSize->setFixedWidth(SLIDER_WIDTH);
_lodSize->setPageStep(PAGE_STEP_LOD_SIZE);
int sliderValue = Menu::getInstance()->getVoxelSizeScale() / TREE_SCALE;
_lodSize->setValue(sliderValue);
form->addRow("LOD Size Scale:", _lodSize);
connect(_lodSize,SIGNAL(valueChanged(int)),this,SLOT(sizeScaleValueChanged(int)));
_boundaryLevelAdjust = new QSlider(Qt::Horizontal);
const int MAX_ADJUST = 10;
const int MIN_ADJUST = 0;
const int STEP_ADJUST = 1;
_boundaryLevelAdjust->setMaximum(MAX_ADJUST);
_boundaryLevelAdjust->setMinimum(MIN_ADJUST);
_boundaryLevelAdjust->setSingleStep(STEP_ADJUST);
_boundaryLevelAdjust->setTickInterval(STEP_ADJUST);
_boundaryLevelAdjust->setTickPosition(QSlider::TicksBelow);
_boundaryLevelAdjust->setFixedWidth(SLIDER_WIDTH);
sliderValue = Menu::getInstance()->getBoundaryLevelAdjust();
_boundaryLevelAdjust->setValue(sliderValue);
form->addRow("Boundary Level Adjust:", _boundaryLevelAdjust);
connect(_boundaryLevelAdjust,SIGNAL(valueChanged(int)),this,SLOT(boundaryLevelValueChanged(int)));
// Create a label with feedback...
_feedback = new QLabel();
QPalette palette = _feedback->palette();
const unsigned redish = 0xfff00000;
palette.setColor(QPalette::WindowText, QColor::fromRgb(redish));
_feedback->setPalette(palette);
_feedback->setText(getFeedbackText());
const int FEEDBACK_WIDTH = 350;
_feedback->setFixedWidth(FEEDBACK_WIDTH);
form->addRow("You can see... ", _feedback);
// Add a button to reset
QPushButton* resetButton = new QPushButton("Reset");
form->addRow("", resetButton);
connect(resetButton,SIGNAL(clicked(bool)),this,SLOT(resetClicked(bool)));
this->QDialog::setLayout(form);
}
QString LodToolsDialog::getFeedbackText() {
// determine granularity feedback
int boundaryLevelAdjust = Menu::getInstance()->getBoundaryLevelAdjust();
QString granularityFeedback;
switch (boundaryLevelAdjust) {
case 0: {
granularityFeedback = QString("at standard granularity.");
} break;
case 1: {
granularityFeedback = QString("at half of standard granularity.");
} break;
case 2: {
granularityFeedback = QString("at a third of standard granularity.");
} break;
default: {
granularityFeedback = QString("at 1/%1th of standard granularity.").arg(boundaryLevelAdjust + 1);
} break;
}
// distance feedback
float voxelSizeScale = Menu::getInstance()->getVoxelSizeScale();
float relativeToDefault = voxelSizeScale / DEFAULT_VOXEL_SIZE_SCALE;
QString result;
if (relativeToDefault > 1.01) {
result = QString("%1 further %2").arg(relativeToDefault,8,'f',2).arg(granularityFeedback);
} else if (relativeToDefault > 0.99) {
result = QString("the default distance %1").arg(granularityFeedback);
} else {
result = QString("%1 of default %2").arg(relativeToDefault,8,'f',3).arg(granularityFeedback);
}
return result;
}
LodToolsDialog::~LodToolsDialog() {
delete _feedback;
delete _lodSize;
delete _boundaryLevelAdjust;
}
void LodToolsDialog::sizeScaleValueChanged(int value) {
float realValue = value * TREE_SCALE;
Menu::getInstance()->setVoxelSizeScale(realValue);
_feedback->setText(getFeedbackText());
}
void LodToolsDialog::boundaryLevelValueChanged(int value) {
Menu::getInstance()->setBoundaryLevelAdjust(value);
_feedback->setText(getFeedbackText());
}
void LodToolsDialog::resetClicked(bool checked) {
int sliderValue = DEFAULT_VOXEL_SIZE_SCALE / TREE_SCALE;
//sizeScaleValueChanged(sliderValue);
_lodSize->setValue(sliderValue);
_boundaryLevelAdjust->setValue(0);
}
void LodToolsDialog::reject() {
// Just regularly close upon ESC
this->QDialog::close();
}
void LodToolsDialog::closeEvent(QCloseEvent* event) {
this->QDialog::closeEvent(event);
emit closed();
}

View file

@ -0,0 +1,48 @@
//
// LodToolsDialog.h
// interface
//
// Created by Brad Hefta-Gaub on 7/19/13.
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
#ifndef __hifi__LodToolsDialog__
#define __hifi__LodToolsDialog__
#include <QDialog>
#include <QLabel>
#include <QSlider>
#include <VoxelSceneStats.h>
class LodToolsDialog : public QDialog {
Q_OBJECT
public:
// Sets up the UI
LodToolsDialog(QWidget* parent);
~LodToolsDialog();
signals:
void closed();
public slots:
void reject();
void sizeScaleValueChanged(int value);
void boundaryLevelValueChanged(int value);
void resetClicked(bool checked);
protected:
// Emits a 'closed' signal when this dialog is closed.
void closeEvent(QCloseEvent*);
private:
QString getFeedbackText();
QSlider* _lodSize;
QSlider* _boundaryLevelAdjust;
QLabel* _feedback;
};
#endif /* defined(__interface__LodToolsDialog__) */

View file

@ -34,7 +34,6 @@ VoxelStatsDialog::VoxelStatsDialog(QWidget* parent, VoxelSceneStats* model) :
VoxelSceneStats::Item item = (VoxelSceneStats::Item)(i);
VoxelSceneStats::ItemInfo& itemInfo = _model->getItemInfo(item);
QLabel* label = _labels[item] = new QLabel();
label->setAlignment(Qt::AlignRight);
// Set foreground color to 62.5% brightness of the meter (otherwise will be hard to read on the bright background)
QPalette palette = label->palette();
@ -45,8 +44,8 @@ VoxelStatsDialog::VoxelStatsDialog(QWidget* parent, VoxelSceneStats* model) :
palette.setColor(QPalette::WindowText, QColor::fromRgb(rgb));
label->setPalette(palette);
// This is my hackery attempt at making QDialog auto-size to a width that will hold our info. It kinda works.
label->setText("123456789012345678901234567890123456789012345678901234567890");
const int STATS_LABEL_WIDTH = 550;
label->setFixedWidth(STATS_LABEL_WIDTH);
snprintf(strBuf, sizeof(strBuf), " %s:", itemInfo.caption);
form->addRow(strBuf, label);

View file

@ -35,7 +35,10 @@ PACKET_VERSION versionForPacketType(PACKET_TYPE type) {
case PACKET_TYPE_DOMAIN_LIST_REQUEST:
case PACKET_TYPE_DOMAIN_REPORT_FOR_DUTY:
return 1;
case PACKET_TYPE_VOXEL_QUERY:
return 1;
default:
return 0;
}

View file

@ -23,7 +23,11 @@ VoxelNodeData::VoxelNodeData(Node* owningNode) :
_viewFrustumChanging(false),
_viewFrustumJustStoppedChanging(true),
_currentPacketIsColor(true),
_voxelSendThread(NULL)
_voxelSendThread(NULL),
_lastClientBoundaryLevelAdjust(0),
_lastClientVoxelSizeScale(DEFAULT_VOXEL_SIZE_SCALE),
_lodChanged(false),
_lodInitialized(false)
{
_voxelPacket = new unsigned char[MAX_VOXEL_PACKET_SIZE];
_voxelPacketAt = _voxelPacket;
@ -140,6 +144,23 @@ bool VoxelNodeData::updateCurrentViewFrustum() {
currentViewFrustumChanged = true;
}
// Also check for LOD changes from the client
if (_lodInitialized) {
if (_lastClientBoundaryLevelAdjust != getBoundaryLevelAdjust()) {
_lastClientBoundaryLevelAdjust = getBoundaryLevelAdjust();
_lodChanged = true;
}
if (_lastClientVoxelSizeScale != getVoxelSizeScale()) {
_lastClientVoxelSizeScale = getVoxelSizeScale();
_lodChanged = true;
}
} else {
_lodInitialized = true;
_lastClientVoxelSizeScale = getVoxelSizeScale();
_lastClientBoundaryLevelAdjust = getBoundaryLevelAdjust();
_lodChanged = false;
}
// When we first detect that the view stopped changing, we record this.
// but we don't change it back to false until we've completely sent this
// scene.
@ -154,6 +175,7 @@ void VoxelNodeData::setViewSent(bool viewSent) {
_viewSent = viewSent;
if (viewSent) {
_viewFrustumJustStoppedChanging = false;
_lodChanged = false;
}
}
@ -171,3 +193,39 @@ void VoxelNodeData::updateLastKnownViewFrustum() {
setLastTimeBagEmpty(now); // is this what we want? poor names
}
bool VoxelNodeData::moveShouldDump() const {
glm::vec3 oldPosition = _lastKnownViewFrustum.getPosition();
glm::vec3 newPosition = _currentViewFrustum.getPosition();
// theoretically we could make this slightly larger but relative to avatar scale.
const float MAXIMUM_MOVE_WITHOUT_DUMP = 0.0f;
if (glm::distance(newPosition, oldPosition) > MAXIMUM_MOVE_WITHOUT_DUMP) {
return true;
}
return false;
}
void VoxelNodeData::dumpOutOfView() {
int stillInView = 0;
int outOfView = 0;
VoxelNodeBag tempBag;
while (!nodeBag.isEmpty()) {
VoxelNode* node = nodeBag.extract();
if (node->isInView(_currentViewFrustum)) {
tempBag.insert(node);
stillInView++;
} else {
outOfView++;
}
}
if (stillInView > 0) {
while (!tempBag.isEmpty()) {
VoxelNode* node = tempBag.extract();
if (node->isInView(_currentViewFrustum)) {
nodeBag.insert(node);
}
}
}
}

View file

@ -48,31 +48,36 @@ public:
VoxelNodeBag nodeBag;
CoverageMap map;
ViewFrustum& getCurrentViewFrustum() { return _currentViewFrustum; };
ViewFrustum& getLastKnownViewFrustum() { return _lastKnownViewFrustum; };
ViewFrustum& getCurrentViewFrustum() { return _currentViewFrustum; };
ViewFrustum& getLastKnownViewFrustum() { return _lastKnownViewFrustum; };
// These are not classic setters because they are calculating and maintaining state
// which is set asynchronously through the network receive
bool updateCurrentViewFrustum();
void updateLastKnownViewFrustum();
bool getViewSent() const { return _viewSent; };
bool getViewSent() const { return _viewSent; };
void setViewSent(bool viewSent);
bool getViewFrustumChanging() const { return _viewFrustumChanging; };
bool getViewFrustumChanging() const { return _viewFrustumChanging; };
bool getViewFrustumJustStoppedChanging() const { return _viewFrustumJustStoppedChanging; };
uint64_t getLastTimeBagEmpty() const { return _lastTimeBagEmpty; };
void setLastTimeBagEmpty(uint64_t lastTimeBagEmpty) { _lastTimeBagEmpty = lastTimeBagEmpty; };
bool moveShouldDump() const;
uint64_t getLastTimeBagEmpty() const { return _lastTimeBagEmpty; };
void setLastTimeBagEmpty(uint64_t lastTimeBagEmpty) { _lastTimeBagEmpty = lastTimeBagEmpty; };
bool getCurrentPacketIsColor() const { return _currentPacketIsColor; };
bool hasLodChanged() const { return _lodChanged; };
VoxelSceneStats stats;
void initializeVoxelSendThread(VoxelServer* voxelServer);
bool isVoxelSendThreadInitalized() { return _voxelSendThread; }
void dumpOutOfView();
private:
VoxelNodeData(const VoxelNodeData &);
VoxelNodeData& operator= (const VoxelNodeData&);
@ -98,6 +103,12 @@ private:
bool _currentPacketIsColor;
VoxelSendThread* _voxelSendThread;
// watch for LOD changes
int _lastClientBoundaryLevelAdjust;
float _lastClientVoxelSizeScale;
bool _lodChanged;
bool _lodInitialized;
};
#endif /* defined(__hifi__VoxelNodeData__) */

View file

@ -175,8 +175,8 @@ void VoxelSendThread::deepestLevelVoxelDistributor(Node* node, VoxelNodeData* no
// if our view has changed, we need to reset these things...
if (viewFrustumChanged) {
if (_myServer->wantDumpVoxelsOnMove()) {
nodeData->nodeBag.deleteAll();
if (_myServer->wantDumpVoxelsOnMove() || nodeData->moveShouldDump() || nodeData->hasLodChanged()) {
nodeData->dumpOutOfView();
}
nodeData->map.erase();
}
@ -194,7 +194,8 @@ void VoxelSendThread::deepestLevelVoxelDistributor(Node* node, VoxelNodeData* no
}
// start tracking our stats
bool isFullScene = (!viewFrustumChanged || !nodeData->getWantDelta()) && nodeData->getViewFrustumJustStoppedChanging();
bool isFullScene = ((!viewFrustumChanged || !nodeData->getWantDelta())
&& nodeData->getViewFrustumJustStoppedChanging()) || nodeData->hasLodChanged();
// If we're starting a full scene, then definitely we want to empty the nodeBag
if (isFullScene) {
@ -250,15 +251,20 @@ void VoxelSendThread::deepestLevelVoxelDistributor(Node* node, VoxelNodeData* no
VoxelNode* subTree = nodeData->nodeBag.extract();
bool wantOcclusionCulling = nodeData->getWantOcclusionCulling();
CoverageMap* coverageMap = wantOcclusionCulling ? &nodeData->map : IGNORE_COVERAGE_MAP;
int boundaryLevelAdjust = viewFrustumChanged && nodeData->getWantLowResMoving()
? LOW_RES_MOVING_ADJUST : NO_BOUNDARY_ADJUST;
bool isFullScene = (!viewFrustumChanged || !nodeData->getWantDelta()) &&
nodeData->getViewFrustumJustStoppedChanging();
float voxelSizeScale = nodeData->getVoxelSizeScale();
int boundaryLevelAdjustClient = nodeData->getBoundaryLevelAdjust();
int boundaryLevelAdjust = boundaryLevelAdjustClient + (viewFrustumChanged && nodeData->getWantLowResMoving()
? LOW_RES_MOVING_ADJUST : NO_BOUNDARY_ADJUST);
bool isFullScene = ((!viewFrustumChanged || !nodeData->getWantDelta()) &&
nodeData->getViewFrustumJustStoppedChanging()) || nodeData->hasLodChanged();
EncodeBitstreamParams params(INT_MAX, &nodeData->getCurrentViewFrustum(), wantColor,
WANT_EXISTS_BITS, DONT_CHOP, wantDelta, lastViewFrustum,
wantOcclusionCulling, coverageMap, boundaryLevelAdjust,
wantOcclusionCulling, coverageMap, boundaryLevelAdjust, voxelSizeScale,
nodeData->getLastTimeBagEmpty(),
isFullScene, &nodeData->stats, _myServer->getJurisdiction());

View file

@ -13,6 +13,7 @@
#define __hifi_VoxelConstants_h__
#include <limits.h>
#include <stdint.h>
#include <OctalCode.h>
#include <glm/glm.hpp>
@ -27,7 +28,8 @@ const uint64_t CHANGE_FUDGE = 1000 * 200; // useconds of fudge in determining if
const int TREE_SCALE = 16384; // ~10 miles.. This is the number of meters of the 0.0 to 1.0 voxel universe
// This controls the LOD. Larger number will make smaller voxels visible at greater distance.
const float VOXEL_SIZE_SCALE = TREE_SCALE * 400.0f;
const float DEFAULT_VOXEL_SIZE_SCALE = TREE_SCALE * 400.0f;
const float MAX_LOD_SIZE_MULTIPLIER = 2000.0f;
const int NUMBER_OF_CHILDREN = 8;
const int MAX_VOXEL_PACKET_SIZE = 1492;

View file

@ -1371,12 +1371,12 @@ ViewFrustum::location VoxelNode::inFrustum(const ViewFrustum& viewFrustum) const
// Since, if we know the camera position and orientation, we can know which of the corners is the "furthest"
// corner. We can use we can use this corner as our "voxel position" to do our distance calculations off of.
// By doing this, we don't need to test each child voxel's position vs the LOD boundary
bool VoxelNode::calculateShouldRender(const ViewFrustum* viewFrustum, int boundaryLevelAdjust) const {
bool VoxelNode::calculateShouldRender(const ViewFrustum* viewFrustum, float voxelScaleSize, int boundaryLevelAdjust) const {
bool shouldRender = false;
if (isColored()) {
float furthestDistance = furthestDistanceToCamera(*viewFrustum);
float boundary = boundaryDistanceForRenderLevel(getLevel() + boundaryLevelAdjust);
float childBoundary = boundaryDistanceForRenderLevel(getLevel() + 1 + boundaryLevelAdjust);
float boundary = boundaryDistanceForRenderLevel(getLevel() + boundaryLevelAdjust, voxelScaleSize);
float childBoundary = boundaryDistanceForRenderLevel(getLevel() + 1 + boundaryLevelAdjust, voxelScaleSize);
bool inBoundary = (furthestDistance <= boundary);
bool inChildBoundary = (furthestDistance <= childBoundary);
shouldRender = (isLeaf() && inChildBoundary) || (inBoundary && !inChildBoundary);

View file

@ -69,7 +69,8 @@ public:
float distanceToCamera(const ViewFrustum& viewFrustum) const;
float furthestDistanceToCamera(const ViewFrustum& viewFrustum) const;
bool calculateShouldRender(const ViewFrustum* viewFrustum, int boundaryLevelAdjust = 0) const;
bool calculateShouldRender(const ViewFrustum* viewFrustum,
float voxelSizeScale = DEFAULT_VOXEL_SIZE_SCALE, int boundaryLevelAdjust = 0) const;
// points are assumed to be in Voxel Coordinates (not TREE_SCALE'd)
float distanceSquareToPoint(const glm::vec3& point) const; // when you don't need the actual distance, use this.

View file

@ -35,7 +35,8 @@ VoxelQuery::VoxelQuery(Node* owningNode) :
_wantDelta(true),
_wantLowResMoving(true),
_wantOcclusionCulling(true),
_maxVoxelPPS(DEFAULT_MAX_VOXEL_PPS)
_maxVoxelPPS(DEFAULT_MAX_VOXEL_PPS),
_voxelSizeScale(DEFAULT_VOXEL_SIZE_SCALE)
{
}
@ -78,6 +79,14 @@ int VoxelQuery::getBroadcastData(unsigned char* destinationBuffer) {
// desired Max Voxel PPS
memcpy(destinationBuffer, &_maxVoxelPPS, sizeof(_maxVoxelPPS));
destinationBuffer += sizeof(_maxVoxelPPS);
// desired voxelSizeScale
memcpy(destinationBuffer, &_voxelSizeScale, sizeof(_voxelSizeScale));
destinationBuffer += sizeof(_voxelSizeScale);
// desired boundaryLevelAdjust
memcpy(destinationBuffer, &_boundaryLevelAdjust, sizeof(_boundaryLevelAdjust));
destinationBuffer += sizeof(_boundaryLevelAdjust);
return destinationBuffer - bufferStart;
}
@ -120,7 +129,15 @@ int VoxelQuery::parseData(unsigned char* sourceBuffer, int numBytes) {
// desired Max Voxel PPS
memcpy(&_maxVoxelPPS, sourceBuffer, sizeof(_maxVoxelPPS));
sourceBuffer += sizeof(_maxVoxelPPS);
// desired voxelSizeScale
memcpy(&_voxelSizeScale, sourceBuffer, sizeof(_voxelSizeScale));
sourceBuffer += sizeof(_voxelSizeScale);
// desired boundaryLevelAdjust
memcpy(&_boundaryLevelAdjust, sourceBuffer, sizeof(_boundaryLevelAdjust));
sourceBuffer += sizeof(_boundaryLevelAdjust);
return sourceBuffer - startPosition;
}

View file

@ -69,6 +69,8 @@ public:
bool getWantLowResMoving() const { return _wantLowResMoving; }
bool getWantOcclusionCulling() const { return _wantOcclusionCulling; }
int getMaxVoxelPacketsPerSecond() const { return _maxVoxelPPS; }
float getVoxelSizeScale() const { return _voxelSizeScale; }
int getBoundaryLevelAdjust() const { return _boundaryLevelAdjust; }
public slots:
void setWantLowResMoving(bool wantLowResMoving) { _wantLowResMoving = wantLowResMoving; }
@ -76,6 +78,8 @@ public slots:
void setWantDelta(bool wantDelta) { _wantDelta = wantDelta; }
void setWantOcclusionCulling(bool wantOcclusionCulling) { _wantOcclusionCulling = wantOcclusionCulling; }
void setMaxVoxelPacketsPerSecond(int maxVoxelPPS) { _maxVoxelPPS = maxVoxelPPS; }
void setVoxelSizeScale(float voxelSizeScale) { _voxelSizeScale = voxelSizeScale; }
void setBoundaryLevelAdjust(int boundaryLevelAdjust) { _boundaryLevelAdjust = boundaryLevelAdjust; }
protected:
QUuid _uuid;
@ -95,6 +99,8 @@ protected:
bool _wantLowResMoving;
bool _wantOcclusionCulling;
int _maxVoxelPPS;
float _voxelSizeScale; /// used for LOD calculations
int _boundaryLevelAdjust; /// used for LOD calculations
private:
// privatize the copy constructor and assignment operator so they cannot be called

View file

@ -33,13 +33,8 @@
#include "VoxelTree.h"
#include <PacketHeaders.h>
float boundaryDistanceForRenderLevel(unsigned int renderLevel) {
return ::VOXEL_SIZE_SCALE / powf(2, renderLevel);
}
float boundaryDistanceSquaredForRenderLevel(unsigned int renderLevel) {
const float voxelSizeScale = (::VOXEL_SIZE_SCALE/TREE_SCALE) * (::VOXEL_SIZE_SCALE/TREE_SCALE);
return voxelSizeScale / powf(2, (2 * renderLevel));
float boundaryDistanceForRenderLevel(unsigned int renderLevel, float voxelSizeScale) {
return voxelSizeScale / powf(2, renderLevel);
}
VoxelTree::VoxelTree(bool shouldReaverage) :
@ -1114,7 +1109,8 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp
// caller can pass NULL as viewFrustum if they want everything
if (params.viewFrustum) {
float distance = node->distanceToCamera(*params.viewFrustum);
float boundaryDistance = boundaryDistanceForRenderLevel(node->getLevel() + params.boundaryLevelAdjust);
float boundaryDistance = boundaryDistanceForRenderLevel(node->getLevel() + params.boundaryLevelAdjust,
params.voxelSizeScale);
// If we're too far away for our render level, then just return
if (distance >= boundaryDistance) {
@ -1147,6 +1143,20 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp
} else {
wasInView = location == ViewFrustum::INSIDE;
}
// If we were in view, double check that we didn't switch LOD visibility... namely, the was in view doesn't
// tell us if it was so small we wouldn't have rendered it. Which may be the case. And we may have moved closer
// to it, and so therefore it may now be visible from an LOD perspective, in which case we don't consider it
// as "was in view"...
if (wasInView) {
float distance = node->distanceToCamera(*params.lastViewFrustum);
float boundaryDistance = boundaryDistanceForRenderLevel(node->getLevel() + params.boundaryLevelAdjust,
params.voxelSizeScale);
if (distance >= boundaryDistance) {
// This would have been invisible... but now should be visible (we wouldn't be here otherwise)...
wasInView = false;
}
}
}
// If we were previously in the view, then we normally will return out of here and stop recursing. But
@ -1288,7 +1298,8 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp
// Before we determine consider this further, let's see if it's in our LOD scope...
float distance = distancesToChildren[i]; // params.viewFrustum ? childNode->distanceToCamera(*params.viewFrustum) : 0;
float boundaryDistance = !params.viewFrustum ? 1 :
boundaryDistanceForRenderLevel(childNode->getLevel() + params.boundaryLevelAdjust);
boundaryDistanceForRenderLevel(childNode->getLevel() + params.boundaryLevelAdjust,
params.voxelSizeScale);
if (!(distance < boundaryDistance)) {
// don't need to check childNode here, because we can't get here with no childNode
@ -1341,7 +1352,8 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp
bool shouldRender = !params.viewFrustum
? true
: childNode->calculateShouldRender(params.viewFrustum, params.boundaryLevelAdjust);
: childNode->calculateShouldRender(params.viewFrustum,
params.voxelSizeScale, params.boundaryLevelAdjust);
// track some stats
if (params.stats) {

View file

@ -47,52 +47,55 @@ const uint64_t IGNORE_LAST_SENT = 0;
class EncodeBitstreamParams {
public:
int maxEncodeLevel;
int maxLevelReached;
const ViewFrustum* viewFrustum;
bool includeColor;
bool includeExistsBits;
int chopLevels;
bool deltaViewFrustum;
const ViewFrustum* lastViewFrustum;
bool wantOcclusionCulling;
int boundaryLevelAdjust;
uint64_t lastViewFrustumSent;
bool forceSendScene;
VoxelSceneStats* stats;
CoverageMap* map;
JurisdictionMap* jurisdictionMap;
int maxEncodeLevel;
int maxLevelReached;
const ViewFrustum* viewFrustum;
bool includeColor;
bool includeExistsBits;
int chopLevels;
bool deltaViewFrustum;
const ViewFrustum* lastViewFrustum;
bool wantOcclusionCulling;
int boundaryLevelAdjust;
float voxelSizeScale;
uint64_t lastViewFrustumSent;
bool forceSendScene;
VoxelSceneStats* stats;
CoverageMap* map;
JurisdictionMap* jurisdictionMap;
EncodeBitstreamParams(
int maxEncodeLevel = INT_MAX,
const ViewFrustum* viewFrustum = IGNORE_VIEW_FRUSTUM,
bool includeColor = WANT_COLOR,
bool includeExistsBits = WANT_EXISTS_BITS,
int chopLevels = 0,
bool deltaViewFrustum = false,
const ViewFrustum* lastViewFrustum = IGNORE_VIEW_FRUSTUM,
bool wantOcclusionCulling= NO_OCCLUSION_CULLING,
CoverageMap* map = IGNORE_COVERAGE_MAP,
int boundaryLevelAdjust = NO_BOUNDARY_ADJUST,
uint64_t lastViewFrustumSent = IGNORE_LAST_SENT,
bool forceSendScene = true,
VoxelSceneStats* stats = IGNORE_SCENE_STATS,
JurisdictionMap* jurisdictionMap = IGNORE_JURISDICTION_MAP) :
maxEncodeLevel (maxEncodeLevel),
maxLevelReached (0),
viewFrustum (viewFrustum),
includeColor (includeColor),
includeExistsBits (includeExistsBits),
chopLevels (chopLevels),
deltaViewFrustum (deltaViewFrustum),
lastViewFrustum (lastViewFrustum),
wantOcclusionCulling (wantOcclusionCulling),
boundaryLevelAdjust (boundaryLevelAdjust),
lastViewFrustumSent (lastViewFrustumSent),
forceSendScene (forceSendScene),
stats (stats),
map (map),
jurisdictionMap (jurisdictionMap)
int maxEncodeLevel = INT_MAX,
const ViewFrustum* viewFrustum = IGNORE_VIEW_FRUSTUM,
bool includeColor = WANT_COLOR,
bool includeExistsBits = WANT_EXISTS_BITS,
int chopLevels = 0,
bool deltaViewFrustum = false,
const ViewFrustum* lastViewFrustum = IGNORE_VIEW_FRUSTUM,
bool wantOcclusionCulling = NO_OCCLUSION_CULLING,
CoverageMap* map = IGNORE_COVERAGE_MAP,
int boundaryLevelAdjust = NO_BOUNDARY_ADJUST,
float voxelSizeScale = DEFAULT_VOXEL_SIZE_SCALE,
uint64_t lastViewFrustumSent = IGNORE_LAST_SENT,
bool forceSendScene = true,
VoxelSceneStats* stats = IGNORE_SCENE_STATS,
JurisdictionMap* jurisdictionMap = IGNORE_JURISDICTION_MAP) :
maxEncodeLevel(maxEncodeLevel),
maxLevelReached(0),
viewFrustum(viewFrustum),
includeColor(includeColor),
includeExistsBits(includeExistsBits),
chopLevels(chopLevels),
deltaViewFrustum(deltaViewFrustum),
lastViewFrustum(lastViewFrustum),
wantOcclusionCulling(wantOcclusionCulling),
boundaryLevelAdjust(boundaryLevelAdjust),
voxelSizeScale(voxelSizeScale),
lastViewFrustumSent(lastViewFrustumSent),
forceSendScene(forceSendScene),
stats(stats),
map(map),
jurisdictionMap(jurisdictionMap)
{}
};
@ -265,7 +268,6 @@ private:
void chunkifyLeaf(VoxelNode* node);
};
float boundaryDistanceForRenderLevel(unsigned int renderLevel);
float boundaryDistanceSquaredForRenderLevel(unsigned int renderLevel);
float boundaryDistanceForRenderLevel(unsigned int renderLevel, float voxelSizeScale);
#endif /* defined(__hifi__VoxelTree__) */