diff --git a/lib/app/include/app/application/renderer/proxy_wrapper.hpp b/lib/app/include/app/application/renderer/proxy_wrapper.hpp new file mode 100644 index 000000000..17cae3aec --- /dev/null +++ b/lib/app/include/app/application/renderer/proxy_wrapper.hpp @@ -0,0 +1,44 @@ +#ifndef __VTX_APP_APPLICATION_RENDERER_PROXY_WRAPPER__ +#define __VTX_APP_APPLICATION_RENDERER_PROXY_WRAPPER__ + +#include "app/application/renderer/renderer_accessor.hpp" +#include "app/application/system/renderer.hpp" +#include + +namespace VTX::App::Application::Renderer +{ + template + class ProxyWrapper + { + public: + class ProxyAccessor + { + friend ProxyWrapper; + + public: + T & proxy() { return _wrapper.proxy(); } + ~ProxyAccessor() = default; + + private: + ProxyAccessor( ProxyWrapper & p_wrapper ) : _wrapper( p_wrapper ), _rendererAccessor( App::RENDERER() ) {} + + Application::Renderer::RendererAccessor _rendererAccessor; + ProxyWrapper & _wrapper; + }; + + ProxyWrapper() {} + ProxyWrapper( std::unique_ptr & p_proxyPtr ) : _proxyPtr( std::move( p_proxyPtr ) ) {} + + void setProxy( std::unique_ptr & p_proxyPtr ) { _proxyPtr = std::move( p_proxyPtr ); } + bool isValid() { return _proxyPtr != nullptr; } + + ProxyAccessor accessor() { return ProxyAccessor( *this ); } + T & proxy() { return *_proxyPtr; } + const T & proxy() const { return *_proxyPtr; } + + private: + std::unique_ptr _proxyPtr = nullptr; + }; + +} // namespace VTX::App::Application::Renderer +#endif diff --git a/lib/app/include/app/application/renderer/renderer.hpp b/lib/app/include/app/application/renderer/renderer.hpp new file mode 100644 index 000000000..404cbca1a --- /dev/null +++ b/lib/app/include/app/application/renderer/renderer.hpp @@ -0,0 +1,23 @@ +#ifndef __VTX_APP_APPLICATION_RENDERER_RENDERER__ +#define __VTX_APP_APPLICATION_RENDERER_RENDERER__ + +#include +#include + +namespace VTX::App::Application::Renderer +{ + class Renderer + { + public: + Renderer() = default; + void init(); + + VTX::Renderer::Facade & get(); + const VTX::Renderer::Facade & get() const; + + private: + std::unique_ptr _rendererPtr = nullptr; + }; + +} // namespace VTX::App::Application::Renderer +#endif diff --git a/lib/app/include/app/application/renderer/renderer_accessor.hpp b/lib/app/include/app/application/renderer/renderer_accessor.hpp new file mode 100644 index 000000000..6568066f6 --- /dev/null +++ b/lib/app/include/app/application/renderer/renderer_accessor.hpp @@ -0,0 +1,34 @@ +#ifndef __VTX_APP_APPLICATION_RENDERER_RENDERER_ACCESSOR__ +#define __VTX_APP_APPLICATION_RENDERER_RENDERER_ACCESSOR__ + +#include "app/application/renderer/renderer.hpp" +#include +#include + +namespace VTX::App::Application::Renderer +{ + class RendererAccessor + { + public: + RendererAccessor( + Renderer & p_renderer, + const Util::Callback<> & p_onGet, + const Util::Callback<> & p_onRelease + ); + ~RendererAccessor(); + + Renderer & get(); + const Renderer & get() const; + + VTX::Renderer::Facade & facade(); + const VTX::Renderer::Facade & facade() const; + + private: + Renderer & _renderer; + + const Util::Callback<> & onGet; + const Util::Callback<> & onRelease; + }; + +} // namespace VTX::App::Application::Renderer +#endif diff --git a/lib/app/include/app/application/selection/selection.hpp b/lib/app/include/app/application/selection/selection.hpp index 85d3d3d0e..35bec929b 100644 --- a/lib/app/include/app/application/selection/selection.hpp +++ b/lib/app/include/app/application/selection/selection.hpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -287,17 +288,37 @@ namespace VTX::App::Application::Selection SelectionData & getSelectionData( const Component::Scene::Selectable & p_selectableComponent ); const SelectionData & getSelectionData( const Component::Scene::Selectable & p_selectableComponent ) const; + template + T & getSelectionData( const Component::Scene::Selectable & p_selectableComponent ) + { + return dynamic_cast( getSelectionData( p_selectableComponent ) ); + } + template + const T & getSelectionData( const Component::Scene::Selectable & p_selectableComponent ) const + { + return dynamic_cast( getSelectionData( p_selectableComponent ) ); + } template - SelectionData & getSelectionData( const C & p_component ) + SelectionData & getSelectionDataFromComponent( const C & p_component ) { return getSelectionData( MAIN_REGISTRY().getComponent( p_component ) ); } template - const SelectionData & getSelectionData( const C & p_component ) const + const SelectionData & getSelectionDataFromComponent( const C & p_component ) const { return getSelectionData( MAIN_REGISTRY().getComponent( p_component ) ); } + template + T & getSelectionDataFromComponent( const C & p_component ) + { + return getSelectionData( MAIN_REGISTRY().getComponent( p_component ) ); + } + template + const T & getSelectionDataFromComponent( const C & p_component ) const + { + return getSelectionData( MAIN_REGISTRY().getComponent( p_component ) ); + } inline size_t getCount() const { return _items.size(); } @@ -338,8 +359,9 @@ namespace VTX::App::Application::Selection std::string toString() const; - protected: - void _notifyDataChanged(); + Util::Callback onSelect; + Util::Callback onDeselect; + Util::Callback onCurrentObjectChange; private: SelectionDataSet _items = SelectionDataSet(); @@ -348,12 +370,8 @@ namespace VTX::App::Application::Selection const std::unique_ptr & _getSelectionDataPtr( const Component::Scene::Selectable & p_selectable ) const; - void _clearWithoutNotify(); - - // void _refreshMoleculeSelection( App::Old::Component::Chemistry::Molecule * const ); - - void _setCurrentObject( const SelectionData * const p_model, const bool p_notify = true ); - void _clearCurrentObject( const bool p_notify = true ); + void _setCurrentObject( const SelectionData * const p_model ); + void _clearCurrentObject(); }; } // namespace VTX::App::Application::Selection diff --git a/lib/app/include/app/application/selection/selection_manager.hpp b/lib/app/include/app/application/selection/selection_manager.hpp index b51f90ff2..17e43685e 100644 --- a/lib/app/include/app/application/selection/selection_manager.hpp +++ b/lib/app/include/app/application/selection/selection_manager.hpp @@ -33,6 +33,9 @@ namespace VTX::App::Application::Selection Selection & getSaved( const std::string & p_name ); private: + void _setCurrentSelection( const Selection & p_selection ); + void _linkCallbackToSelectables(); + std::unique_ptr _currentSelection = std::make_unique(); mutable std::map> _savedSelectionMap diff --git a/lib/app/include/app/application/system/renderer.hpp b/lib/app/include/app/application/system/renderer.hpp new file mode 100644 index 000000000..6da69c320 --- /dev/null +++ b/lib/app/include/app/application/system/renderer.hpp @@ -0,0 +1,37 @@ +#ifndef __VTX_APP_APPLICATION_SYSTEM_RENDERER__ +#define __VTX_APP_APPLICATION_SYSTEM_RENDERER__ + +#include "app/application/renderer/renderer.hpp" +#include "app/application/renderer/renderer_accessor.hpp" +#include "app/application/system/system_registration.hpp" +#include "app/core/system/base_system.hpp" +#include +#include + +namespace VTX::App::Application::System +{ + class Renderer : public Core::System::BaseSystem + { + public: + inline static const System::SystemRegistration SYSTEM = System::SystemRegistration(); + + public: + Renderer() = default; + Application::Renderer::RendererAccessor accessor(); + VTX::Renderer::Facade & facade(); + + Util::Callback<> onGet; + Util::Callback<> onRelease; + + private: + Application::Renderer::Renderer _renderer; + }; + +} // namespace VTX::App::Application::System + +namespace VTX::App +{ + Application::System::Renderer & RENDERER_SYSTEM(); + Application::Renderer::RendererAccessor RENDERER(); +} // namespace VTX::App +#endif diff --git a/lib/app/include/app/component/chemistry/bond.hpp b/lib/app/include/app/component/chemistry/bond.hpp index 5dd98a69e..d77f7e70d 100644 --- a/lib/app/include/app/component/chemistry/bond.hpp +++ b/lib/app/include/app/component/chemistry/bond.hpp @@ -25,6 +25,9 @@ namespace VTX::App::Component::Chemistry atom_index_t getIndexSecondAtom() const; void setIndexSecondAtom( const atom_index_t p_atomIndex ); + bool isVisible() const; + void setVisible( const bool p_visible ); + private: Molecule * _moleculePtr = nullptr; size_t _index = INVALID_INDEX; diff --git a/lib/app/include/app/component/chemistry/chain.hpp b/lib/app/include/app/component/chemistry/chain.hpp index b03c8a362..3ba1cda81 100644 --- a/lib/app/include/app/component/chemistry/chain.hpp +++ b/lib/app/include/app/component/chemistry/chain.hpp @@ -46,6 +46,11 @@ namespace VTX::App::Component::Chemistry Iterator::ResidueContainer residues() const; Iterator::AtomContainer atoms() const; + bool isVisible() const; + bool isFullyVisible() const; + + void setVisible( const bool p_visible ); + private: Molecule * _moleculePtr = nullptr; size_t _index = INVALID_INDEX; diff --git a/lib/app/include/app/component/chemistry/molecule.hpp b/lib/app/include/app/component/chemistry/molecule.hpp index 1e40dc5da..7245e7855 100644 --- a/lib/app/include/app/component/chemistry/molecule.hpp +++ b/lib/app/include/app/component/chemistry/molecule.hpp @@ -4,9 +4,11 @@ #include "_fwd.hpp" #include "app/application/system/ecs_system.hpp" #include "app/core/uid/uid.hpp" +#include #include #include #include +#include #include #include #include @@ -18,6 +20,10 @@ namespace VTX::App::Component::Render namespace VTX::App::Component::Chemistry { + + using AtomIndexRange = Util::Math::Range; + using AtomIndexRangeList = Util::Math::RangeList; + class Molecule { private: @@ -76,12 +82,16 @@ namespace VTX::App::Component::Chemistry const std::string & getPdbIdCode() const { return _pdbIdCode; } void setPdbIdCode( const std::string & p_pdbIdCode ) { _pdbIdCode = p_pdbIdCode; } - bool getAtomVisibility( const size_t p_index ) const { return _atomVisibilities[ p_index ]; } - void setAtomVisibility( const size_t p_index, const bool p_visible ) - { - _atomVisibilities[ p_index ] = p_visible; - } - const std::vector & getAtomVisibilities() const { return _atomVisibilities; } + bool isVisible() const; + bool isFullyVisible() const; + + void setVisible( const bool p_visible ); + void setVisible( const atom_index_t & p_atomId, bool p_visible ); + void setVisible( const AtomIndexRange & p_atomRange, bool p_visible ); + void setVisible( const AtomIndexRangeList & p_atomRange, bool p_visible ); + + const AtomIndexRangeList & getAtomVisibilities() const { return _visibleAtomIds; } + void setAtomVisibilities( const AtomIndexRangeList & p_visibility ); const Core::UID::UIDRange & getAtomUIDs() const { return _atomUidRange; } const Atom * getAtomFromUID( Core::UID::uid p_uid ) const; @@ -91,7 +101,8 @@ namespace VTX::App::Component::Chemistry const Residue * getResidueFromUID( Core::UID::uid p_uid ) const; Residue * getResidueFromUID( Core::UID::uid p_uid ); - Util::Callback<> onStruct; + Util::Callback<> onStruct; + Util::Callback onVisibilityChange; private: VTX::Core::Struct::Molecule _moleculeStruct = VTX::Core::Struct::Molecule(); @@ -104,8 +115,7 @@ namespace VTX::App::Component::Chemistry Util::Math::Transform _transform = Util::Math::Transform(); std::string _pdbIdCode = ""; - std::vector _atomVisibilities = std::vector(); - std::vector _atomSelections = std::vector(); + AtomIndexRangeList _visibleAtomIds = AtomIndexRangeList(); Core::UID::UIDRange _atomUidRange = Core::UID::UIDRange(); Core::UID::UIDRange _residueUidRange = Core::UID::UIDRange(); diff --git a/lib/app/include/app/component/chemistry/residue.hpp b/lib/app/include/app/component/chemistry/residue.hpp index cd76313e1..882176438 100644 --- a/lib/app/include/app/component/chemistry/residue.hpp +++ b/lib/app/include/app/component/chemistry/residue.hpp @@ -63,6 +63,11 @@ namespace VTX::App::Component::Chemistry Iterator::AtomContainer atoms() const; + bool isVisible() const; + bool isFullyVisible() const; + + void setVisible( const bool p_visible ); + private: Molecule * _moleculePtr = nullptr; size_t _index = INVALID_INDEX; diff --git a/lib/app/include/app/component/chemistry/trajectory.hpp b/lib/app/include/app/component/chemistry/trajectory.hpp index 619267246..456a20abe 100644 --- a/lib/app/include/app/component/chemistry/trajectory.hpp +++ b/lib/app/include/app/component/chemistry/trajectory.hpp @@ -5,6 +5,7 @@ #include "app/application/system/ecs_system.hpp" #include "app/core/trajectory_player/base_player.hpp" #include "enum_trajectory.hpp" +#include namespace VTX::App::Component::Chemistry { @@ -23,11 +24,15 @@ namespace VTX::App::Component::Chemistry Molecule * const getMoleculePtr() const { return _moleculePtr; } size_t getCurrentFrame() const; + void setCurrentFrame( const size_t p_frameIndex ); + size_t getFrameCount() const; App::Core::TrajectoryPlayer::BasePlayer & getPlayer() const { return *_player; } void setPlayer( std::unique_ptr & p_player ); + Util::Callback onFrameChange; + private: void _update( const float p_deltaTime ); void _referenceUpdateFunction(); diff --git a/lib/app/include/app/component/render/proxy_camera.hpp b/lib/app/include/app/component/render/proxy_camera.hpp index 29c369c76..0943bcaef 100644 --- a/lib/app/include/app/component/render/proxy_camera.hpp +++ b/lib/app/include/app/component/render/proxy_camera.hpp @@ -1,8 +1,9 @@ #ifndef __VTX_APP_COMPONENT_RENDER_PROXY_CAMERA__ #define __VTX_APP_COMPONENT_RENDER_PROXY_CAMERA__ -#include "app/component/render/camera.hpp" +#include "app/application/renderer/proxy_wrapper.hpp" #include +#include #include namespace VTX::App::Component::Render @@ -11,16 +12,15 @@ namespace VTX::App::Component::Render { public: ProxyCamera(); - void init(); + ~ProxyCamera(); - VTX::Renderer::Proxy::Camera & getProxy() { return *_proxyPtr; } - const VTX::Renderer::Proxy::Camera & getProxy() const { return *_proxyPtr; } + void setInRenderer( Renderer::Facade & p_renderer ); private: void _generateProxy(); void _initCallbacks(); - std::unique_ptr _proxyPtr = nullptr; + Application::Renderer::ProxyWrapper _proxyWrapper; }; } // namespace VTX::App::Component::Render diff --git a/lib/app/include/app/component/render/proxy_molecule.hpp b/lib/app/include/app/component/render/proxy_molecule.hpp index 4437d1fef..f2c346f9f 100644 --- a/lib/app/include/app/component/render/proxy_molecule.hpp +++ b/lib/app/include/app/component/render/proxy_molecule.hpp @@ -1,11 +1,12 @@ #ifndef __VTX_APP_COMPONENT_RENDER_PROXY_MOLECULE__ #define __VTX_APP_COMPONENT_RENDER_PROXY_MOLECULE__ +#include "app/application/renderer/proxy_wrapper.hpp" #include "app/component/chemistry/molecule.hpp" +#include "app/core/visibility/enum.hpp" #include -#include +#include #include -#include #include #include @@ -15,19 +16,30 @@ namespace VTX::App::Component::Render { public: ProxyMolecule(); - void init(); + ~ProxyMolecule(); - VTX::Renderer::Proxy::Molecule & getProxy() { return *_proxyPtr; } - const VTX::Renderer::Proxy::Molecule & getProxy() const { return *_proxyPtr; } + void setup( Renderer::Facade & p_renderer ); private: - std::vector generateAtomColors( const VTX::Core::Struct::Molecule & p_molStruct ) const; - std::vector generateAtomRadii( const VTX::Core::Struct::Molecule & p_molStruct ) const; - std::vector generateAtomUids( const Component::Chemistry::Molecule & p_molComp ) const; - std::vector generateResidueColors( const VTX::Core::Struct::Molecule & p_molStruct ) const; - std::vector generateResidueUids( const Component::Chemistry::Molecule & p_molComp ) const; + void _addInRenderer( Renderer::Facade & p_renderer ); + void _setupCallbacks(); - std::unique_ptr _proxyPtr = nullptr; + std::vector _generateAtomColors( const VTX::Core::Struct::Molecule & p_molStruct ) const; + std::vector _generateAtomRadii( const VTX::Core::Struct::Molecule & p_molStruct ) const; + std::vector _generateAtomUids( const Component::Chemistry::Molecule & p_molComp ) const; + std::vector _generateResidueColors( const VTX::Core::Struct::Molecule & p_molStruct ) const; + std::vector _generateResidueUids( const Component::Chemistry::Molecule & p_molComp ) const; + + void _applyOnVisibility( + const Component::Chemistry::AtomIndexRangeList & p_rangeList, + const App::Core::VISIBILITY_APPLY_MODE p_applyMode + ); + + void _applyVisibilityCallbacks(); + void _applySelectionCallbacks(); + void _applyAtomPositionCallbacks(); + + Application::Renderer::ProxyWrapper _proxyWrapper; }; } // namespace VTX::App::Component::Render diff --git a/lib/app/include/app/component/scene/pickable.hpp b/lib/app/include/app/component/scene/pickable.hpp index 75be10abb..757c46a65 100644 --- a/lib/app/include/app/component/scene/pickable.hpp +++ b/lib/app/include/app/component/scene/pickable.hpp @@ -14,6 +14,12 @@ namespace VTX::App::Component::Scene class Pickable : public Core::ECS::BaseComponent { public: + enum PickType + { + SET, + TOGGLE + }; + using PickableFunc = std::function< std::unique_ptr( const Application::Selection::PickingInfo & )>; @@ -26,15 +32,14 @@ namespace VTX::App::Component::Scene Pickable(); ~Pickable(); - void pick( - const Application::Selection::PickingInfo & p_ids, - const Application::Selection::AssignmentType & p_assignmentType - ) const; + void pick( const Application::Selection::PickingInfo & p_ids, const PickType p_pickType ) const; bool isSelected( const Core::UID::uid & p_uid ) const; void setPickingFunction( PickableFunc p_pickableFunc ) { _pickableFunc = p_pickableFunc; }; private: + bool _isSelectionDataSelected( const Application::Selection::SelectionData & p_selectionData ) const; + PickableFunc _pickableFunc; }; } // namespace VTX::App::Component::Scene diff --git a/lib/app/include/app/component/scene/selectable.hpp b/lib/app/include/app/component/scene/selectable.hpp index 0a6f6c7e8..e08060872 100644 --- a/lib/app/include/app/component/scene/selectable.hpp +++ b/lib/app/include/app/component/scene/selectable.hpp @@ -7,6 +7,7 @@ #include "app/core/ecs/base_component.hpp" #include #include +#include namespace VTX::App::Component::Scene { @@ -37,10 +38,13 @@ namespace VTX::App::Component::Scene std::unique_ptr instantiateSelectionData() const; - private: - SelectionDataGenerator _selectionDataGenerator; + Util::Callback onSelect; + Util::Callback onDeselect; + private: std::unique_ptr _defaultSelectionDataGenerator(); + + SelectionDataGenerator _selectionDataGenerator; }; } // namespace VTX::App::Component::Scene #endif diff --git a/lib/app/include/app/core/trajectory_player/base_player.hpp b/lib/app/include/app/core/trajectory_player/base_player.hpp index 70fe59873..1cf7fa49d 100644 --- a/lib/app/include/app/core/trajectory_player/base_player.hpp +++ b/lib/app/include/app/core/trajectory_player/base_player.hpp @@ -1,10 +1,11 @@ #ifndef __VTX_APP_CORE_TRAJECTORY_PLAYER_BASE_PLAYER__ #define __VTX_APP_CORE_TRAJECTORY_PLAYER_BASE_PLAYER__ +#include "app/component/chemistry/_fwd.hpp" #include "app/core/collection.hpp" -#include #include #include +#include #include namespace VTX::App::Core::TrajectoryPlayer @@ -14,16 +15,14 @@ namespace VTX::App::Core::TrajectoryPlayer public: BasePlayer() = default; BasePlayer( const BasePlayer & p_source ) = default; - BasePlayer( VTX::Core::Struct::Trajectory * const p_trajectory ) : _trajectoryPtr( p_trajectory ) {} virtual ~BasePlayer() = default; - bool isLinkedToTrajectory() const { return _trajectoryPtr != nullptr; } - void setTrajectory( VTX::Core::Struct::Trajectory & p_trajectory ); + size_t getCount() const { return _count; } + void setCount( const size_t p_count ); - size_t getCurrentFrameIndex() const; - void setCurrentFrameIndex( const size_t p_frameIndex ); - size_t getFrameCount() const; + size_t getCurrent() const; + void setCurrent( const size_t p_frameIndex ); virtual void play(); virtual void pause(); @@ -43,8 +42,15 @@ namespace VTX::App::Core::TrajectoryPlayer virtual const std::string & getDisplayName() const = 0; virtual const CollectionKey & getCollectionKey() const = 0; + Util::Callback<> onPlay; + Util::Callback<> onPause; + Util::Callback<> onStop; + Util::Callback onFrameChange; + Util::Callback onFPSChange; + private: - VTX::Core::Struct::Trajectory * _trajectoryPtr = nullptr; + size_t _count = 0; + size_t _current = 0; bool _isPlaying = true; uint _fps = 1u; diff --git a/lib/app/include/app/core/trajectory_player/loop.hpp b/lib/app/include/app/core/trajectory_player/loop.hpp index fdae70faa..27ad1d275 100644 --- a/lib/app/include/app/core/trajectory_player/loop.hpp +++ b/lib/app/include/app/core/trajectory_player/loop.hpp @@ -1,9 +1,7 @@ #ifndef __VTX_APP_CORE_TRAJECTORY_PLAYER_LOOP__ #define __VTX_APP_CORE_TRAJECTORY_PLAYER_LOOP__ -#include "app/core/collection.hpp" #include "base_player.hpp" -#include "ping_pong.hpp" #include "players.hpp" namespace VTX::App::Core::TrajectoryPlayer @@ -20,7 +18,6 @@ namespace VTX::App::Core::TrajectoryPlayer public: Loop() = default; Loop( const Loop & p_source ) = default; - Loop( VTX::Core::Struct::Trajectory * const p_trajectory ); const std::string & getDisplayName() const override { return DISPLAYED_NAME; } const CollectionKey & getCollectionKey() const override { return COLLECTION_ID; } diff --git a/lib/app/include/app/core/trajectory_player/once.hpp b/lib/app/include/app/core/trajectory_player/once.hpp index 31ca90fcd..ed9eca589 100644 --- a/lib/app/include/app/core/trajectory_player/once.hpp +++ b/lib/app/include/app/core/trajectory_player/once.hpp @@ -3,7 +3,6 @@ #include "base_player.hpp" #include "players.hpp" -#include namespace VTX::App::Core::TrajectoryPlayer { @@ -19,7 +18,6 @@ namespace VTX::App::Core::TrajectoryPlayer public: Once() = default; Once( const Once & p_source ) = default; - Once( VTX::Core::Struct::Trajectory * const p_trajectory ); const std::string & getDisplayName() const override { return DISPLAYED_NAME; } const CollectionKey & getCollectionKey() const override { return COLLECTION_ID; } diff --git a/lib/app/include/app/core/trajectory_player/ping_pong.hpp b/lib/app/include/app/core/trajectory_player/ping_pong.hpp index 33b9de475..abdc2708b 100644 --- a/lib/app/include/app/core/trajectory_player/ping_pong.hpp +++ b/lib/app/include/app/core/trajectory_player/ping_pong.hpp @@ -3,7 +3,6 @@ #include "base_player.hpp" #include "players.hpp" -#include namespace VTX::App::Core::TrajectoryPlayer { @@ -19,7 +18,6 @@ namespace VTX::App::Core::TrajectoryPlayer public: PingPong() = default; PingPong( const PingPong & p_source ) = default; - PingPong( VTX::Core::Struct::Trajectory * const p_trajectory ); const std::string & getDisplayName() const override { return DISPLAYED_NAME; } const CollectionKey & getCollectionKey() const override { return COLLECTION_ID; } diff --git a/lib/app/include/app/core/trajectory_player/revert_loop.hpp b/lib/app/include/app/core/trajectory_player/revert_loop.hpp index cf2abbaa7..2cff1700a 100644 --- a/lib/app/include/app/core/trajectory_player/revert_loop.hpp +++ b/lib/app/include/app/core/trajectory_player/revert_loop.hpp @@ -3,7 +3,6 @@ #include "base_player.hpp" #include "players.hpp" -#include namespace VTX::App::Core::TrajectoryPlayer { @@ -19,7 +18,6 @@ namespace VTX::App::Core::TrajectoryPlayer public: RevertLoop() = default; RevertLoop( const RevertLoop & p_source ) = default; - RevertLoop( VTX::Core::Struct::Trajectory * const p_trajectory ); const std::string & getDisplayName() const override { return DISPLAYED_NAME; } const CollectionKey & getCollectionKey() const override { return COLLECTION_ID; } diff --git a/lib/app/include/app/core/trajectory_player/revert_once.hpp b/lib/app/include/app/core/trajectory_player/revert_once.hpp index 8d46edfb3..5ba1520c1 100644 --- a/lib/app/include/app/core/trajectory_player/revert_once.hpp +++ b/lib/app/include/app/core/trajectory_player/revert_once.hpp @@ -3,7 +3,6 @@ #include "base_player.hpp" #include "players.hpp" -#include namespace VTX::App::Core::TrajectoryPlayer { @@ -19,7 +18,6 @@ namespace VTX::App::Core::TrajectoryPlayer public: RevertOnce() = default; RevertOnce( const RevertOnce & p_source ) = default; - RevertOnce( VTX::Core::Struct::Trajectory * const p_trajectory ); const std::string & getDisplayName() const override { return DISPLAYED_NAME; } const CollectionKey & getCollectionKey() const override { return COLLECTION_ID; } diff --git a/lib/app/include/app/core/trajectory_player/stop.hpp b/lib/app/include/app/core/trajectory_player/stop.hpp index 759f347fb..b58694a18 100644 --- a/lib/app/include/app/core/trajectory_player/stop.hpp +++ b/lib/app/include/app/core/trajectory_player/stop.hpp @@ -3,7 +3,6 @@ #include "base_player.hpp" #include "players.hpp" -#include namespace VTX::App::Core::TrajectoryPlayer { @@ -19,7 +18,6 @@ namespace VTX::App::Core::TrajectoryPlayer public: Stop(); Stop( const Stop & p_source ); - Stop( VTX::Core::Struct::Trajectory * const p_trajectory ); void play() override; diff --git a/lib/app/include/app/core/visibility/enum.hpp b/lib/app/include/app/core/visibility/enum.hpp new file mode 100644 index 000000000..4bc912650 --- /dev/null +++ b/lib/app/include/app/core/visibility/enum.hpp @@ -0,0 +1,13 @@ +#ifndef __VTX_APP_CORE_VISIBILITY_ENUM__ +#define __VTX_APP_CORE_VISIBILITY_ENUM__ + +namespace VTX::App::Core +{ + enum class VISIBILITY_APPLY_MODE + { + SHOW, + HIDE, + SET + }; +} // namespace VTX::App::Core +#endif diff --git a/lib/app/include/app/vtx_app.hpp b/lib/app/include/app/vtx_app.hpp index b0a6c5bc9..37170c6a2 100644 --- a/lib/app/include/app/vtx_app.hpp +++ b/lib/app/include/app/vtx_app.hpp @@ -12,87 +12,73 @@ #include #include -namespace VTX +namespace VTX::App { - namespace Renderer + class VTXApp final : public Util::Generic::BaseStaticSingleton { - class Facade; - } - - namespace App - { - class VTXApp final : public Util::Generic::BaseStaticSingleton + private: + inline static const Util::Hashing::Hash SETTINGS_KEY = Util::Hashing::hash( "SETTINGS" ); + inline static const Util::Hashing::Hash SCENE_KEY = Util::Hashing::hash( "SCENE" ); + + public: + VTXApp( StructPrivacyToken ); + VTXApp( std::initializer_list ) = delete; + VTXApp( const VTXApp & ) = delete; + VTXApp & operator=( const VTXApp & ) = delete; + ~VTXApp(); + + void start( const std::vector & ); + void update( const float p_elapsedTime = 0 ); + void goToState( const std::string &, void * const = nullptr ); + void stop(); + + inline const Core::System::SystemHandler & getSystemHandler() const { return *_systemHandlerPtr; }; + inline Core::System::SystemHandler & getSystemHandler() { return *_systemHandlerPtr; }; + + inline std::shared_ptr & getSystemHandlerPtr() { return _systemHandlerPtr; }; + inline void referenceSystemHandler( std::shared_ptr p_systemHandlerPtr ) { - private: - inline static const Util::Hashing::Hash SETTINGS_KEY = Util::Hashing::hash( "SETTINGS" ); - inline static const Util::Hashing::Hash SCENE_KEY = Util::Hashing::hash( "SCENE" ); - - public: - VTXApp( StructPrivacyToken ); - VTXApp( std::initializer_list ) = delete; - VTXApp( const VTXApp & ) = delete; - VTXApp & operator=( const VTXApp & ) = delete; - ~VTXApp(); - - void start( const std::vector & ); - void update( const float p_elapsedTime = 0 ); - void goToState( const std::string &, void * const = nullptr ); - void stop(); - - inline const Core::System::SystemHandler & getSystemHandler() const { return *_systemHandlerPtr; }; - inline Core::System::SystemHandler & getSystemHandler() { return *_systemHandlerPtr; }; - - inline std::shared_ptr & getSystemHandlerPtr() { return _systemHandlerPtr; }; - inline void referenceSystemHandler( std::shared_ptr p_systemHandlerPtr ) - { - _systemHandlerPtr = p_systemHandlerPtr; - }; - - const Core::Monitoring::Stats & getStats() const { return _stats; } - Core::Monitoring::Stats & getStats() { return _stats; } - - Application::Scene & getScene(); - const Application::Scene & getScene() const; + _systemHandlerPtr = p_systemHandlerPtr; + }; - inline Renderer::Facade & getRenderer() { return *_renderer; } - inline const Renderer::Facade & getRenderer() const { return *_renderer; } + const Core::Monitoring::Stats & getStats() const { return _stats; } + Core::Monitoring::Stats & getStats() { return _stats; } - Application::Settings & getSettings(); - const Application::Settings & getSettings() const; + Application::Scene & getScene(); + const Application::Scene & getScene() const; - Util::Callback onPreUpdate; - Util::Callback onUpdate; - Util::Callback onLateUpdate; - Util::Callback onPostUpdate; + Application::Settings & getSettings(); + const Application::Settings & getSettings() const; - Util::Callback onPreRender; - Util::Callback onRender; - Util::Callback onPostRender; + Util::Callback onPreUpdate; + Util::Callback onUpdate; + Util::Callback onLateUpdate; + Util::Callback onPostUpdate; - Util::Callback<> onEndOfFrameOneShot; + Util::Callback onPreRender; + Util::Callback onRender; + Util::Callback onPostRender; - private: - Util::Chrono _tickChrono = Util::Chrono(); + Util::Callback<> onEndOfFrameOneShot; - std::shared_ptr _systemHandlerPtr - = std::make_shared(); + private: + Util::Chrono _tickChrono = Util::Chrono(); - std::unique_ptr _renderer; + std::shared_ptr _systemHandlerPtr + = std::make_shared(); - std::unique_ptr _settings; + std::unique_ptr _settings; - Core::Monitoring::Stats _stats; + Core::Monitoring::Stats _stats; - void _handleArgs( const std::vector & ); - void _update( const float p_elapsedTime ); - void _stop(); - }; + void _handleArgs( const std::vector & ); + void _update( const float p_elapsedTime ); + void _stop(); + }; - // Convenient accessors - Application::Scene & SCENE(); - Renderer::Facade & RENDERER(); - Application::Settings & SETTINGS(); - } // namespace App -} // namespace VTX + // Convenient accessors + Application::Scene & SCENE(); + Application::Settings & SETTINGS(); +} // namespace VTX::App #endif diff --git a/lib/app/src/app/application/renderer/renderer.cpp b/lib/app/src/app/application/renderer/renderer.cpp new file mode 100644 index 000000000..bf32b858a --- /dev/null +++ b/lib/app/src/app/application/renderer/renderer.cpp @@ -0,0 +1,15 @@ +#include "app/application/renderer/renderer.hpp" +#include + +namespace VTX::App::Application::Renderer +{ + void Renderer::init() + { + const FilePath shaderDir = Util::Filesystem::getExecutableDir() / "shaders"; + _rendererPtr = std::make_unique( 1920, 1080, shaderDir ); + } + + VTX::Renderer::Facade & Renderer::get() { return *_rendererPtr; } + const VTX::Renderer::Facade & Renderer::get() const { return *_rendererPtr; } + +} // namespace VTX::App::Application::Renderer diff --git a/lib/app/src/app/application/renderer/renderer_accessor.cpp b/lib/app/src/app/application/renderer/renderer_accessor.cpp new file mode 100644 index 000000000..1a3d66f1d --- /dev/null +++ b/lib/app/src/app/application/renderer/renderer_accessor.cpp @@ -0,0 +1,21 @@ +#include "app/application/renderer/renderer_accessor.hpp" + +namespace VTX::App::Application::Renderer +{ + RendererAccessor::RendererAccessor( + Renderer & p_renderer, + const Util::Callback<> & p_onGet, + const Util::Callback<> & p_onRelease + ) : + _renderer( p_renderer ), + onGet( p_onGet ), onRelease( p_onRelease ) + { + onGet(); + } + RendererAccessor::~RendererAccessor() { onRelease(); } + + Renderer & RendererAccessor::get() { return _renderer; } + const Renderer & RendererAccessor::get() const { return _renderer; } + VTX::Renderer::Facade & RendererAccessor::facade() { return _renderer.get(); } + const VTX::Renderer::Facade & RendererAccessor::facade() const { return _renderer.get(); } +} // namespace VTX::App::Application::Renderer diff --git a/lib/app/src/app/application/selection/molecule_data.cpp b/lib/app/src/app/application/selection/molecule_data.cpp index d91e3b5b4..44b8a544a 100644 --- a/lib/app/src/app/application/selection/molecule_data.cpp +++ b/lib/app/src/app/application/selection/molecule_data.cpp @@ -34,7 +34,10 @@ namespace VTX::App::Application::Selection && _residueIds == castedOther._residueIds && _atomIds == castedOther._atomIds; } - bool MoleculeData::isValid() const { return _chainIds.size() > 0 || _residueIds.size() > 0 || _atomIds.size() > 0; } + bool MoleculeData::isValid() const + { + return !( _chainIds.isEmpty() && _residueIds.isEmpty() && _atomIds.isEmpty() ); + } std::unique_ptr MoleculeData::_cloneImpl() const { @@ -149,13 +152,29 @@ namespace VTX::App::Application::Selection setCurrentObject( *_molecule ); } - bool MoleculeData::isFullySelected() const { return _atomIds.size() == _molecule->getAtoms().size(); } + bool MoleculeData::isFullySelected() const { return _atomIds.count() == _molecule->getAtoms().size(); } // Chains //////////////////////////////////////////////////////////////////////////////////////// - void MoleculeData::referenceChain( const Chain & p_chain ) { _referenceChain( p_chain ); } - void MoleculeData::selectFullChain( const Chain & p_chain ) { _selectFullChain( p_chain ); } - void MoleculeData::referenceChains( const IndexRange & p_range ) { _referenceChains( p_range ); } - void MoleculeData::selectFullChains( const IndexRange & p_range ) { _selectFullChains( p_range ); } + void MoleculeData::referenceChain( const Chain & p_chain ) + { + _referenceChain( p_chain ); + setCurrentObject( p_chain ); + } + void MoleculeData::selectFullChain( const Chain & p_chain ) + { + _selectFullChain( p_chain ); + setCurrentObject( p_chain ); + } + void MoleculeData::referenceChains( const IndexRange & p_range ) + { + _referenceChains( p_range ); + setCurrentObject( *_molecule->getChain( p_range.getLast() ) ); + } + void MoleculeData::selectFullChains( const IndexRange & p_range ) + { + _selectFullChains( p_range ); + setCurrentObject( *_molecule->getChain( p_range.getLast() ) ); + } void MoleculeData::referenceChains( const IndexRangeList & p_rangeList ) { for ( const size_t index : p_rangeList ) @@ -165,6 +184,8 @@ namespace VTX::App::Application::Selection if ( chainPtr != nullptr ) _referenceChain( *chainPtr ); } + + setCurrentObject( *_molecule->getChain( p_rangeList.getLast() ) ); } void MoleculeData::selectFullChains( const IndexRangeList & p_rangeList ) { @@ -175,20 +196,32 @@ namespace VTX::App::Application::Selection if ( chainPtr != nullptr ) _selectFullChain( *chainPtr ); } + + setCurrentObject( *_molecule->getChain( p_rangeList.getLast() ) ); } - void MoleculeData::unselectChain( const Chain & p_chain ) { _unselectChain( p_chain ); } + void MoleculeData::unselectChain( const Chain & p_chain ) + { + _unselectChain( p_chain ); + _refreshCurrentObject(); + } void MoleculeData::unselectChain( const size_t p_chainIndex ) { unselectChain( *_molecule->getChain( p_chainIndex ) ); + _refreshCurrentObject(); + } + void MoleculeData::unselectChains( const IndexRange & p_chains ) + { + _unselectChains( p_chains ); + _refreshCurrentObject(); } - void MoleculeData::unselectChains( const IndexRange & p_chains ) { _unselectChains( p_chains ); } void MoleculeData::unselectChains( const IndexRangeList & p_chain ) { for ( auto it = p_chain.rangeBegin(); it != p_chain.rangeEnd(); ++it ) { _unselectChains( *it ); } + _refreshCurrentObject(); } void MoleculeData::unselectChains( const std::initializer_list & p_chains ) { @@ -197,13 +230,16 @@ namespace VTX::App::Application::Selection if ( chainPtr != nullptr ) _unselectChain( *chainPtr ); } + _refreshCurrentObject(); } void MoleculeData::unselectChains( const std::initializer_list & p_chains ) { for ( const size_t chainIndex : p_chains ) { - unselectChain( chainIndex ); + _unselectChain( *_molecule->getChain( chainIndex ) ); } + + _refreshCurrentObject(); } bool MoleculeData::isChainSelected( const size_t & p_chainIndex ) const @@ -290,11 +326,15 @@ namespace VTX::App::Application::Selection { _referenceChain( *p_residue.getConstChainPtr() ); _referenceResidue( p_residue ); + + setCurrentObject( p_residue ); } void MoleculeData::selectFullResidue( const Residue & p_residue ) { _referenceChain( *p_residue.getConstChainPtr() ); _selectFullResidue( p_residue ); + + setCurrentObject( p_residue ); } void MoleculeData::referenceResidues( const IndexRange & p_range ) { @@ -303,8 +343,14 @@ namespace VTX::App::Application::Selection _referenceChains( IndexRange::createFirstLast( firstChainIndex, lastChainIndex ) ); _referenceResidues( p_range ); + + setCurrentObject( *( _molecule->getResidue( p_range.getLast() ) ) ); + } + void MoleculeData::selectFullResidues( const IndexRange & p_range ) + { + _selectFullResidues( p_range ); + setCurrentObject( *( _molecule->getResidue( p_range.getLast() ) ) ); } - void MoleculeData::selectFullResidues( const IndexRange & p_range ) { _selectFullResidues( p_range ); } void MoleculeData::referenceResidues( const IndexRangeList & p_rangeList ) { for ( const size_t index : p_rangeList ) @@ -315,6 +361,8 @@ namespace VTX::App::Application::Selection if ( residuePtr != nullptr ) _referenceResidue( *residuePtr ); } + + setCurrentObject( *( _molecule->getResidue( p_rangeList.getLast() ) ) ); } void MoleculeData::selectFullResidues( const IndexRangeList & p_rangeList ) { @@ -326,14 +374,25 @@ namespace VTX::App::Application::Selection if ( residuePtr != nullptr ) _selectFullResidue( *residuePtr ); } + + setCurrentObject( *( _molecule->getResidue( p_rangeList.getLast() ) ) ); } - void MoleculeData::unselectResidue( const Residue & p_residue ) { _unselectResidue( p_residue ); } + void MoleculeData::unselectResidue( const Residue & p_residue ) + { + _unselectResidue( p_residue ); + _refreshCurrentObject(); + } void MoleculeData::unselectResidue( const size_t p_residueIndex ) { _unselectResidue( *_molecule->getResidue( p_residueIndex ) ); + _refreshCurrentObject(); + } + void MoleculeData::unselectResidues( const IndexRange & p_residues ) + { + _unselectResidues( p_residues ); + _refreshCurrentObject(); } - void MoleculeData::unselectResidues( const IndexRange & p_residues ) { _unselectResidues( p_residues ); } void MoleculeData::unselectResidues( const IndexRangeList & p_residues ) { for ( Util::Math::RangeList::RangeConstIterator itRange = p_residues.rangeBegin(); @@ -342,6 +401,8 @@ namespace VTX::App::Application::Selection { _unselectResidues( *itRange ); } + + _refreshCurrentObject(); } void MoleculeData::unselectResidues( const std::initializer_list & p_atoms ) { @@ -350,6 +411,8 @@ namespace VTX::App::Application::Selection if ( residuePtr != nullptr ) _unselectResidue( *residuePtr ); } + + _refreshCurrentObject(); } void MoleculeData::unselectResidues( const std::initializer_list & p_atoms ) { @@ -360,6 +423,8 @@ namespace VTX::App::Application::Selection if ( atomPtr != nullptr ) _unselectResidue( *atomPtr ); } + + _refreshCurrentObject(); } bool MoleculeData::isResidueSelected( const size_t & p_residueIndex ) const @@ -450,6 +515,8 @@ namespace VTX::App::Application::Selection _referenceChain( *p_atom.getConstChainPtr() ); _referenceAtom( p_atom ); + + setCurrentObject( p_atom ); } void MoleculeData::selectAtoms( const AtomIndexRange & p_range ) { @@ -463,27 +530,43 @@ namespace VTX::App::Application::Selection ) ); _referenceAtoms( p_range ); + + setCurrentObject( *_molecule->getAtom( p_range.getLast() ) ); } void MoleculeData::selectAtoms( const AtomIndexRangeList & p_rangeList ) { - for ( const atom_index_t index : p_rangeList ) + for ( AtomIndexRangeList::RangeConstIterator it = p_rangeList.rangeBegin(); it != p_rangeList.rangeEnd(); it++ ) { - const Atom * const atomPtr = _molecule->getAtom( index ); + const Residue & firstResidue = *_molecule->getAtom( it->getFirst() )->getConstResiduePtr(); + const Residue & lastResidue = *_molecule->getAtom( it->getLast() )->getConstResiduePtr(); - _referenceResidue( *atomPtr->getConstResiduePtr() ); - _referenceChain( *atomPtr->getConstChainPtr() ); + _referenceResidues( IndexRange::createFirstLast( firstResidue.getIndex(), lastResidue.getIndex() ) ); - if ( atomPtr != nullptr ) - _referenceAtom( *atomPtr ); + const size_t firstChainIndex = firstResidue.getConstChainPtr()->getIndex(); + const size_t lastChainIndex = lastResidue.getConstChainPtr()->getIndex(); + _referenceChains( IndexRange::createFirstLast( firstChainIndex, lastChainIndex ) ); + + _referenceAtoms( *it ); } + + setCurrentObject( *_molecule->getAtom( p_rangeList.getLast() ) ); } - void MoleculeData::unselectAtom( const Atom & p_atom ) { _unselectAtom( p_atom ); } + void MoleculeData::unselectAtom( const Atom & p_atom ) + { + _unselectAtom( p_atom ); + _refreshCurrentObject(); + } void MoleculeData::unselectAtom( const atom_index_t p_atomIndex ) { _unselectAtom( *_molecule->getAtom( p_atomIndex ) ); + _refreshCurrentObject(); + } + void MoleculeData::unselectAtoms( const AtomIndexRange & p_atoms ) + { + _unselectAtoms( p_atoms ); + _refreshCurrentObject(); } - void MoleculeData::unselectAtoms( const AtomIndexRange & p_atoms ) { _unselectAtoms( p_atoms ); } void MoleculeData::unselectAtoms( const AtomIndexRangeList & p_atoms ) { for ( AtomIndexRangeList::RangeConstIterator itRange = p_atoms.rangeBegin(); itRange != p_atoms.rangeEnd(); @@ -491,6 +574,8 @@ namespace VTX::App::Application::Selection { unselectAtoms( *itRange ); } + + _refreshCurrentObject(); } void MoleculeData::unselectAtoms( const std::initializer_list & p_atoms ) { @@ -499,6 +584,8 @@ namespace VTX::App::Application::Selection if ( atomPtr != nullptr ) _unselectAtom( *atomPtr ); } + + _refreshCurrentObject(); } void MoleculeData::unselectAtoms( const std::initializer_list & p_atoms ) { @@ -509,6 +596,8 @@ namespace VTX::App::Application::Selection if ( atomPtr != nullptr ) _unselectAtom( *atomPtr ); } + + _refreshCurrentObject(); } bool MoleculeData::isAtomSelected( const atom_index_t & p_atomIndex ) const @@ -541,24 +630,15 @@ namespace VTX::App::Application::Selection } ////////////////////////////////////////////////////////////////////////////////////////////////// - void MoleculeData::_referenceChain( const Chain & p_chain ) - { - _chainIds.addValue( p_chain.getIndex() ); - setCurrentObject( p_chain ); - } + void MoleculeData::_referenceChain( const Chain & p_chain ) { _chainIds.addValue( p_chain.getIndex() ); } void MoleculeData::_selectFullChain( const Chain & p_chain ) { const size_t firstResidueIndex = p_chain.getIndexFirstResidue(); const size_t residueCount = p_chain.getResidueCount(); _selectFullResidues( IndexRange( firstResidueIndex, residueCount ) ); - _referenceChain( p_chain ); - } - void MoleculeData::_referenceChains( const IndexRange & p_range ) - { - _chainIds.addRange( p_range ); - setCurrentObject( *_molecule->getChain( p_range.getLast() ) ); } + void MoleculeData::_referenceChains( const IndexRange & p_range ) { _chainIds.addRange( p_range ); } void MoleculeData::_selectFullChains( const IndexRange & p_range ) { const Chain & firstChain = *_molecule->getChain( p_range.getFirst() ); @@ -578,8 +658,6 @@ namespace VTX::App::Application::Selection ); _atomIds.removeRange( AtomIndexRange::createFirstLast( p_chain.getIndexFirstAtom(), p_chain.getIndexLastAtom() ) ); - - _refreshCurrentObject(); } void MoleculeData::_unselectChains( const IndexRange & p_range ) { @@ -593,15 +671,9 @@ namespace VTX::App::Application::Selection IndexRange::createFirstLast( firstChain.getIndexFirstResidue(), lastChain.getIndexLastResidue() ) ); _chainIds.removeRange( p_range ); - - _refreshCurrentObject(); } - void MoleculeData::_referenceResidue( const Residue & p_residue ) - { - _residueIds.addValue( p_residue.getIndex() ); - setCurrentObject( p_residue ); - } + void MoleculeData::_referenceResidue( const Residue & p_residue ) { _residueIds.addValue( p_residue.getIndex() ); } void MoleculeData::_selectFullResidue( const Residue & p_residue ) { const atom_index_t firstAtomIndex = p_residue.getIndexFirstAtom(); @@ -610,11 +682,7 @@ namespace VTX::App::Application::Selection _referenceAtoms( AtomIndexRange( firstAtomIndex, atomCount ) ); _referenceResidue( p_residue ); } - void MoleculeData::_referenceResidues( const IndexRange & p_range ) - { - _residueIds.addRange( p_range ); - setCurrentObject( *_molecule->getResidue( p_range.getLast() ) ); - } + void MoleculeData::_referenceResidues( const IndexRange & p_range ) { _residueIds.addRange( p_range ); } void MoleculeData::_selectFullResidues( const IndexRange & p_range ) { const Residue * const firstResidue = _molecule->getResidue( p_range.getFirst() ); @@ -640,8 +708,6 @@ namespace VTX::App::Application::Selection { _unselectChain( chainParent ); } - - _refreshCurrentObject(); } void MoleculeData::_unselectResidues( const IndexRange & p_range ) { @@ -678,21 +744,16 @@ namespace VTX::App::Application::Selection { _chainIds.removeValue( lastChainParent.getIndex() ); } - - _refreshCurrentObject(); } void MoleculeData::_referenceAtom( const Atom & p_atom ) { _atomIds.addValue( p_atom.getIndex() ); - setCurrentObject( p_atom ); - _localAABB.extend( p_atom.getLocalPosition(), p_atom.getVdwRadius() ); } void MoleculeData::_referenceAtoms( const AtomIndexRange & p_range ) { _atomIds.addRange( p_range ); - setCurrentObject( *_molecule->getAtom( p_range.getLast() ) ); for ( atom_index_t atomIndex = p_range.getFirst(); atomIndex <= p_range.getLast(); atomIndex++ ) { @@ -721,7 +782,6 @@ namespace VTX::App::Application::Selection _unselectChain( chainParent ); } - _refreshCurrentObject(); _localAABB.invalidate(); } void MoleculeData::_unselectAtoms( const AtomIndexRange & p_range ) @@ -774,7 +834,6 @@ namespace VTX::App::Application::Selection _chainIds.removeValue( lastChainParent.getIndex() ); } - _refreshCurrentObject(); _localAABB.invalidate(); } @@ -868,7 +927,7 @@ namespace VTX::App::Application::Selection const int maxItemDisplayed = 20; sStr << SelectionData::toString() << std::endl; - sStr << "Chains (" << _chainIds.size() << '/' << _molecule->getChains().size() << ")" << std::endl; + sStr << "Chains (" << _chainIds.count() << '/' << _molecule->getChains().size() << ")" << std::endl; int counter = 0; @@ -888,7 +947,7 @@ namespace VTX::App::Application::Selection sStr << std::endl << std::endl; counter = 0; - sStr << "Residues (" << _residueIds.size() << '/' << _molecule->getResidues().size() << ")" << std::endl; + sStr << "Residues (" << _residueIds.count() << '/' << _molecule->getResidues().size() << ")" << std::endl; for ( const size_t residueId : _residueIds ) { const Residue & residue = *_molecule->getResidue( residueId ); @@ -905,7 +964,7 @@ namespace VTX::App::Application::Selection sStr << std::endl << std::endl; counter = 0; - sStr << "Atoms (" << _atomIds.size() << '/' << _molecule->getAtoms().size() << ")" << std::endl; + sStr << "Atoms (" << _atomIds.count() << '/' << _molecule->getAtoms().size() << ")" << std::endl; for ( const atom_index_t atomId : _atomIds ) { const Atom & atom = *_molecule->getAtom( atomId ); diff --git a/lib/app/src/app/application/selection/selection.cpp b/lib/app/src/app/application/selection/selection.cpp index 91830cea2..88e310914 100644 --- a/lib/app/src/app/application/selection/selection.cpp +++ b/lib/app/src/app/application/selection/selection.cpp @@ -146,6 +146,8 @@ namespace VTX::App::Application::Selection SelectionData & res = getSelectionData( p_selectableComponent ); res.selectAll(); + onSelect( res ); + _setCurrentObject( &res ); return res; @@ -155,10 +157,14 @@ namespace VTX::App::Application::Selection std::unique_ptr selectionItem = p_selectableComponent.instantiateSelectionData(); - auto it = _items.emplace( std::move( selectionItem ) ); - _setCurrentObject( it.first->get() ); + auto it = _items.emplace( std::move( selectionItem ) ); + const std::unique_ptr & selectionDataPtr = *( it.first ); + + onSelect( *selectionDataPtr ); + + _setCurrentObject( selectionDataPtr.get() ); - return **( it.first ); + return *selectionDataPtr; } } SelectionData & Selection::select( @@ -175,6 +181,8 @@ namespace VTX::App::Application::Selection SelectionData & res = getSelectionData( p_selectableComponent ); res.add( p_selectionData ); + onSelect( res ); + _setCurrentObject( &res ); return res; @@ -185,10 +193,14 @@ namespace VTX::App::Application::Selection = p_selectableComponent.instantiateSelectionData(); selectionItem->set( p_selectionData ); - auto it = _items.emplace( std::move( selectionItem ) ); - _setCurrentObject( it.first->get() ); + auto it = _items.emplace( std::move( selectionItem ) ); + const std::unique_ptr & selectionDataPtr = *( it.first ); + + onSelect( *selectionDataPtr ); - return **( it.first ); + _setCurrentObject( selectionDataPtr.get() ); + + return *selectionDataPtr; } } @@ -207,6 +219,12 @@ namespace VTX::App::Application::Selection void Selection::unselect( const Component::Scene::Selectable & p_selectableComponent ) { const std::unique_ptr & selItem = _getSelectionDataPtr( p_selectableComponent ); + + onDeselect( *selItem ); + + if ( _currentSelectionData == selItem.get() ) + _clearCurrentObject(); + _items.erase( selItem ); } @@ -236,8 +254,15 @@ namespace VTX::App::Application::Selection void Selection::clear() { - _clearWithoutNotify(); - _notifyDataChanged(); + _clearCurrentObject(); + + while ( _items.size() > 0 ) + { + const std::unique_ptr & selectionData = *_items.begin(); + onDeselect( *selectionData ); + + _items.erase( _items.begin() ); + } } Util::Math::AABB Selection::getAABB() const @@ -257,10 +282,6 @@ namespace VTX::App::Application::Selection } void Selection::setCurrentObject( const SelectionData & p_selectionData ) { _setCurrentObject( &p_selectionData ); } - void Selection::_notifyDataChanged() {} - - void Selection::_clearWithoutNotify() { _items.clear(); } - SelectionData & Selection::getSelectionData( const Component::Scene::Selectable & p_selectable ) { return *_getSelectionDataPtr( p_selectable ); @@ -286,24 +307,20 @@ namespace VTX::App::Application::Selection throw VTXException( "Selectable object not found in selection." ); } - void Selection::_setCurrentObject( const SelectionData * const p_selectionData, const bool p_notify ) + void Selection::_setCurrentObject( const SelectionData * const p_selectionData ) { if ( _currentSelectionData != p_selectionData ) { _currentSelectionData = p_selectionData; - - if ( p_notify ) - _notifyDataChanged(); + onCurrentObjectChange( p_selectionData ); } } - void Selection::_clearCurrentObject( const bool p_notify ) + void Selection::_clearCurrentObject() { if ( _currentSelectionData != nullptr ) { _currentSelectionData = nullptr; - - if ( p_notify ) - _notifyDataChanged(); + onCurrentObjectChange( nullptr ); } } diff --git a/lib/app/src/app/application/selection/selection_manager.cpp b/lib/app/src/app/application/selection/selection_manager.cpp index 9f1b87d31..e70eaba97 100644 --- a/lib/app/src/app/application/selection/selection_manager.cpp +++ b/lib/app/src/app/application/selection/selection_manager.cpp @@ -2,7 +2,7 @@ namespace VTX::App::Application::Selection { - SelectionManager::SelectionManager() = default; + SelectionManager::SelectionManager() { _linkCallbackToSelectables(); }; SelectionManager::~SelectionManager() = default; const Selection & SelectionManager::getCurrent() const { return *_currentSelection; } @@ -24,13 +24,26 @@ namespace VTX::App::Application::Selection } Selection & SelectionManager::getSaved( const std::string & p_name ) { return *_savedSelectionMap[ p_name ]; } - void SelectionManager::apply( const Selection & p_selection ) + void SelectionManager::apply( const Selection & p_selection ) { _setCurrentSelection( p_selection ); } + void SelectionManager::apply( const std::string & p_selectionName ) + { + _setCurrentSelection( *_savedSelectionMap[ p_selectionName ] ); + } + + void SelectionManager::_setCurrentSelection( const Selection & p_selection ) { + // Clear Callbacks ? _currentSelection = std::make_unique( p_selection ); + _linkCallbackToSelectables(); } - void SelectionManager::apply( const std::string & p_selectionName ) + + void SelectionManager::_linkCallbackToSelectables() { - _currentSelection = std::make_unique( *_savedSelectionMap[ p_selectionName ] ); + _currentSelection->onSelect += []( const SelectionData & p_selectionData ) + { p_selectionData.getSelectionComponent().onSelect( p_selectionData ); }; + + _currentSelection->onDeselect += []( const SelectionData & p_selectionData ) + { p_selectionData.getSelectionComponent().onDeselect( p_selectionData ); }; } } // namespace VTX::App::Application::Selection diff --git a/lib/app/src/app/application/system/renderer.cpp b/lib/app/src/app/application/system/renderer.cpp new file mode 100644 index 000000000..77af7bb85 --- /dev/null +++ b/lib/app/src/app/application/system/renderer.cpp @@ -0,0 +1,18 @@ +#include "app/application/system/renderer.hpp" + +namespace VTX::App::Application::System +{ + Application::Renderer::RendererAccessor Renderer::accessor() + { + return Application::Renderer::RendererAccessor( _renderer, onGet, onRelease ); + } + + VTX::Renderer::Facade & Renderer::facade() { return _renderer.get(); } + +} // namespace VTX::App::Application::System + +namespace VTX::App +{ + Application::System::Renderer & RENDERER_SYSTEM() { return Application::System::Renderer::SYSTEM.get(); } + Application::Renderer::RendererAccessor RENDERER() { return RENDERER_SYSTEM().accessor(); } +} // namespace VTX::App diff --git a/lib/app/src/app/component/behaviour/molecule_behaviour.cpp b/lib/app/src/app/component/behaviour/molecule_behaviour.cpp index d29addada..8424c922e 100644 --- a/lib/app/src/app/component/behaviour/molecule_behaviour.cpp +++ b/lib/app/src/app/component/behaviour/molecule_behaviour.cpp @@ -2,6 +2,7 @@ #include "app/application/selection/molecule_data.hpp" #include "app/application/selection/molecule_granularity.hpp" #include "app/application/settings.hpp" +#include "app/application/system/renderer.hpp" #include "app/component/chemistry/molecule.hpp" #include "app/component/chemistry/trajectory.hpp" #include "app/component/render/proxy_molecule.hpp" @@ -62,7 +63,7 @@ namespace VTX::App::Component::Behaviour Component::Render::ProxyMolecule & gpuProxyComponent = MAIN_REGISTRY().getComponent( _entity ); - gpuProxyComponent.init(); + gpuProxyComponent.setup( App::RENDERER().facade() ); } void Molecule::_initTrajectoryComponent() const { diff --git a/lib/app/src/app/component/chemistry/atom.cpp b/lib/app/src/app/component/chemistry/atom.cpp index 71073dc56..2a3a65054 100644 --- a/lib/app/src/app/component/chemistry/atom.cpp +++ b/lib/app/src/app/component/chemistry/atom.cpp @@ -55,8 +55,14 @@ namespace VTX::App::Component::Chemistry _moleculePtr->_moleculeStruct.atomSymbols[ _index ] = p_symbol; } - bool Atom::isVisible() const { return _moleculePtr->_atomVisibilities[ _index ]; } - void Atom::setVisible( const bool p_visible ) { _moleculePtr->_atomVisibilities[ _index ] = p_visible; } + bool Atom::isVisible() const { return _moleculePtr->_visibleAtomIds.contains( _index ); } + void Atom::setVisible( const bool p_visible ) + { + if ( p_visible ) + _moleculePtr->_visibleAtomIds.addValue( _index ); + else + _moleculePtr->_visibleAtomIds.removeValue( _index ); + } ChemDB::Atom::TYPE Atom::getType() const { diff --git a/lib/app/src/app/component/chemistry/bond.cpp b/lib/app/src/app/component/chemistry/bond.cpp index c6bfecd10..b8e4c09c8 100644 --- a/lib/app/src/app/component/chemistry/bond.cpp +++ b/lib/app/src/app/component/chemistry/bond.cpp @@ -1,4 +1,5 @@ #include "app/component/chemistry/bond.hpp" +#include "app/component/chemistry/atom.hpp" #include "app/component/chemistry/molecule.hpp" namespace VTX::App::Component::Chemistry @@ -19,4 +20,21 @@ namespace VTX::App::Component::Chemistry { _moleculePtr->_moleculeStruct.bondPairAtomIndexes[ _index * 2 + 1 ] = p_atomIndex; } + + bool Bond::isVisible() const + { + const Chemistry::Atom * const atom1 = _moleculePtr->getAtom( getIndexFirstAtom() ); + const Chemistry::Atom * const atom2 = _moleculePtr->getAtom( getIndexSecondAtom() ); + + return atom1 != nullptr && atom1->isVisible() && atom2 != nullptr && atom2->isVisible(); + } + void Bond::setVisible( const bool p_visible ) + { + AtomIndexRangeList atomRange = AtomIndexRangeList(); + + atomRange.addValue( getIndexFirstAtom() ); + atomRange.addValue( getIndexSecondAtom() ); + + _moleculePtr->setVisible( atomRange, p_visible ); + } } // namespace VTX::App::Component::Chemistry diff --git a/lib/app/src/app/component/chemistry/chain.cpp b/lib/app/src/app/component/chemistry/chain.cpp index a41869ae8..c7ad22364 100644 --- a/lib/app/src/app/component/chemistry/chain.cpp +++ b/lib/app/src/app/component/chemistry/chain.cpp @@ -51,4 +51,21 @@ namespace VTX::App::Component::Chemistry return Iterator::AtomContainer( _moleculePtr, getIndexFirstAtom(), atomCount ); } + bool Chain::isVisible() const + { + const AtomIndexRange atomRange = AtomIndexRange::createFirstLast( getIndexFirstAtom(), getIndexLastAtom() ); + return _moleculePtr->_visibleAtomIds.intersectWith( atomRange ); + } + bool Chain::isFullyVisible() const + { + const AtomIndexRange atomRange = AtomIndexRange::createFirstLast( getIndexFirstAtom(), getIndexLastAtom() ); + return _moleculePtr->_visibleAtomIds.contains( atomRange ); + } + + void Chain::setVisible( const bool p_visible ) + { + const AtomIndexRange atomRange = AtomIndexRange::createFirstLast( getIndexFirstAtom(), getIndexLastAtom() ); + _moleculePtr->setVisible( atomRange, p_visible ); + } + } // namespace VTX::App::Component::Chemistry diff --git a/lib/app/src/app/component/chemistry/molecule.cpp b/lib/app/src/app/component/chemistry/molecule.cpp index 48bfd6395..9e4e2a8e9 100644 --- a/lib/app/src/app/component/chemistry/molecule.cpp +++ b/lib/app/src/app/component/chemistry/molecule.cpp @@ -8,6 +8,7 @@ #include "app/component/scene/scene_item_component.hpp" #include "app/vtx_app.hpp" #include +#include #include namespace VTX::App::Component::Chemistry @@ -70,10 +71,7 @@ namespace VTX::App::Component::Chemistry [ this, n = 0 ]() mutable { return std::move( std::make_unique( this, n++ ) ); } ); - _atomVisibilities.resize( p_atomCount, uint( true ) ); - _atomUidRange = UID_SYSTEM().registerRange( Core::UID::uid( p_atomCount ) ); - _atomSelections.resize( p_atomCount, uint( false ) ); } void Molecule::initBonds( const size_t p_bondCount ) @@ -108,4 +106,84 @@ namespace VTX::App::Component::Chemistry return getResidue( p_uid - _residueUidRange.getFirst() ); } + bool Molecule::isVisible() const { return !_visibleAtomIds.isEmpty(); } + bool Molecule::isFullyVisible() const { return _visibleAtomIds.count() == atom_index_t( _atoms.size() ); } + + void Molecule::setVisible( const bool p_visible ) + { + const AtomIndexRange atomRange = AtomIndexRange( 0, atom_index_t( _atoms.size() ) ); + + if ( p_visible ) + { + _visibleAtomIds.addRange( atomRange ); + } + else + { + // = _visibleAtomIds.removeRange( atomRange ), but quicker + _visibleAtomIds.clear(); + } + + const App::Core::VISIBILITY_APPLY_MODE applyMode + = p_visible ? App::Core::VISIBILITY_APPLY_MODE::SHOW : App::Core::VISIBILITY_APPLY_MODE::HIDE; + onVisibilityChange( AtomIndexRangeList( { atomRange } ), applyMode ); + } + void Molecule::setVisible( const atom_index_t & p_atomId, bool p_visible ) + { + App::Core::VISIBILITY_APPLY_MODE applyMode; + + if ( p_visible ) + { + _visibleAtomIds.addValue( p_atomId ); + applyMode = App::Core::VISIBILITY_APPLY_MODE::SHOW; + } + else + { + _visibleAtomIds.removeValue( p_atomId ); + applyMode = App::Core::VISIBILITY_APPLY_MODE::HIDE; + } + + onVisibilityChange( AtomIndexRangeList( { AtomIndexRange( p_atomId ) } ), applyMode ); + } + void Molecule::setVisible( const AtomIndexRange & p_atomRange, bool p_visible ) + { + App::Core::VISIBILITY_APPLY_MODE applyMode; + + if ( p_visible ) + { + _visibleAtomIds.addRange( p_atomRange ); + applyMode = App::Core::VISIBILITY_APPLY_MODE::SHOW; + } + else + { + _visibleAtomIds.removeRange( p_atomRange ); + applyMode = App::Core::VISIBILITY_APPLY_MODE::HIDE; + } + + onVisibilityChange( AtomIndexRangeList( { p_atomRange } ), applyMode ); + } + + void Molecule::setVisible( const AtomIndexRangeList & p_atomRange, bool p_visible ) + { + App::Core::VISIBILITY_APPLY_MODE applyMode; + + if ( p_visible ) + { + Util::Algorithm::Range::mergeInSitu( _visibleAtomIds, p_atomRange ); + applyMode = App::Core::VISIBILITY_APPLY_MODE::SHOW; + } + else + { + Util::Algorithm::Range::substractInSitu( _visibleAtomIds, p_atomRange ); + applyMode = App::Core::VISIBILITY_APPLY_MODE::HIDE; + } + + onVisibilityChange( p_atomRange, applyMode ); + } + + void Molecule::setAtomVisibilities( const AtomIndexRangeList & p_visibility ) + { + _visibleAtomIds = p_visibility; + onVisibilityChange( _visibleAtomIds, App::Core::VISIBILITY_APPLY_MODE::SET ); + } + } // namespace VTX::App::Component::Chemistry diff --git a/lib/app/src/app/component/chemistry/residue.cpp b/lib/app/src/app/component/chemistry/residue.cpp index 04c76a2c2..ae18c46fd 100644 --- a/lib/app/src/app/component/chemistry/residue.cpp +++ b/lib/app/src/app/component/chemistry/residue.cpp @@ -113,4 +113,21 @@ namespace VTX::App::Component::Chemistry return Iterator::AtomContainer( _moleculePtr, getIndexFirstAtom(), getAtomCount() ); } + bool Residue::isVisible() const + { + const AtomIndexRange atomRange = AtomIndexRange( getIndexFirstAtom(), getAtomCount() ); + return _moleculePtr->_visibleAtomIds.intersectWith( atomRange ); + } + bool Residue::isFullyVisible() const + { + const AtomIndexRange atomRange = AtomIndexRange( getIndexFirstAtom(), getAtomCount() ); + return _moleculePtr->_visibleAtomIds.contains( atomRange ); + } + + void Residue::setVisible( const bool p_visible ) + { + const AtomIndexRange atomRange = AtomIndexRange( getIndexFirstAtom(), getAtomCount() ); + _moleculePtr->setVisible( atomRange, p_visible ); + } + } // namespace VTX::App::Component::Chemistry diff --git a/lib/app/src/app/component/chemistry/trajectory.cpp b/lib/app/src/app/component/chemistry/trajectory.cpp index 4dffe2e51..eb404d7ad 100644 --- a/lib/app/src/app/component/chemistry/trajectory.cpp +++ b/lib/app/src/app/component/chemistry/trajectory.cpp @@ -14,19 +14,28 @@ namespace VTX::App::Component::Chemistry Trajectory::Trajectory( Molecule * const p_molecule ) : _moleculePtr( p_molecule ) { _referenceUpdateFunction(); } - size_t Trajectory::getCurrentFrame() const + size_t Trajectory::getCurrentFrame() const { return _moleculePtr->getTrajectory().currentFrameIndex; } + void Trajectory::setCurrentFrame( const size_t p_frameIndex ) { - return _moleculePtr->getMoleculeStruct().trajectory.currentFrameIndex; + _moleculePtr->getTrajectory().currentFrameIndex = p_frameIndex; } - size_t Trajectory::getFrameCount() const { return _moleculePtr->getMoleculeStruct().trajectory.frames.size(); } + size_t Trajectory::getFrameCount() const { return _moleculePtr->getTrajectory().frames.size(); } void Trajectory::setPlayer( std::unique_ptr & p_player ) { const bool resetPlayer = _player == nullptr; + onFrameChange.clear(); + _player = std::move( p_player ); - _player->setTrajectory( _moleculePtr->getTrajectory() ); + _player->setCount( _moleculePtr->getTrajectory().getFrameCount() ); + + _player->onFrameChange += [ this ]( const size_t p_frameIndex ) + { + _moleculePtr->getTrajectory().currentFrameIndex = p_frameIndex; + onFrameChange( p_frameIndex ); + }; if ( resetPlayer ) _player->reset(); diff --git a/lib/app/src/app/component/render/proxy_camera.cpp b/lib/app/src/app/component/render/proxy_camera.cpp index d4a5642f8..3acdb578e 100644 --- a/lib/app/src/app/component/render/proxy_camera.cpp +++ b/lib/app/src/app/component/render/proxy_camera.cpp @@ -1,18 +1,26 @@ #include "app/component/render/proxy_camera.hpp" +#include "app/application/system/ecs_system.hpp" +#include "app/component/render/camera.hpp" #include "app/component/scene/transform_component.hpp" -#include "app/vtx_app.hpp" -#include -#include -#include +#include namespace VTX::App::Component::Render { ProxyCamera::ProxyCamera() {} + ProxyCamera::~ProxyCamera() + { + if ( _proxyWrapper.isValid() ) + { + //_proxyWrapper.accessor().proxy().onRemove(); + } + } - void ProxyCamera::init() + void ProxyCamera::setInRenderer( Renderer::Facade & p_renderer ) { _generateProxy(); _initCallbacks(); + + p_renderer.setProxyCamera( _proxyWrapper.proxy() ); } void ProxyCamera::_generateProxy() @@ -21,34 +29,38 @@ namespace VTX::App::Component::Render Component::Scene::Transform & transformComp = MAIN_REGISTRY().getComponent( *this ); - _proxyPtr = std::make_unique( VTX::Renderer::Proxy::Camera { - &cameraComp.getViewMatrix(), - &cameraComp.getProjectionMatrix(), + std::unique_ptr proxyPtr + = std::make_unique( VTX::Renderer::Proxy::Camera { + &cameraComp.getViewMatrix(), + &cameraComp.getProjectionMatrix(), - transformComp.getPosition(), - VEC2I_ZERO, - cameraComp.getNear(), - cameraComp.getFar(), - cameraComp.getProjection() == CAMERA_PROJECTION::PERSPECTIVE, - } ); + transformComp.getPosition(), + VEC2I_ZERO, + cameraComp.getNear(), + cameraComp.getFar(), + cameraComp.getProjection() == CAMERA_PROJECTION::PERSPECTIVE, + } ); + + _proxyWrapper.setProxy( proxyPtr ); } void ProxyCamera::_initCallbacks() { Component::Render::Camera & cameraComp = MAIN_REGISTRY().getComponent( *this ); - cameraComp.onMatrixViewChange += [ this ]( const Mat4f & p_viewMatrix ) { _proxyPtr->onMatrixView(); }; + cameraComp.onMatrixViewChange += + [ this ]( const Mat4f & p_viewMatrix ) { _proxyWrapper.accessor().proxy().onMatrixView(); }; cameraComp.onMatrixProjectionChange += - [ this ]( const Mat4f & p_projMatrix ) { _proxyPtr->onMatrixProjection(); }; + [ this ]( const Mat4f & p_projMatrix ) { _proxyWrapper.accessor().proxy().onMatrixProjection(); }; - cameraComp.onClipInfosChange += - [ this ]( float p_near, float p_far ) { _proxyPtr->onCameraNearFar( p_near, p_far ); }; + cameraComp.onClipInfosChange += [ this ]( float p_near, float p_far ) + { _proxyWrapper.accessor().proxy().onCameraNearFar( p_near, p_far ); }; cameraComp.onProjectionChange += [ this ]( CAMERA_PROJECTION p_projection ) - { _proxyPtr->onPerspective( p_projection == CAMERA_PROJECTION::PERSPECTIVE ); }; + { _proxyWrapper.accessor().proxy().onPerspective( p_projection == CAMERA_PROJECTION::PERSPECTIVE ); }; - // Component::Scene::Transform & transformComp - // = MAIN_REGISTRY().getComponent( *this ); - // transformComp.onTransformChanged += [ this ]( const Util::Math::Transform & p_transform ) - //{ _proxyPtr->onCameraPosition( p_transform.getTranslationVector() ); }; + Component::Scene::Transform & transformComp + = MAIN_REGISTRY().getComponent( *this ); + transformComp.onTransform += [ this ]( const Util::Math::Transform & p_transform ) + { _proxyWrapper.accessor().proxy().onCameraPosition( p_transform.getTranslationVector() ); }; } } // namespace VTX::App::Component::Render diff --git a/lib/app/src/app/component/render/proxy_molecule.cpp b/lib/app/src/app/component/render/proxy_molecule.cpp index ed070b8ea..db2ae8b1a 100644 --- a/lib/app/src/app/component/render/proxy_molecule.cpp +++ b/lib/app/src/app/component/render/proxy_molecule.cpp @@ -1,15 +1,31 @@ #include "app/component/render/proxy_molecule.hpp" +#include "app/application/selection/molecule_data.hpp" +#include "app/application/selection/selection.hpp" +#include "app/application/selection/selection_manager.hpp" #include "app/application/system/ecs_system.hpp" +#include "app/component/chemistry/trajectory.hpp" #include "app/component/scene/transform_component.hpp" #include -#include -#include +#include +#include namespace VTX::App::Component::Render { ProxyMolecule::ProxyMolecule() {} + ProxyMolecule::~ProxyMolecule() + { + if ( _proxyWrapper.isValid() ) + { + _proxyWrapper.accessor().proxy().onRemove(); + } + } + void ProxyMolecule::setup( Renderer::Facade & p_renderer ) + { + _addInRenderer( p_renderer ); + _setupCallbacks(); + } - void ProxyMolecule::init() + void ProxyMolecule::_addInRenderer( Renderer::Facade & p_renderer ) { Component::Chemistry::Molecule & molComp = MAIN_REGISTRY().getComponent( *this ); @@ -18,39 +34,49 @@ namespace VTX::App::Component::Render Component::Scene::Transform & transformComp = MAIN_REGISTRY().getComponent( *this ); - const std::vector atomColors = generateAtomColors( molStruct ); - const std::vector atomRadii = generateAtomRadii( molStruct ); - const std::vector atomIds = generateAtomUids( molComp ); - const std::vector residueColors = generateResidueColors( molStruct ); - const std::vector residueIds = generateResidueUids( molComp ); - - _proxyPtr = std::make_unique( VTX::Renderer::Proxy::Molecule { - &transformComp.getTransform().get(), - - &molStruct.trajectory.getCurrentFrame(), - &molStruct.bondPairAtomIndexes, - &molStruct.atomNames, - reinterpret_cast *>( &molStruct.residueSecondaryStructureTypes ), - &molStruct.residueFirstAtomIndexes, - &molStruct.residueAtomCounts, - &molStruct.chainFirstResidues, - &molStruct.chainResidueCounts, - - atomColors, - atomRadii, - atomIds, - residueColors, - residueIds } ); + const std::vector atomColors = _generateAtomColors( molStruct ); + const std::vector atomRadii = _generateAtomRadii( molStruct ); + const std::vector atomIds = _generateAtomUids( molComp ); + const std::vector residueColors = _generateResidueColors( molStruct ); + const std::vector residueIds = _generateResidueUids( molComp ); + + std::unique_ptr proxyPtr + = std::make_unique( VTX::Renderer::Proxy::Molecule { + &transformComp.getTransform().get(), + + &molStruct.trajectory.getCurrentFrame(), + &molStruct.bondPairAtomIndexes, + &molStruct.atomNames, + reinterpret_cast *>( &molStruct.residueSecondaryStructureTypes ), + &molStruct.residueFirstAtomIndexes, + &molStruct.residueAtomCounts, + &molStruct.chainFirstResidues, + &molStruct.chainResidueCounts, + + atomColors, + atomRadii, + atomIds, + residueColors, + residueIds } ); + + _proxyWrapper.setProxy( proxyPtr ); + p_renderer.addProxyMolecule( _proxyWrapper.proxy() ); + } + void ProxyMolecule::_setupCallbacks() + { + _applyVisibilityCallbacks(); + _applySelectionCallbacks(); + _applyAtomPositionCallbacks(); } - std::vector ProxyMolecule::generateAtomColors( const VTX::Core::Struct::Molecule & p_molStruct ) const + std::vector ProxyMolecule::_generateAtomColors( const VTX::Core::Struct::Molecule & p_molStruct ) const { std::vector atomColors; atomColors.resize( p_molStruct.getAtomCount(), 0 ); return atomColors; } - std::vector ProxyMolecule::generateAtomRadii( const VTX::Core::Struct::Molecule & p_molStruct ) const + std::vector ProxyMolecule::_generateAtomRadii( const VTX::Core::Struct::Molecule & p_molStruct ) const { std::vector atomRadii; @@ -64,7 +90,7 @@ namespace VTX::App::Component::Render return atomRadii; } - std::vector ProxyMolecule::generateAtomUids( const Component::Chemistry::Molecule & p_molComp ) const + std::vector ProxyMolecule::_generateAtomUids( const Component::Chemistry::Molecule & p_molComp ) const { std::vector atomUids; const uint offset = uint( p_molComp._atomUidRange.getFirst() ); @@ -74,14 +100,14 @@ namespace VTX::App::Component::Render return atomUids; } - std::vector ProxyMolecule::generateResidueColors( const VTX::Core::Struct::Molecule & p_molStruct ) const + std::vector ProxyMolecule::_generateResidueColors( const VTX::Core::Struct::Molecule & p_molStruct ) const { std::vector residueColors; residueColors.resize( p_molStruct.getResidueCount(), 0 ); return residueColors; } - std::vector ProxyMolecule::generateResidueUids( const Component::Chemistry::Molecule & p_molComp ) const + std::vector ProxyMolecule::_generateResidueUids( const Component::Chemistry::Molecule & p_molComp ) const { std::vector residueUids; const uint offset = uint( p_molComp._residueUidRange.getFirst() ); @@ -93,4 +119,80 @@ namespace VTX::App::Component::Render return residueUids; } + + void ProxyMolecule::_applyOnVisibility( + const Component::Chemistry::AtomIndexRangeList & p_rangeList, + const App::Core::VISIBILITY_APPLY_MODE p_applyMode + ) + { + switch ( p_applyMode ) + { + case App::Core::VISIBILITY_APPLY_MODE::SHOW: + _proxyWrapper.accessor().proxy().onAtomVisibilities( p_rangeList, true ); + break; + + case App::Core::VISIBILITY_APPLY_MODE::HIDE: + _proxyWrapper.accessor().proxy().onAtomVisibilities( p_rangeList, false ); + break; + + case App::Core::VISIBILITY_APPLY_MODE::SET: + _proxyWrapper.accessor().proxy().onVisible( false ); + _proxyWrapper.accessor().proxy().onAtomVisibilities( p_rangeList, true ); + break; + + default: + throw VTXException( + "Unhandled Component::Chemistry::VISIBILITY_APPLY_MODE in ProxyMolecule::onVisibilityChange " + "callback." + ); + } + } + + void ProxyMolecule::_applyVisibilityCallbacks() + { + Component::Chemistry::Molecule & molecule + = MAIN_REGISTRY().getComponent( *this ); + + molecule.onVisibilityChange += + [ this ]( + Component::Chemistry::AtomIndexRangeList p_rangeList, App::Core::VISIBILITY_APPLY_MODE p_applyMode + ) { _applyOnVisibility( p_rangeList, p_applyMode ); }; + } + void ProxyMolecule::_applySelectionCallbacks() + { + Component::Scene::Selectable & selectableComponent + = MAIN_REGISTRY().getComponent( *this ); + + selectableComponent.onSelect += [ this ]( const Application::Selection::SelectionData & p_selectionData ) + { + const Application::Selection::MoleculeData & castedSelectionData + = dynamic_cast( p_selectionData ); + _proxyWrapper.accessor().proxy().onAtomSelections( castedSelectionData.getAtomIds(), true ); + }; + + selectableComponent.onDeselect += [ this ]( const Application::Selection::SelectionData & p_selectionData ) + { + const Application::Selection::MoleculeData & castedSelectionData + = dynamic_cast( p_selectionData ); + _proxyWrapper.accessor().proxy().onAtomSelections( castedSelectionData.getAtomIds(), false ); + }; + } + void ProxyMolecule::_applyAtomPositionCallbacks() + { + if ( MAIN_REGISTRY().hasComponent( *this ) ) + { + Component::Chemistry::Trajectory & trajectoryComponent + = MAIN_REGISTRY().getComponent( *this ); + + trajectoryComponent.onFrameChange += [ this ]( const size_t p_frameIndex ) + { + Component::Chemistry::Molecule & moleculeComponent + = MAIN_REGISTRY().getComponent( *this ); + + _proxyWrapper.accessor().proxy().atomPositions = &moleculeComponent.getTrajectory().getCurrentFrame(); + _proxyWrapper.accessor().proxy().onAtomPositions(); + }; + } + } + } // namespace VTX::App::Component::Render diff --git a/lib/app/src/app/component/scene/pickable.cpp b/lib/app/src/app/component/scene/pickable.cpp index dbb9d23a8..54e5e1f8c 100644 --- a/lib/app/src/app/component/scene/pickable.cpp +++ b/lib/app/src/app/component/scene/pickable.cpp @@ -8,23 +8,52 @@ namespace VTX::App::Component::Scene Pickable::Pickable() {} Pickable::~Pickable() {} - void Pickable::pick( - const Application::Selection::PickingInfo & p_ids, - const Application::Selection::AssignmentType & p_assignmentType - ) const + void Pickable::pick( const Application::Selection::PickingInfo & p_ids, const PickType p_pickType ) const { const std::unique_ptr selectionData = _pickableFunc( p_ids ); - VTX_ACTION().execute( *selectionData, p_assignmentType ); + + switch ( p_pickType ) + { + case PickType::SET: + { + VTX_ACTION().execute( + *selectionData, Application::Selection::AssignmentType::SET + ); + } + break; + + case PickType::TOGGLE: + { + if ( _isSelectionDataSelected( *selectionData ) ) + { + VTX_ACTION().execute( *selectionData ); + } + else + { + VTX_ACTION().execute( + *selectionData, Application::Selection::AssignmentType::APPEND + ); + } + } + break; + + default: assert( false ); break; + } } bool Pickable::isSelected( const Core::UID::uid & p_uid ) const { const std::unique_ptr selectionData = _pickableFunc( { p_uid, Core::UID::INVALID_UID } ); - return CURRENT_SELECTION().isSelected( selectionData->getSelectionComponent() ) + return _isSelectionDataSelected( *selectionData ); + } + + bool Pickable::_isSelectionDataSelected( const Application::Selection::SelectionData & p_selectionData ) const + { + return CURRENT_SELECTION().isSelected( p_selectionData.getSelectionComponent() ) && CURRENT_SELECTION() - .getSelectionData( selectionData->getSelectionComponent() ) - .contains( *selectionData ); + .getSelectionData( p_selectionData.getSelectionComponent() ) + .contains( p_selectionData ); } } // namespace VTX::App::Component::Scene diff --git a/lib/app/src/app/core/trajectory_player/base_player.cpp b/lib/app/src/app/core/trajectory_player/base_player.cpp index 5f7afe094..bc5be9c39 100644 --- a/lib/app/src/app/core/trajectory_player/base_player.cpp +++ b/lib/app/src/app/core/trajectory_player/base_player.cpp @@ -1,32 +1,44 @@ #include "app/core/trajectory_player/base_player.hpp" -#include +#include namespace VTX::App::Core::TrajectoryPlayer { - void BasePlayer::setTrajectory( VTX::Core::Struct::Trajectory & p_trajectory ) { _trajectoryPtr = &p_trajectory; } + void BasePlayer::setCount( const size_t p_count ) + { + _count = p_count; - size_t BasePlayer::getCurrentFrameIndex() const + if ( _current >= p_count ) + { + _current = p_count - 1; + onFrameChange( _current ); + } + } + + size_t BasePlayer::getCurrent() const { return _current; } + void BasePlayer::setCurrent( const size_t p_frameIndex ) { - assert( isLinkedToTrajectory() ); - return _trajectoryPtr->currentFrameIndex; + if ( _current = p_frameIndex ) + { + _current = p_frameIndex; + onFrameChange( p_frameIndex ); + } } - void BasePlayer::setCurrentFrameIndex( const size_t p_frameIndex ) + + void BasePlayer::play() { - assert( isLinkedToTrajectory() ); - _trajectoryPtr->currentFrameIndex = p_frameIndex; + _isPlaying = true; + onPlay(); } - size_t BasePlayer::getFrameCount() const + void BasePlayer::pause() { - assert( isLinkedToTrajectory() ); - return _trajectoryPtr->frames.size(); + _isPlaying = false; + onPause(); } - - void BasePlayer::play() { _isPlaying = true; } - void BasePlayer::pause() { _isPlaying = false; } void BasePlayer::stop() { - pause(); + _isPlaying = false; reset(); + onStop(); } void BasePlayer::update( const float p_deltaTime ) @@ -42,22 +54,29 @@ namespace VTX::App::Core::TrajectoryPlayer } else { - const size_t currentFrameIndex = getCurrentFrameIndex(); - size_t nextFrameIndex = currentFrameIndex; + const size_t previousCurrent = _current; + size_t nextIndex = _current; const float offset = 1.f / float( _fps ); while ( _trajectoryTimer >= offset ) { - nextFrameIndex++; + nextIndex++; _trajectoryTimer -= offset; } - if ( nextFrameIndex != currentFrameIndex ) + if ( nextIndex != previousCurrent ) { - nextFrame( nextFrameIndex - currentFrameIndex ); + nextFrame( nextIndex - previousCurrent ); } } } - void BasePlayer::setFPS( const uint p_fps ) { _fps = p_fps; } + void BasePlayer::setFPS( const uint p_fps ) + { + if ( _fps != p_fps ) + { + _fps = p_fps; + onFPSChange( p_fps ); + } + } } // namespace VTX::App::Core::TrajectoryPlayer diff --git a/lib/app/src/app/core/trajectory_player/loop.cpp b/lib/app/src/app/core/trajectory_player/loop.cpp index 8d07852bd..52dd6c2a9 100644 --- a/lib/app/src/app/core/trajectory_player/loop.cpp +++ b/lib/app/src/app/core/trajectory_player/loop.cpp @@ -2,13 +2,11 @@ namespace VTX::App::Core::TrajectoryPlayer { - Loop::Loop( VTX::Core::Struct::Trajectory * const p_trajectory ) : BasePlayer( p_trajectory ) {} - - void Loop::reset() { setCurrentFrameIndex( 0 ); } - void Loop::nextFrame( const size_t p_frameCount ) + void Loop::reset() { setCurrent( 0 ); } + void Loop::nextFrame( const size_t p_count ) { - const size_t newFrameIndex = ( getCurrentFrameIndex() + p_frameCount ) % getFrameCount(); - setCurrentFrameIndex( newFrameIndex ); + const size_t newFrameIndex = ( getCurrent() + p_count ) % getCount(); + setCurrent( newFrameIndex ); } } // namespace VTX::App::Core::TrajectoryPlayer diff --git a/lib/app/src/app/core/trajectory_player/once.cpp b/lib/app/src/app/core/trajectory_player/once.cpp index ac912f0a1..a36e3192e 100644 --- a/lib/app/src/app/core/trajectory_player/once.cpp +++ b/lib/app/src/app/core/trajectory_player/once.cpp @@ -2,20 +2,18 @@ namespace VTX::App::Core::TrajectoryPlayer { - Once::Once( VTX::Core::Struct::Trajectory * const p_trajectory ) : BasePlayer( p_trajectory ) {} - - void Once::reset() { setCurrentFrameIndex( 0 ); } - void Once::nextFrame( const size_t p_frameCount ) + void Once::reset() { setCurrent( 0 ); } + void Once::nextFrame( const size_t p_count ) { - const size_t newFrameIndex = getCurrentFrameIndex() + p_frameCount; + const size_t newFrameIndex = getCurrent() + p_count; - if ( newFrameIndex < getFrameCount() - 1 ) + if ( newFrameIndex < getCount() - 1 ) { - setCurrentFrameIndex( newFrameIndex ); + setCurrent( newFrameIndex ); } else { - setCurrentFrameIndex( getFrameCount() - 1 ); + setCurrent( getCount() - 1 ); pause(); } } diff --git a/lib/app/src/app/core/trajectory_player/ping_pong.cpp b/lib/app/src/app/core/trajectory_player/ping_pong.cpp index b7a8e9e86..d5597c718 100644 --- a/lib/app/src/app/core/trajectory_player/ping_pong.cpp +++ b/lib/app/src/app/core/trajectory_player/ping_pong.cpp @@ -2,40 +2,38 @@ namespace VTX::App::Core::TrajectoryPlayer { - PingPong::PingPong( VTX::Core::Struct::Trajectory * const p_trajectory ) : BasePlayer( p_trajectory ) {} - void PingPong::reset() { - setCurrentFrameIndex( 0 ); + setCurrent( 0 ); _forward = true; } - void PingPong::nextFrame( const size_t p_frameCount ) + void PingPong::nextFrame( const size_t p_count ) { - size_t newFrameIndex = getCurrentFrameIndex(); + size_t newFrameIndex = getCurrent(); if ( _forward ) { - newFrameIndex += p_frameCount; + newFrameIndex += p_count; } else { - if ( newFrameIndex < p_frameCount ) + if ( newFrameIndex < p_count ) { - newFrameIndex = p_frameCount - newFrameIndex; + newFrameIndex = p_count - newFrameIndex; _forward = !_forward; } else { - newFrameIndex -= p_frameCount; + newFrameIndex -= p_count; } } // Here forward always true - if ( newFrameIndex >= getFrameCount() ) + if ( newFrameIndex >= getCount() ) { - const size_t roundCount = newFrameIndex / getFrameCount(); - const size_t modulo = newFrameIndex % ( getFrameCount() - 1 ); + const size_t roundCount = newFrameIndex / getCount(); + const size_t modulo = newFrameIndex % ( getCount() - 1 ); _forward = ( roundCount % 2 == 0 ); @@ -45,10 +43,10 @@ namespace VTX::App::Core::TrajectoryPlayer } else { - newFrameIndex = ( getFrameCount() - 1 ) - modulo; + newFrameIndex = ( getCount() - 1 ) - modulo; } } - setCurrentFrameIndex( newFrameIndex ); + setCurrent( newFrameIndex ); } } // namespace VTX::App::Core::TrajectoryPlayer diff --git a/lib/app/src/app/core/trajectory_player/revert_loop.cpp b/lib/app/src/app/core/trajectory_player/revert_loop.cpp index e207cfd9f..d2e082d8f 100644 --- a/lib/app/src/app/core/trajectory_player/revert_loop.cpp +++ b/lib/app/src/app/core/trajectory_player/revert_loop.cpp @@ -2,20 +2,17 @@ namespace VTX::App::Core::TrajectoryPlayer { - RevertLoop::RevertLoop( VTX::Core::Struct::Trajectory * const p_trajectory ) : BasePlayer( p_trajectory ) {} - - void RevertLoop::reset() { setCurrentFrameIndex( getFrameCount() - 1 ); } - void RevertLoop::nextFrame( const size_t p_frameCount ) + void RevertLoop::reset() { setCurrent( getCount() - 1 ); } + void RevertLoop::nextFrame( const size_t p_count ) { - if ( p_frameCount > getCurrentFrameIndex() ) + if ( p_count > getCurrent() ) { - const size_t newFrameIndex - = getFrameCount() - ( ( p_frameCount - getCurrentFrameIndex() ) % getFrameCount() ); - setCurrentFrameIndex( newFrameIndex ); + const size_t newFrameIndex = getCount() - ( ( p_count - getCurrent() ) % getCount() ); + setCurrent( newFrameIndex ); } else { - setCurrentFrameIndex( getCurrentFrameIndex() - p_frameCount ); + setCurrent( getCurrent() - p_count ); } } diff --git a/lib/app/src/app/core/trajectory_player/revert_once.cpp b/lib/app/src/app/core/trajectory_player/revert_once.cpp index 49d549507..4317c98bc 100644 --- a/lib/app/src/app/core/trajectory_player/revert_once.cpp +++ b/lib/app/src/app/core/trajectory_player/revert_once.cpp @@ -2,19 +2,17 @@ namespace VTX::App::Core::TrajectoryPlayer { - RevertOnce::RevertOnce( VTX::Core::Struct::Trajectory * const p_trajectory ) : BasePlayer( p_trajectory ) {} - - void RevertOnce::reset() { setCurrentFrameIndex( getFrameCount() - 1 ); } + void RevertOnce::reset() { setCurrent( getCount() - 1 ); } void RevertOnce::nextFrame( const size_t p_frameCount ) { - if ( p_frameCount >= getCurrentFrameIndex() ) + if ( p_frameCount >= getCurrent() ) { - setCurrentFrameIndex( 0 ); + setCurrent( 0 ); pause(); } else { - setCurrentFrameIndex( getCurrentFrameIndex() - p_frameCount ); + setCurrent( getCurrent() - p_frameCount ); } } diff --git a/lib/app/src/app/core/trajectory_player/stop.cpp b/lib/app/src/app/core/trajectory_player/stop.cpp index 537cac678..65fc69409 100644 --- a/lib/app/src/app/core/trajectory_player/stop.cpp +++ b/lib/app/src/app/core/trajectory_player/stop.cpp @@ -4,15 +4,10 @@ namespace VTX::App::Core::TrajectoryPlayer { Stop::Stop() : BasePlayer() { pause(); } Stop::Stop( const Stop & p_source ) : BasePlayer( p_source ) { pause(); } - Stop::Stop( VTX::Core::Struct::Trajectory * const p_trajectory ) : BasePlayer( p_trajectory ) { pause(); } void Stop::play() {} - void Stop::reset() - { - if ( isLinkedToTrajectory() ) - setCurrentFrameIndex( 0 ); - } + void Stop::reset() { setCurrent( 0 ); } void Stop::nextFrame( const size_t p_frameCount ) {} } // namespace VTX::App::Core::TrajectoryPlayer diff --git a/lib/app/src/app/core/uid/uid_registration.cpp b/lib/app/src/app/core/uid/uid_registration.cpp index 6f14ab0e7..863e99d28 100644 --- a/lib/app/src/app/core/uid/uid_registration.cpp +++ b/lib/app/src/app/core/uid/uid_registration.cpp @@ -13,7 +13,7 @@ namespace VTX::App::Core::UID { std::lock_guard guard( _idMutex ); - if ( _availableUIDs.size() == 0 ) + if ( _availableUIDs.isEmpty() ) throw VTXException( "Unable to reserve UID." ); const uid res = _availableUIDs.rangeBegin()->getFirst(); diff --git a/lib/app/src/app/entity/scene/camera_entity.cpp b/lib/app/src/app/entity/scene/camera_entity.cpp index 9fc04d361..7ce426856 100644 --- a/lib/app/src/app/entity/scene/camera_entity.cpp +++ b/lib/app/src/app/entity/scene/camera_entity.cpp @@ -22,9 +22,5 @@ namespace VTX::App::Entity::Scene { Component::Render::Camera & camera = MAIN_REGISTRY().getComponent( p_entity ); camera.init(); - - Component::Render::ProxyCamera & cameraProxy - = MAIN_REGISTRY().getComponent( p_entity ); - cameraProxy.init(); } } // namespace VTX::App::Entity::Scene diff --git a/lib/app/src/app/internal/serialization/app_serializers.cpp b/lib/app/src/app/internal/serialization/app_serializers.cpp index 922d94fa6..c916d76eb 100644 --- a/lib/app/src/app/internal/serialization/app_serializers.cpp +++ b/lib/app/src/app/internal/serialization/app_serializers.cpp @@ -74,13 +74,15 @@ namespace VTX::App::Internal::Serialization // TrajectoryPlayers Util::JSon::Object serialize( const App::Core::TrajectoryPlayer::BasePlayer & p_player ) { - return { { "CURRENT_FRAME", p_player.getCurrentFrameIndex() }, + return { { "COUNT", p_player.getCount() }, + { "CURRENT", p_player.getCurrent() }, { "FPS", p_player.getFPS() }, { "IS_PLAYING", p_player.isPlaying() } }; } void deserialize( const Util::JSon::Object & p_json, App::Core::TrajectoryPlayer::BasePlayer & p_player ) { - p_player.setCurrentFrameIndex( SERIALIZER().deserializeField( p_json, "CURRENT_FRAME" ) ); + p_player.setCount( SERIALIZER().deserializeField( p_json, "COUNT" ) ); + p_player.setCurrent( SERIALIZER().deserializeField( p_json, "CURRENT" ) ); p_player.setFPS( SERIALIZER().deserializeField( p_json, "FPS" ) ); if ( SERIALIZER().deserializeField( p_json, "IS_PLAYING", false ) ) diff --git a/lib/app/src/app/internal/serialization/scene_serializers.cpp b/lib/app/src/app/internal/serialization/scene_serializers.cpp index db8f3c196..a0cd36432 100644 --- a/lib/app/src/app/internal/serialization/scene_serializers.cpp +++ b/lib/app/src/app/internal/serialization/scene_serializers.cpp @@ -115,15 +115,10 @@ namespace VTX::App::Internal::Serialization const Component::Chemistry::Molecule & moleculeComponent = MAIN_REGISTRY().getComponent( MAIN_REGISTRY().getEntity( p_component ) ); - // Store not visible atom indexes - Util::Math::RangeList visibilities = Util::Algorithm::Range::generateIndexRangeList( - moleculeComponent.getAtomVisibilities(), []( const uint & p_visibility ) { return !p_visibility; } - ); - return { { "PATH", SERIALIZER().serialize( p_component.path ) }, { "PDB_ID", p_component.pdbIDCode }, { "SECONDARY_STRUCTURE_FROM_FILE", p_component.isSecondaryStructureLoadedFromFile }, - { "VISIBILITY", SERIALIZER().serialize( visibilities ) } }; + { "VISIBILITY", SERIALIZER().serialize( moleculeComponent.getAtomVisibilities() ) } }; } void deserialize( const Util::JSon::Object & p_json, Component::IO::MoleculeMetadata & p_component ) { @@ -140,13 +135,10 @@ namespace VTX::App::Internal::Serialization loader.readFile( path, moleculeComponent ); - const Util::Math::RangeList visibilities - = SERIALIZER().deserializeField>( p_json, "VISIBILITY" ); + const Component::Chemistry::AtomIndexRangeList visibilities + = SERIALIZER().deserializeField( p_json, "VISIBILITY" ); - for ( const uint index : visibilities ) - { - moleculeComponent.setAtomVisibility( index, false ); - } + moleculeComponent.setAtomVisibilities( visibilities ); } // TrajectoryComponent diff --git a/lib/app/src/app/vtx_app.cpp b/lib/app/src/app/vtx_app.cpp index 85a9ae144..3d1929036 100644 --- a/lib/app/src/app/vtx_app.cpp +++ b/lib/app/src/app/vtx_app.cpp @@ -4,6 +4,7 @@ #include "app/application/scene.hpp" #include "app/application/selection/selection_manager.hpp" #include "app/application/settings.hpp" +#include "app/application/system/renderer.hpp" #include "app/application/system/threading.hpp" #include "app/component/io/scene_file_info.hpp" #include "app/component/render/camera.hpp" @@ -17,7 +18,6 @@ #include "app/internal/monitoring/all_metrics.hpp" #include #include -#include #include #include @@ -54,7 +54,7 @@ namespace VTX::App _systemHandlerPtr->reference( SCENE_KEY, &scene ); // Create renderer - _renderer = std::make_unique( 1920, 1080, Util::Filesystem::getExecutableDir() / "shaders" ); + RENDERER().get().init(); // Regsiter loop events onUpdate += []( const float p_elapsedTime ) { SCENE().update( p_elapsedTime ); }; @@ -181,14 +181,6 @@ namespace VTX::App // } } - // void VTXApp::_applyCameraUniforms() const - //{ - // // TODO: do not apply each frame, only when camera changes. - // _renderer->setMatrixView( SCENE().getCamera().getViewMatrix() ); - // _renderer->setMatrixProjection( SCENE().getCamera().getProjectionMatrix() ); - // _renderer->setCameraClipInfos( SCENE().getCamera().getNear(), SCENE().getCamera().getFar() ); - // } - // bool VTXApp::hasAnyModifications() const // { // const bool hasSavePath = !getScenePathData().getCurrentPath().empty(); @@ -246,7 +238,6 @@ namespace VTX::App const Application::Settings & VTXApp::getSettings() const { return *_settings; } Application::Scene & SCENE() { return VTXApp::get().getScene(); } - Renderer::Facade & RENDERER() { return VTXApp::get().getRenderer(); } Application::Settings & SETTINGS() { return VTXApp::get().getSettings(); } } // namespace VTX::App diff --git a/lib/app/test/src/entt.cpp b/lib/app/test/src/entt.cpp index b0dd2dfef..3dd581582 100644 --- a/lib/app/test/src/entt.cpp +++ b/lib/app/test/src/entt.cpp @@ -96,13 +96,13 @@ TEST_CASE( "VTX_APP - Full sequence", "[integration]" ) const App::Core::ECS::View view = SCENE().getAllSceneItemsOfType(); REQUIRE( view.size() == 1 ); - const Component::Chemistry::Molecule & moleculeComponent - = MAIN_REGISTRY().getComponent( moleculeEntity ); + // const Component::Chemistry::Molecule & moleculeComponent + // = MAIN_REGISTRY().getComponent( moleculeEntity ); - const Component::Render::ProxyMolecule & gpuProxyComponent - = MAIN_REGISTRY().getComponent( moleculeEntity ); + // const Component::Render::ProxyMolecule & gpuProxyComponent + // = MAIN_REGISTRY().getComponent( moleculeEntity ); - REQUIRE( gpuProxyComponent.getProxy().atomNames == &moleculeComponent.getMoleculeStruct().atomNames ); + // REQUIRE( gpuProxyComponent.getProxy().atomNames == &moleculeComponent.getMoleculeStruct().atomNames ); } TEST_CASE( "VTX_APP - Benchmark", "[.][perfs]" ) diff --git a/lib/app/test/src/serialization.cpp b/lib/app/test/src/serialization.cpp index 61537f7d0..0f3646585 100644 --- a/lib/app/test/src/serialization.cpp +++ b/lib/app/test/src/serialization.cpp @@ -300,10 +300,11 @@ TEST_CASE( "VTX_APP - Serialization - Scene", "[unit]" ) App::Component::Chemistry::Molecule & molecule = VTXApp::get().getScene().getComponentByName( moleculeName ); - for ( size_t i = molecule.getResidue( 1 )->getIndexFirstAtom(); i <= molecule.getResidue( 1 )->getIndexLastAtom(); + for ( atom_index_t i = molecule.getResidue( 1 )->getIndexFirstAtom(); + i <= molecule.getResidue( 1 )->getIndexLastAtom(); i++ ) { - molecule.setAtomVisibility( i, false ); + molecule.getAtom( i )->setVisible( false ); } const FilePath jsonPath = Util::Filesystem::getExecutableDir() / "data/serialization/scene.vtx"; diff --git a/lib/core/include/core/struct/trajectory.hpp b/lib/core/include/core/struct/trajectory.hpp index 46211a505..3721283ee 100644 --- a/lib/core/include/core/struct/trajectory.hpp +++ b/lib/core/include/core/struct/trajectory.hpp @@ -20,6 +20,8 @@ namespace VTX::Core::Struct const Frame & getCurrentFrame() const { return frames[ currentFrameIndex ]; } Frame & getCurrentFrame() { return frames[ currentFrameIndex ]; } + size_t getFrameCount() const { return frames.size(); } + std::vector frames; size_t currentFrameIndex = 0; }; diff --git a/lib/python_binding/src/python_binding/api/selection/molecule_interpretor.cpp b/lib/python_binding/src/python_binding/api/selection/molecule_interpretor.cpp index c0f8a9355..efde5d24e 100644 --- a/lib/python_binding/src/python_binding/api/selection/molecule_interpretor.cpp +++ b/lib/python_binding/src/python_binding/api/selection/molecule_interpretor.cpp @@ -311,12 +311,12 @@ namespace VTX::PythonBinding::API::Selection const App::Application::Selection::MoleculeData::IndexRangeList & residueIDs = p_moleculeSelectionData.getResidueIds(); - if ( residueIDs.size() == 0 ) + if ( residueIDs.isEmpty() ) { const App::Application::Selection::MoleculeData::IndexRangeList & chainIDs = p_moleculeSelectionData.getChainIds(); - if ( chainIDs.size() == 0 ) + if ( chainIDs.isEmpty() ) { _addAtomsFollowingKwargs( 0, atom_index_t( molecule.getAtoms().size() - 1 ), molecule, p_moleculeSelectionData, p_kwargs diff --git a/lib/python_binding/src/python_binding/api/selection/selection_wrapper.cpp b/lib/python_binding/src/python_binding/api/selection/selection_wrapper.cpp index f5102c166..eb0492595 100644 --- a/lib/python_binding/src/python_binding/api/selection/selection_wrapper.cpp +++ b/lib/python_binding/src/python_binding/api/selection/selection_wrapper.cpp @@ -127,8 +127,7 @@ namespace VTX::PythonBinding::API::Selection App::Component::Chemistry::Molecule & mol = *it; const App::Application::Selection::MoleculeData & molSelection - = dynamic_cast( _selection->getSelectionData( *it ) - ); + = _selection->getSelectionDataFromComponent( mol ); for ( const atom_index_t & atomID : molSelection.getAtomIds() ) { diff --git a/lib/renderer/include/renderer/proxy/molecule.hpp b/lib/renderer/include/renderer/proxy/molecule.hpp index 0809196dd..bae061865 100644 --- a/lib/renderer/include/renderer/proxy/molecule.hpp +++ b/lib/renderer/include/renderer/proxy/molecule.hpp @@ -28,17 +28,17 @@ namespace VTX::Renderer::Proxy const uint idDefaultRepresentation = 0; - Util::Callback<> onTransform; // Move/rotate. - Util::Callback onVisible; // Show/hide the whole molecule. - Util::Callback onSelect; // Select/deselect the whole molecule. - Util::Callback onRepresentation; // Change the representation of the whole molecule. - Util::Callback<> onRemove; // Remove proxy. - Util::Callback<> onAtomPositions; // Update dynamics. - Util::Callback &> onAtomColors; // Update colors (ATOM/CHAIN/RESIDUE)... - Util::Callback &> onResidueColors; // Update colors (ATOM/CHAIN/RESIDUE)... - Util::Callback &, bool> onAtomVisibilities; // Update atom visibility with ranges. - Util::Callback &, bool> onAtomSelections; // Update atom selection with ranges. - Util::Callback &, uint> + Util::Callback<> onTransform; // Move/rotate. + Util::Callback onVisible; // Show/hide the whole molecule. + Util::Callback onSelect; // Select/deselect the whole molecule. + Util::Callback onRepresentation; // Change the representation of the whole molecule. + Util::Callback<> onRemove; // Remove proxy. + Util::Callback<> onAtomPositions; // Update dynamics. + Util::Callback> onAtomColors; // Update colors (ATOM/CHAIN/RESIDUE)... + Util::Callback> onResidueColors; // Update colors (ATOM/CHAIN/RESIDUE)... + Util::Callback, bool> onAtomVisibilities; // Update atom visibility with ranges. + Util::Callback, bool> onAtomSelections; // Update atom selection with ranges. + Util::Callback, uint> onAtomRepresentations; // Update atom representations with ranges. }; diff --git a/lib/renderer/src/renderer/renderer.cpp b/lib/renderer/src/renderer/renderer.cpp index c404b0ee6..b7d6e6ffc 100644 --- a/lib/renderer/src/renderer/renderer.cpp +++ b/lib/renderer/src/renderer/renderer.cpp @@ -176,7 +176,7 @@ namespace VTX::Renderer _context->setSubData( *p_proxy.atomPositions, "SpheresCylindersPositions", cacheSC.offset ); }; - p_proxy.onAtomColors += [ this, &p_proxy ]( std::vector & p_colors ) + p_proxy.onAtomColors += [ this, &p_proxy ]( const std::vector & p_colors ) { Cache::SphereCylinder & cacheSC = _cacheSpheresCylinders[ &p_proxy ]; _context->setSubData( p_colors, "SpheresCylindersColors", cacheSC.offset ); diff --git a/lib/ui/include/ui/core/base_ui_application.hpp b/lib/ui/include/ui/core/base_ui_application.hpp index 2cbde718e..25bdd70c9 100644 --- a/lib/ui/include/ui/core/base_ui_application.hpp +++ b/lib/ui/include/ui/core/base_ui_application.hpp @@ -28,10 +28,9 @@ namespace VTX::UI::Core virtual void _initVTXApp( const std::vector & p_args ); virtual void _initUI( const std::vector & p_args ) = 0; void _buildUI(); + virtual void _startUI( const std::vector & p_args ) = 0; virtual void _postInit( const std::vector & p_args ); - - virtual void _handleArgs( const std::vector & p_args ); }; } // namespace VTX::UI::Core diff --git a/lib/ui/include/ui/internal/animation/translation.hpp b/lib/ui/include/ui/internal/animation/translation.hpp index 607e2f2a3..61a0addd0 100644 --- a/lib/ui/include/ui/internal/animation/translation.hpp +++ b/lib/ui/include/ui/internal/animation/translation.hpp @@ -30,7 +30,7 @@ namespace VTX::UI::Internal::Animation class Translation : public UI::Core::Animation::BaseAnimation { private: - inline static const float TRANSLATION_THRESHOLD = 1e-4f; + inline static const float TRANSLATION_THRESHOLD = 0.1f; public: inline static const Util::Hashing::Hash ANIMATION_ID = Util::Hashing::hash( "INTERNAL_TRANSLATION" ); diff --git a/lib/ui/include/ui/qt/application_qt.hpp b/lib/ui/include/ui/qt/application_qt.hpp index b0df0a571..a29dd7668 100644 --- a/lib/ui/include/ui/qt/application_qt.hpp +++ b/lib/ui/include/ui/qt/application_qt.hpp @@ -5,7 +5,6 @@ #include "ui/environment.hpp" #include "ui/qt/input/_fwd.hpp" #include "ui/qt/mode/_fwd.hpp" -#include "ui/qt/renderer_qt.hpp" #include #include #include @@ -51,7 +50,7 @@ namespace VTX::UI::QT protected: void _initUI( const std::vector & p_args ) override; - void _postInit( const std::vector & p_args ) override; + void _startUI( const std::vector & p_args ) override; void _initQt(); void _instantiateMainWindow(); @@ -70,7 +69,6 @@ namespace VTX::UI::QT inline ApplicationQt * const QT_APP() { return VTX::UI::Environment::get().getUIApp(); } Mode::BaseMode & MODE(); - RendererQt QT_RENDERER(); } // namespace VTX::UI::QT diff --git a/lib/ui/include/ui/qt/renderer_qt.hpp b/lib/ui/include/ui/qt/renderer_qt.hpp deleted file mode 100644 index e8ff639d2..000000000 --- a/lib/ui/include/ui/qt/renderer_qt.hpp +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef __VTX_UI_QT_RENDERER__ -#define __VTX_UI_QT_RENDERER__ - -#include - -namespace VTX::UI::QT -{ - class RendererQt - { - private: - inline static int MAKE_CURRENT_COUNT = 0; - - public: - RendererQt( Renderer::Facade & p_renderer ); - ~RendererQt(); - - Renderer::Facade & get(); - const Renderer::Facade & get() const; - - private: - Renderer::Facade & _rendererFacade; - }; -} // namespace VTX::UI::QT - -#endif diff --git a/lib/ui/include/ui/qt/tool/render/widget/opengl_widget.hpp b/lib/ui/include/ui/qt/tool/render/widget/opengl_widget.hpp index 1c0badf8c..6e5ace88e 100644 --- a/lib/ui/include/ui/qt/tool/render/widget/opengl_widget.hpp +++ b/lib/ui/include/ui/qt/tool/render/widget/opengl_widget.hpp @@ -34,6 +34,9 @@ namespace VTX void _setupUi( const QString & p_name ) override {} void _setupSlots() override {} + + private: + int _makeCurrentCounter = 0; }; } // namespace UI::QT::Tool::Render::Widget diff --git a/lib/ui/src/ui/core/base_ui_application.cpp b/lib/ui/src/ui/core/base_ui_application.cpp index 707587fb5..097f700bb 100644 --- a/lib/ui/src/ui/core/base_ui_application.cpp +++ b/lib/ui/src/ui/core/base_ui_application.cpp @@ -21,7 +21,7 @@ namespace VTX::UI::Core _initVTXApp( p_args ); _initUI( p_args ); _buildUI(); - _handleArgs( p_args ); + _startUI( p_args ); _postInit( p_args ); } @@ -30,18 +30,6 @@ namespace VTX::UI::Core { App::VTXApp::get().start( p_args ); } - void BaseUIApplication::_postInit( const std::vector & p_args ) - { -#ifndef VTX_PRODUCTION - if ( p_args.size() == 0 ) - { - // VTX_ACTION( - // new App::Old::Action::Main::Open( Util::Filesystem::getDataPath( FilePath( "4hhb.pdb" ) ).absolute() ) - //); - // App::Application::VTX_ACTION( new App::Old::Action::Main::OpenApi( "1aga" ) ); - } -#endif - } void BaseUIApplication::_buildUI() { @@ -52,13 +40,7 @@ namespace VTX::UI::Core layoutBuilder.build( reader.getResult().layoutDescriptor ); } - void BaseUIApplication::update() { App::VTXApp::get().update(); } - - void BaseUIApplication::stop() { App::VTXApp::get().stop(); } - - void BaseUIApplication::quit() {}; - - void BaseUIApplication::_handleArgs( const std::vector & p_args ) + void BaseUIApplication::_postInit( const std::vector & p_args ) { using FILE_TYPE_ENUM = VTX::IO::Internal::Filesystem::FILE_TYPE_ENUM; for ( const std::string & p_arg : p_args ) @@ -96,6 +78,22 @@ namespace VTX::UI::Core } } } + +#ifndef VTX_PRODUCTION + if ( p_args.size() == 0 ) + { + // VTX_ACTION( + // new App::Old::Action::Main::Open( Util::Filesystem::getDataPath( FilePath( "4hhb.pdb" ) ).absolute() ) + //); + // App::Application::VTX_ACTION( new App::Old::Action::Main::OpenApi( "1aga" ) ); + } +#endif } + void BaseUIApplication::update() { App::VTXApp::get().update(); } + + void BaseUIApplication::stop() { App::VTXApp::get().stop(); } + + void BaseUIApplication::quit() {}; + } // namespace VTX::UI::Core diff --git a/lib/ui/src/ui/internal/animation/translation.cpp b/lib/ui/src/ui/internal/animation/translation.cpp index baac19ab5..9b59363db 100644 --- a/lib/ui/src/ui/internal/animation/translation.cpp +++ b/lib/ui/src/ui/internal/animation/translation.cpp @@ -13,8 +13,8 @@ namespace VTX::UI::Internal::Animation _info.targetPtr->setPosition( _info.startPosition ); _info.targetPtr->setRotation( _info.startRotation ); - const bool needAnimation - = Util::Math::distance( _info.startPosition, _info.finalPosition ) > TRANSLATION_THRESHOLD; + const float translationDistance = Util::Math::distance( _info.startPosition, _info.finalPosition ); + const bool needAnimation = translationDistance > TRANSLATION_THRESHOLD; if ( !needAnimation ) stop(); diff --git a/lib/ui/src/ui/qt/application_qt.cpp b/lib/ui/src/ui/qt/application_qt.cpp index 41a68db22..3e45a9f36 100644 --- a/lib/ui/src/ui/qt/application_qt.cpp +++ b/lib/ui/src/ui/qt/application_qt.cpp @@ -103,10 +103,8 @@ namespace VTX::UI::QT _mainWindow = WidgetFactory::get().instantiateWidget( nullptr, "MainWindow" ); } - void ApplicationQt::_postInit( const std::vector & p_args ) + void ApplicationQt::_startUI( const std::vector & p_args ) { - Core::BaseUIApplication::_postInit( p_args ); - _mainWindow->show(); _mainWindow->initWindowLayout(); } @@ -146,6 +144,5 @@ namespace VTX::UI::QT } Mode::BaseMode & MODE() { return QT_APP()->getCurrentMode(); } - RendererQt QT_RENDERER() { return RendererQt( App::RENDERER() ); }; } // namespace VTX::UI::QT diff --git a/lib/ui/src/ui/qt/controller/selection_picker.cpp b/lib/ui/src/ui/qt/controller/selection_picker.cpp index e531d4529..e0a6adf34 100644 --- a/lib/ui/src/ui/qt/controller/selection_picker.cpp +++ b/lib/ui/src/ui/qt/controller/selection_picker.cpp @@ -2,13 +2,13 @@ #include "ui/qt/application_qt.hpp" #include "ui/qt/input/input_manager.hpp" #include "ui/qt/main_window.hpp" -#include "ui/qt/renderer_qt.hpp" #include "ui/qt/tool/render/widget/render_widget.hpp" #include #include #include #include #include +#include #include #include #include @@ -47,7 +47,8 @@ namespace VTX::UI::QT::Controller void SelectionPicker::_onMouseLeftClick( const Vec2i & p_mousePos ) { - const PickingInfo pickingInfo = PickingInfo( QT_RENDERER().get().getPickedIds( p_mousePos.x, p_mousePos.y ) ); + const PickingInfo pickingInfo + = PickingInfo( App::RENDERER().facade().getPickedIds( p_mousePos.x, p_mousePos.y ) ); _performSelection( pickingInfo ); _lastPickingInfo = pickingInfo; @@ -55,7 +56,8 @@ namespace VTX::UI::QT::Controller void SelectionPicker::_onMouseRightClick( const Vec2i & p_mousePos ) { - const PickingInfo pickingInfo = PickingInfo( QT_RENDERER().get().getPickedIds( p_mousePos.x, p_mousePos.y ) ); + const PickingInfo pickingInfo + = PickingInfo( App::RENDERER().facade().getPickedIds( p_mousePos.x, p_mousePos.y ) ); if ( !_isTargetSelected( pickingInfo ) ) { @@ -80,7 +82,8 @@ namespace VTX::UI::QT::Controller void SelectionPicker::_onMouseLeftDoubleClick( const Vec2i & p_mousePos ) { - const PickingInfo pickingInfo = PickingInfo( QT_RENDERER().get().getPickedIds( p_mousePos.x, p_mousePos.y ) ); + const PickingInfo pickingInfo + = PickingInfo( App::RENDERER().facade().getPickedIds( p_mousePos.x, p_mousePos.y ) ); if ( !pickingInfo.hasValue() || pickingInfo != _lastPickingInfo ) return; @@ -94,15 +97,15 @@ namespace VTX::UI::QT::Controller void SelectionPicker::_performSelection( const PickingInfo & p_pickingInfo ) const { // Append to selection if CTRL modifier pressed. - const App::Application::Selection::AssignmentType assignmentType + const App::Component::Scene::Pickable::PickType pickType = INPUT_MANAGER().isModifierExclusive( Input::ModifierEnum::Ctrl ) - ? App::Application::Selection::AssignmentType::APPEND - : App::Application::Selection::AssignmentType::SET; + ? App::Component::Scene::Pickable::PickType::TOGGLE + : App::Component::Scene::Pickable::PickType::SET; if ( !p_pickingInfo.hasValue() ) { - // Clear selection when the user clicks in void. - if ( assignmentType == App::Application::Selection::AssignmentType::SET ) + // Clear selection when the user clicks in void without modfiers. + if ( pickType == App::Component::Scene::Pickable::PickType::SET ) { App::CURRENT_SELECTION().clear(); } @@ -112,7 +115,7 @@ namespace VTX::UI::QT::Controller const auto pickableComponentOptional = _tryGetPickableFromUid( p_pickingInfo.getFirst() ); if ( pickableComponentOptional ) - pickableComponentOptional->pick( p_pickingInfo, assignmentType ); + pickableComponentOptional->pick( p_pickingInfo, pickType ); } } diff --git a/lib/ui/src/ui/qt/renderer_qt.cpp b/lib/ui/src/ui/qt/renderer_qt.cpp deleted file mode 100644 index 169279a56..000000000 --- a/lib/ui/src/ui/qt/renderer_qt.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include "ui/qt/renderer_qt.hpp" -#include "ui/qt/application_qt.hpp" -#include "ui/qt/main_window.hpp" -#include "ui/qt/tool/render/widget/render_widget.hpp" -#include - -namespace VTX::UI::QT -{ - RendererQt::RendererQt( Renderer::Facade & p_rendererFacade ) : _rendererFacade( p_rendererFacade ) - { - if ( MAKE_CURRENT_COUNT == 0 ) - QT_APP()->getMainWindow().getRender()->makeCurrentContext(); - - MAKE_CURRENT_COUNT++; - } - RendererQt::~RendererQt() - { - MAKE_CURRENT_COUNT--; - - if ( MAKE_CURRENT_COUNT == 0 ) - QT_APP()->getMainWindow().getRender()->doneCurrentContext(); - } - - Renderer::Facade & RendererQt::get() { return _rendererFacade; } - const Renderer::Facade & RendererQt::get() const { return _rendererFacade; } - -} // namespace VTX::UI::QT diff --git a/lib/ui/src/ui/qt/tool/render/widget/opengl_widget.cpp b/lib/ui/src/ui/qt/tool/render/widget/opengl_widget.cpp index 0431b4a9f..d76495602 100644 --- a/lib/ui/src/ui/qt/tool/render/widget/opengl_widget.cpp +++ b/lib/ui/src/ui/qt/tool/render/widget/opengl_widget.cpp @@ -1,9 +1,12 @@ #include "ui/qt/tool/render/widget/opengl_widget.hpp" #include "ui/qt/application_qt.hpp" #include +#include #include +#include #include #include +#include #include #include #include @@ -21,18 +24,6 @@ namespace VTX::UI::QT::Tool::Render::Widget format.setSwapBehavior( QSurfaceFormat::DoubleBuffer ); format.setSwapInterval( 0 ); QSurfaceFormat::setDefaultFormat( format ); - - // TO_REMOVE : Force update camera position - App::VTXApp::get().onUpdate += []( const float p_deltaTime ) - { - const App::Component::Scene::Transform & transformComponent - = App::MAIN_REGISTRY().getComponent( App::SCENE().getCamera() ); - - const App::Component::Render::ProxyCamera & proxyComponent - = App::MAIN_REGISTRY().getComponent( App::SCENE().getCamera() ); - - proxyComponent.getProxy().onCameraPosition( transformComponent.getPosition() ); - }; } OpenGLWidget::~OpenGLWidget() {} @@ -41,20 +32,55 @@ namespace VTX::UI::QT::Tool::Render::Widget { assert( context()->isValid() ); - App::RENDERER().build( defaultFramebufferObject() ); + _makeCurrentCounter++; + + // We are in openGL context here => direct access to renderer + VTX::Renderer::Facade & rendererFacade = App::RENDERER_SYSTEM().facade(); + + rendererFacade.build( defaultFramebufferObject() ); + rendererFacade.setProxyColorLayout( VTX::Core::ChemDB::Color::COLOR_LAYOUT_JMOL ); + rendererFacade.setProxyRepresentations( { VTX::Renderer::Proxy::Representation() } ); + + App::Component::Render::ProxyCamera & proxyCamera + = App::MAIN_REGISTRY().getComponent( App::SCENE().getCamera() ); + proxyCamera.setInRenderer( rendererFacade ); + + App::RENDERER_SYSTEM().onGet += [ this ]() + { + if ( _makeCurrentCounter == 0 ) + makeCurrent(); + + _makeCurrentCounter++; + }; + App::RENDERER_SYSTEM().onRelease += [ this ]() + { + _makeCurrentCounter--; + + if ( _makeCurrentCounter == 0 ) + doneCurrent(); + }; + App::VTXApp::get().onPostRender += [ this ]( const float p_deltaTime ) { update(); }; - App::RENDERER().setProxyColorLayout( VTX::Core::ChemDB::Color::COLOR_LAYOUT_JMOL ); - App::RENDERER().setProxyRepresentations( { VTX::Renderer::Proxy::Representation() } ); + _makeCurrentCounter--; } - void OpenGLWidget::paintGL() { VTX::App::VTXApp::get().getRenderer().render( 0.15f ); } + void OpenGLWidget::paintGL() + { + _makeCurrentCounter++; + // We are in openGL context here => direct access to renderer + App::RENDERER_SYSTEM().facade().render( 0.15f ); + _makeCurrentCounter--; + } void OpenGLWidget::resizeGL( int p_width, int p_height ) { + _makeCurrentCounter++; App::SCENE().getCamera().setScreenSize( width(), height() ); - RendererQt renderer = QT_RENDERER(); - renderer.get().resize( p_width, p_height ); - renderer.get().setOutput( defaultFramebufferObject() ); + VTX::Renderer::Facade & rendererFacade = App::RENDERER_SYSTEM().facade(); + + rendererFacade.resize( p_width, p_height ); + rendererFacade.setOutput( defaultFramebufferObject() ); + _makeCurrentCounter--; } } // namespace VTX::UI::QT::Tool::Render::Widget diff --git a/lib/util/include/util/math/range_list.hpp b/lib/util/include/util/math/range_list.hpp index c9a213cca..5eecae1a0 100644 --- a/lib/util/include/util/math/range_list.hpp +++ b/lib/util/include/util/math/range_list.hpp @@ -127,6 +127,14 @@ namespace VTX::Util::Math addRange( range ); } } + RangeList( const std::initializer_list & p_values ) + { + for ( const T value : p_values ) + { + addValue( value ); + } + } + RangeList( const T & p_value ) { addValue( p_value ); } friend bool operator==( const RangeList & p_lhs, const RangeList & p_rhs ) { @@ -377,11 +385,15 @@ namespace VTX::Util::Math return false; } - void clear() { _ranges.clear(); } - bool isEmpty() const { return _ranges.size() == 0; } - size_t size() const + T getFirst() const { return _ranges.cbegin()->getFirst(); } + T getLast() const { return _ranges.crbegin()->getLast(); } + + void clear() { _ranges.clear(); } + bool isEmpty() const { return _ranges.size() == 0; } + + T count() const { - size_t res = 0; + T res = 0; for ( const Range & range : _ranges ) res += range.getCount();