KiCad PCB EDA Suite
Loading...
Searching...
No Matches
nl_3d_viewer_plugin_impl.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2024 3Dconnexion
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software: you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
22
23// 3d-viewer
26
27// KiCad includes
28#include <bitmaps.h>
29#include <navlib_safe_init.h>
30#include <tool/action_manager.h>
31#include <tool/tool_manager.h>
32#include <tool/tools_holder.h>
35
36// stdlib
37#include <map>
38#include <string>
39#include <vector>
40
41#include <wx/mstream.h>
42
50const wxChar* NL_3D_VIEWER_PLUGIN_IMPL::m_logTrace = wxT( "KI_TRACE_NL_3D_VIEWER_PLUGIN" );
51
52
61template <glm::length_t L, glm::length_t C, class T, glm::qualifier Q>
62bool equals( glm::mat<L, C, T, Q> const& aFirst, glm::mat<L, C, T, Q> const& aSecond,
63 T aEpsilon = static_cast<T>( FLT_EPSILON * 10 ) )
64{
65 T const* first = glm::value_ptr( aFirst );
66 T const* second = glm::value_ptr( aSecond );
67
68 for( glm::length_t j = 0; j < L * C; ++j )
69 {
70 if( !equals( first[j], second[j], aEpsilon ) )
71 {
72 return false;
73 }
74 }
75
76 return true;
77}
78
79
81 const std::string& aProfileHint ) :
82 NAV_3D( false, false ),
83 m_canvas( aCanvas ),
84 m_capIsMoving( false ),
85 m_newWidth( 0.0 )
86{
87 m_camera = dynamic_cast<TRACK_BALL*>( m_canvas->GetCamera() );
88
89 PutProfileHint( aProfileHint );
90}
91
92
94{
95 if( IsEnabled() )
96 EnableNavigation( false );
97}
98
99
101{
102 wxLogTrace( m_logTrace, wxT( "NL_3D_VIEWER_PLUGIN_IMPL::SetFocus %d" ), aFocus );
103 NAV_3D::Write( navlib::focus_k, aFocus );
104}
105
106
111
112
114{
115 SafeNavlibInit( [this]()
116 {
117 EnableNavigation( true );
118 PutFrameTimingSource( TimingSource::SpaceMouse );
120 } );
121}
122
123
124CATEGORY_STORE::iterator add_category( std::string aCategoryPath, CATEGORY_STORE& aCategoryStore )
125{
126 using TDx::SpaceMouse::CCategory;
127
128 CATEGORY_STORE::iterator parent_iter = aCategoryStore.begin();
129 std::string::size_type pos = aCategoryPath.find_last_of( '.' );
130
131 if( pos != std::string::npos )
132 {
133 std::string parentPath = aCategoryPath.substr( 0, pos );
134 parent_iter = aCategoryStore.find( parentPath );
135
136 if( parent_iter == aCategoryStore.end() )
137 {
138 parent_iter = add_category( parentPath, aCategoryStore );
139 }
140 }
141
142 std::string name = aCategoryPath.substr( pos + 1 );
143 std::unique_ptr<CCategory> categoryNode =
144 std::make_unique<CCategory>( aCategoryPath.c_str(), name.c_str() );
145
146 CATEGORY_STORE::iterator iter = aCategoryStore.insert(
147 aCategoryStore.end(), CATEGORY_STORE::value_type( aCategoryPath, categoryNode.get() ) );
148
149 parent_iter->second->push_back( std::move( categoryNode ) );
150 return iter;
151}
152
153
155{
156 wxLogTrace( m_logTrace, wxT( "NL_3D_VIEWER_PLUGIN_IMPL::exportCommandsAndImages" ) );
157
158 std::list<TOOL_ACTION*> actions = ACTION_MANAGER::GetActionList();
159
160 if( actions.size() == 0 )
161 {
162 return;
163 }
164
165 using TDx::SpaceMouse::CCommand;
166 using TDx::SpaceMouse::CCommandSet;
167
168 // The root action set node
169 CCommandSet commandSet( "EDA_3D_CANVAS", "3D Viewer" );
170
171 // Activate the command set
172 NAV_3D::PutActiveCommands( commandSet.GetId() );
173
174 // temporary store for the categories
175 CATEGORY_STORE categoryStore;
176
177 std::vector<TDx::CImage> vImages;
178
179 // add the action set to the category_store
180 categoryStore.insert( categoryStore.end(), CATEGORY_STORE::value_type( ".", &commandSet ) );
181
182 std::list<TOOL_ACTION*>::const_iterator it;
183
184 for( it = actions.begin(); it != actions.end(); ++it )
185 {
186 const TOOL_ACTION* action = *it;
187 std::string label = action->GetMenuLabel().ToStdString();
188
189 if( label.empty() )
190 {
191 continue;
192 }
193
194 std::string name = action->GetName();
195
196 // Do no export commands for the Pcbnew app.
197 if( name.rfind( "pcbnew.", 0 ) == 0 )
198 {
199 continue;
200 }
201
202 std::string strCategory = action->GetToolName();
203 CATEGORY_STORE::iterator iter = categoryStore.find( strCategory );
204
205 if( iter == categoryStore.end() )
206 {
207 iter = add_category( std::move( strCategory ), categoryStore );
208 }
209
210 std::string description = action->GetDescription().ToStdString();
211
212 // Arbitrary 8-bit data stream
213 wxMemoryOutputStream imageStream;
214
215 if( action->GetIcon() != BITMAPS::INVALID_BITMAP )
216 {
217 wxImage image = KiBitmap( action->GetIcon() ).ConvertToImage();
218 image.SaveFile( imageStream, wxBitmapType::wxBITMAP_TYPE_PNG );
219 image.Destroy();
220
221 if( imageStream.GetSize() )
222 {
223 wxStreamBuffer* streamBuffer = imageStream.GetOutputStreamBuffer();
224 TDx::CImage tdxImage = TDx::CImage::FromData( "", 0, name.c_str() );
225 tdxImage.AssignImage( std::string( reinterpret_cast<const char*>(
226 streamBuffer->GetBufferStart() ),
227 streamBuffer->GetBufferSize() ),
228 0 );
229
230 wxLogTrace( m_logTrace, wxT( "Adding image for : %s" ), name );
231 vImages.push_back( std::move( tdxImage ) );
232 }
233 }
234
235 wxLogTrace( m_logTrace, wxT( "Inserting command: %s, description: %s, in category: %s" ),
236 name, description, iter->first );
237
238 iter->second->push_back(
239 CCommand( std::move( name ), std::move( label ), std::move( description ) ) );
240 }
241
242 NAV_3D::AddCommandSet( commandSet );
243 NAV_3D::AddImages( vImages );
244}
245
246
247long NL_3D_VIEWER_PLUGIN_IMPL::GetCameraMatrix( navlib::matrix_t& matrix ) const
248{
249 // cache the camera matrix so that we can tell if the view has been moved and
250 // calculate a delta transform if required.
251 m_cameraMatrix = m_camera->GetViewMatrix();
252
253 std::copy_n( glm::value_ptr( glm::inverse( m_cameraMatrix ) ), 16, matrix.m );
254
255 return 0;
256}
257
258
259long NL_3D_VIEWER_PLUGIN_IMPL::GetPointerPosition( navlib::point_t& position ) const
260{
261 SFVEC3F origin, direction;
262 m_camera->MakeRayAtCurrentMousePosition( origin, direction );
263
264 position = { origin.x, origin.y, origin.z };
265
266 return 0;
267}
268
269
270long NL_3D_VIEWER_PLUGIN_IMPL::GetViewExtents( navlib::box_t& extents ) const
271{
272 if( m_camera->GetProjection() == PROJECTION_TYPE::PERSPECTIVE )
273 {
274 return navlib::make_result_code( navlib::navlib_errc::invalid_operation );
275 }
276
277 const CAMERA_FRUSTUM& f = m_camera->GetFrustum();
278
279 double half_width = f.fw / 2.;
280 double half_height = f.fh / 2.;
281 extents = { -half_width, -half_height, f.nearD, half_width, half_height, f.farD };
282
283 return 0;
284}
285
286
287long NL_3D_VIEWER_PLUGIN_IMPL::GetViewFOV( double& aFov ) const
288{
289 const CAMERA_FRUSTUM& f = m_camera->GetFrustum();
290
291 aFov = glm::radians( f.angle );
292 return 0;
293}
294
295
296long NL_3D_VIEWER_PLUGIN_IMPL::GetViewFrustum( navlib::frustum_t& aFrustum ) const
297{
298 if( m_camera->GetProjection() != PROJECTION_TYPE::PERSPECTIVE )
299 {
300 return navlib::make_result_code( navlib::navlib_errc::invalid_operation );
301 }
302
303 const CAMERA_FRUSTUM& f = m_camera->GetFrustum();
304 double half_width = f.nw / 2.;
305 double half_height = f.nh / 2.;
306 aFrustum = { -half_width, half_width, -half_height, half_height, f.nearD, f.farD };
307
308 return 0;
309}
310
311
312long NL_3D_VIEWER_PLUGIN_IMPL::GetIsViewPerspective( navlib::bool_t& perspective ) const
313{
314 perspective = m_camera->GetProjection() == PROJECTION_TYPE::PERSPECTIVE ? 1 : 0;
315
316 return 0;
317}
318
319
320long NL_3D_VIEWER_PLUGIN_IMPL::SetCameraMatrix( const navlib::matrix_t& aCameraMatrix )
321{
322 long result = 0;
323
324 glm::mat4 cam, viewMatrix;
325 std::copy_n( aCameraMatrix.m, 16, glm::value_ptr( cam ) );
326 viewMatrix = glm::inverse( cam );
327
328 glm::mat4 camera = m_camera->GetViewMatrix();
329
330 // The navlib does not move the camera in its z-axis in an orthographic projection
331 // as this does not change the viewed object size. However ...
332
333 if( m_camera->GetProjection() == PROJECTION_TYPE::ORTHO )
334 {
335 // ... the CAMERA class couples zoom and distance to the object: we need to
336 // ensure that The CAMERA's z position relative to the lookat_pos is not changed
337 // in an orthographic projection.
338 glm::vec4 lookat( m_camera->GetLookAtPos(), 1.0f );
339 glm::vec4 lookat_new = viewMatrix * lookat;
340 glm::vec4 lookat_old = camera * lookat;
341
342 viewMatrix[3].z += lookat_old.z - lookat_new.z;
343 }
344
345 if( !equals( camera, m_cameraMatrix ) )
346 {
347 // Some other input device has moved the camera. Apply only the intended delta
348 // transform ...
349 m_camera->SetViewMatrix( viewMatrix * glm::inverse( m_cameraMatrix ) * camera );
350 m_camera->Update();
351
352 // .., cache the intended camera matrix so that we can calculate the delta
353 // transform when needed ...
354 m_cameraMatrix = viewMatrix;
355
356 // ... and let the 3DMouse controller know, that something is amiss.
357 return navlib::make_result_code( navlib::navlib_errc::error );
358 }
359
360 m_camera->SetViewMatrix( viewMatrix );
361 m_camera->Update();
362
363 // cache the view matrix so that we know when it has changed.
364 m_cameraMatrix = m_camera->GetViewMatrix();
365
366 // The camera has a constraint on the z position so we need to check that ...
367
368 if( !equals( m_cameraMatrix[3].z, viewMatrix[3].z ) )
369 {
370 // ... and let the 3DMouse controller know, when something is amiss.
371 return navlib::make_result_code( navlib::navlib_errc::error );
372 }
373
374 return 0;
375}
376
377
378long NL_3D_VIEWER_PLUGIN_IMPL::SetViewExtents( const navlib::box_t& extents )
379{
380 const CAMERA_FRUSTUM& f = m_camera->GetFrustum();
381
382 float factor = f.nw / ( extents.max_x - extents.min_x );
383 float zoom = m_camera->GetZoom() / factor;
384
385 m_camera->Zoom( factor );
386
387 // The camera auto positions the camera to match the zoom values. We need to
388 // update our cached camera matrix to match the new z value
389 m_cameraMatrix[3].z = m_camera->GetViewMatrix()[3].z;
390
391 // The camera has a constraint on the zoom factor so we need to check that ...
392 if( zoom != m_camera->GetZoom() )
393 {
394 // ... and let the 3DMouse controller know, when something is amiss.
395 return navlib::make_result_code( navlib::navlib_errc::error );
396 }
397
398 return 0;
399}
400
401
403{
404 return navlib::make_result_code( navlib::navlib_errc::function_not_supported );
405}
406
407
408long NL_3D_VIEWER_PLUGIN_IMPL::SetViewFrustum( const navlib::frustum_t& frustum )
409{
410 return navlib::make_result_code( navlib::navlib_errc::permission_denied );
411}
412
413
414long NL_3D_VIEWER_PLUGIN_IMPL::GetModelExtents( navlib::box_t& extents ) const
415{
416 SFVEC3F min = m_canvas->GetBoardAdapter().GetBBox().Min();
417 SFVEC3F max = m_canvas->GetBoardAdapter().GetBBox().Max();
418
419 extents = { min.x, min.y, min.z, max.x, max.y, max.z };
420
421 return 0;
422}
423
424
425long NL_3D_VIEWER_PLUGIN_IMPL::GetSelectionExtents( navlib::box_t& extents ) const
426{
427 return navlib::make_result_code( navlib::navlib_errc::no_data_available );
428}
429
430
431long NL_3D_VIEWER_PLUGIN_IMPL::GetSelectionTransform( navlib::matrix_t& transform ) const
432{
433 return navlib::make_result_code( navlib::navlib_errc::no_data_available );
434}
435
436
438{
439 empty = true;
440
441 return 0;
442}
443
444
445long NL_3D_VIEWER_PLUGIN_IMPL::SetSelectionTransform( const navlib::matrix_t& matrix )
446{
447 return navlib::make_result_code( navlib::navlib_errc::invalid_operation );
448}
449
450
451long NL_3D_VIEWER_PLUGIN_IMPL::GetPivotPosition( navlib::point_t& position ) const
452{
453 SFVEC3F lap = m_camera->GetLookAtPos();
454
455 position = { lap.x, lap.y, lap.z };
456
457 return 0;
458}
459
460
461long NL_3D_VIEWER_PLUGIN_IMPL::IsUserPivot( navlib::bool_t& userPivot ) const
462{
463 userPivot = false;
464
465 return 0;
466}
467
468
469long NL_3D_VIEWER_PLUGIN_IMPL::SetPivotPosition( const navlib::point_t& position )
470{
471 SFVEC3F pivotPos = SFVEC3F( position.x, position.y, position.z );
472
473 // Set the 3dmouse pivot position.
474 m_canvas->Set3dmousePivotPos( pivotPos );
475
476 // Set the camera lookat pos.
477 m_camera->SetLookAtPos_T1( pivotPos );
478
479 m_canvas->Request_refresh();
480
481 return 0;
482}
483
484
485long NL_3D_VIEWER_PLUGIN_IMPL::GetPivotVisible( navlib::bool_t& visible ) const
486{
487 visible = m_canvas->GetRender3dmousePivot();
488
489 return 0;
490}
491
492
494{
495 m_canvas->SetRender3dmousePivot( visible );
496
497 m_canvas->Request_refresh();
498
499 return 0;
500}
501
502
503long NL_3D_VIEWER_PLUGIN_IMPL::GetHitLookAt( navlib::point_t& position ) const
504{
505 RAY mouseRay;
506 mouseRay.Init( m_rayOrigin, m_rayDirection );
507
508 float hit;
509 glm::vec3 vec;
510
511 // Test it with the board bounding box
512
513 if( m_canvas->GetBoardAdapter().GetBBox().Intersect( mouseRay, &hit ) )
514 {
515 vec = mouseRay.at( hit );
516 position = { vec.x, vec.y, vec.z };
517 return 0;
518 }
519
520 return navlib::make_result_code( navlib::navlib_errc::no_data_available );
521}
522
523
525{
526 return navlib::make_result_code( navlib::navlib_errc::function_not_supported );
527}
528
529
530long NL_3D_VIEWER_PLUGIN_IMPL::SetHitDirection( const navlib::vector_t& direction )
531{
532 m_rayDirection = { direction.x, direction.y, direction.z };
533
534 return 0;
535}
536
537
538long NL_3D_VIEWER_PLUGIN_IMPL::SetHitLookFrom( const navlib::point_t& eye )
539{
540 m_rayOrigin = { eye.x, eye.y, eye.z };
541
542 return 0;
543}
544
545
547{
548 return navlib::make_result_code( navlib::navlib_errc::function_not_supported );
549}
550
551
553{
554 if( commandId.empty() )
555 return 0;
556
557 std::list<TOOL_ACTION*> actions = ACTION_MANAGER::GetActionList();
558 TOOL_ACTION* context = nullptr;
559
560 for( std::list<TOOL_ACTION*>::const_iterator it = actions.begin(); it != actions.end(); it++ )
561 {
562 TOOL_ACTION* action = *it;
563 std::string nm = action->GetName();
564
565 if( commandId == nm )
566 context = action;
567 }
568
569 if( context != nullptr )
570 {
571 wxWindow* parent = m_canvas->GetParent();
572
573 // Only allow command execution if the window is enabled. i.e. there is not a modal dialog
574 // currently active.
575 if( parent && parent->IsEnabled() )
576 {
577 TOOLS_HOLDER* tools_holder = dynamic_cast<TOOLS_HOLDER*>( parent );
578 TOOL_MANAGER* tool_manager = tools_holder ? tools_holder->GetToolManager() : nullptr;
579
580 if( !tool_manager )
581 return navlib::make_result_code( navlib::navlib_errc::invalid_operation );
582
583 // Get the selection to use to test if the action is enabled
584 SELECTION& sel = tool_manager->GetToolHolder()->GetCurrentSelection();
585
586 bool runAction = true;
587
588 if( const ACTION_CONDITIONS* aCond = tool_manager->GetActionManager()->GetCondition( *context ) )
589 runAction = aCond->GetHotkeyCondition()( sel );
590
591 if( runAction )
592 {
593 tool_manager->RunAction( *context );
594 m_canvas->Request_refresh();
595 }
596 }
597 else
598 {
599 return navlib::make_result_code( navlib::navlib_errc::invalid_operation );
600 }
601 }
602
603 return 0;
604}
605
606
608{
609 return 0;
610}
611
612
614{
615 m_capIsMoving = value;
616
617 return 0;
618}
619
620
622{
623 if( value != 0L )
624 {
625 }
626 else
627 {
628 m_canvas->Request_refresh( true );
629 wxLogTrace( m_logTrace, wxT( "End of transaction" ) );
630 }
631
632 return 0;
633}
634
635
636long NL_3D_VIEWER_PLUGIN_IMPL::SetCameraTarget( const navlib::point_t& position )
637{
638 return navlib::make_result_code( navlib::navlib_errc::function_not_supported );
639}
640
641
642long NL_3D_VIEWER_PLUGIN_IMPL::GetFrontView( navlib::matrix_t& matrix ) const
643{
644 matrix = { 1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1 };
645 return 0;
646}
647
648
649long NL_3D_VIEWER_PLUGIN_IMPL::GetCoordinateSystem( navlib::matrix_t& matrix ) const
650{
651 // Use the right-handed coordinate system X-right, Z-up, Y-in (row vectors)
652 matrix = { 1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1 };
653 return 0;
654}
655
656
657long NL_3D_VIEWER_PLUGIN_IMPL::GetIsViewRotatable( navlib::bool_t& isRotatable ) const
658{
659 isRotatable = true;
660 return 0;
661}
const char * name
wxBitmap KiBitmap(BITMAPS aBitmap, int aHeightTag)
Construct a wxBitmap from an image identifier Returns the image from the active theme if the image ha...
Definition bitmap.cpp:100
@ INVALID_BITMAP
const ACTION_CONDITIONS * GetCondition(const TOOL_ACTION &aAction) const
Get the conditions to use for a specific tool action.
static std::list< TOOL_ACTION * > & GetActionList()
Return list of TOOL_ACTIONs.
Implement a canvas based on a wxGLCanvas.
long GetViewExtents(navlib::box_t &aExtents) const override
long GetCameraMatrix(navlib::matrix_t &aMatrix) const override
void Connect()
Connect plugin implementation to the driver.
long SetHitLookFrom(const navlib::point_t &aPosition) override
long SetActiveCommand(std::string aCommandId) override
EDA_3D_CANVAS * GetCanvas() const
Get the m_canvas pointer.
long GetPivotPosition(navlib::point_t &aPosition) const override
long GetModelExtents(navlib::box_t &aExtents) const override
long GetPointerPosition(navlib::point_t &aPosition) const override
long SetPivotVisible(bool aVisible) override
long SetTransaction(long aValue) override
long SetViewFOV(double aFov) override
long SetMotionFlag(bool aValue) override
long SetCameraMatrix(const navlib::matrix_t &aMatrix) override
long GetHitLookAt(navlib::point_t &aPosition) const override
long SetHitAperture(double aAperture) override
long SetPivotPosition(const navlib::point_t &aPosition) override
long SetHitDirection(const navlib::vector_t &aDirection) override
long GetSelectionTransform(navlib::matrix_t &aTransform) const override
long SetSelectionTransform(const navlib::matrix_t &aMatrix) override
long SetSettingsChanged(long aChangeNumber) override
long SetHitSelectionOnly(bool aSelectionOnly) override
long GetIsSelectionEmpty(navlib::bool_t &aEmpty) const override
long GetSelectionExtents(navlib::box_t &aExtents) const override
long GetCoordinateSystem(navlib::matrix_t &aMatrix) const override
long IsUserPivot(navlib::bool_t &aUserPivot) const override
long GetViewFOV(double &aFov) const override
long GetPivotVisible(navlib::bool_t &aVisible) const override
long GetFrontView(navlib::matrix_t &aMatrix) const override
NL_3D_VIEWER_PLUGIN_IMPL(EDA_3D_CANVAS *aCanvas, const std::string &aProfileHint)
Initializes a new instance of the NL_3DVIEWER_PLUGIN.
long GetViewFrustum(navlib::frustum_t &aFrustum) const override
long GetIsViewPerspective(navlib::bool_t &aPerspective) const override
long SetViewFrustum(const navlib::frustum_t &aFrustum) override
long SetViewExtents(const navlib::box_t &aExtents) override
virtual void exportCommandsAndImages()
Export the invocable actions and images to the 3Dconnexion UI.
void SetFocus(bool aFocus=true)
Set the connection to the 3Dconnexion driver to the focus state so that 3DMouse data is routed here.
long GetIsViewRotatable(navlib::bool_t &isRotatable) const override
long SetCameraTarget(const navlib::point_t &aPosition) override
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
virtual SELECTION & GetCurrentSelection()
Get the current selection from the canvas area.
Represent a single user action.
wxString GetMenuLabel() const
Return the translated label for the action.
BITMAPS GetIcon() const
Return an icon associated with the action.
std::string GetToolName() const
Return name of the tool associated with the action.
const std::string & GetName() const
Return name of the action.
wxString GetDescription() const
Master controller class:
bool RunAction(const std::string &aActionName, T aParam)
Run the specified action immediately, pausing the current action to run the new one.
TOOLS_HOLDER * GetToolHolder() const
ACTION_MANAGER * GetActionManager() const
static bool empty(const wxTextEntryBase *aCtrl)
static const wxChar * m_logTrace
Trace mask used to enable or disable the trace output of this class.
bool SafeNavlibInit(const std::function< void()> &aInitFunc)
Attempt to run the given function, recovering from both C++ exceptions and abort() calls triggered by...
Safe initialization wrapper for the 3Dconnexion navlib SDK.
bool equals(glm::mat< L, C, T, Q > const &aFirst, glm::mat< L, C, T, Q > const &aSecond, T aEpsilon=static_cast< T >(FLT_EPSILON *10))
Template to compare two glm::mat<T> values for equality within a required epsilon.
CATEGORY_STORE::iterator add_category(std::string aCategoryPath, CATEGORY_STORE &aCategoryStore)
Add a category to the store.
Declaration of the NL_3D_VIEWER_PLUGIN_IMPL class.
std::map< std::string, TDx::CCommandTreeNode * > CATEGORY_STORE
CATEGORY_STORE::iterator add_category(std::string aCategoryPath, CATEGORY_STORE &aCategoryStore)
Add a category to the store.
TDx::SpaceMouse::Navigation3D::CNavigation3D NAV_3D
Functors that can be used to figure out how the action controls should be displayed in the UI and if ...
Frustum is a implementation based on a tutorial by http://www.lighthouse3d.com/tutorials/view-frustum...
Definition camera.h:41
float angle
Definition camera.h:52
float farD
Definition camera.h:52
float nearD
Definition camera.h:52
Definition ray.h:59
void Init(const SFVEC3F &o, const SFVEC3F &d)
Definition ray.cpp:31
SFVEC3F at(float t) const
Definition ray.h:80
wxString result
Test unit parsing edge cases and error handling.
Declaration for a track ball camera.
glm::vec3 SFVEC3F
Definition xv3d_types.h:40