<commit_before>#include <glbinding-aux/ContextInfo.h>
#include <glbinding-aux/debug.h>
#include <glbinding-aux/types_to_string.h>
#include <glbinding/Binding.h>
#include <glbinding/glbinding.h>

#include <glbinding/Version.h>
// Do not import namespace to prevent glbinding/QTOpenGL collision
#include <glbinding/gl/gl.h>

#include <globjects/globjects.h>

#include <Engine/RadiumEngine.hpp>

#include <Core/Asset/FileData.hpp>
#include <Core/Utils/StringUtils.hpp>
#include <Gui/Viewer/Viewer.hpp>

#include <iostream>

#include <QOpenGLContext>

#include <QMouseEvent>
#include <QPainter>
#include <QTimer>

#define STB_IMAGE_WRITE_IMPLEMENTATION
#include <stb/stb_image_write.h>

#include <Core/Containers/MakeShared.hpp>
#include <Core/Math/Math.hpp>
#include <Core/Utils/Color.hpp>
#include <Core/Utils/Log.hpp>
#include <Core/Utils/StringUtils.hpp>

#include <Engine/Data/ShaderProgramManager.hpp>
#include <Engine/Data/ViewingParameters.hpp>
#include <Engine/Rendering/ForwardRenderer.hpp>
#include <Engine/Rendering/Renderer.hpp>
#include <Engine/Scene/Camera.hpp>
#include <Engine/Scene/Component.hpp>
#include <Engine/Scene/DirLight.hpp>
#include <Engine/Scene/EntityManager.hpp>
#include <Engine/Scene/SystemDisplay.hpp>

#include <Gui/Utils/KeyMappingManager.hpp>
#include <Gui/Utils/Keyboard.hpp>
#include <Gui/Utils/PickingManager.hpp>

#include <Engine/Scene/Camera.hpp>
#include <Gui/Viewer/Gizmo/GizmoManager.hpp>
#include <Gui/Viewer/TrackballCameraManipulator.hpp>

namespace Ra {

using namespace Core::Utils; // log
using namespace glbinding;

using ViewerMapping = Gui::KeyMappingManageable<Gui::Viewer>;

#define KMA_VALUE( x ) Gui::KeyMappingManager::KeyMappingAction Gui::Viewer::x;
KeyMappingViewer
#undef KMA_VALUE

    // Register all keymapings related to the viewer and its managed functionalities (Trackball
    // camera, Gizmo, ..)
    void
    Gui::Viewer::setupKeyMappingCallbacks() {
    auto keyMappingManager = Gui::KeyMappingManager::getInstance();

    // Add default manipulator listener
    keyMappingManager->addListener( Gui::TrackballCameraManipulator::configureKeyMapping );
    // add viewer related listener
    keyMappingManager->addListener( Gui::GizmoManager::configureKeyMapping );
    keyMappingManager->addListener( configureKeyMapping );
}

void Gui::Viewer::configureKeyMapping_impl() {
    auto keyMappingManager = Gui::KeyMappingManager::getInstance();
    ViewerMapping::setContext( keyMappingManager->getContext( "ViewerContext" ) );
    if ( ViewerMapping::getContext().isInvalid() )
    {
        LOG( logINFO )
            << "ViewerContext not defined (maybe the configuration file do not contains it)";
        LOG( Ra::Core::Utils::logERROR ) << "ViewerContext all keymapping invalide !";
        return;
    }

#define KMA_VALUE( XX ) XX = keyMappingManager->getActionIndex( ViewerMapping::getContext(), #XX );
    KeyMappingViewer
#undef KMA_VALUE
}

Gui::Viewer::Viewer( QScreen* screen ) :
    WindowQt( screen ),
    m_currentRenderer( nullptr ),
    m_pickingManager( new PickingManager() ),
    m_isBrushPickingEnabled( false ),
    m_brushRadius( 10 ),
    m_camera( nullptr ),
    m_gizmoManager( nullptr ) {}

Gui::Viewer::~Viewer() {
    if ( m_glInitialized.load() )
    {
        makeCurrent();
        m_renderers.clear();

        delete m_gizmoManager;
        doneCurrent();
    }
}

void Gui::Viewer::setCameraManipulator( CameraManipulator* ci ) {
    m_camera.reset( ci );
}

Gui::CameraManipulator* Gui::Viewer::getCameraManipulator() {
    return m_camera.get();
}

void Gui::Viewer::setCamera( Engine::Scene::Camera* camera ) {
    m_camera->setCamera( camera );
}

Gui::GizmoManager* Gui::Viewer::getGizmoManager() {
    return m_gizmoManager;
}

const Engine::Rendering::Renderer* Gui::Viewer::getRenderer() const {
    return m_currentRenderer;
}

Engine::Rendering::Renderer* Gui::Viewer::getRenderer() {
    return m_currentRenderer;
}

int Gui::Viewer::addRenderer( const std::shared_ptr<Engine::Rendering::Renderer>& e ) {
    // initial state and lighting (deferred if GL is not ready yet)
    if ( m_glInitialized.load() )
    {
        LOG( logINFO ) << "[Viewer] New Renderer (" << e->getRendererName() << ") added.";
        makeCurrent();
        initializeRenderer( e.get() );
        doneCurrent();
    }
    else
    {
        LOG( logINFO ) << "[Viewer] New Renderer (" << e->getRendererName()
                       << ") added with deferred init.";
    }

    m_renderers.push_back( e );

    return m_renderers.size() - 1;
}

Gui::PickingManager* Gui::Viewer::getPickingManager() {
    return m_pickingManager;
}

void Gui::Viewer::update( const Scalar dt ) {
    CORE_UNUSED( dt );
    if ( m_gizmoManager != nullptr ) { m_gizmoManager->updateValues(); }
}

// Asynchronous rendering implementation

void Gui::Viewer::startRendering( const Scalar dt ) {

    CORE_ASSERT( m_glInitialized.load(), "OpenGL needs to be initialized before rendering." );

    CORE_ASSERT( m_currentRenderer != nullptr, "No renderer found." );

    m_pickingManager->clear();
    makeCurrent();

    // TODO : as soon as everything could be computed efficiently, activate z-bounds fitting.
    // For the moment (sept 2019), request of the scene bounding box is really inefficient (all is
    // recomputed, even if no change since last computation)
    // TODO : implement better management of UI and debug render objects so that the are drawn with
    // an adequate
    //  znear/zfar values
#if 0
    // update znear/zfar to fit the scene ...
    auto roManager = Engine::RadiumEngine::getInstance()->getRenderObjectManager();
    if (roManager) {
        // TODO : make the aabb only recomputed when needed. For now, getSceneAabb loop over scene vertices to (re)compute the aabb at each call.
        auto aabb = roManager->getSceneAabb();
        if ( !aabb.isEmpty() ) {
            // tight depth bounds
            m_camera->getCamera()->fitZRange(aabb);
        } else {
            // scene is empty, reset to defaults bounds ?
            m_camera->setCameraZNear(0.1);
            m_camera->setCameraZFar(100);
        }
    }
#endif

    // FIXME : move this outside of the rendering loop. must be done once per renderer ...
    // if there is no light on the renderer, add the head light attached to the camera ...
    if ( !m_currentRenderer->hasLight() )
    {
        if ( m_camera->hasLightAttached() )
            m_currentRenderer->addLight( m_camera->getLight() );
        else
            LOG( logDEBUG ) << "Unable to attach the head light!";
    }
    Engine::Data::ViewingParameters data {m_camera->getViewMatrix(), m_camera->getProjMatrix(), dt};
    m_currentRenderer->render( data );
}

void Gui::Viewer::swapBuffers() {
    if ( isExposed() ) { m_context->swapBuffers( this ); }
    doneCurrent();
}

void Gui::Viewer::processPicking() {<commit_msg>[gui] call z near z far update at each frame.<commit_after>#include <glbinding-aux/ContextInfo.h>
#include <glbinding-aux/debug.h>
#include <glbinding-aux/types_to_string.h>
#include <glbinding/Binding.h>
#include <glbinding/glbinding.h>

#include <glbinding/Version.h>
// Do not import namespace to prevent glbinding/QTOpenGL collision
#include <glbinding/gl/gl.h>

#include <globjects/globjects.h>

#include <Engine/RadiumEngine.hpp>

#include <Core/Asset/FileData.hpp>
#include <Core/Utils/StringUtils.hpp>
#include <Gui/Viewer/Viewer.hpp>

#include <iostream>

#include <QOpenGLContext>

#include <QMouseEvent>
#include <QPainter>
#include <QTimer>

#define STB_IMAGE_WRITE_IMPLEMENTATION
#include <stb/stb_image_write.h>

#include <Core/Containers/MakeShared.hpp>
#include <Core/Math/Math.hpp>
#include <Core/Utils/Color.hpp>
#include <Core/Utils/Log.hpp>
#include <Core/Utils/StringUtils.hpp>

#include <Engine/Data/ShaderProgramManager.hpp>
#include <Engine/Data/ViewingParameters.hpp>
#include <Engine/Rendering/ForwardRenderer.hpp>
#include <Engine/Rendering/Renderer.hpp>
#include <Engine/Scene/Camera.hpp>
#include <Engine/Scene/Component.hpp>
#include <Engine/Scene/DirLight.hpp>
#include <Engine/Scene/EntityManager.hpp>
#include <Engine/Scene/SystemDisplay.hpp>

#include <Gui/Utils/KeyMappingManager.hpp>
#include <Gui/Utils/Keyboard.hpp>
#include <Gui/Utils/PickingManager.hpp>

#include <Engine/Scene/Camera.hpp>
#include <Gui/Viewer/Gizmo/GizmoManager.hpp>
#include <Gui/Viewer/TrackballCameraManipulator.hpp>

namespace Ra {

using namespace Core::Utils; // log
using namespace glbinding;

using ViewerMapping = Gui::KeyMappingManageable<Gui::Viewer>;

#define KMA_VALUE( x ) Gui::KeyMappingManager::KeyMappingAction Gui::Viewer::x;
KeyMappingViewer
#undef KMA_VALUE

    // Register all keymapings related to the viewer and its managed functionalities (Trackball
    // camera, Gizmo, ..)
    void
    Gui::Viewer::setupKeyMappingCallbacks() {
    auto keyMappingManager = Gui::KeyMappingManager::getInstance();

    // Add default manipulator listener
    keyMappingManager->addListener( Gui::TrackballCameraManipulator::configureKeyMapping );
    // add viewer related listener
    keyMappingManager->addListener( Gui::GizmoManager::configureKeyMapping );
    keyMappingManager->addListener( configureKeyMapping );
}

void Gui::Viewer::configureKeyMapping_impl() {
    auto keyMappingManager = Gui::KeyMappingManager::getInstance();
    ViewerMapping::setContext( keyMappingManager->getContext( "ViewerContext" ) );
    if ( ViewerMapping::getContext().isInvalid() )
    {
        LOG( logINFO )
            << "ViewerContext not defined (maybe the configuration file do not contains it)";
        LOG( Ra::Core::Utils::logERROR ) << "ViewerContext all keymapping invalide !";
        return;
    }

#define KMA_VALUE( XX ) XX = keyMappingManager->getActionIndex( ViewerMapping::getContext(), #XX );
    KeyMappingViewer
#undef KMA_VALUE
}

Gui::Viewer::Viewer( QScreen* screen ) :
    WindowQt( screen ),
    m_currentRenderer( nullptr ),
    m_pickingManager( new PickingManager() ),
    m_isBrushPickingEnabled( false ),
    m_brushRadius( 10 ),
    m_camera( nullptr ),
    m_gizmoManager( nullptr ) {}

Gui::Viewer::~Viewer() {
    if ( m_glInitialized.load() )
    {
        makeCurrent();
        m_renderers.clear();

        delete m_gizmoManager;
        doneCurrent();
    }
}

void Gui::Viewer::setCameraManipulator( CameraManipulator* ci ) {
    m_camera.reset( ci );
}

Gui::CameraManipulator* Gui::Viewer::getCameraManipulator() {
    return m_camera.get();
}

void Gui::Viewer::setCamera( Engine::Scene::Camera* camera ) {
    m_camera->setCamera( camera );
}

Gui::GizmoManager* Gui::Viewer::getGizmoManager() {
    return m_gizmoManager;
}

const Engine::Rendering::Renderer* Gui::Viewer::getRenderer() const {
    return m_currentRenderer;
}

Engine::Rendering::Renderer* Gui::Viewer::getRenderer() {
    return m_currentRenderer;
}

int Gui::Viewer::addRenderer( const std::shared_ptr<Engine::Rendering::Renderer>& e ) {
    // initial state and lighting (deferred if GL is not ready yet)
    if ( m_glInitialized.load() )
    {
        LOG( logINFO ) << "[Viewer] New Renderer (" << e->getRendererName() << ") added.";
        makeCurrent();
        initializeRenderer( e.get() );
        doneCurrent();
    }
    else
    {
        LOG( logINFO ) << "[Viewer] New Renderer (" << e->getRendererName()
                       << ") added with deferred init.";
    }

    m_renderers.push_back( e );

    return m_renderers.size() - 1;
}

Gui::PickingManager* Gui::Viewer::getPickingManager() {
    return m_pickingManager;
}

void Gui::Viewer::update( const Scalar dt ) {
    CORE_UNUSED( dt );
    if ( m_gizmoManager != nullptr ) { m_gizmoManager->updateValues(); }
}

// Asynchronous rendering implementation

void Gui::Viewer::startRendering( const Scalar dt ) {

    CORE_ASSERT( m_glInitialized.load(), "OpenGL needs to be initialized before rendering." );

    CORE_ASSERT( m_currentRenderer != nullptr, "No renderer found." );

    m_pickingManager->clear();
    makeCurrent();

    // TODO : as soon as everything could be computed efficiently, activate z-bounds fitting.
    // For the moment (sept 2019), request of the scene bounding box is really inefficient (all is
    // recomputed, even if no change since last computation)
    // TODO : implement better management of UI and debug render objects so that the are drawn with
    // an adequate
    //  znear/zfar values
#if 1
    // update znear/zfar to fit the scene ...
    auto entityManager = Engine::RadiumEngine::getInstance()->getEntityManager();
    if ( entityManager )
    {
        Core::Aabb aabb;

        for ( const auto& entity : entityManager->getEntities() )
        {
            // transform is applied in ro aabb computation ...
            aabb.extend( entity->computeAabb() );
        }
        if ( !aabb.isEmpty() )
        {
            // tight depth boundsCM
            m_camera->getCamera()->fitZRange( aabb );
        }
        else
        {
            // scene is empty, reset to defaults bounds ?
            m_camera->setCameraZNear( 0.1 );
            m_camera->setCameraZFar( 100 );
        }
    }
#endif

    // FIXME : move this outside of the rendering loop. must be done once per renderer ...
    // if there is no light on the renderer, add the head light attached to the camera ...
    if ( !m_currentRenderer->hasLight() )
    {
        if ( m_camera->hasLightAttached() )
            m_currentRenderer->addLight( m_camera->getLight() );
        else
            LOG( logDEBUG ) << "Unable to attach the head light!";
    }
    Engine::Data::ViewingParameters data {m_camera->getViewMatrix(), m_camera->getProjMatrix(), dt};
    m_currentRenderer->render( data );
}

void Gui::Viewer::swapBuffers() {
    if ( isExposed() ) { m_context->swapBuffers( this ); }
    doneCurrent();
}

void Gui::Viewer::processPicking() {
{'fraction_non_alphanumeric': 0.12812545165486341, 'fraction_numerical': 0.0018788842318254082, 'mean_word_length': 3.715161839863714, 'pattern_counts': {'":': 0, '<': 119, '<?xml version=': 0, '>': 132, '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': '3188315', 'n_tokens_mistral': 4315, 'n_tokens_neox': 4264, 'n_words': 987}