1#include <Gui/Viewer/Gizmo/TranslateGizmo.hpp>
3#include <Core/Containers/VectorArray.hpp>
4#include <Core/Geometry/MeshPrimitives.hpp>
5#include <Core/Utils/Color.hpp>
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>
16TranslateGizmo::TranslateGizmo( Engine::Scene::Component* c,
17 const Core::Transform& worldTo,
18 const Core::Transform& t,
20 Gizmo( c, worldTo, t, mode ),
21 m_startPoint( Core::Vector3::Zero() ),
22 m_initialPix( Core::Vector2::Zero() ),
24 m_selectedPlane( -1 ) {
25 constexpr Scalar arrowScale = .1_ra;
26 constexpr Scalar axisWidth = .05_ra;
27 constexpr Scalar arrowFrac = .15_ra;
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();
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 );
41 new Engine::Data::Mesh(
"Translate Gizmo Arrow" ) );
42 mesh->loadGeometry(
std::move( cylinder ) );
44 Engine::Rendering::RenderObject* arrowDrawable =
new Engine::Rendering::RenderObject(
45 "Translate Gizmo Arrow", m_comp, Engine::Rendering::RenderObjectType::UI );
47 arrowDrawable->setRenderTechnique( rt );
48 arrowDrawable->setMesh( mesh );
49 addRenderObject( arrowDrawable );
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;
60 Core::Geometry::TriangleMesh plane = Core::Geometry::makePlaneGrid(
61 1, 1, Core::Vector2( arrowScale / 8_ra, arrowScale / 8_ra ), T );
65 auto& normals = plane.normalsWithLock();
66 normals.getMap().fill( 0_ra );
67 plane.normalsUnlock();
72 Engine::Rendering::RenderObject* planeDrawable =
new Engine::Rendering::RenderObject(
73 "Gizmo Plane", m_comp, Engine::Rendering::RenderObjectType::UI );
75 planeDrawable->setRenderTechnique( rt );
76 planeDrawable->setMesh( mesh );
77 addRenderObject( planeDrawable );
80 updateTransform( mode, m_worldTo, m_transform );
83void TranslateGizmo::updateTransform( Gizmo::Mode mode,
84 const Core::Transform& worldTo,
85 const Core::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 );
99 for (
auto ro : ros() ) {
100 ro->setLocalTransform( m_worldTo * displayTransform );
104void TranslateGizmo::selectConstraint(
int drawableIdx ) {
106 if ( m_selectedAxis != -1 ) {
107 getControler( m_selectedAxis )->clearState();
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;
119 if ( drawableIdx < 0 ) {
return; }
122 auto found =
std::find_if( ros().cbegin(), ros().cend(), [drawableIdx](
const auto& ro ) {
123 return ro->getIndex() == Core::Utils::Index( drawableIdx );
125 if ( found != ros().cend() ) {
127 getControler( i )->setState();
128 ( i < 3 ) ? m_selectedAxis = i : m_selectedPlane = i - 3;
130 if ( m_selectedPlane != -1 ) {
131 getControler( ( m_selectedPlane + 1 ) % 3 )->setState();
132 getControler( ( m_selectedPlane + 2 ) % 3 )->setState();
138 const Core::Vector2& nextXY,
141 CORE_UNUSED( whole );
142 static const Scalar step = .2_ra;
144 if ( m_selectedAxis == -1 && m_selectedPlane == -1 )
return m_transform;
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 );
156 Ra::Core::Vector3 endPoint;
158 if ( m_selectedAxis > -1 ) {
159 found = findPointOnAxis( cam, origin, translateDir, m_initialPix + nextXY, endPoint, hits );
161 else if ( m_selectedPlane > -1 ) {
163 findPointOnPlane( cam, origin, translateDir, m_initialPix + nextXY, endPoint, hits );
170 m_startPoint = endPoint;
171 m_initialTrans = origin;
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;
184 const Core::Vector2& ) {
185 m_initialPix = Core::Vector2::Zero();
Camera class storing the Camera frame and the projection properties The view direction is -z in camer...
hepler function to manage enum as underlying types in VariableSet