26#include <glm/geometric.hpp>
47 gluQuadricNormals(
m_quadric, GLU_SMOOTH );
75 glEnable( GL_COLOR_MATERIAL );
76 glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE );
83 glMaterialfv( GL_FRONT_AND_BACK, GL_SPECULAR, &specular.r );
84 glMaterialf( GL_FRONT_AND_BACK, GL_SHININESS, 96.0f );
86 glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT, &ambient.r );
87 glMaterialfv( GL_FRONT_AND_BACK, GL_DIFFUSE, &diffuse.r );
88 glMaterialfv( GL_FRONT_AND_BACK, GL_EMISSION, &emissive.r );
96 bool inside = ( aMouseX >=
m_gizmoPosX && aMouseX <= m_gizmoPosX + smallViewportW && aMouseY >=
m_gizmoPosY
101 m_ndcX = 2.0f *
static_cast<float>( aMouseX -
m_gizmoPosX ) / smallViewportW - 1.0f;
102 m_ndcY = 2.0f *
static_cast<float>( aMouseY -
m_gizmoPosY ) / smallViewportH - 1.0f;
116 glDisable( GL_CULL_FACE );
120 glClear( GL_DEPTH_BUFFER_BIT );
122 glMatrixMode( GL_PROJECTION );
127 glMatrixMode( GL_MODELVIEW );
130 glm::mat4 TranslationMatrix = glm::translate( glm::mat4( 1.0f ),
SFVEC3F( 0.0f, 0.0f, -(
m_arrowSize * 2.75f ) ) );
131 glm::mat4 ViewMatrix = TranslationMatrix * aCameraRotationMatrix;
132 glLoadMatrixf( glm::value_ptr( ViewMatrix ) );
137 glm::mat4 proj = glm::perspective( glm::radians( fov ), 1.0f, 0.001f, 2.0f *
RANGE_SCALE_3D );
138 glm::mat4 invVP = glm::inverse( proj * ViewMatrix );
143 glm::vec4 rayStartWorld = invVP * rayStartNDC;
144 rayStartWorld /= rayStartWorld.w;
146 glm::vec4 rayEndWorld = invVP * rayEndNDC;
147 rayEndWorld /= rayEndWorld.w;
149 glm::vec3 rayOrigin = glm::vec3( rayStartWorld );
150 glm::vec3 rayDirection = glm::normalize( glm::vec3( rayEndWorld - rayStartWorld ) );
153 [](
const glm::vec3& aRayOrigin,
const glm::vec3& aRayDir,
const glm::vec3& aSphereCenter,
float aRadius )
155 glm::vec3 L = aSphereCenter - aRayOrigin;
156 float tca = glm::dot( L, aRayDir );
157 float d2 = glm::dot( L, L ) - tca * tca;
158 return d2 <= aRadius * aRadius;
161 int clickedIndex = -1;
163 for(
size_t i = 0; i <
m_spheres.size(); ++i )
166 if( intersects( rayOrigin, rayDirection, sphere.m_position, sphere.m_radius ) )
168 clickedIndex =
static_cast<int>( i );
176 for(
size_t i = 0; i <
m_spheres.size(); ++i )
178 if(
static_cast<int>( i ) == clickedIndex )
180 m_spheres[i].m_color = { 1.0f, 1.0f, 1.0f };
190 auto drawBillboardCircle = [](
const glm::vec3& aCenter,
float aRadius,
const glm::vec3& aColor,
191 const glm::vec3& aCamRight,
const glm::vec3& aCamUp,
int aSegments = 64 )
193 float thickness = aRadius * 0.4f;
194 glColor3f( aColor.r, aColor.g, aColor.b );
196 glBegin( GL_TRIANGLE_STRIP );
197 for(
int i = 0; i <= aSegments; ++i )
199 float angle = 2.0f * glm::pi<float>() * i / aSegments;
200 glm::vec3 dir = cos( angle ) * aCamRight + sin( angle ) * aCamUp;
202 glm::vec3 outer = aCenter + dir * ( aRadius + thickness * 0.5f );
203 glm::vec3 inner = aCenter + dir * ( aRadius - thickness * 0.5f );
205 glVertex3f( outer.x, outer.y, outer.z );
206 glVertex3f( inner.x, inner.y, inner.z );
211 glm::vec3 camRight( aCameraRotationMatrix[0][0], aCameraRotationMatrix[1][0], aCameraRotationMatrix[2][0] );
212 glm::vec3 camUp( aCameraRotationMatrix[0][1], aCameraRotationMatrix[1][1], aCameraRotationMatrix[2][1] );
214 glEnable( GL_BLEND );
215 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
219 glColor4f( sphere.m_color.r, sphere.m_color.g, sphere.m_color.b, 0.3f );
221 glTranslatef( sphere.m_position.x, sphere.m_position.y, sphere.m_position.z );
224 gluSphere(
m_quadric, sphere.m_radius, 32, 32 );
228 drawBillboardCircle( sphere.m_position, sphere.m_radius, sphere.m_color, camRight, camUp );
233 glDisable( GL_DEPTH_TEST );
234 glDisable( GL_LIGHTING );
236 std::array<std::string, 6> labels = {
"X",
"",
"Y",
"",
"Z",
"" };
240 glm::vec3 offset = glm::normalize( -rayDirection ) * 0.02f;
242 glColor4f( 0.0f, 0.0f, 0.0f, 1.0f );
244 auto drawX = [](
const glm::vec3& aPos,
float aSize,
const glm::vec3& aColor,
const glm::vec3& aCamRight,
245 const glm::vec3& aCamUp )
247 glColor3f( aColor.r, aColor.g, aColor.b );
250 float h = aSize * 0.5f;
253 glm::vec3 dir1 = ( -aCamRight + aCamUp ) * h;
254 glm::vec3 dir2 = ( -aCamRight - aCamUp ) * h;
257 glVertex3f( ( aPos - dir1 ).x, ( aPos - dir1 ).y, ( aPos - dir1 ).z );
258 glVertex3f( ( aPos + dir1 ).x, ( aPos + dir1 ).y, ( aPos + dir1 ).z );
260 glVertex3f( ( aPos - dir2 ).x, ( aPos - dir2 ).y, ( aPos - dir2 ).z );
261 glVertex3f( ( aPos + dir2 ).x, ( aPos + dir2 ).y, ( aPos + dir2 ).z );
265 auto drawY = [](
const glm::vec3& aPos,
float aSize,
const glm::vec3& aColor,
const glm::vec3& aCamRight,
266 const glm::vec3& aCamUp )
268 glColor3f( aColor.r, aColor.g, aColor.b );
271 float h = aSize * 0.5f;
274 glm::vec3 topLeft = aPos + aCamUp * h - aCamRight * h;
275 glm::vec3 topRight = aPos + aCamUp * h + aCamRight * h;
276 glm::vec3 bottom = aPos - aCamUp * h;
279 glVertex3f( topLeft.x, topLeft.y, topLeft.z );
280 glVertex3f( aPos.x, aPos.y, aPos.z );
282 glVertex3f( topRight.x, topRight.y, topRight.z );
283 glVertex3f( aPos.x, aPos.y, aPos.z );
285 glVertex3f( aPos.x, aPos.y, aPos.z );
286 glVertex3f( bottom.x, bottom.y, bottom.z );
290 auto drawZ = [](
const glm::vec3& aPos,
float aSize,
const glm::vec3& aColor,
const glm::vec3& aCamRight,
291 const glm::vec3& aCamUp )
293 glColor3f( aColor.r, aColor.g, aColor.b );
296 float h = aSize * 0.5f;
299 glm::vec3 topLeft = aPos + aCamUp * h - aCamRight * h;
300 glm::vec3 topRight = aPos + aCamUp * h + aCamRight * h;
301 glm::vec3 bottomLeft = aPos - aCamUp * h - aCamRight * h;
302 glm::vec3 bottomRight = aPos - aCamUp * h + aCamRight * h;
304 glBegin( GL_LINE_STRIP );
305 glVertex3f( topLeft.x, topLeft.y, topLeft.z );
306 glVertex3f( topRight.x, topRight.y, topRight.z );
307 glVertex3f( bottomLeft.x, bottomLeft.y, bottomLeft.z );
308 glVertex3f( bottomRight.x, bottomRight.y, bottomRight.z );
312 for(
size_t i = 0; i <
m_spheres.size(); ++i )
314 if( labels[i].
empty() )
317 glm::vec3 textPos =
m_spheres[i].m_position + offset;
318 const std::string& label = labels[i];
322 drawX( textPos, 0.30f, glm::vec3( 0.0f ), camRight, camUp );
324 else if( label ==
"Y" )
326 drawY( textPos, 0.30f, glm::vec3( 0.0f ), camRight, camUp );
328 else if( label ==
"Z" )
330 drawZ( textPos, 0.30f, glm::vec3( 0.0f ), camRight, camUp );
334 glEnable( GL_LIGHTING );
335 glEnable( GL_DEPTH_TEST );
341 glColor3f( 0.9f, 0.0f, 0.0f );
342 glVertex3f( 0.0f, 0.0f, 0.0f );
345 glColor3f( 0.0f, 0.9f, 0.0f );
346 glVertex3f( 0.0f, 0.0f, 0.0f );
349 glColor3f( 0.0f, 0.0f, 0.9f );
350 glVertex3f( 0.0f, 0.0f, 0.0f );
355 glEnable( GL_CULL_FACE );
#define RANGE_SCALE_3D
This defines the range that all coord will have to be rendered.
GizmoSphereSelection
Enum to indicate which sphere (direction) is selected.
@ None
No sphere selected.
void handleMouseInput(int aMouseX, int aMouseY)
void render3dSpheresGizmo(glm::mat4 aCameraRotationMatrix)
std::array< GizmoSphere, 6 > m_spheres
List of all directional gizmo spheres.
GizmoSphereSelection getSelectedGizmoSphere() const
std::tuple< int, int, int, int > getViewport() const
void setViewport(int ax, int ay, int aWidth, int aHeight)
GizmoSphereSelection m_selectedGizmoSphere
SPHERES_GIZMO(int aGizmoPosX, int aGizmoPosY)
void resetSelectedGizmoSphere()
void setGizmoPosition(int ax, int ay)
static bool empty(const wxTextEntryBase *aCtrl)