mirror of
https://github.com/overte-org/overte.git
synced 2025-04-21 19:04:32 +02:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
8b781bf9cd
25 changed files with 567 additions and 159 deletions
|
@ -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",
|
||||
|
|
|
@ -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());
|
||||
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
#include "ui/ChatEntry.h"
|
||||
#include "ui/VoxelStatsDialog.h"
|
||||
#include "ui/RearMirrorTools.h"
|
||||
#include "ui/LodToolsDialog.h"
|
||||
|
||||
class QAction;
|
||||
class QActionGroup;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
153
interface/src/ui/LodToolsDialog.cpp
Normal file
153
interface/src/ui/LodToolsDialog.cpp
Normal 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();
|
||||
}
|
||||
|
||||
|
48
interface/src/ui/LodToolsDialog.h
Normal file
48
interface/src/ui/LodToolsDialog.h
Normal 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__) */
|
||||
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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__) */
|
||||
|
|
|
@ -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());
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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__) */
|
||||
|
|
Loading…
Reference in a new issue