diff --git a/TODO b/TODO index a7754c2..6455d68 100644 --- a/TODO +++ b/TODO @@ -17,7 +17,6 @@ Technology Preview 2 : => Improve curve rendering => Add axis labels - Improve 3d explorer - => Improve priority rendering (prioritize on screen chunks) => Restore LOD and intelligent poly count => Interrupt chunk rendering when quitting dialog => Don't display the water if it's below all ground diff --git a/gui_qt/wandererchunk.cpp b/gui_qt/wandererchunk.cpp index 0888c33..622bb10 100644 --- a/gui_qt/wandererchunk.cpp +++ b/gui_qt/wandererchunk.cpp @@ -5,6 +5,7 @@ #include #include #include +#include "../lib_paysages/camera.h" #include "../lib_paysages/color.h" #include "../lib_paysages/euclid.h" #include "../lib_paysages/tools.h" @@ -17,8 +18,7 @@ WandererChunk::WandererChunk(Renderer* renderer, double x, double z, double size _startz = z; _size = size; - _ideal_tessellation = 1; - _ideal_priority = 0.0; + priority = 0.0; _tessellation_max_size = 32; _tessellation = new double[(_tessellation_max_size + 1) * (_tessellation_max_size + 1)]; @@ -82,31 +82,42 @@ void WandererChunk::render(QGLWidget* widget) } } -void WandererChunk::updatePriority(Vector3 camera_location) +void WandererChunk::updatePriority(CameraDefinition* camera) { // Compute new priority _lock_data.lock(); if (_tessellation_current_size == _tessellation_max_size && _texture_current_size == _texture_max_size) { - _ideal_priority = -1000.0; + priority = -1000.0; } else { - double distance = v3Norm(v3Sub(camera_location, getCenter())); + double distance, wanted_size; + Vector3 center; + + center = getCenter(); + + distance = v3Norm(v3Sub(camera->location, center)); distance = distance < 0.1 ? 0.1 : distance; - _ideal_tessellation = (int)ceil(120.0 - distance / 3.0); - _ideal_priority = _ideal_tessellation - _texture_current_size; + wanted_size = (int)ceil(120.0 - distance / 3.0); + + priority = wanted_size - _texture_current_size; if (_texture_current_size == 1) { - _ideal_priority += 100.0; + priority += 100.0; } else if (distance < 15.0 && _texture_current_size < _texture_max_size) { - _ideal_priority += 75.0; + priority += 75.0; } else if (distance < 30.0 && _texture_current_size < _texture_max_size / 2) { - _ideal_priority += 50.0; + priority += 50.0; + } + + if (!cameraIsBoxInView(camera, center, _size, _size, 40.0)) + { + priority -= 100.0; } } _lock_data.unlock(); diff --git a/gui_qt/wandererchunk.h b/gui_qt/wandererchunk.h index a44a7ba..5f2bd21 100644 --- a/gui_qt/wandererchunk.h +++ b/gui_qt/wandererchunk.h @@ -13,12 +13,12 @@ public: ~WandererChunk(); bool maintain(); - void updatePriority(Vector3 camera_location); + void updatePriority(CameraDefinition* camera); void render(QGLWidget* widget); Vector3 getCenter(); - double _ideal_priority; + double priority; private: QMutex _lock_data; @@ -28,8 +28,6 @@ private: double _startz; double _size; - int _ideal_tessellation; - double* _tessellation; int _tessellation_max_size; int _tessellation_current_size; diff --git a/gui_qt/widgetwanderer.cpp b/gui_qt/widgetwanderer.cpp index f7b6cbd..d21d90d 100644 --- a/gui_qt/widgetwanderer.cpp +++ b/gui_qt/widgetwanderer.cpp @@ -169,7 +169,7 @@ void WidgetWanderer::stopThreads() bool _cmpChunks(const WandererChunk* c1, const WandererChunk* c2) { - return c1->_ideal_priority > c2->_ideal_priority; + return c1->priority > c2->priority; } void WidgetWanderer::performChunksMaintenance() @@ -354,7 +354,7 @@ void WidgetWanderer::timerEvent(QTimerEvent *event) for (int i = 0; i < _chunks.count(); i++) { - _chunks[i]->updatePriority(_current_camera.location); + _chunks[i]->updatePriority(&_current_camera); } _lock_chunks.lock(); qSort(_updateQueue.begin(), _updateQueue.end(), _cmpChunks); diff --git a/lib_paysages/camera.c b/lib_paysages/camera.c index f33aa16..eb26aac 100644 --- a/lib_paysages/camera.c +++ b/lib_paysages/camera.c @@ -2,6 +2,7 @@ #include #include +#include #include "euclid.h" #include "render.h" #include "shared/types.h" @@ -296,3 +297,56 @@ void cameraProjectToFragment(CameraDefinition* camera, Renderer* renderer, doubl renderPushQuad(&v1, &v2, &v3, &v4); }*/ + +static inline void _updateBox(Vector3* point, double* xmin, double* xmax, double* ymin, double* ymax, double* zmax) +{ + *xmin = MIN(*xmax, point->x); + *xmax = MAX(*xmin, point->x); + *ymin = MIN(*ymax, point->y); + *ymax = MAX(*ymin, point->y); + *zmax = MAX(*zmax, point->z); +} + +int cameraIsBoxInView(CameraDefinition* camera, Vector3 center, double xsize, double ysize, double zsize) +{ + Vector3 projected; + double xmin, xmax, ymin, ymax, zmax; + + center.x -= xsize / 2.0; + center.y -= ysize / 2.0; + center.z -= zsize / 2.0; + projected = cameraProject(camera, NULL, center); + xmin = xmax = projected.x; + ymin = ymax = projected.y; + zmax = projected.z; + + center.x += xsize; + projected = cameraProject(camera, NULL, center); + _updateBox(&projected, &xmin, &xmax, &ymin, &ymax, &zmax); + + center.y += ysize; + projected = cameraProject(camera, NULL, center); + _updateBox(&projected, &xmin, &xmax, &ymin, &ymax, &zmax); + + center.z += zsize; + projected = cameraProject(camera, NULL, center); + _updateBox(&projected, &xmin, &xmax, &ymin, &ymax, &zmax); + + center.x -= xsize; + projected = cameraProject(camera, NULL, center); + _updateBox(&projected, &xmin, &xmax, &ymin, &ymax, &zmax); + + center.y -= ysize; + projected = cameraProject(camera, NULL, center); + _updateBox(&projected, &xmin, &xmax, &ymin, &ymax, &zmax); + + center.x += xsize; + projected = cameraProject(camera, NULL, center); + _updateBox(&projected, &xmin, &xmax, &ymin, &ymax, &zmax); + + center.z -= zsize; + projected = cameraProject(camera, NULL, center); + _updateBox(&projected, &xmin, &xmax, &ymin, &ymax, &zmax); + + return xmin <= camera->width && xmax >= 0.0 && ymin <= camera->height && ymax >= 0.0 && zmax >= camera->znear; +} diff --git a/lib_paysages/camera.h b/lib_paysages/camera.h index 86ff0a0..be2caa3 100644 --- a/lib_paysages/camera.h +++ b/lib_paysages/camera.h @@ -36,7 +36,8 @@ Vector3 cameraProject(CameraDefinition* camera, Renderer* renderer, Vector3 poin Vector3 cameraUnproject(CameraDefinition* camera, Renderer* renderer, Vector3 point); void cameraProjectToFragment(CameraDefinition* camera, Renderer* renderer, double x, double y, double z, RenderFragment* result); /*void cameraPushOverlay(CameraDefinition* camera, Color col, f_RenderFragmentCallback callback);*/ - +int cameraIsBoxInView(CameraDefinition* camera, Vector3 center, double xsize, double ysize, double zsize); + #ifdef __cplusplus } #endif