Radium Engine  1.5.20
Loading...
Searching...
No Matches
TranslateGizmo.cpp
1#include <Gui/Viewer/Gizmo/TranslateGizmo.hpp>
2
3#include <Core/Containers/VectorArray.hpp>
4#include <Core/Geometry/MeshPrimitives.hpp>
5#include <Core/Utils/Color.hpp>
6
7#include <Core/Asset/Camera.hpp>
8#include <Engine/Data/Mesh.hpp>
9#include <Engine/Rendering/RenderObject.hpp>
10#include <Engine/Rendering/RenderTechnique.hpp>
11#include <Engine/Scene/CameraComponent.hpp>
12
13namespace Ra {
14namespace Gui {
15
16TranslateGizmo::TranslateGizmo( Engine::Scene::Component* c,
17 const Core::Transform& worldTo,
18 const Core::Transform& t,
19 Mode mode ) :
20 Gizmo( c, worldTo, t, mode ),
21 m_startPoint( Core::Vector3::Zero() ),
22 m_initialPix( Core::Vector2::Zero() ),
23 m_selectedAxis( -1 ),
24 m_selectedPlane( -1 ) {
25 constexpr Scalar arrowScale = .1_ra;
26 constexpr Scalar axisWidth = .05_ra;
27 constexpr Scalar arrowFrac = .15_ra;
28
29 for ( uint i = 0; i < 3; ++i ) {
30 Core::Vector3 cylinderEnd = Core::Vector3::Zero();
31 cylinderEnd[i] = ( 1_ra - arrowFrac );
32 Core::Vector3 arrowEnd = Core::Vector3::Zero();
33 arrowEnd[i] = 1_ra;
34 Core::Geometry::TriangleMesh cylinder = Core::Geometry::makeCylinder(
35 Core::Vector3::Zero(), arrowScale * cylinderEnd, arrowScale * axisWidth / 2_ra, 32 );
36 Core::Geometry::TriangleMesh cone = Core::Geometry::makeCone(
37 arrowScale * cylinderEnd, arrowScale * arrowEnd, arrowScale * arrowFrac / 2_ra, 32 );
38 cylinder.append( cone );
39
41 new Engine::Data::Mesh( "Translate Gizmo Arrow" ) );
42 mesh->loadGeometry( std::move( cylinder ) );
43
44 Engine::Rendering::RenderObject* arrowDrawable = new Engine::Rendering::RenderObject(
45 "Translate Gizmo Arrow", m_comp, Engine::Rendering::RenderObjectType::UI );
46 auto rt = std::shared_ptr<Engine::Rendering::RenderTechnique>( makeRenderTechnique( i ) );
47 arrowDrawable->setRenderTechnique( rt );
48 arrowDrawable->setMesh( mesh );
49 addRenderObject( arrowDrawable );
50 }
51
52 for ( uint i = 0; i < 3; ++i ) {
53 Core::Vector3 axis = Core::Vector3::Zero();
54 axis[( i == 0 ? 1 : ( i == 1 ? 0 : 2 ) )] = 1;
55 Core::Transform T = Core::Transform::Identity();
56 T.rotate( Core::AngleAxis( Core::Math::PiDiv2, axis ) );
57 T.translation()[( i + 1 ) % 3] += arrowScale / 8_ra * 3_ra;
58 T.translation()[( i + 2 ) % 3] += arrowScale / 8_ra * 3_ra;
59
60 Core::Geometry::TriangleMesh plane = Core::Geometry::makePlaneGrid(
61 1, 1, Core::Vector2( arrowScale / 8_ra, arrowScale / 8_ra ), T );
62
63 // \FIXME this hack is here to be sure the plane will be selected (see shader)
64
65 auto& normals = plane.normalsWithLock();
66 normals.getMap().fill( 0_ra );
67 plane.normalsUnlock();
68
69 std::shared_ptr<Engine::Data::Mesh> mesh( new Engine::Data::Mesh( "Gizmo Plane" ) );
70 mesh->loadGeometry( std::move( plane ) );
71
72 Engine::Rendering::RenderObject* planeDrawable = new Engine::Rendering::RenderObject(
73 "Gizmo Plane", m_comp, Engine::Rendering::RenderObjectType::UI );
74 auto rt = std::shared_ptr<Engine::Rendering::RenderTechnique>( makeRenderTechnique( i ) );
75 planeDrawable->setRenderTechnique( rt );
76 planeDrawable->setMesh( mesh );
77 addRenderObject( planeDrawable );
78 }
79
80 updateTransform( mode, m_worldTo, m_transform );
81}
82
83void TranslateGizmo::updateTransform( Gizmo::Mode mode,
84 const Core::Transform& worldTo,
85 const Core::Transform& t ) {
86 m_mode = mode;
87 m_worldTo = worldTo;
88 m_transform = t;
89 Core::Transform displayTransform = Core::Transform::Identity();
90 displayTransform.translate( m_transform.translation() );
91 if ( m_mode == LOCAL ) {
92 Core::Matrix3 R = m_transform.rotation();
93 R.col( 0 ).normalize();
94 R.col( 1 ).normalize();
95 R.col( 2 ).normalize();
96 displayTransform.rotate( R );
97 }
98
99 for ( auto ro : ros() ) {
100 ro->setLocalTransform( m_worldTo * displayTransform );
101 }
102}
103
104void TranslateGizmo::selectConstraint( int drawableIdx ) {
105 // deselect previously selected axis
106 if ( m_selectedAxis != -1 ) {
107 getControler( m_selectedAxis )->clearState();
108 m_selectedAxis = -1;
109 }
110 // deselect previously selected plane
111 if ( m_selectedPlane != -1 ) {
112 getControler( m_selectedPlane + 3 )->clearState();
113 getControler( ( m_selectedPlane + 1 ) % 3 )->clearState();
114 getControler( ( m_selectedPlane + 2 ) % 3 )->clearState();
115 m_selectedPlane = -1;
116 }
117
118 // Return if no component is selected
119 if ( drawableIdx < 0 ) { return; }
120
121 // update the state of the selected component
122 auto found = std::find_if( ros().cbegin(), ros().cend(), [drawableIdx]( const auto& ro ) {
123 return ro->getIndex() == Core::Utils::Index( drawableIdx );
124 } );
125 if ( found != ros().cend() ) {
126 int i = int( std::distance( ros().cbegin(), found ) );
127 getControler( i )->setState();
128 ( i < 3 ) ? m_selectedAxis = i : m_selectedPlane = i - 3;
129 // Activate the axes correponding to the selected plane
130 if ( m_selectedPlane != -1 ) {
131 getControler( ( m_selectedPlane + 1 ) % 3 )->setState();
132 getControler( ( m_selectedPlane + 2 ) % 3 )->setState();
133 }
134 }
135}
136
137Core::Transform TranslateGizmo::mouseMove( const Core::Asset::Camera& cam,
138 const Core::Vector2& nextXY,
139 bool stepped,
140 bool whole ) {
141 CORE_UNUSED( whole );
142 static const Scalar step = .2_ra;
143
144 if ( m_selectedAxis == -1 && m_selectedPlane == -1 ) return m_transform;
145
146 // Get gizmo center and translation axis / plane normal
148 int axis = std::max( m_selectedAxis, m_selectedPlane );
149 const Core::Vector3 origin = m_transform.translation();
150 const Core::Vector3 translateDir =
151 m_mode == LOCAL ? Core::Vector3( m_transform.rotation() * Core::Vector3::Unit( axis ) )
152 : Core::Vector3::Unit( axis );
153
154 // Project the clicked points against the axis defined by the translation axis,
155 // or the planes defined by the translation plane.
156 Ra::Core::Vector3 endPoint;
157 bool found = false;
158 if ( m_selectedAxis > -1 ) {
159 found = findPointOnAxis( cam, origin, translateDir, m_initialPix + nextXY, endPoint, hits );
160 }
161 else if ( m_selectedPlane > -1 ) {
162 found =
163 findPointOnPlane( cam, origin, translateDir, m_initialPix + nextXY, endPoint, hits );
164 }
165
166 if ( found ) {
167 // Initialize translation
168 if ( !m_start ) {
169 m_start = true;
170 m_startPoint = endPoint;
171 m_initialTrans = origin;
172 }
173
174 // Apply translation
175 Ra::Core::Vector3 tr = endPoint - m_startPoint;
176 if ( stepped ) { tr = int( tr.norm() / step ) * step * tr.normalized(); }
177 m_transform.translation() = m_initialTrans + tr;
178 }
179
180 return m_transform;
181}
182
183void TranslateGizmo::setInitialState( const Core::Asset::Camera& /*cam*/,
184 const Core::Vector2& /*initialXY*/ ) {
185 m_initialPix = Core::Vector2::Zero();
186 m_start = false;
187}
188
189} // namespace Gui
190} // namespace Ra
Camera class storing the Camera frame and the projection properties The view direction is -z in camer...
Definition Camera.hpp:16
T distance(T... args)
T find_if(T... args)
T max(T... args)
T move(T... args)
hepler function to manage enum as underlying types in VariableSet
Definition Cage.cpp:3