build a cached lookup table for the shouldRenderMesh() LOD method

This commit is contained in:
ZappoMan 2014-10-16 01:00:32 -07:00
parent bf77adc4bc
commit d238d06df5
2 changed files with 38 additions and 15 deletions

View file

@ -122,7 +122,8 @@ Menu::Menu() :
_hasLoginDialogDisplayed(false), _hasLoginDialogDisplayed(false),
_snapshotsLocation(), _snapshotsLocation(),
_scriptsLocation(), _scriptsLocation(),
_walletPrivateKey() _walletPrivateKey(),
_shouldRenderTableNeedsRebuilding(true)
{ {
Application *appInstance = Application::getInstance(); Application *appInstance = Application::getInstance();
@ -1551,6 +1552,7 @@ void Menu::autoAdjustLOD(float currentFPS) {
&& _voxelSizeScale > ADJUST_LOD_MIN_SIZE_SCALE) { && _voxelSizeScale > ADJUST_LOD_MIN_SIZE_SCALE) {
_voxelSizeScale *= ADJUST_LOD_DOWN_BY; _voxelSizeScale *= ADJUST_LOD_DOWN_BY;
if (_voxelSizeScale < ADJUST_LOD_MIN_SIZE_SCALE) { if (_voxelSizeScale < ADJUST_LOD_MIN_SIZE_SCALE) {
_voxelSizeScale = ADJUST_LOD_MIN_SIZE_SCALE; _voxelSizeScale = ADJUST_LOD_MIN_SIZE_SCALE;
} }
@ -1573,6 +1575,7 @@ void Menu::autoAdjustLOD(float currentFPS) {
} }
if (changed) { if (changed) {
_shouldRenderTableNeedsRebuilding = true;
if (_lodToolsDialog) { if (_lodToolsDialog) {
_lodToolsDialog->reloadSliders(); _lodToolsDialog->reloadSliders();
} }
@ -1587,36 +1590,53 @@ void Menu::resetLODAdjust() {
void Menu::setVoxelSizeScale(float sizeScale) { void Menu::setVoxelSizeScale(float sizeScale) {
_voxelSizeScale = sizeScale; _voxelSizeScale = sizeScale;
_shouldRenderTableNeedsRebuilding = true;
bumpSettings(); bumpSettings();
} }
void Menu::setBoundaryLevelAdjust(int boundaryLevelAdjust) { void Menu::setBoundaryLevelAdjust(int boundaryLevelAdjust) {
_boundaryLevelAdjust = boundaryLevelAdjust; _boundaryLevelAdjust = boundaryLevelAdjust;
_shouldRenderTableNeedsRebuilding = true;
bumpSettings(); bumpSettings();
} }
// TODO: This could be optimized to be a table, or something that doesn't require recalculation on every
// render call for every entity
// TODO: This is essentially the same logic used to render voxels, but since models are more detailed then voxels // TODO: This is essentially the same logic used to render voxels, but since models are more detailed then voxels
// I've added a voxelToModelRatio that adjusts how much closer to a model you have to be to see it. // I've added a voxelToModelRatio that adjusts how much closer to a model you have to be to see it.
bool Menu::shouldRenderMesh(float largestDimension, float distanceToCamera) const { bool Menu::shouldRenderMesh(float largestDimension, float distanceToCamera) {
const float voxelToMeshRatio = 4.0f; // must be this many times closer to a mesh than a voxel to see it. const float voxelToMeshRatio = 4.0f; // must be this many times closer to a mesh than a voxel to see it.
float voxelSizeScale = getVoxelSizeScale(); float voxelSizeScale = getVoxelSizeScale();
int boundaryLevelAdjust = getBoundaryLevelAdjust(); int boundaryLevelAdjust = getBoundaryLevelAdjust();
float maxScale = (float)TREE_SCALE;
float visibleDistanceAtMaxScale = boundaryDistanceForRenderLevel(boundaryLevelAdjust, voxelSizeScale) / voxelToMeshRatio;
float scale = (float)TREE_SCALE; if (_shouldRenderTableNeedsRebuilding) {
float visibleDistanceAtScale = boundaryDistanceForRenderLevel(boundaryLevelAdjust, voxelSizeScale) / voxelToMeshRatio; _shouldRenderTable.clear();
while (scale > largestDimension) { float SMALLEST_SCALE_IN_TABLE = 0.001f; // 1mm is plenty small
scale /= 2.0f; float scale = maxScale;
visibleDistanceAtScale /= 2.0f; float visibleDistanceAtScale = visibleDistanceAtMaxScale;
}
while (scale > SMALLEST_SCALE_IN_TABLE) {
if (scale < largestDimension) { scale /= 2.0f;
visibleDistanceAtScale *= 2.0f; visibleDistanceAtScale /= 2.0f;
_shouldRenderTable[scale] = visibleDistanceAtScale;
}
_shouldRenderTableNeedsRebuilding = false;
} }
return (distanceToCamera <= visibleDistanceAtScale); float closestScale = maxScale;
float visibleDistanceAtClosestScale = visibleDistanceAtMaxScale;
QMap<float, float>::const_iterator lowerBound = _shouldRenderTable.lowerBound(largestDimension);
if (lowerBound != _shouldRenderTable.constEnd()) {
closestScale = lowerBound.key();
visibleDistanceAtClosestScale = lowerBound.value();
}
if (closestScale < largestDimension) {
visibleDistanceAtClosestScale *= 2.0f;
}
return (distanceToCamera <= visibleDistanceAtClosestScale);
} }

View file

@ -143,7 +143,7 @@ public:
void setBoundaryLevelAdjust(int boundaryLevelAdjust); void setBoundaryLevelAdjust(int boundaryLevelAdjust);
int getBoundaryLevelAdjust() const { return _boundaryLevelAdjust; } int getBoundaryLevelAdjust() const { return _boundaryLevelAdjust; }
bool shouldRenderMesh(float largestDimension, float distanceToCamera) const; bool shouldRenderMesh(float largestDimension, float distanceToCamera);
#ifdef Q_OS_MAC #ifdef Q_OS_MAC
SpeechRecognizer* getSpeechRecognizer() { return &_speechRecognizer; } SpeechRecognizer* getSpeechRecognizer() { return &_speechRecognizer; }
@ -312,6 +312,9 @@ private:
QString _snapshotsLocation; QString _snapshotsLocation;
QString _scriptsLocation; QString _scriptsLocation;
QByteArray _walletPrivateKey; QByteArray _walletPrivateKey;
bool _shouldRenderTableNeedsRebuilding;
QMap<float, float> _shouldRenderTable;
}; };