<commit_before>#include "view.h"
#include "util/tileID.h"
#include "platform.h"
#include "glm/gtx/string_cast.hpp"

const int View::s_maxZoom; // Create a stack reference to the static member variable

View::View(int _width, int _height, ProjectionType _projType) {
    
    setMapProjection(_projType);
    setSize(_width, _height);
    setZoom(16); // Arbitrary zoom for testing
    setPosition(0.0, 0.0);
    
    m_changed = false;
    m_dirty = true;
    
}

void View::setMapProjection(ProjectionType _projType) {
    
    switch(_projType) {
        case ProjectionType::mercator:
            m_projection.reset(new MercatorProjection());
            break;
        default:
            logMsg("Error: not a valid map projection specified.\n Setting map projection to mercator by default");
            m_projection.reset(new MercatorProjection());
            break;
    }
    
    m_dirty = true;
    
}

const MapProjection& View::getMapProjection() {
    return *m_projection.get();
}

void View::setPixelScale(float _pixelsPerPoint) {
    
    m_pixelScale = _pixelsPerPoint;
    m_dirty = true;
    
}

void View::setSize(int _width, int _height) {

    m_vpWidth = _width;
    m_vpHeight = _height;
    m_aspect = (float)_width / (float)_height;
    m_dirty = true;

}

void View::setPosition(double _x, double _y) {

    translate(_x - m_pos.x, _y - m_pos.y);
    m_dirty = true;

}

void View::translate(double _dx, double _dy) {

    m_pos.x += _dx;
    m_pos.y += _dy;
    m_dirty = true;

}

void View::zoom(int _dz) {
    
    setZoom(m_zoom + _dz);
    m_dirty = true;
    
}

void View::setZoom(int _z) {

    // ensure zoom value is allowed
    m_zoom = glm::clamp(_z, 0, s_maxZoom);
    m_dirty = true;

}

void View::update() {
    
    if (!m_dirty) {
        return;
    }
    
    updateMatrices();
    
    updateTiles();
    
    m_dirty = false;
    
    m_changed = true;
    
}

const glm::dmat4 View::getViewProjectionMatrix() {
    
    return m_proj * m_view;
    
}

glm::dmat2 View::getBoundsRect() const {

    double hw = m_width * 0.5;
    double hh = m_height * 0.5;
    return glm::dmat2(m_pos.x - hw, m_pos.y - hh, m_pos.x + hw, m_pos.y + hh);

}

const std::set<TileID>& View::getVisibleTiles() {

    return m_visibleTiles;

}

bool View::changedSinceLastCheck() {
    
    if (m_changed) {
        m_changed = false;
        return true;
    }
    return false;
    
}

void View::updateMatrices() {
    
    // find dimensions of tiles in world space at new zoom level
    float worldTileSize = 2 * MapProjection::HALF_CIRCUMFERENCE * pow(2, -m_zoom);
    
    // viewport height in world space is such that each tile is [m_pixelsPerTile] px square in screen space
    float screenTileSize = m_pixelsPerTile * m_pixelScale;
    m_height = (float)m_vpHeight * worldTileSize / screenTileSize;
    m_width = m_height * m_aspect;
    
    // set vertical field-of-view
    double fovy = PI * 0.5;
    
    // we assume portrait orientation by default, so in landscape
    // mode we scale the vertical FOV such that the wider dimension
    // gets the intended FOV
    if (m_width > m_height) {
        fovy /= m_aspect;
    }
    
    // set camera z to produce desired viewable area
    m_pos.z = m_height * 0.5 / tan(fovy * 0.5);
    
    // set near clipping distance as a function of camera z
    // TODO: this is a simple heuristic that deserves more thought
    double near = m_pos.z / 50.0;
    
    // update view and projection matrices
    m_view = glm::lookAt(m_pos, m_pos + glm::dvec3(0, 0, -1), glm::dvec3(0, 1, 0));
    m_proj = glm::perspective(fovy, double(m_aspect), near, m_pos.z + 1.0);
    
}

void View::updateTiles() {
    
    m_visibleTiles.clear();
    
    float tileSize = 2 * MapProjection::HALF_CIRCUMFERENCE * pow(2, -m_zoom);
    float invTileSize = 1.0 / tileSize;
    
    float vpLeftEdge = m_pos.x - m_width * 0.5 + MapProjection::HALF_CIRCUMFERENCE;
    float vpRightEdge = vpLeftEdge + m_width;
    float vpBottomEdge = -m_pos.y - m_height * 0.5 + MapProjection::HALF_CIRCUMFERENCE;
    float vpTopEdge = vpBottomEdge + m_height;
    
    int tileX = (int) vpLeftEdge * invTileSize;
    int tileY = (int) vpBottomEdge * invTileSize;
    
    float x = tileX * tileSize;
    float y = tileY * tileSize;
    
    while (x < vpRightEdge) {
        
        if(tileX >= pow(2, m_zoom)) {
            break;
        }
        
        while (y < vpTopEdge) {
            
            if(tileY >= pow(2, m_zoom)) {
                break;
            }
            else if(tileX >= 0 && tileY >= 0) {
                m_visibleTiles.insert(TileID(tileX, tileY, m_zoom));
            }
            tileY++;
            y += tileSize;
            
        }
        
        tileY = (int) vpBottomEdge * invTileSize;
        y = tileY * tileSize;
        
        tileX++;
        x += tileSize;
    }

}<commit_msg>Simplifications to View logic<commit_after>#include "view.h"
#include "util/tileID.h"
#include "platform.h"
#include "glm/gtx/string_cast.hpp"

const int View::s_maxZoom; // Create a stack reference to the static member variable

View::View(int _width, int _height, ProjectionType _projType) {
    
    setMapProjection(_projType);
    setSize(_width, _height);
    setZoom(16); // Arbitrary zoom for testing
    setPosition(0.0, 0.0);
    
    m_changed = false;
    m_dirty = true;
    
}

void View::setMapProjection(ProjectionType _projType) {
    
    switch(_projType) {
        case ProjectionType::mercator:
            m_projection.reset(new MercatorProjection());
            break;
        default:
            logMsg("Error: not a valid map projection specified.\n Setting map projection to mercator by default");
            m_projection.reset(new MercatorProjection());
            break;
    }
    
    m_dirty = true;
    
}

const MapProjection& View::getMapProjection() {
    return *m_projection.get();
}

void View::setPixelScale(float _pixelsPerPoint) {
    
    m_pixelScale = _pixelsPerPoint;
    m_dirty = true;
    
}

void View::setSize(int _width, int _height) {

    m_vpWidth = _width;
    m_vpHeight = _height;
    m_aspect = (float)_width / (float)_height;
    m_dirty = true;

}

void View::setPosition(double _x, double _y) {

    m_pos.x = _x;
    m_pos.y = _y;
    m_dirty = true;

}

void View::setZoom(int _z) {
    
    // ensure zoom value is allowed
    m_zoom = glm::clamp(_z, 0, s_maxZoom);
    m_dirty = true;
    
}

void View::translate(double _dx, double _dy) {

    setPosition(m_pos.x + _dx, m_pos.y + _dy);

}

void View::zoom(int _dz) {
    
    setZoom(m_zoom + _dz);
    
}

void View::update() {
    
    if (!m_dirty) {
        return;
    }
    
    updateMatrices();
    
    updateTiles();
    
    m_dirty = false;
    
    m_changed = true;
    
}

const glm::dmat4 View::getViewProjectionMatrix() {
    
    return m_proj * m_view;
    
}

glm::dmat2 View::getBoundsRect() const {

    double hw = m_width * 0.5;
    double hh = m_height * 0.5;
    return glm::dmat2(m_pos.x - hw, m_pos.y - hh, m_pos.x + hw, m_pos.y + hh);

}

const std::set<TileID>& View::getVisibleTiles() {

    return m_visibleTiles;

}

bool View::changedSinceLastCheck() {
    
    if (m_changed) {
        m_changed = false;
        return true;
    }
    return false;
    
}

void View::updateMatrices() {
    
    // find dimensions of tiles in world space at new zoom level
    float worldTileSize = 2 * MapProjection::HALF_CIRCUMFERENCE * pow(2, -m_zoom);
    
    // viewport height in world space is such that each tile is [m_pixelsPerTile] px square in screen space
    float screenTileSize = m_pixelsPerTile * m_pixelScale;
    m_height = (float)m_vpHeight * worldTileSize / screenTileSize;
    m_width = m_height * m_aspect;
    
    // set vertical field-of-view
    double fovy = PI * 0.5;
    
    // we assume portrait orientation by default, so in landscape
    // mode we scale the vertical FOV such that the wider dimension
    // gets the intended FOV
    if (m_width > m_height) {
        fovy /= m_aspect;
    }
    
    // set camera z to produce desired viewable area
    m_pos.z = m_height * 0.5 / tan(fovy * 0.5);
    
    // set near clipping distance as a function of camera z
    // TODO: this is a simple heuristic that deserves more thought
    double near = m_pos.z / 50.0;
    
    // update view and projection matrices
    m_view = glm::lookAt(m_pos, m_pos + glm::dvec3(0, 0, -1), glm::dvec3(0, 1, 0));
    m_proj = glm::perspective(fovy, double(m_aspect), near, m_pos.z + 1.0);
    
}

void View::updateTiles() {
    
    m_visibleTiles.clear();
    
    float tileSize = 2 * MapProjection::HALF_CIRCUMFERENCE * pow(2, -m_zoom);
    float invTileSize = 1.0 / tileSize;
    
    float vpLeftEdge = m_pos.x - m_width * 0.5 + MapProjection::HALF_CIRCUMFERENCE;
    float vpRightEdge = vpLeftEdge + m_width;
    float vpBottomEdge = -m_pos.y - m_height * 0.5 + MapProjection::HALF_CIRCUMFERENCE;
    float vpTopEdge = vpBottomEdge + m_height;
    
    int tileX = (int) fmax(0, vpLeftEdge * invTileSize);
    int tileY = (int) fmax(0, vpBottomEdge * invTileSize);
    
    float x = tileX * tileSize;
    float y = tileY * tileSize;
    
    int maxTileIndex = pow(2, m_zoom);
    
    while (x < vpRightEdge && tileX < maxTileIndex) {
        
        while (y < vpTopEdge && tileY < maxTileIndex) {
            
            m_visibleTiles.insert(TileID(tileX, tileY, m_zoom));

            tileY++;
            y += tileSize;
            
        }
        
        tileY = (int) vpBottomEdge * invTileSize;
        y = tileY * tileSize;
        
        tileX++;
        x += tileSize;
    }

}
{'fraction_non_alphanumeric': 0.11015544041450777, 'fraction_numerical': 0.009637305699481865, 'mean_word_length': 2.3348306841741535, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1320398', 'n_tokens_mistral': 3483, 'n_tokens_neox': 3403, 'n_words': 828}