From 7d479af9c77d60a534cbe23e07bb0e2e7ddf1023 Mon Sep 17 00:00:00 2001 From: tosh Date: Thu, 4 Apr 2013 10:52:42 +0200 Subject: [PATCH 1/5] adjusts braces to agreed conventions --- shared/src/AngleUtils.h | 38 ++++++++++----------- shared/src/FloodFill.h | 55 +++++++++++++++++-------------- shared/src/Radix2InplaceSort.h | 34 +++++++++---------- shared/src/Radix2IntegerScanner.h | 21 ++++++------ shared/src/UrlReader.cpp | 16 ++++----- shared/src/UrlReader.h | 55 +++++++++++++++---------------- 6 files changed, 111 insertions(+), 108 deletions(-) diff --git a/shared/src/AngleUtils.h b/shared/src/AngleUtils.h index 533df57da9..dfe4f09124 100644 --- a/shared/src/AngleUtils.h +++ b/shared/src/AngleUtils.h @@ -11,22 +11,22 @@ #include -struct Degrees -{ +struct Degrees { + static float pi() { return 180.0f; } static float twicePi() { return 360.0f; } static float halfPi() { return 90.0f; } }; -struct Radians -{ +struct Radians { + static float pi() { return 3.141592653589793f; } static float twicePi() { return 6.283185307179586f; } static float halfPi() { return 1.5707963267948966; } }; -struct Rotations -{ +struct Rotations { + static float pi() { return 0.5f; } static float twicePi() { return 1.0f; } static float halfPi() { return 0.25f; } @@ -36,8 +36,8 @@ struct Rotations * Converts an angle from one unit to another. */ template< class UnitFrom, class UnitTo > -float angleConvert(float a) -{ +float angleConvert(float a) { + return a * (UnitTo::halfPi() / UnitFrom::halfPi()); } @@ -46,8 +46,8 @@ float angleConvert(float a) * Clamps an angle to the range of [-180; 180) degrees. */ template< class Unit > -float angleSignedNormal(float a) -{ +float angleSignedNormal(float a) { + float result = remainder(a, Unit::twicePi()); if (result == Unit::pi()) result = -Unit::pi(); @@ -58,8 +58,8 @@ float angleSignedNormal(float a) * Clamps an angle to the range of [0; 360) degrees. */ template< class Unit > -float angleUnsignedNormal(float a) -{ +float angleUnsignedNormal(float a) { + return angleSignedNormal(a - Unit::pi()) + Unit::pi(); } @@ -72,16 +72,16 @@ float angleUnsignedNormal(float a) * Both poles can be reached from any azimuthal direction. */ template< class Unit > -void angleHorizontalPolar(float& azimuth, float& altitude) -{ +void angleHorizontalPolar(float& azimuth, float& altitude) { + altitude = angleSignedNormal(altitude); - if (altitude > Unit::halfPi()) - { + if (altitude > Unit::halfPi()) { + altitude = Unit::pi() - altitude; azimuth += Unit::pi(); - } - else if (altitude < -Unit::halfPi()) - { + + } else if (altitude < -Unit::halfPi()) { + altitude = -Unit::pi() - altitude; azimuth += Unit::pi(); } diff --git a/shared/src/FloodFill.h b/shared/src/FloodFill.h index ff278b185b..b52720a7b1 100644 --- a/shared/src/FloodFill.h +++ b/shared/src/FloodFill.h @@ -18,8 +18,8 @@ void floodFill(Cursor const& position, template< class Strategy, typename Cursor > -struct floodFill_impl : Strategy -{ +struct floodFill_impl : Strategy { + floodFill_impl(Strategy const& s) : Strategy(s) { } using Strategy::select; @@ -33,14 +33,15 @@ struct floodFill_impl : Strategy using Strategy::defer; using Strategy::deferred; - void go(Cursor position) - { + void go(Cursor position) { + Cursor higher, lower, h,l, i; bool higherFound, lowerFound, hf, lf; - do - { - if (! select(position)) + do { + + if (! select(position)) { continue; + } process(position); @@ -51,33 +52,39 @@ struct floodFill_impl : Strategy i = position, h = higher, l = lower; hf = higherFound, lf = lowerFound; - do { right(i), right(h), right(l); yTest(h,hf); yTest(l,lf); } - while (selectAndProcess(i)); + do { + right(i), right(h), right(l); yTest(h,hf); yTest(l,lf); + + } while (selectAndProcess(i)); i = position, h = higher, l = lower; hf = higherFound, lf = lowerFound; - do { left(i); left(h); left(l); yTest(h,hf); yTest(l,lf); } - while (selectAndProcess(i)); - } - while (deferred(position)); + do { + left(i); left(h); left(l); yTest(h,hf); yTest(l,lf); + + } while (selectAndProcess(i)); + + } while (deferred(position)); } - bool selectAndProcess(Cursor const& i) - { - if (select(i)) - { + bool selectAndProcess(Cursor const& i) { + + if (select(i)) { + process(i); return true; } return false; } - void yTest(Cursor const& i, bool& state) - { - if (! select(i)) + void yTest(Cursor const& i, bool& state) { + + if (! select(i)) { + state = false; - else if (! state) - { + + } else if (! state) { + state = true; defer(i); } @@ -85,8 +92,8 @@ struct floodFill_impl : Strategy }; template< class Strategy, typename Cursor > -void floodFill(Cursor const& p, Strategy const& s) -{ +void floodFill(Cursor const& p, Strategy const& s) { + floodFill_impl(s).go(p); } diff --git a/shared/src/Radix2InplaceSort.h b/shared/src/Radix2InplaceSort.h index cf89f13583..abd650b2a6 100644 --- a/shared/src/Radix2InplaceSort.h +++ b/shared/src/Radix2InplaceSort.h @@ -25,30 +25,27 @@ void radix2InplaceSort( BidiIterator from, BidiIterator to, template< class Scanner, typename Iterator > -struct radix2InplaceSort_impl : Scanner -{ +struct radix2InplaceSort_impl : Scanner { + radix2InplaceSort_impl(Scanner const& s) : Scanner(s) { } using Scanner::advance; using Scanner::bit; - void go(Iterator& from, Iterator& to, typename Scanner::state_type s) - { + void go(Iterator& from, Iterator& to, typename Scanner::state_type s) { + Iterator l(from), r(to); unsigned cl, cr; using std::swap; - for (;;) - { + while (true) { // scan from left for set bit for (cl = cr = 0u; l != r ; ++l, ++cl) - if (bit(*l, s)) - { + if (bit(*l, s)) { // scan from the right for unset bit for (++cr; --r != l ;++cr) - if (! bit(*r, s)) - { + if (! bit(*r, s)) { // swap, continue scanning from left swap(*l, *r); break; @@ -58,22 +55,23 @@ struct radix2InplaceSort_impl : Scanner } // on to the next digit, if any - if (! advance(s)) + if (! advance(s)) { return; + } // recurse into smaller branch and prepare iterative // processing of the other - if (cl < cr) - { + if (cl < cr) { + if (cl > 1u) go(from, l, s); else if (cr <= 1u) return; l = from = r; r = to; - } - else - { + + } else { + if (cr > 1u) go(r, to, s); else if (cl <= 1u) return; @@ -87,8 +85,8 @@ struct radix2InplaceSort_impl : Scanner template< class Radix2Scanner, typename BidiIterator > void radix2InplaceSort( BidiIterator from, BidiIterator to, - Radix2Scanner const& scanner) -{ + Radix2Scanner const& scanner) { + radix2InplaceSort_impl(scanner) .go(from, to, scanner.initial_state()); } diff --git a/shared/src/Radix2IntegerScanner.h b/shared/src/Radix2IntegerScanner.h index c617a1080d..355ecfef46 100644 --- a/shared/src/Radix2IntegerScanner.h +++ b/shared/src/Radix2IntegerScanner.h @@ -12,8 +12,8 @@ #include #include -namespace type_traits // those are needed for the declaration, see below -{ +namespace type_traits { // those are needed for the declaration, see below + // Note: There are better / more generally appicable implementations // in C++11, make_signed is missing in TR1 too - so I just use C++98 // hacks that get the job done... @@ -39,8 +39,8 @@ class Radix2IntegerScanner; template< typename UInt > -class Radix2IntegerScanner< UInt, false > -{ +class Radix2IntegerScanner< UInt, false > { + UInt valMsb; public: @@ -48,9 +48,8 @@ class Radix2IntegerScanner< UInt, false > : valMsb(~UInt(0) &~ (~UInt(0) >> 1)) { } explicit Radix2IntegerScanner(int bits) - : valMsb(UInt(1u) << (bits - 1)) - { } - + : valMsb(UInt(1u) << (bits - 1)) { + } typedef UInt state_type; @@ -67,12 +66,12 @@ class Radix2IntegerScanner< Int, true > public: Radix2IntegerScanner() - : valMsb(~state_type(0u) &~ (~state_type(0u) >> 1)) - { } + : valMsb(~state_type(0u) &~ (~state_type(0u) >> 1)) { + } explicit Radix2IntegerScanner(int bits) - : valMsb(state_type(1u) << (bits - 1)) - { } + : valMsb(state_type(1u) << (bits - 1)) { + } typedef typename type_traits::make_unsigned::type state_type; diff --git a/shared/src/UrlReader.cpp b/shared/src/UrlReader.cpp index ee1f6efc3f..571456f2be 100644 --- a/shared/src/UrlReader.cpp +++ b/shared/src/UrlReader.cpp @@ -23,8 +23,8 @@ char const* const UrlReader::error_leftover_input = "UrlReader: Incomplete pro #define hnd_curl static_cast(_ptrImpl) UrlReader::UrlReader() - : _ptrImpl(0l), _arrXtra(0l), _strError(0l) -{ + : _ptrImpl(0l), _arrXtra(0l), _strError(0l) { + _arrXtra = new(std::nothrow) char[max_read_ahead]; if (! _arrXtra) { _strError = error_init_failed; return; } _ptrImpl = curl_easy_init(); @@ -34,15 +34,15 @@ UrlReader::UrlReader() curl_easy_setopt(hnd_curl, CURLOPT_FILETIME, 1l); } -UrlReader::~UrlReader() -{ +UrlReader::~UrlReader() { + delete _arrXtra; if (! hnd_curl) return; curl_easy_cleanup(hnd_curl); } -bool UrlReader::perform(char const* url, transfer_callback* cb) -{ +bool UrlReader::perform(char const* url, transfer_callback* cb) { + curl_easy_setopt(hnd_curl, CURLOPT_URL, url); curl_easy_setopt(hnd_curl, CURLOPT_WRITEFUNCTION, cb); curl_easy_setopt(hnd_curl, CURLOPT_WRITEDATA, this); @@ -61,8 +61,8 @@ bool UrlReader::perform(char const* url, transfer_callback* cb) } void UrlReader::getinfo(char const*& url, - char const*& type, int64_t& length, int64_t& stardate) -{ + char const*& type, int64_t& length, int64_t& stardate) { + curl_easy_getinfo(hnd_curl, CURLINFO_EFFECTIVE_URL, & url); curl_easy_getinfo(hnd_curl, CURLINFO_CONTENT_TYPE, & type); diff --git a/shared/src/UrlReader.h b/shared/src/UrlReader.h index 3ee4f04241..c50fe88d5b 100644 --- a/shared/src/UrlReader.h +++ b/shared/src/UrlReader.h @@ -17,8 +17,8 @@ * UrlReader class that encapsulates a context for sequential data retrieval * via URLs. Use one per thread. */ -class UrlReader -{ +class UrlReader { + void* _ptrImpl; char* _arrXtra; char const* _strError; @@ -149,8 +149,7 @@ class UrlReader }; template< class ContentStream > -bool UrlReader::readUrl(char const* url, ContentStream& s) -{ +bool UrlReader::readUrl(char const* url, ContentStream& s) { if (! _ptrImpl) return false; _strError = success; _ptrStream = & s; @@ -162,24 +161,24 @@ bool UrlReader::readUrl(char const* url, ContentStream& s) inline char const* UrlReader::getError() const { return this->_strError; } -inline void UrlReader::setError(char const* static_c_string) -{ +inline void UrlReader::setError(char const* static_c_string) { + if (this->_strError == success) this->_strError = static_c_string; } template< class Stream > size_t UrlReader::callback_template( - char *input, size_t size, size_t nmemb, void* thiz) -{ + char *input, size_t size, size_t nmemb, void* thiz) { + size *= nmemb; UrlReader* me = static_cast(thiz); Stream* stream = static_cast(me->_ptrStream); // first call? - if (me->_valXtraSize == ~size_t(0)) - { + if (me->_valXtraSize == ~size_t(0)) { + me->_valXtraSize = 0u; // extract meta information and call 'begin' char const* url, * type; @@ -190,14 +189,14 @@ size_t UrlReader::callback_template( size_t input_offset = 0u; - for (;;) - { + while (true) { + char* buffer = input + input_offset; size_t bytes = size - input_offset; // data in extra buffer? - if (me->_valXtraSize > 0) - { + if (me->_valXtraSize > 0) { + // fill extra buffer with beginning of input size_t fill = max_read_ahead - me->_valXtraSize; if (bytes < fill) fill = bytes; @@ -210,36 +209,36 @@ size_t UrlReader::callback_template( // call 'transfer' size_t processed = stream->transfer(buffer, bytes); - if (processed == abort) - { + if (processed == abort) { + me->setError(error_aborted); return 0u; - } - else if (! processed && ! input) - { + + } else if (! processed && ! input) { + me->setError(error_leftover_input); return 0u; } size_t unprocessed = bytes - processed; // can switch to input buffer, now? - if (buffer == me->_arrXtra && unprocessed <= input_offset) - { + if (buffer == me->_arrXtra && unprocessed <= input_offset) { + me->_valXtraSize = 0u; input_offset -= unprocessed; - } - else // no? unprocessed data -> extra buffer - { - if (unprocessed > max_read_ahead) - { + + } else { // no? unprocessed data -> extra buffer + + if (unprocessed > max_read_ahead) { + me->setError(error_buffer_overflow); return 0; } me->_valXtraSize = unprocessed; memmove(me->_arrXtra, buffer + processed, unprocessed); - if (input_offset == size || buffer != me->_arrXtra) - { + if (input_offset == size || buffer != me->_arrXtra) { + return size; } } From 9046e5e89c1c0cae77b1a47f58f7f058bc7a9989 Mon Sep 17 00:00:00 2001 From: tosh Date: Thu, 4 Apr 2013 10:55:08 +0200 Subject: [PATCH 2/5] silences warning by using pointer to const as string parameter for 'drawtext' (conversion of string literals to char* is deprecated) --- interface/src/Util.cpp | 4 ++-- interface/src/Util.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/interface/src/Util.cpp b/interface/src/Util.cpp index 99dafa8c23..03a11e3308 100644 --- a/interface/src/Util.cpp +++ b/interface/src/Util.cpp @@ -90,8 +90,8 @@ double diffclock(timeval *clock1,timeval *clock2) return diffms; } -void drawtext(int x, int y, float scale, float rotate, float thick, int mono, char *string, - float r, float g, float b) +void drawtext(int x, int y, float scale, float rotate, float thick, int mono, + char const* string, float r, float g, float b) { // // Draws text on screen as stroked so it can be resized diff --git a/interface/src/Util.h b/interface/src/Util.h index e2cd566b6e..448258932f 100644 --- a/interface/src/Util.h +++ b/interface/src/Util.h @@ -23,8 +23,8 @@ float angle_to(glm::vec3 head_pos, glm::vec3 source_pos, float render_yaw, float float randFloat(); void render_world_box(); void render_vector(glm::vec3 * vec); -void drawtext(int x, int y, float scale, float rotate, float thick, int mono, char *string, - float r=1.0, float g=1.0, float b=1.0); +void drawtext(int x, int y, float scale, float rotate, float thick, int mono, + char const* string, float r=1.0, float g=1.0, float b=1.0); void drawvec3(int x, int y, float scale, float rotate, float thick, int mono, glm::vec3 vec, float r=1.0, float g=1.0, float b=1.0); double diffclock(timeval *clock1,timeval *clock2); From de4734d6fb435d09dbe8a06e6ff42fc84745c3e9 Mon Sep 17 00:00:00 2001 From: tosh Date: Thu, 4 Apr 2013 10:59:57 +0200 Subject: [PATCH 3/5] tightens ogl state handling (also fixes unreadably thick text for stats display) --- interface/src/main.cpp | 16 ++++++++-------- interface/src/starfield/renderer/Renderer.h | 11 +++++++---- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 2cba377d8f..e6f6b6fd52 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -527,8 +527,6 @@ void display(void) { PerfStat("display"); - glEnable (GL_DEPTH_TEST); - glEnable(GL_LIGHTING); glEnable(GL_LINE_SMOOTH); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); @@ -559,14 +557,12 @@ void display(void) -myHead.getRenderPitch(), glm::vec3(1.0f,0.0f,0.0f)) ); glLoadMatrixf( glm::value_ptr(fov.getWorldViewerXform()) ); - glRotatef(myHead.getRenderPitch(), 1, 0, 0); - glRotatef(myHead.getRenderYaw(), 0, 1, 0); - glDisable(GL_LIGHTING); - glDisable(GL_DEPTH_TEST); if (::starsOn) { + // should be the first rendering pass - w/o depth buffer / lighting stars.render(fov); } + glEnable(GL_LIGHTING); glEnable(GL_DEPTH_TEST); @@ -670,8 +666,12 @@ void display(void) if (display_levels) serialPort.renderLevels(WIDTH,HEIGHT); // Display miscellaneous text stats onscreen - if (stats_on) display_stats(); - + if (stats_on) { + glLineWidth(1.0f); + glPointSize(1.0f); + display_stats(); + } + // Draw number of nearby people always char agents[100]; sprintf(agents, "Agents nearby: %ld\n", agentList.getAgents().size()); diff --git a/interface/src/starfield/renderer/Renderer.h b/interface/src/starfield/renderer/Renderer.h index abb553cd06..0cfb6df0c9 100644 --- a/interface/src/starfield/renderer/Renderer.h +++ b/interface/src/starfield/renderer/Renderer.h @@ -106,8 +106,8 @@ namespace starfield { this->glUpload(n); } - ~Renderer() - { + ~Renderer() { + delete[] _arrData; delete[] _arrTile; delete[] _arrBatchCount; @@ -119,8 +119,7 @@ namespace starfield { void render(float perspective, float aspect, mat4 const& orientation, - BrightnessLevel minBright) - { + BrightnessLevel minBright) { // fprintf(stderr, " // Stars.cpp: rendering at minimal brightness %d\n", minBright); @@ -479,6 +478,9 @@ namespace starfield { // fprintf(stderr, "Stars.cpp: Batch #%d - %d stars @ %d\n", i, // _arrBatchOffs[i], _arrBatchCount[i]); + glDisable(GL_DEPTH_TEST); + glDisable(GL_LIGHTING); + // setup modelview matrix (identity) glMatrixMode(GL_MODELVIEW); glPushMatrix(); @@ -507,6 +509,7 @@ namespace starfield { glBindVertexArray(0); glUseProgram(0); glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); + glDisable(GL_POINT_SMOOTH); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); From 284530f7d6940540838215b258e96688dafc04db Mon Sep 17 00:00:00 2001 From: tosh Date: Thu, 4 Apr 2013 11:59:16 +0200 Subject: [PATCH 4/5] tightens memory use --- interface/src/starfield/renderer/Renderer.h | 34 +++++++++++++++------ shared/src/FloodFill.h | 31 +++++++++++++++++-- 2 files changed, 52 insertions(+), 13 deletions(-) diff --git a/interface/src/starfield/renderer/Renderer.h b/interface/src/starfield/renderer/Renderer.h index 0cfb6df0c9..a45e1f50a5 100644 --- a/interface/src/starfield/renderer/Renderer.h +++ b/interface/src/starfield/renderer/Renderer.h @@ -96,10 +96,14 @@ namespace starfield { Tiling tiling(k); size_t nTiles = tiling.getTileCount(); + // REVISIT: could coalesce allocation for faster rebuild + // REVISIT: batch arrays are probably oversized, but - hey - they + // are not very large (unless for insane tiling) and we're better + // off safe than sorry _arrData = new GpuVertex[n]; _arrTile = new Tile[nTiles + 1]; - _arrBatchOffs = new GLint[nTiles]; - _arrBatchCount = new GLsizei[nTiles]; + _arrBatchOffs = new GLint[nTiles * 2]; + _arrBatchCount = new GLsizei[nTiles * 2]; prepareVertexData(src, n, tiling, b, bMin); @@ -290,21 +294,31 @@ namespace starfield { bool select(Tile* t) { if (t < _arrTile || t >= _itrTilesEnd || - !! (t->flags & Tile::visited)) { + !! (t->flags & Tile::checked)) { - return false; + // out of bounds or been here already + return false; } - if (! (t->flags & Tile::checked)) { - if (_refRenderer.visitTile(t)) - t->flags |= Tile::render; + // will check now and never again + t->flags |= Tile::checked; + if (_refRenderer.visitTile(t)) { + + // good one -> remember (for batching) and propagate + t->flags |= Tile::render; + return true; } - return !! (t->flags & Tile::render); + return false; } - void process(Tile* t) { + bool process(Tile* t) { - t->flags |= Tile::visited; + if (! (t->flags & Tile::visited)) { + + t->flags |= Tile::visited; + return true; + } + return false; } void right(Tile*& cursor) const { cursor += 1; } diff --git a/shared/src/FloodFill.h b/shared/src/FloodFill.h index b52720a7b1..273c1c4f6e 100644 --- a/shared/src/FloodFill.h +++ b/shared/src/FloodFill.h @@ -11,6 +11,29 @@ /** * Line scanning, iterative flood fill algorithm. + * + * The strategy must obey the following contract: + * + * There is an associated cursor that represents a position on the image. + * The member functions 'left(C&)', 'right(C&)', 'up(C&)', and 'down(C&)' + * move it. + * The state of a cursor can be deferred to temporary storage (typically a + * stack or a queue) using the 'defer(C const&)' member function. + * Calling 'deferred(C&)' restores a cursor's state from temporary storage + * and removes it there. + * The 'select(C const&)' and 'process(C const&)' functions control the + * algorithm. The former is called to determine where to go. It may be + * called multiple times but does not have to (and should not) return + * 'true' more than once for a pixel to be selected (will cause memory + * overuse, otherwise). The latter will never be called for a given pixel + * unless previously selected. It may be called multiple times, in which + * case it should return 'true' upon successful processing and 'false' + * when an already processed pixel has been visited. + * + * Note: The terms "image" and "pixel" are used for illustratory purposes + * and mean "undirected graph with 4-connected 2D grid topology" and "node", + * respectively. + * */ template< class Strategy, typename Cursor > void floodFill(Cursor const& position, @@ -35,16 +58,18 @@ struct floodFill_impl : Strategy { void go(Cursor position) { + if (! select(position)) { + return; + } + Cursor higher, lower, h,l, i; bool higherFound, lowerFound, hf, lf; do { - if (! select(position)) { + if (! process(position)) { continue; } - process(position); - higher = position; higherFound = false; up(higher); yTest(higher, higherFound); lower = position; lowerFound = false; From 31262340d4c773301b16dc54d4e5da36591015f6 Mon Sep 17 00:00:00 2001 From: tosh Date: Fri, 5 Apr 2013 01:24:00 +0200 Subject: [PATCH 5/5] adjusts formatting to agreed conventions --- interface/src/FieldOfView.cpp | 98 ++++++++++++------------ interface/src/FieldOfView.h | 137 ++++++++++++++++------------------ 2 files changed, 114 insertions(+), 121 deletions(-) diff --git a/interface/src/FieldOfView.cpp b/interface/src/FieldOfView.cpp index d1f535bb39..c255d7232f 100644 --- a/interface/src/FieldOfView.cpp +++ b/interface/src/FieldOfView.cpp @@ -15,95 +15,93 @@ using namespace glm; -FieldOfView::FieldOfView() - : mat_orientation(mat4(1.0f)), - vec_bounds_low(vec3(-1.0f,-1.0f,-1.0f)), - vec_bounds_high(vec3(1.0f,1.0f,1.0f)), - val_width(256.0f), - val_height(256.0f), - val_angle(0.61), - val_zoom(1.0f), - enm_aspect_balancing(expose_less) -{ +FieldOfView::FieldOfView() : + _matOrientation(mat4(1.0f)), + _vecBoundsLow(vec3(-1.0f,-1.0f,-1.0f)), + _vecBoundsHigh(vec3(1.0f,1.0f,1.0f)), + _valWidth(256.0f), + _valHeight(256.0f), + _valAngle(0.61), + _valZoom(1.0f), + _enmAspectBalancing(expose_less) { } -mat4 FieldOfView::getViewerScreenXform() const -{ +mat4 FieldOfView::getViewerScreenXform() const { + mat4 projection; vec3 low, high; getFrustum(low, high); // perspective projection? determine correct near distance - if (val_angle != 0.0f) - { + if (_valAngle != 0.0f) { + projection = translate( frustum(low.x, high.x, low.y, high.y, low.z, high.z), vec3(0.f, 0.f, -low.z) ); - } - else - { + } else { + projection = ortho(low.x, high.x, low.y, high.y, low.z, high.z); } return projection; } -mat4 FieldOfView::getWorldViewerXform() const -{ - return translate(affineInverse(mat_orientation), - vec3(0.0f, 0.0f, -vec_bounds_high.z) ); +mat4 FieldOfView::getWorldViewerXform() const { + + return translate(affineInverse(_matOrientation), + vec3(0.0f, 0.0f, -_vecBoundsHigh.z) ); } -mat4 FieldOfView::getWorldScreenXform() const -{ +mat4 FieldOfView::getWorldScreenXform() const { + return translate( - getViewerScreenXform() * affineInverse(mat_orientation), - vec3(0.0f, 0.0f, -vec_bounds_high.z) ); + getViewerScreenXform() * affineInverse(_matOrientation), + vec3(0.0f, 0.0f, -_vecBoundsHigh.z) ); } -mat4 FieldOfView::getViewerWorldXform() const -{ - vec3 n_translate = vec3(0.0f, 0.0f, vec_bounds_high.z); +mat4 FieldOfView::getViewerWorldXform() const { + + vec3 n_translate = vec3(0.0f, 0.0f, _vecBoundsHigh.z); return translate( translate(mat4(1.0f), n_translate) - * mat_orientation, -n_translate ); + * _matOrientation, -n_translate ); } -float FieldOfView::getPixelSize() const -{ +float FieldOfView::getPixelSize() const { + vec3 low, high; getFrustum(low, high); return std::min( - abs(high.x - low.x) / val_width, - abs(high.y - low.y) / val_height); + abs(high.x - low.x) / _valWidth, + abs(high.y - low.y) / _valHeight); } -void FieldOfView::getFrustum(vec3& low, vec3& high) const -{ - low = vec_bounds_low; - high = vec_bounds_high; +void FieldOfView::getFrustum(vec3& low, vec3& high) const { + + low = _vecBoundsLow; + high = _vecBoundsHigh; // start with uniform zoom - float inv_zoom = 1.0f / val_zoom; + float inv_zoom = 1.0f / _valZoom; float adj_x = inv_zoom, adj_y = inv_zoom; // balance aspect - if (enm_aspect_balancing != stretch) - { - float f_aspect = (high.x - low.x) / (high.y - low.y); - float vp_aspect = val_width / val_height; + if (_enmAspectBalancing != stretch) { + + float f_aspect = (high.x - low.x) / (high.y - low.y); + float vp_aspect = _valWidth / _valHeight; + + if ((_enmAspectBalancing == expose_more) + != (f_aspect > vp_aspect)) { - if ((enm_aspect_balancing == expose_more) - != (f_aspect > vp_aspect)) - { // expose_more -> f_aspect <= vp_aspect <=> adj >= 1 // expose_less -> f_aspect > vp_aspect <=> adj < 1 adj_x = vp_aspect / f_aspect; - } - else - { + + } else { + // expose_more -> f_aspect > vp_aspect <=> adj > 1 // expose_less -> f_aspect <= vp_aspect <=> adj <= 1 adj_y = f_aspect / vp_aspect; @@ -121,8 +119,8 @@ void FieldOfView::getFrustum(vec3& low, vec3& high) const // calc and apply near distance based on near diagonal and perspective float w = high.x - low.x, h = high.y - low.y; high.z -= low.z; - low.z = val_angle == 0.0f ? 0.0f : - sqrt(w*w+h*h) * 0.5f / tan(val_angle * 0.5f); + low.z = _valAngle == 0.0f ? 0.0f : + sqrt(w*w+h*h) * 0.5f / tan(_valAngle * 0.5f); high.z += low.z; } diff --git a/interface/src/FieldOfView.h b/interface/src/FieldOfView.h index 1bfa7c7f33..f4caf582c2 100644 --- a/interface/src/FieldOfView.h +++ b/interface/src/FieldOfView.h @@ -11,39 +11,35 @@ #include -/** - * Viewing parameter encapsulation. - */ -class FieldOfView -{ - glm::mat4 mat_orientation; - glm::vec3 vec_bounds_low; - glm::vec3 vec_bounds_high; - float val_width; - float val_height; - float val_angle; - float val_zoom; - int enm_aspect_balancing; +// +// Viewing parameter encapsulation. +// +class FieldOfView { + + glm::mat4 _matOrientation; + glm::vec3 _vecBoundsLow; + glm::vec3 _vecBoundsHigh; + float _valWidth; + float _valHeight; + float _valAngle; + float _valZoom; + int _enmAspectBalancing; public: FieldOfView(); // mutators - FieldOfView& setBounds(glm::vec3 const& low, glm::vec3 const& high) - { vec_bounds_low = low; vec_bounds_high = high; return *this; } + FieldOfView& setBounds(glm::vec3 const& low, glm::vec3 const& high) { + _vecBoundsLow = low; _vecBoundsHigh = high; return *this; } - FieldOfView& setOrientation(glm::mat4 const& matrix) - { mat_orientation = matrix; return *this; } + FieldOfView& setOrientation(glm::mat4 const& matrix) { _matOrientation = matrix; return *this; } - FieldOfView& setPerspective(float angle) - { val_angle = angle; return *this; } + FieldOfView& setPerspective(float angle) { _valAngle = angle; return *this; } - FieldOfView& setResolution(unsigned width, unsigned height) - { val_width = width; val_height = height; return *this; } + FieldOfView& setResolution(unsigned width, unsigned height) { _valWidth = width; _valHeight = height; return *this; } - FieldOfView& setZoom(float factor) - { val_zoom = factor; return *this; } + FieldOfView& setZoom(float factor) { _valZoom = factor; return *this; } enum aspect_balancing { @@ -52,76 +48,75 @@ class FieldOfView stretch }; - FieldOfView& setAspectBalancing(aspect_balancing v) - { enm_aspect_balancing = v; return *this; } + FieldOfView& setAspectBalancing(aspect_balancing v) { _enmAspectBalancing = v; return *this; } // dumb accessors - glm::mat4 const& getOrientation() const { return mat_orientation; } - float getWidthInPixels() const { return val_width; } - float getHeightInPixels() const { return val_height; } - float getPerspective() const { return val_angle; } + glm::mat4 const& getOrientation() const { return _matOrientation; } + float getWidthInPixels() const { return _valWidth; } + float getHeightInPixels() const { return _valHeight; } + float getPerspective() const { return _valAngle; } // matrices - /** - * Returns a full transformation matrix to project world coordinates - * onto the screen. - */ + // + // Returns a full transformation matrix to project world coordinates + // onto the screen. + // glm::mat4 getWorldScreenXform() const; - /** - * Transforms world coordinates to viewer-relative coordinates. - * - * This matrix can be used as the modelview matrix in legacy GL code - * where the projection matrix is kept separately. - */ + // + // Transforms world coordinates to viewer-relative coordinates. + // + // This matrix can be used as the modelview matrix in legacy GL code + // where the projection matrix is kept separately. + // glm::mat4 getWorldViewerXform() const; - /** - * Returns the transformation to of viewer-relative coordinates back - * to world space. - * - * This matrix can be used to set up a coordinate system for avatar - * rendering. - */ + // + // Returns the transformation to of viewer-relative coordinates back + // to world space. + // + // This matrix can be used to set up a coordinate system for avatar + // rendering. + // glm::mat4 getViewerWorldXform() const; - /** - * Returns the transformation of viewer-relative coordinates to the - * screen. - * - * This matrix can be used as the projection matrix in legacy GL code. - */ + // + // Returns the transformation of viewer-relative coordinates to the + // screen. + // + // This matrix can be used as the projection matrix in legacy GL code. + // glm::mat4 getViewerScreenXform() const; // other useful information - /** - * Returns the size of a pixel in world space, that is the minimum - * in respect to x/y screen directions. - */ + // + // Returns the size of a pixel in world space, that is the minimum + // in respect to x/y screen directions. + // float getPixelSize() const; - /** - * Returns the frustum as used for the projection matrices. - * The result depdends on the bounds, eventually aspect correction - * for the current resolution, the perspective angle (specified in - * respect to diagonal) and zoom. - */ + // + // Returns the frustum as used for the projection matrices. + // The result depdends on the bounds, eventually aspect correction + // for the current resolution, the perspective angle (specified in + // respect to diagonal) and zoom. + // void getFrustum(glm::vec3& low, glm::vec3& high) const; - /** - * Returns the z-offset from the origin to where orientation ia - * applied. - */ - float getTransformOffset() const { return vec_bounds_high.z; } + // + // Returns the z-offset from the origin to where orientation ia + // applied. + // + float getTransformOffset() const { return _vecBoundsHigh.z; } - /** - * Returns the aspect ratio. - */ - float getAspectRatio() const { return val_height / val_width; } + // + // Returns the aspect ratio. + // + float getAspectRatio() const { return _valHeight / _valWidth; } }; #endif