Divide Framework 0.1
A free and open-source 3D Framework under heavy development
Loading...
Searching...
No Matches
ProjectManager.cpp
Go to the documentation of this file.
1
2
6
16
18
19#include "GUI/Headers/GUI.h"
21
27
31
34
38
41
47#include <filesystem>
48
49namespace Divide
50{
51
52 constexpr U16 BYTE_BUFFER_VERSION = 1u;
53
54 bool operator==( const SceneEntry& lhs, const SceneEntry& rhs ) noexcept
55 {
56 return Util::CompareIgnoreCase(lhs._name.c_str(), rhs._name.c_str());
57 }
58
59 bool Project::CreateNewProject( const ProjectID& projectID )
60 {
61 const ResourcePath sourceProjectPath = Paths::g_projectsLocation / Config::DEFAULT_PROJECT_NAME;
62 const ResourcePath targetProjectPath = Paths::g_projectsLocation / projectID._name;
63 const FileError ret = copyDirectory( sourceProjectPath, targetProjectPath, true, true );
64
65 return ret == FileError::NONE;
66
67 }
68
69 bool Project::CreateNewScene( const SceneEntry& scene, const ProjectID& projectID )
70 {
71 const ResourcePath scenePath = Paths::g_projectsLocation / projectID._name / Paths::g_scenesLocation;
72
73 FileError ret = copyDirectory( scenePath / Config::DEFAULT_SCENE_NAME, scenePath / scene._name, true, false );
74 if ( ret != FileError::NONE )
75 {
76 return false;
77 }
78
79 ret = copyFile( scenePath,
80 (Config::DEFAULT_SCENE_NAME + string( ".xml" )).c_str(),
81 scenePath,
82 (scene._name + ".xml").c_str(),
83 true );
84
85 if ( ret != FileError::NONE )
86 {
87 ret = removeDirectory( scenePath / scene._name );
88 if (ret != FileError::NONE)
89 {
91 }
92 return false;
93 }
94
95 return true;
96 }
97
98 Project::Project( ProjectManager& parentMgr, const ProjectID& projectID )
99 : _id( projectID )
100 , _scenePool( *this )
101 , _parentManager( parentMgr )
102 {
103 const std::filesystem::directory_iterator end;
104 for ( std::filesystem::directory_iterator iter{ (Paths::g_projectsLocation / projectID._name / Paths::g_scenesLocation).fileSystemPath() }; iter != end; ++iter )
105 {
106 if ( std::filesystem::is_directory( *iter ) &&
107 iter->path().filename().string().compare( Config::DELETED_FOLDER_NAME ) != 0 )
108 {
109 auto name = iter->path().filename().string();
110 if ( name.length() > 255 )
111 {
112 name = name.substr( 0, 255 );
113 }
114
115 _sceneEntries.emplace_back( SceneEntry
116 {
117 ._name = name.c_str()
118 });
119 }
120 }
121 }
122
124 {
125 Console::printfn( LOCALE_STR( "SCENE_MANAGER_REMOVE_SCENES" ) );
126 // ScenePool destruction should unload our active scene
127 }
128
130 {
131
132 if ( getActiveScene()->idle() )
133 {
134 NOP();
135 }
136 }
137
139 {
140 if ( IsSet( _sceneSwitchTarget ) )
141 {
142 parent().platformContext().gfx().getRenderer().postFX().setFadeOut( UColour3( 0 ), 1000.0, 0.0 );
143 if ( !switchSceneInternal() )
144 {
145 return false;
146 }
149 }
150
151 return true;
152 }
153
155 {
156 return true;
157 }
158
160 {
161 return _scenePool.activeScene();
162 }
163
165 {
166 const ResourcePath scenePath = Paths::g_projectsLocation / id()._name / Paths::g_scenesLocation / scene._targetScene._name;
167 if ( !pathExists( scenePath ) )
168 {
169 if (!scene._createIfNotExist || !CreateNewScene( scene._targetScene, id() ) )
170 {
171 return false;
172 }
173 }
174
175 if ( !fileExists( ResourcePath{ scenePath.string() + ".xml" } ) )
176 {
177 return false;
178 }
179
180 _sceneSwitchTarget = scene;
181
183 {
184 return switchSceneInternal();
185 }
186
187 return true;
188 }
189
191 {
194
195 const SceneEntry& scene = target._targetScene;
196
197 STUBBED("ToDo: Threaded scene load is currently disabled -Ionut");
198
199 const bool threaded = false;//target._loadInSeparateThread;
200 bool unloadPrevious = target._unloadPreviousScene;
201
202 DIVIDE_ASSERT( !scene._name.empty() );
203
204 Scene* sceneToUnload = _scenePool.activeScene();
205 if ( sceneToUnload != nullptr && sceneToUnload->resourceName().compare( scene._name ) == 0 )
206 {
207 unloadPrevious = false;
208 }
209
210 // We use our rendering task pool for scene changes because we might be creating / loading GPU assets (shaders, textures, buffers, etc)
211 Start( *CreateTask([this, unloadPrevious, &scene, &sceneToUnload]( const Task& /*parentTask*/ )
212 {
213 // Load first, unload after to make sure we don't reload common resources
214 if ( loadScene( scene ) != nullptr )
215 {
216 if ( unloadPrevious && sceneToUnload )
217 {
219 if ( !unloadScene( sceneToUnload ))
220 {
222 }
223 }
224 }
225 }),
228 [this, scene, unloadPrevious, &sceneToUnload]()
229 {
230 bool foundInCache = false;
231 Scene* loadedScene = _scenePool.getOrCreateScene( parent().platformContext(), *this, scene, foundInCache );
232 assert( loadedScene != nullptr && foundInCache );
233
234 if ( loadedScene->getState() == ResourceState::RES_LOADING )
235 {
237 }
238 assert( loadedScene->getState() == ResourceState::RES_LOADED );
239 setActiveScene( loadedScene );
240
241 if ( unloadPrevious && sceneToUnload != nullptr )
242 {
243 _scenePool.deleteScene( sceneToUnload->getGUID() );
244 }
245
247 }
248 );
249
250 return true;
251 }
252
253 Scene* Project::loadScene( const SceneEntry& sceneEntry )
254 {
255 bool foundInCache = false;
256 Scene* loadingScene = _scenePool.getOrCreateScene( parent().platformContext(), *this, sceneEntry, foundInCache );
257
258 if ( !loadingScene )
259 {
260 Console::errorfn( LOCALE_STR( "ERROR_XML_LOAD_INVALID_SCENE" ) );
261 return nullptr;
262 }
263
264 if ( loadingScene->getState() != ResourceState::RES_LOADED && !Attorney::SceneProjectManager::load( loadingScene ) )
265 {
266 return nullptr;
267 }
268
269 return loadingScene;
270 }
271
273 {
274 assert( scene != nullptr );
276
280 }
281
282 void Project::setActiveScene( Scene* const scene )
283 {
284 assert( scene != nullptr );
285
287 Attorney::SceneProjectManager::onRemoveActive( _scenePool.defaultSceneActive() ? _scenePool.defaultScene()
288 : getActiveScene() );
289
290 _scenePool.activeScene( *scene );
291
293 if ( !LoadSave::loadScene( scene ) )
294 {
295 //corrupt save
296 }
297
300 }
301
303 {
305 }
306
308 {
310 }
311
313 : FrameListener( "ProjectManager", parentKernel.frameListenerMgr(), 2 )
314 , InputAggregatorInterface()
315 , KernelComponent( parentKernel )
316 {
317 }
318
320 {
321 destroy();
322 }
323
324
325 bool ProjectManager::loadComplete() const noexcept
326 {
327 if ( activeProject() == nullptr )
328 {
329 return false;
330 }
331
332 return Attorney::SceneProjectManager::loadComplete( activeProject()->scenePool().activeScene() );
333 }
334
336 {
337 if ( _playerQueueDirty )
338 {
339 while ( !_playerAddQueue.empty() )
340 {
341 auto& [targetScene, playerSGN] = _playerAddQueue.front();
342 addPlayerInternal( targetScene, playerSGN );
343 _playerAddQueue.pop();
344 }
345 while ( !_playerRemoveQueue.empty() )
346 {
347 auto& [targetScene, playerSGN] = _playerRemoveQueue.front();
348 removePlayerInternal( targetScene, playerSGN );
349 _playerRemoveQueue.pop();
350 }
351 _playerQueueDirty = false;
352 }
353 else
354 {
355 Attorney::ProjectManagerProject::idle( *activeProject() );
356 }
357 }
358
360 {
361 if (!_init)
362 {
363 _init = true;
364 DIVIDE_ASSERT( _availableProjects.empty() );
366
367 _recast = std::make_unique<AI::Navigation::DivideRecast>();
368
369 for ( U8 i = 0u; i < to_base( RenderStage::COUNT ); ++i )
370 {
371 _sceneGraphCullTimers[i] = &Time::ADD_TIMER( Util::StringFormat( "SceneGraph cull timer: {}", TypeUtil::RenderStageToString( static_cast<RenderStage>(i) ) ).c_str() );
372 }
373
375 }
376
377 efficient_clear(_availableProjects);
378 const std::filesystem::directory_iterator end;
379 for ( std::filesystem::directory_iterator iter{ Paths::g_projectsLocation.fileSystemPath() }; iter != end; ++iter )
380 {
381 if ( !std::filesystem::is_directory( *iter ) ||
382 iter->path().filename().string().compare( Config::DELETED_FOLDER_NAME ) == 0 )
383 {
384 continue;
385 }
386
387 const std::string projectName = iter->path().filename().string();
388
389 _availableProjects.emplace_back( ProjectID
390 {
391 ._guid = _ID( projectName ),
392 ._name = projectName.c_str()
393 });
394 }
395
396 return _availableProjects;
397 }
398
400 {
401 if ( _init )
402 {
404 Console::printfn( LOCALE_STR( "STOP_SCENE_MANAGER" ) );
405 // Console::printfn(Locale::Get("SCENE_MANAGER_DELETE"));
406 _recast.reset();
407 _init = false;
408 }
409 }
410
411 ErrorCode ProjectManager::loadProject( const ProjectID& targetProject, const bool deferToStartOfFrame )
412 {
413 _projectSwitchTarget._targetProject = targetProject;
414
415 if (!deferToStartOfFrame)
416 {
417 return loadProjectInternal();
418 }
419
420 return ErrorCode::NO_ERR;
421 }
422
423
425 {
428
429 if ( _activeProject != nullptr )
430 {
431 Console::warnfn( LOCALE_STR( "WARN_PROJECT_CHANGE" ), _activeProject->id()._name, target._targetProject._name );
432 }
433
434 _activeProject = std::make_unique<Project>( *this, target._targetProject );
435
436 if ( _activeProject == nullptr || _activeProject->getSceneEntries().empty() )
437 {
438 Console::errorfn( LOCALE_STR( "ERROR_PROJECT_LOAD" ), target._targetProject._name );
440 }
441
442 SwitchSceneTarget sceneTarget
443 {
444 ._targetScene = _activeProject->getSceneEntries().front(),
445 ._unloadPreviousScene = true,
446 ._loadInSeparateThread = false,
447 ._deferToStartOfFrame = false,
448 ._createIfNotExist = false
449 };
450
451 if ( !_activeProject->switchScene( sceneTarget ) )
452 {
453 Console::errorfn( LOCALE_STR( "ERROR_SCENE_LOAD" ), _activeProject->getSceneEntries().front()._name.c_str() );
455 }
456
457 return ErrorCode::NO_ERR;
458 }
459
461 {
462 if ( _saveTask == nullptr )
463 {
464 return;
465 }
466
468 }
469
471 {
472 _processInput = true;
473 if constexpr( Config::Build::IS_EDITOR_BUILD )
474 {
475 static_assert(Config::Build::ENABLE_EDITOR);
477 if ( window.type() == WindowType::WINDOW )
478 {
479 window.maximized( true );
480 }
481
482 platformContext().editor().toggle( true );
483 }
484 }
485
487 {
488 if ( _init )
489 {
490 const F32 aspectRatio = to_F32( params.width ) / params.height;
491 const F32 vFoV = Angle::to_VerticalFoV( platformContext().config().runtime.horizontalFOV, to_D64( aspectRatio ) );
492 const vec2<F32> zPlanes( Camera::s_minNearZ, platformContext().config().runtime.cameraViewDistance );
493
494 auto& players = Attorney::SceneProjectManager::getPlayers( activeProject()->getActiveScene() );
495 for ( const auto& crtPlayer : players )
496 {
497 if ( crtPlayer != nullptr )
498 {
499 crtPlayer->camera()->setProjection( aspectRatio, vFoV, zPlanes );
500 }
501 }
502 }
503 }
504
505 void ProjectManager::addPlayer( Scene* parentScene, SceneGraphNode* playerNode, const bool queue )
506 {
507 if ( queue )
508 {
509 _playerAddQueue.push( std::make_pair( parentScene, playerNode ) );
510 _playerQueueDirty = true;
511 }
512 else
513 {
514 addPlayerInternal( parentScene, playerNode );
515 }
516 }
517
519 {
520 const I64 sgnGUID = playerNode->getGUID();
521
522 auto& players = Attorney::SceneProjectManager::getPlayers( parentScene );
523
524 for ( const auto& crtPlayer : players )
525 {
526 if ( crtPlayer && crtPlayer->getBoundNode()->getGUID() == sgnGUID )
527 {
528 return;
529 }
530 }
531
532 U32 i = 0u;
533 for ( ; i < Config::MAX_LOCAL_PLAYER_COUNT; ++i )
534 {
535 if ( players[i] == nullptr )
536 {
537 break;
538 }
539 }
540
542 {
543 players[i] = std::make_shared<Player>( to_U8( i ) );
544 players[i]->camera()->fromCamera( *Camera::GetUtilityCamera( Camera::UtilityCamera::DEFAULT ) );
545 players[i]->camera()->setFixedYawAxis( true );
546
547 {
548 boost::property_tree::ptree pt;
549
550 const ResourcePath sceneDataFile = Scene::GetSceneRootFolder( parentScene->parent() ) / (parentScene->resourceName() + ".xml");
551 XML::readXML( sceneDataFile, pt );
552 players[i]->camera()->loadFromXML( pt );
553 }
554
555 playerNode->get<UnitComponent>()->setUnit( players[i] );
556 Attorney::SceneProjectManager::onPlayerAdd( parentScene, players[i] );
557 }
558 }
559
560 void ProjectManager::removePlayer( Scene* parentScene, SceneGraphNode* playerNode, const bool queue )
561 {
562 if ( queue )
563 {
564 _playerRemoveQueue.push( std::make_pair( parentScene, playerNode ) );
565 _playerQueueDirty = true;
566 }
567 else
568 {
569 removePlayerInternal( parentScene, playerNode );
570 }
571 }
572
574 {
575 if ( playerNode == nullptr )
576 {
577 return;
578 }
579
580 const I64 targetGUID = playerNode->getGUID();
581
582 auto& players = Attorney::SceneProjectManager::getPlayers( parentScene );
583 for ( U32 i = 0; i < Config::MAX_LOCAL_PLAYER_COUNT; ++i )
584 {
585 if ( players[i] != nullptr && players[i]->getBoundNode()->getGUID() == targetGUID )
586 {
587 Attorney::SceneProjectManager::onPlayerRemove( parentScene, players[i] );
588 players[i] = nullptr;
589 break;
590 }
591 }
592 }
593
594 void ProjectManager::getNodesInScreenRect( const Rect<I32>& screenRect, const Camera& camera, vector<SceneGraphNode*>& nodesOut ) const
595 {
597
598 constexpr SceneNodeType s_ignoredNodes[6]
599 {
606 };
607
608 static vector<SGNRayResult> rayResults = {};
609 static VisibleNodeList<VisibleNode, 1024> inRectList;
611
612 nodesOut.clear();
613 inRectList.reset();
614 LoSList.reset();
615 rayResults.clear();
616
617 const auto& sceneGraph = activeProject()->getActiveScene()->sceneGraph();
618 const vec3<F32>& eye = camera.snapshot()._eye;
619 const vec2<F32> zPlanes = camera.snapshot()._zPlanes;
620
621 SGNIntersectionParams intersectionParams = {};
622 intersectionParams._includeTransformNodes = false;
623 intersectionParams._ignoredTypes = &s_ignoredNodes[0];
624 intersectionParams._ignoredTypesCount = std::size(s_ignoredNodes);
625
626 const GFXDevice& gfx = parent().platformContext().gfx();
627
628 const auto CheckPointLoS = [&]( const vec3<F32>& point, const I64 nodeGUID, const I64 parentNodeGUID ) -> bool
629 {
630 intersectionParams._ray = { point, point.direction( eye ) };
631 intersectionParams._range = { 0.f, zPlanes.y };
632
633 const F32 distanceToPoint = eye.distance( point );
634
635 sceneGraph->intersect( intersectionParams, rayResults );
636
637 for ( const SGNRayResult& result : rayResults )
638 {
639 if ( result.sgnGUID == nodeGUID ||
640 result.sgnGUID == parentNodeGUID )
641 {
642 continue;
643 }
644
645 if ( result.inside || result.dist < distanceToPoint )
646 {
647 return false;
648 }
649 }
650 return true;
651 };
652
653 const auto HasLoSToCamera = [&]( SceneGraphNode* node, const vec3<F32>& point )
654 {
655 I64 parentNodeGUID = -1;
656 const I64 nodeGUID = node->getGUID();
657 if ( Is3DObject( node->getNode().type() ) )
658 {
659 parentNodeGUID = node->parent()->getGUID();
660 }
661 return CheckPointLoS( point, nodeGUID, parentNodeGUID );
662 };
663
664 const auto IsNodeInRect = [&screenRect, &camera, &gfx]( SceneGraphNode* node )
665 {
666 assert( node != nullptr );
667 const SceneNode& sNode = node->getNode();
668 if ( Is3DObject( sNode.type() ))
669 {
670 auto* sComp = node->get<SelectionComponent>();
671 if ( sComp == nullptr &&
672 (sNode.type() == SceneNodeType::TYPE_SUBMESH) )
673 {
674 if ( node->parent() != nullptr )
675 {
676 // Already selected. Skip.
677 if ( node->parent()->hasFlag( SceneGraphNode::Flags::SELECTED ) )
678 {
679 return false;
680 }
681 sComp = node->parent()->get<SelectionComponent>();
682 }
683 }
684 if ( sComp != nullptr && sComp->enabled() )
685 {
686 const BoundsComponent* bComp = node->get<BoundsComponent>();
687 if ( bComp != nullptr )
688 {
689 const vec3<F32>& center = bComp->getBoundingSphere().getCenter();
690 const vec2<U16> resolution = gfx.renderingResolution();
691 const Rect<I32> targetViewport( 0, 0, to_I32( resolution.width ), to_I32( resolution.height ) );
692 return screenRect.contains( camera.project( center, targetViewport ) );
693 }
694 }
695 }
696
697 return false;
698 };
699
700 //Step 1: Grab ALL nodes in rect
701 for ( size_t i = 0u; i < _recentlyRenderedNodes.size(); ++i )
702 {
703 const VisibleNode& node = _recentlyRenderedNodes.node( i );
704 if ( IsNodeInRect( node._node ) )
705 {
706 inRectList.append( node );
707 if ( inRectList.size() == 1024 )
708 {
709 break;
710 }
711 }
712 }
713
714 //Step 2: Check Straight LoS to camera
715 for ( size_t i = 0u; i < inRectList.size(); ++i )
716 {
717 const VisibleNode& node = inRectList.node( i );
718 if ( HasLoSToCamera( node._node, node._node->get<BoundsComponent>()->getBoundingSphere().getCenter() ) )
719 {
720 LoSList.append( node );
721 }
722 else
723 {
724 // This is gonna hurt.The raycast failed, but the node might still be visible
725 const OBB& obb = node._node->get<BoundsComponent>()->getOBB();
726 for ( U8 p = 0; p < 8; ++p )
727 {
728 if ( HasLoSToCamera( node._node, obb.cornerPoint( p ) ) )
729 {
730 LoSList.append( node );
731 break;
732 }
733 }
734 }
735 }
736
737 //Step 3: Create list of visible nodes
738 for ( size_t i = 0; i < LoSList.size(); ++i )
739 {
740 SceneGraphNode* parsedNode = LoSList.node( i )._node;
741 if ( parsedNode != nullptr )
742 {
743 while ( true )
744 {
745 const SceneNode& node = parsedNode->getNode();
746 if ( node.type() == SceneNodeType::TYPE_SUBMESH )
747 {
748 parsedNode = parsedNode->parent();
749 }
750 else
751 {
752 break;
753 }
754 }
755
756 if ( eastl::find( cbegin( nodesOut ), cend( nodesOut ), parsedNode ) == cend( nodesOut ) )
757 {
758 nodesOut.push_back( parsedNode );
759 }
760 }
761 }
762 }
763
764 bool ProjectManager::frameStarted( [[maybe_unused]] const FrameEvent& evt )
765 {
766 if ( _init )
767 {
769 {
770 return false;
771 }
772
773 if ( !Attorney::ProjectManagerProject::onFrameStart( *activeProject() ) )
774 {
775 return false;
776 }
777
778 return Attorney::SceneProjectManager::frameStarted( activeProject()->getActiveScene() );
779 }
780
781 return true;
782 }
783
784 bool ProjectManager::frameEnded( [[maybe_unused]] const FrameEvent& evt )
785 {
786 if ( _init )
787 {
788 if (!Attorney::ProjectManagerProject::onFrameEnd( *activeProject() ))
789 {
790 return false;
791 }
792
793 return Attorney::SceneProjectManager::frameEnded( activeProject()->getActiveScene() );
794 }
795
796 return true;
797 }
798
799 void ProjectManager::updateSceneState( const U64 deltaGameTimeUS, const U64 deltaAppTimeUS )
800 {
802
803 Scene* activeScene = activeProject()->getActiveScene();
804 assert( activeScene->getState() == ResourceState::RES_LOADED );
805 // Update internal timers
806 _elapsedGameTime += deltaGameTimeUS;
807 _elapsedGameTimeMS = Time::MicrosecondsToMilliseconds<U32>( _elapsedGameTime );
808 _elapsedAppTime += deltaAppTimeUS;
809 _elapsedAppTimeMS = Time::MicrosecondsToMilliseconds<U32>( _elapsedAppTime );
810
811 const Scene::DayNightData& dayNightData = activeScene->dayNightData();
812
813 const FColour3 sunColour = dayNightData._sunLight != nullptr
814 ? dayNightData._sunLight->getDiffuseColour()
816
817 const GFXDevice& gfx = parent().platformContext().gfx();
818 SceneShaderData* sceneData = gfx.sceneData().get();
819
821 const Angle::DEGREES<F32> sunAltitudeMax = Angle::RadiansToDegrees( activeScene->getCurrentSunDetails().altitudeMax);
823
824 sceneData->sunDetails( activeScene->getSunDirection(), sunColour, (sunAltitude / sunAltitudeMax), sunAzimuth);
825 sceneData->appData( _elapsedGameTimeMS, _elapsedAppTimeMS, gfx.materialDebugFlag() );
826
827 //_sceneData->skyColour(horizonColour, zenithColour);
828
829 FogDetails fog = activeScene->state()->renderState().fogDetails();
830 fog._colourSunScatter.rgb = sunColour;
831
832 if ( !platformContext().config().rendering.enableFog )
833 {
834 fog._colourAndDensity.a = 0.f;
835 }
836 sceneData->fogDetails( fog );
837
838 const auto& activeSceneState = activeScene->state();
839 sceneData->windDetails( activeSceneState->windDirX(),
840 0.0f,
841 activeSceneState->windDirZ(),
842 activeSceneState->windSpeed() );
843
844 Attorney::GFXDeviceProjectManager::shadowingSettings( _parent.platformContext().gfx(), activeSceneState->lightBleedBias(), activeSceneState->minShadowVariance() );
845
846 activeScene->updateSceneState( deltaGameTimeUS );
847
848 U8 index = 0u;
849
850 const auto& waterBodies = activeSceneState->waterBodies();
851 for ( const auto& body : waterBodies )
852 {
853 sceneData->waterDetails( index++, body );
854 }
855 _saveTimer += deltaGameTimeUS;
856
858 {
859 if ( !saveActiveScene( true, true ) )
860 {
861 NOP();
862 }
863 _saveTimer = 0ULL;
864 }
865 if ( dayNightData._skyInstance != nullptr )
866 {
867 _parent.platformContext().gfx().getRenderer().postFX().isDayTime( dayNightData._skyInstance->isDay() );
868 }
869 }
870
871 void ProjectManager::drawCustomUI( const Rect<I32>& targetViewport, GFX::CommandBuffer& bufferInOut, GFX::MemoryBarrierCommand& memCmdInOut )
872 {
873 //Set a 2D camera for rendering
874 GFX::EnqueueCommand<GFX::SetCameraCommand>( bufferInOut)->_cameraSnapshot = Camera::GetUtilityCamera( Camera::UtilityCamera::_2D )->snapshot();
875 GFX::EnqueueCommand<GFX::SetViewportCommand>( bufferInOut )->_viewport = targetViewport;
876
877 Attorney::SceneProjectManager::drawCustomUI( activeProject()->getActiveScene(), targetViewport, bufferInOut, memCmdInOut );
878 }
879
880 void ProjectManager::postRender( GFX::CommandBuffer& bufferInOut, [[maybe_unused]] GFX::MemoryBarrierCommand& memCmdInOut )
881 {
883
884 Scene* activeScene = activeProject()->getActiveScene();
885 if ( activeScene->state()->screenshotRequestQueued() )
886 {
888 activeScene->state()->screenshotRequestQueued(false);
889 }
890 }
891
893 {
895
896 Scene* activeScene = activeProject()->getActiveScene();
897
898 Attorney::SceneProjectManager::debugDraw( activeScene, bufferInOut, memCmdInOut );
899 // Draw bounding boxes, skeletons, axis gizmo, etc.
900 platformContext().gfx().debugDraw( activeScene->state()->renderState(), bufferInOut, memCmdInOut );
901 }
902
903 Camera* ProjectManager::playerCamera( const PlayerIndex idx, const bool skipOverride ) const noexcept
904 {
905 if ( activePlayerCount() <= idx )
906 {
907 return nullptr;
908 }
909
910 Scene* activeScene = activeProject()->getActiveScene();
911 if ( !skipOverride )
912 {
913 Camera* overrideCamera = activeScene->state()->playerState( idx ).overrideCamera();
914 if ( overrideCamera != nullptr )
915 {
916 return overrideCamera;
917 }
918 }
919
920 return Attorney::SceneProjectManager::getPlayers(activeScene)[idx]->camera();
921 }
922
923 Camera* ProjectManager::playerCamera( const bool skipOverride ) const noexcept
924 {
925 return playerCamera( _currentPlayerPass, skipOverride );
926 }
927
929 {
931
932 _currentPlayerPass = idx;
933 Attorney::SceneProjectManager::currentPlayerPass( activeProject()->getActiveScene(), _currentPlayerPass );
935 }
936
937 void ProjectManager::editorPreviewNode( const I64 editorPreviewNode ) noexcept
938 {
939 activeProject()->getActiveScene()->state()->renderState().singleNodeRenderGUID( editorPreviewNode );
940 }
941
943 {
945
946 BoundingSphere bSphere;
947 vec3<F32> targetPos = WORLD_Z_NEG_AXIS;
948 vec3<F32> eyePos = VECTOR3_ZERO;
949
950 if ( camera == nullptr )
951 {
952 camera = playerCamera();
953 }
954
956 if ( targetNode->parent() != nullptr )
957 {
958 bSphere = SceneGraph::GetBounds(targetNode);
959 targetPos = bSphere.getCenter();
960 eyePos = targetPos - (bSphere.getRadius() * 1.5f * camera->viewMatrix().getForwardDirection());
961 }
962 else
963 {
964 bSphere.setCenter(VECTOR3_ZERO);
965 bSphere.setRadius(1.f);
966 }
967
968 camera->lookAt( eyePos, targetPos );
969 return bSphere;
970 }
971
972 bool ProjectManager::saveNode( const SceneGraphNode* targetNode ) const
973 {
974 return LoadSave::saveNodeToXML( activeProject()->getActiveScene(), targetNode );
975 }
976
977 bool ProjectManager::loadNode( SceneGraphNode* targetNode ) const
978 {
979 return LoadSave::loadNodeFromXML( activeProject()->getActiveScene(), targetNode );
980 }
981
982
983 void ProjectManager::getSortedReflectiveNodes( const Camera* camera, const RenderStage stage, const bool inView, VisibleNodeList<>& nodesOut ) const
984 {
986
987 static vector<SceneGraphNode*> allNodes = {};
988 activeProject()->getActiveScene()->sceneGraph()->getNodesByType( { SceneNodeType::TYPE_WATER, SceneNodeType::TYPE_SUBMESH, SceneNodeType::TYPE_SPHERE_3D, SceneNodeType::TYPE_BOX_3D, SceneNodeType::TYPE_QUAD_3D }, allNodes );
989
990 erase_if( allNodes,
991 []( SceneGraphNode* node ) noexcept -> bool
992 {
993 Handle<Material> mat = node->get<RenderingComponent>()->getMaterialInstance();
994 return node->getNode().type() != SceneNodeType::TYPE_WATER && (mat == INVALID_HANDLE<Material> || !Get(mat)->isReflective());
995 } );
996
997 if ( inView )
998 {
999 NodeCullParams cullParams = {};
1000 cullParams._lodThresholds = activeProject()->getActiveScene()->state()->renderState().lodThresholds();
1001 cullParams._stage = stage;
1002 cullParams._cameraEyePos = camera->snapshot()._eye;
1003 cullParams._frustum = &camera->getFrustum();
1004 cullParams._cullMaxDistance = camera->snapshot()._zPlanes.max;
1005
1007 }
1008 else
1009 {
1010 RenderPassCuller::ToVisibleNodes( camera, allNodes, nodesOut );
1011 }
1012 }
1013
1014 void ProjectManager::getSortedRefractiveNodes( const Camera* camera, const RenderStage stage, const bool inView, VisibleNodeList<>& nodesOut ) const
1015 {
1017
1018 static vector<SceneGraphNode*> allNodes = {};
1019 activeProject()->getActiveScene()->sceneGraph()->getNodesByType( { SceneNodeType::TYPE_WATER, SceneNodeType::TYPE_SUBMESH, SceneNodeType::TYPE_SPHERE_3D, SceneNodeType::TYPE_BOX_3D, SceneNodeType::TYPE_QUAD_3D }, allNodes );
1020
1021 erase_if( allNodes,
1022 []( SceneGraphNode* node ) noexcept -> bool
1023 {
1024 Handle<Material> mat = node->get<RenderingComponent>()->getMaterialInstance();
1025 return node->getNode().type() != SceneNodeType::TYPE_WATER && (mat == INVALID_HANDLE<Material> || !Get(mat)->isRefractive());
1026 } );
1027 if ( inView )
1028 {
1029 NodeCullParams cullParams = {};
1030 cullParams._lodThresholds = activeProject()->getActiveScene()->state()->renderState().lodThresholds();
1031 cullParams._stage = stage;
1032 cullParams._cameraEyePos = camera->snapshot()._eye;
1033 cullParams._frustum = &camera->getFrustum();
1034 cullParams._cullMaxDistance = camera->snapshot()._zPlanes.max;
1035
1037 }
1038 else
1039 {
1040 RenderPassCuller::ToVisibleNodes( camera, allNodes, nodesOut );
1041 }
1042 }
1043
1045 {
1047 }
1048
1049 void ProjectManager::initDefaultCullValues( const RenderStage stage, NodeCullParams& cullParamsInOut ) noexcept
1050 {
1051 Scene* activeScene = activeProject()->getActiveScene();
1052
1053 cullParamsInOut._stage = stage;
1054 cullParamsInOut._lodThresholds = activeScene->state()->renderState().lodThresholds( stage );
1055 if ( stage != RenderStage::SHADOW )
1056 {
1057 cullParamsInOut._cullMaxDistance = activeScene->state()->renderState().generalVisibility();
1058 }
1059 else
1060 {
1061 cullParamsInOut._cullMaxDistance = F32_MAX;
1062 }
1063 }
1064
1065 void ProjectManager::cullSceneGraph( const NodeCullParams& params, const U16 cullFlags, VisibleNodeList<>& nodesOut )
1066 {
1068
1070
1071 Scene* activeScene = activeProject()->getActiveScene();
1072 RenderPassCuller::FrustumCull( params, cullFlags, *activeScene->sceneGraph(), *activeScene->state(), _parent.platformContext(), nodesOut );
1073
1074 if ( params._stage == RenderStage::DISPLAY )
1075 {
1076 _recentlyRenderedNodes = nodesOut;
1077 }
1078 }
1079
1080 void ProjectManager::findNode( const vec3<F32>& cameraEye, const I64 nodeGUID, VisibleNodeList<>& nodesOut )
1081 {
1083
1084 if ( nodeGUID != -1 )
1085 {
1086 SceneGraphNode* sgn = activeProject()->getActiveScene()->sceneGraph()->findNode( nodeGUID );
1087 if ( sgn != nullptr )
1088 {
1089 const auto appendNode = [&nodesOut, &cameraEye]( SceneGraphNode* sgn )
1090 {
1091 const BoundsComponent* bComp = sgn->get<BoundsComponent>();
1092 VisibleNode temp{};
1093 temp._node = sgn;
1094 temp._distanceToCameraSq = bComp == nullptr ? 0.f : bComp->getBoundingSphere().getDistanceFromPoint( cameraEye );
1095 nodesOut.append( temp );
1096 };
1097 appendNode( sgn );
1098
1099 const BoundsComponent* bComp = sgn->get<BoundsComponent>();
1100 VisibleNode temp{};
1101 temp._node = sgn;
1102 temp._distanceToCameraSq = bComp == nullptr ? 0.f : bComp->getBoundingSphere().getDistanceFromPoint( cameraEye );
1103 nodesOut.append( temp );
1104
1105 const auto& children = sgn->getChildren();
1106 SharedLock<SharedMutex> w_lock( children._lock );
1107 const U32 childCount = children._count;
1108 for ( U32 i = 0u; i < childCount; ++i )
1109 {
1110 appendNode( children._data[i] );
1111 }
1112 }
1113 }
1114 }
1115
1116 void ProjectManager::prepareLightData( const RenderStage stage, const CameraSnapshot& cameraSnapshot, GFX::MemoryBarrierCommand& memCmdInOut )
1117 {
1119
1120 if ( stage != RenderStage::SHADOW )
1121 {
1122 LightPool* pool = activeProject()->getActiveScene()->lightPool().get();
1123 pool->sortLightData( stage, cameraSnapshot );
1124 pool->uploadLightData( stage, cameraSnapshot, memCmdInOut );
1125 }
1126 }
1127
1128 void ProjectManager::onChangeFocus( const bool hasFocus )
1129 {
1130 if ( !_init )
1131 {
1132 return;
1133 }
1134
1135 activeProject()->getActiveScene()->onChangeFocus( hasFocus );
1136 }
1137
1138 bool ProjectManager::resetSelection( const PlayerIndex idx, const bool resetIfLocked )
1139 {
1141
1142 if ( Attorney::SceneProjectManager::resetSelection( activeProject()->getActiveScene(), idx, resetIfLocked ) )
1143 {
1144 for ( auto& cbk : _selectionChangeCallbacks )
1145 {
1146 cbk.second( idx, {} );
1147 }
1148 return true;
1149 }
1150
1151 return false;
1152 }
1153
1154 void ProjectManager::setSelected( const PlayerIndex idx, const vector<SceneGraphNode*>& SGNs, const bool recursive )
1155 {
1157
1158 Attorney::SceneProjectManager::setSelected( activeProject()->getActiveScene(), idx, SGNs, recursive );
1159 for ( auto& cbk : _selectionChangeCallbacks )
1160 {
1161 cbk.second( idx, SGNs );
1162 }
1163 }
1164
1165 void ProjectManager::onNodeDestroy( Scene* parentScene, [[maybe_unused]] SceneGraphNode* node )
1166 {
1167 auto& players = Attorney::SceneProjectManager::getPlayers( parentScene );
1168 for ( U32 i = 0; i < Config::MAX_LOCAL_PLAYER_COUNT; ++i )
1169 {
1170 if ( players[i] != nullptr && !resetSelection( players[i]->index(), true ) )
1171 {
1173 }
1174 }
1175 }
1176
1178 {
1179 Attorney::SceneProjectManager::clearHoverTarget( activeProject()->getActiveScene(), arg );
1180 }
1181
1183 {
1184 return Attorney::SceneProjectManager::getEnvProbes( activeProject()->getActiveScene() );
1185 }
1186
1188 {
1189 return activeProject()->getActiveScene()->playerCount();
1190 }
1191
1192 std::pair<Handle<Texture>, SamplerDescriptor> ProjectManager::getSkyTexture() const
1193 {
1194 const auto& skies = activeProject()->getActiveScene()->sceneGraph()->getNodesByType( SceneNodeType::TYPE_SKY );
1195 if ( !skies.empty() )
1196 {
1197 const Sky& sky = skies.front()->getNode<Sky>();
1198 return std::make_pair( sky.activeSkyBox(), sky.skyboxSampler() );
1199 }
1200
1201 return { INVALID_HANDLE<Texture>, {} };
1202 }
1203
1205
1207 {
1208 if ( !_processInput )
1209 {
1210 return false;
1211 }
1212
1213 return activeProject()->getActiveScene()->input()->onKeyDown( key );
1214 }
1215
1217 {
1218 if ( !_processInput )
1219 {
1220 return false;
1221 }
1222
1223 return activeProject()->getActiveScene()->input()->onKeyUp( key );
1224 }
1225
1227 {
1228 if ( !_processInput )
1229 {
1230 return false;
1231
1232 }
1233
1234 return activeProject()->getActiveScene()->input()->mouseMoved( arg );
1235 }
1236
1238 {
1239 if ( !_processInput )
1240 {
1241 return false;
1242 }
1243
1244 return activeProject()->getActiveScene()->input()->mouseButtonPressed( arg );
1245 }
1246
1248 {
1249 if ( !_processInput )
1250 {
1251 return false;
1252 }
1253
1254 return activeProject()->getActiveScene()->input()->mouseButtonReleased( arg );
1255 }
1256
1258 {
1259 if ( !_processInput )
1260 {
1261 return false;
1262 }
1263
1264 return activeProject()->getActiveScene()->input()->joystickAxisMoved( arg );
1265 }
1266
1268 {
1269 if ( !_processInput )
1270 {
1271 return false;
1272 }
1273
1274 return activeProject()->getActiveScene()->input()->joystickPovMoved( arg );
1275 }
1276
1278 {
1279 if ( !_processInput )
1280 {
1281 return false;
1282 }
1283
1284 return activeProject()->getActiveScene()->input()->joystickButtonPressed( arg );
1285 }
1286
1288 {
1289 if ( !_processInput )
1290 {
1291 return false;
1292 }
1293
1294 return activeProject()->getActiveScene()->input()->joystickButtonReleased( arg );
1295 }
1296
1298 {
1299 if ( !_processInput )
1300 {
1301 return false;
1302 }
1303
1304 return activeProject()->getActiveScene()->input()->joystickBallMoved( arg );
1305 }
1306
1308 {
1309 if ( !_processInput )
1310 {
1311 return false;
1312 }
1313
1314 return activeProject()->getActiveScene()->input()->joystickAddRemove( arg );
1315 }
1316
1318 {
1319 if ( !_processInput )
1320 {
1321 return false;
1322 }
1323
1324 return activeProject()->getActiveScene()->input()->joystickRemap( arg );
1325 }
1326
1328 {
1329 if ( !_processInput )
1330 {
1331 return false;
1332 }
1333
1334 return activeProject()->getActiveScene()->input()->onTextEvent( arg );
1335 }
1336
1338 {
1339 return parent().platformContext();
1340 }
1341
1343 {
1344 return parent().platformContext();
1345 }
1346
1347 namespace
1348 {
1349 constexpr const char* g_saveFile = "current_save.sav";
1350 constexpr const char* g_bakSaveFile = "save.bak";
1351 }
1352
1353 bool LoadSave::loadScene( Scene* activeScene )
1354 {
1355 if ( activeScene->state()->saveLoadDisabled() )
1356 {
1357 return true;
1358 }
1359
1360 const Str<256>& sceneName = activeScene->resourceName();
1361
1362 const ResourcePath path = Paths::g_saveLocation / sceneName;
1363
1364 bool isLoadFromBackup = false;
1365 // If file is missing, restore from bak
1366 if ( !fileExists( path / g_saveFile ) )
1367 {
1368 isLoadFromBackup = true;
1369
1370 // Save file might be deleted if it was corrupted
1371 if ( fileExists( path / g_bakSaveFile ) )
1372 {
1373 if ( copyFile( path, g_bakSaveFile, path, g_saveFile, false ) != FileError::NONE )
1374 {
1375 NOP();
1376 }
1377 }
1378 }
1379
1380 ByteBuffer save;
1381 if ( save.loadFromFile( path, g_saveFile ) )
1382 {
1383 auto tempVer = decltype(BYTE_BUFFER_VERSION){0};
1384 save >> tempVer;
1385 if ( tempVer == BYTE_BUFFER_VERSION )
1386 {
1387 if ( !Attorney::SceneLoadSave::load( activeScene, save ) )
1388 {
1389 //Remove the save and try the backup
1390 if ( deleteFile( path, g_saveFile ) != FileError::NONE )
1391 {
1392 NOP();
1393 }
1394 if ( !isLoadFromBackup )
1395 {
1396 return loadScene( activeScene );
1397 }
1398 }
1399 }
1400 }
1401 return false;
1402 }
1403
1404
1405 bool LoadSave::saveNodeToXML( Scene* activeScene, const SceneGraphNode* node )
1406 {
1407 return Attorney::SceneLoadSave::saveNodeToXML( activeScene, node );
1408 }
1409
1411 {
1412 return Attorney::SceneLoadSave::loadNodeFromXML( activeScene, node );
1413 }
1414
1415 bool LoadSave::saveScene( Scene* activeScene, const bool toCache, const DELEGATE<void, std::string_view>& msgCallback, const DELEGATE<void, bool>& finishCallback )
1416 {
1417 if ( !toCache )
1418 {
1419 return Attorney::SceneLoadSave::saveXML( activeScene, msgCallback, finishCallback );
1420 }
1421
1422 bool ret = false;
1423 if ( activeScene->state()->saveLoadDisabled() )
1424 {
1425 ret = true;
1426 }
1427 else
1428 {
1429 const Str<256>& sceneName = activeScene->resourceName();
1430 const ResourcePath path = Paths::g_saveLocation / sceneName;
1431
1432 if ( fileExists( path / g_saveFile) )
1433 {
1434 if ( copyFile( path, g_saveFile, path, g_bakSaveFile, true ) != FileError::NONE )
1435 {
1436 return false;
1437 }
1438 }
1439
1440 ByteBuffer save;
1441 save << BYTE_BUFFER_VERSION;
1442 if ( Attorney::SceneLoadSave::save( activeScene, save ) )
1443 {
1444 ret = save.dumpToFile( path, g_saveFile );
1445 assert( ret );
1446 }
1447 }
1448 if ( finishCallback )
1449 {
1450 finishCallback( ret );
1451 }
1452 return ret;
1453 }
1454
1455 bool ProjectManager::saveActiveScene( bool toCache, const bool deferred, const DELEGATE<void, std::string_view>& msgCallback, const DELEGATE<void, bool>& finishCallback )
1456 {
1458
1459 Scene* activeScene = activeProject()->getActiveScene();
1460
1461 // Ignore any auto-save (or manual saves) on the default scene
1462 if ( activeScene->getGUID() == Scene::DEFAULT_SCENE_GUID )
1463 {
1464 return true;
1465 }
1466
1468 if ( _saveTask != nullptr )
1469 {
1470 if ( !Finished( *_saveTask ) )
1471 {
1472 if ( toCache )
1473 {
1474 return false;
1475 }
1477 }
1478 Wait( *_saveTask, pool );
1479 }
1480
1481 _saveTask = CreateTask( nullptr,
1482 [activeScene, msgCallback, finishCallback, toCache]( const Task& /*parentTask*/ )
1483 {
1484 LoadSave::saveScene( activeScene, toCache, msgCallback, finishCallback );
1485 },
1486 false );
1488
1489 return true;
1490 }
1491
1492 bool ProjectManager::networkUpdate( [[maybe_unused]] const U64 frameCount )
1493 {
1494 return true;
1495 }
1496
1497} //namespace Divide
#define LOCALE_STR(X)
Definition: Localization.h:91
#define DIVIDE_ASSERT(...)
#define STUBBED(x)
#define DIVIDE_UNEXPECTED_CALL()
#define NOP()
#define PROFILE_SCOPE_AUTO(CATEGORY)
Definition: Profiler.h:87
Time::ApplicationTimer & timer() noexcept
Definition: Application.inl:92
static void shadowingSettings(GFXDevice &device, const F32 lightBleedBias, const F32 minShadowVariance) noexcept
Definition: GFXDevice.h:646
static bool onFrameStart(Divide::Project &project)
static void idle(Divide::Project &project)
static void waitForSaveTask(Divide::ProjectManager &mgr)
static bool onFrameEnd(Divide::Project &project)
static bool saveXML(Scene *scene, const DELEGATE< void, std::string_view > &msgCallback, const DELEGATE< void, bool > &finishCallback)
Definition: Scene.h:484
static bool load(Scene *scene, ByteBuffer &inputBuffer)
Definition: Scene.h:472
static bool save(const Scene *scene, ByteBuffer &outputBuffer)
Definition: Scene.h:468
static bool saveNodeToXML(Scene *scene, const SceneGraphNode *node)
Definition: Scene.h:476
static bool loadNodeFromXML(Scene *scene, SceneGraphNode *node)
Definition: Scene.h:480
static bool onShutdown(PlatformContext &context)
Definition: Scene.h:416
static void postLoadMainThread(Scene *scene)
Definition: Scene.h:399
static void drawCustomUI(Scene *scene, const Rect< I32 > &targetViewport, GFX::CommandBuffer &bufferInOut, GFX::MemoryBarrierCommand &memCmdInOut)
Definition: Scene.h:379
static bool resetSelection(Scene *scene, const PlayerIndex idx, const bool resetIfLocked)
Definition: Scene.h:424
static void onSetActive(Scene *scene)
Definition: Scene.h:403
static bool load(Scene *scene)
Definition: Scene.h:391
static bool frameEnded(Scene *scene)
Definition: Scene.h:387
static bool onStartup(PlatformContext &context)
Definition: Scene.h:412
static PlayerList & getPlayers(Scene *scene) noexcept
Definition: Scene.h:440
static bool loadComplete(Scene *scene) noexcept
Definition: Scene.h:358
static bool unload(Scene *scene)
Definition: Scene.h:395
static void onPlayerRemove(Scene *scene, const Player_ptr &player)
Definition: Scene.h:367
static void onPlayerAdd(Scene *scene, const Player_ptr &player)
Definition: Scene.h:363
static void onRemoveActive(Scene *scene)
Definition: Scene.h:407
static bool frameStarted(Scene *scene)
Definition: Scene.h:383
static SceneEnvironmentProbePool * getEnvProbes(Scene *scene) noexcept
Definition: Scene.h:436
static void currentPlayerPass(Scene *scene, const PlayerIndex idx)
Definition: Scene.h:371
static void debugDraw(Scene *scene, GFX::CommandBuffer &bufferInOut, GFX::MemoryBarrierCommand &memCmdInOut)
Definition: Scene.h:375
static void clearHoverTarget(Scene *scene, const Input::MouseMoveEvent &arg)
Definition: Scene.h:432
static void setSelected(Scene *scene, const PlayerIndex idx, const vector< SceneGraphNode * > &sgns, const bool recursive)
Definition: Scene.h:428
const vec3< F32 > & getCenter() const noexcept
F32 getDistanceFromPoint(const vec3< F32 > &point) const noexcept
void setRadius(F32 radius) noexcept
F32 getRadius() const noexcept
void setCenter(const vec3< F32 > &center) noexcept
const BoundingSphere & getBoundingSphere() const noexcept
bool loadFromFile(const ResourcePath &path, std::string_view fileName, const U8 version=BUFFER_FORMAT_VERSION)
Definition: ByteBuffer.cpp:57
bool dumpToFile(const ResourcePath &path, std::string_view fileName, const U8 version=BUFFER_FORMAT_VERSION)
Saves the entire buffer contents to file. Always appends the version at the end of the file.
Definition: ByteBuffer.cpp:47
const mat4< F32 > & viewMatrix() const noexcept
Returns the most recent/up-to-date view matrix.
Definition: Camera.inl:157
static Camera * GetUtilityCamera(const UtilityCamera type)
Definition: Camera.cpp:120
const mat4< F32 > & lookAt(const mat4< F32 > &viewMatrix)
Sets the camera's view matrix to specify the specified value by extracting the eye position,...
Definition: Camera.cpp:354
const Frustum & getFrustum() const noexcept
Returns the most recent/up-to-date frustum.
Definition: Camera.inl:202
const CameraSnapshot & snapshot() const noexcept
Returns the internal camera snapshot data (eye, orientation, etc)
Definition: Camera.inl:43
static constexpr F32 s_minNearZ
Definition: Camera.h:95
bool updateLookAt()
Return true if the cached camera state wasn't up-to-date.
Definition: Camera.cpp:384
vec2< F32 > project(const vec3< F32 > &worldCoords, const Rect< I32 > &viewport) const noexcept
Definition: Camera.cpp:917
bool maximized() const noexcept
void onChangeScene(Scene *newScene)
Definition: Editor.cpp:2268
void toggle(bool state)
Definition: Editor.cpp:883
void registerFrameListener(FrameListener *listener, U32 callOrder)
Register a new Frame Listener to be processed every frame.
Rough around the edges Adapter pattern abstracting the actual rendering API and access to the GPU.
Definition: GFXDevice.h:215
vec2< U16 > renderingResolution() const noexcept
Definition: GFXDevice.inl:174
Renderer & getRenderer() const
Definition: GFXDevice.inl:117
void debugDraw(const SceneRenderState &sceneRenderState, GFX::CommandBuffer &bufferInOut, GFX::MemoryBarrierCommand &memCmdInOut)
Render all of our immediate mode primitives. This isn't very optimised and most are recreated per fra...
Definition: GFXDevice.cpp:3029
static U64 FrameCount() noexcept
Definition: GFXDevice.h:340
void screenshot(std::string_view fileName, GFX::CommandBuffer &bufferInOut) const
Save a screenshot in TGA format.
Definition: GFXDevice.cpp:3120
FORCE_INLINE I64 getGUID() const noexcept
Definition: GUIDWrapper.h:51
void onUnloadScene(Scene *scene)
When we unload a scene, we unload all of its GUI elements. ToDo: Scene should own these and scene sho...
Definition: GUI.cpp:169
void onChangeScene(Scene *newScene)
When we change a scene, we want to toggle our current scene GUI elements off and toggle the new scene...
Definition: GUI.cpp:140
Kernel & parent() noexcept
The kernel is the main system that connects all of our various systems: windows, gfx,...
Definition: Kernel.h:81
FORCE_INLINE PlatformContext & platformContext() noexcept
Definition: Kernel.h:129
FORCE_INLINE FrameListenerManager & frameListenerMgr() noexcept
Definition: Kernel.h:128
void uploadLightData(RenderStage stage, const CameraSnapshot &cameraSnapshot, GFX::MemoryBarrierCommand &memCmdInOut)
Definition: LightPool.cpp:465
void sortLightData(RenderStage stage, const CameraSnapshot &cameraSnapshot)
Definition: LightPool.cpp:423
static void DestroyStaticData()
Definition: LightPool.cpp:121
static void InitStaticData(PlatformContext &context)
Definition: LightPool.cpp:55
static bool saveNodeToXML(Scene *activeScene, const SceneGraphNode *node)
static bool saveScene(Scene *activeScene, bool toCache, const DELEGATE< void, std::string_view > &msgCallback, const DELEGATE< void, bool > &finishCallback)
static bool loadNodeFromXML(Scene *activeScene, SceneGraphNode *node)
static bool loadScene(Scene *activeScene)
vec3< F32 > cornerPoint(U8 cornerIndex) const noexcept
Definition: OBB.cpp:26
PlatformContext & context() noexcept
DisplayWindow & mainWindow() noexcept
Application & app() noexcept
Editor & editor() noexcept
TaskPool & taskPool(const TaskPoolType type) noexcept
GFXDevice & gfx() noexcept
void setFadeOut(const UColour3 &targetColour, D64 durationMS, D64 waitDurationMS, DELEGATE< void > onComplete=DELEGATE< void >())
Definition: PostFX.cpp:298
void setFadeIn(D64 durationMS, DELEGATE< void > onComplete=DELEGATE< void >())
Definition: PostFX.cpp:312
void setActiveScene(Scene *scene)
Scene * getActiveScene() const noexcept
SwitchSceneTarget _sceneSwitchTarget
bool unloadScene(Scene *scene)
vector< SceneEntry > _sceneEntries
Project(ProjectManager &parentMgr, const ProjectID &name)
static bool CreateNewScene(const SceneEntry &scene, const ProjectID &projectID)
static bool CreateNewProject(const ProjectID &projectID)
bool switchScene(const SwitchSceneTarget &scene)
Scene * loadScene(const SceneEntry &sceneEntry)
ProjectManager & parent() noexcept
bool loadComplete() const noexcept
Check if the scene was loaded properly.
void addPlayerInternal(Scene *parentScene, SceneGraphNode *playerNode)
SwitchProjectTarget _projectSwitchTarget
bool joystickPovMoved(const Input::JoystickEvent &arg) override
Joystick direction change: return true if input was consumed.
bool mouseButtonPressed(const Input::MouseButtonEvent &arg) override
Mouse button pressed: return true if input was consumed.
bool saveActiveScene(bool toCache, bool deferred, const DELEGATE< void, std::string_view > &msgCallback={}, const DELEGATE< void, bool > &finishCallback={})
bool joystickBallMoved(const Input::JoystickEvent &arg) override
void initPostLoadState() noexcept
bool mouseButtonReleased(const Input::MouseButtonEvent &arg) override
Mouse button released: return true if input was consumed.
vector< std::pair< size_t, DELEGATE< void, U8, const vector< SceneGraphNode * > & > > > _selectionChangeCallbacks
void getSortedReflectiveNodes(const Camera *camera, RenderStage stage, bool inView, VisibleNodeList<> &nodesOut) const
get the full list of reflective nodes
static bool OnStartup(PlatformContext &context)
void setSelected(PlayerIndex idx, const vector< SceneGraphNode * > &SGNs, bool recursive)
bool frameStarted(const FrameEvent &evt) override
void drawCustomUI(const Rect< I32 > &targetViewport, GFX::CommandBuffer &bufferInOut, GFX::MemoryBarrierCommand &memCmdInOut)
void findNode(const vec3< F32 > &cameraEye, const I64 nodeGUID, VisibleNodeList<> &nodesOut)
Searches the scenegraph for the specified nodeGUID and, if found, adds it to nodesOut.
ProjectManager(Kernel &parentKernel)
VisibleNodeList _recentlyRenderedNodes
eastl::queue< std::pair< Scene *, SceneGraphNode * > > _playerAddQueue
void getSortedRefractiveNodes(const Camera *camera, RenderStage stage, bool inView, VisibleNodeList<> &nodesOut) const
get the full list of refractive nodes
void editorPreviewNode(const I64 editorPreviewNode) noexcept
void removePlayerInternal(Scene *parentScene, SceneGraphNode *playerNode)
bool onKeyDown(const Input::KeyEvent &key) override
Key pressed: return true if input was consumed.
eastl::queue< std::pair< Scene *, SceneGraphNode * > > _playerRemoveQueue
std::pair< Handle< Texture >, SamplerDescriptor > getSkyTexture() const
Camera * playerCamera(bool skipOverride=false) const noexcept
bool networkUpdate(U64 frameCount)
const PlatformContext & platformContext() const noexcept
bool joystickRemap(const Input::JoystickEvent &arg) override
bool saveNode(const SceneGraphNode *targetNode) const
void removePlayer(Scene *parentScene, SceneGraphNode *playerNode, bool queue)
void addPlayer(Scene *parentScene, SceneGraphNode *playerNode, bool queue)
void prepareLightData(RenderStage stage, const CameraSnapshot &cameraSnapshot, GFX::MemoryBarrierCommand &memCmdInOut)
bool joystickButtonPressed(const Input::JoystickEvent &arg) override
Joystick button pressed: return true if input was consumed.
ErrorCode loadProject(const ProjectID &targetProject, bool deferToStartOfFrame)
bool joystickAddRemove(const Input::JoystickEvent &arg) override
bool frameEnded(const FrameEvent &evt) override
frameEnded is called after the buffers have been swapped
const VisibleNodeList & getRenderedNodeList() const noexcept
std::array< Time::ProfileTimer *, to_base(RenderStage::COUNT)> _sceneGraphCullTimers
void postRender(GFX::CommandBuffer &bufferInOut, GFX::MemoryBarrierCommand &memCmdInOut)
void getNodesInScreenRect(const Rect< I32 > &screenRect, const Camera &camera, vector< SceneGraphNode * > &nodesOut) const
void debugDraw(GFX::CommandBuffer &bufferInOut, GFX::MemoryBarrierCommand &memCmdInOut)
void initDefaultCullValues(RenderStage stage, NodeCullParams &cullParamsInOut) noexcept
init default culling values like max cull distance and other scene related states
bool joystickAxisMoved(const Input::JoystickEvent &arg) override
Joystick axis change: return true if input was consumed.
void cullSceneGraph(const NodeCullParams &cullParams, const U16 cullFlags, VisibleNodeList<> &nodesOut)
cull the SceneGraph against the current view frustum.
bool onKeyUp(const Input::KeyEvent &key) override
Key released: return true if input was consumed.
bool mouseMoved(const Input::MouseMoveEvent &arg) override
Mouse moved: return true if input was consumed.
PlayerIndex _currentPlayerPass
void onResolutionChange(const SizeChangeParams &params)
void onNodeDestroy(Scene *parentScene, SceneGraphNode *node)
void currentPlayerPass(PlayerIndex idx)
bool resetSelection(PlayerIndex idx, const bool resetIfLocked)
SceneEnvironmentProbePool * getEnvProbes() const noexcept
void mouseMovedExternally(const Input::MouseMoveEvent &arg)
bool loadNode(SceneGraphNode *targetNode) const
U8 activePlayerCount() const noexcept
void onChangeFocus(bool hasFocus)
AI::Navigation::DivideRecast_uptr _recast
static bool OnShutdown(PlatformContext &context)
BoundingSphere moveCameraToNode(Camera *camera, const SceneGraphNode *targetNode) const
bool joystickButtonReleased(const Input::JoystickEvent &arg) override
Joystick button released: return true if input was consumed.
void updateSceneState(U64 deltaGameTimeUS, U64 deltaAppTimeUS)
Update animations, network data, sounds, triggers etc.
bool onTextEvent(const Input::TextEvent &arg) override
bool contains(U xIn, U yIn) const noexcept
Definition: MathVectors.h:1465
PostFX & postFX()
Definition: Renderer.h:61
ResourceState getState() const noexcept
Definition: Resource.cpp:17
static BoundingSphere GetBounds(const SceneGraphNode *sgn)
Definition: SceneGraph.cpp:36
SceneGraphNode * findNode(const Str< 128 > &name, bool sceneNodeName=false) const
Definition: SceneGraph.cpp:503
SceneGraph * sceneGraph() noexcept
Return a reference to the parent graph. Operator= should be disabled.
FORCE_INLINE T * get() const
Returns a pointer to a specific component. Returns null if the SGN does not have the component reques...
T & getNode() noexcept
bool hasFlag(const Flags flag) const noexcept
Returns true only if the current node has the specified flag. Does not check children!
ChildContainer & getChildren() noexcept
static I64 DEFAULT_SCENE_GUID
Definition: Scene.h:131
void updateSceneState(U64 deltaTimeUS)
Update animations, network data, sounds, triggers etc.
Definition: Scene.cpp:1585
static ResourcePath GetSceneRootFolder(const Project &project)
Return the full path to the location of Scenes folder in the project (e.g. ./Projects/Foo/Scenes/ for...
Definition: Scene.cpp:128
vec3< F32 > getSunDirection() const
Definition: Scene.cpp:2309
Project & parent() noexcept
Definition: Scene.h:163
SunInfo getCurrentSunDetails() const noexcept
Definition: Scene.cpp:2319
void fogDetails(const FogDetails &details) noexcept
void windDetails(const F32 directionX, const F32 directionY, const F32 directionZ, const F32 speed) noexcept
bool waterDetails(const U8 index, const WaterBodyData &data) noexcept
void appData(const U32 elapsedGameTimeMS, const U32 elapsedAppTimeMS, const MaterialDebugFlag materialDebugFlag)
void sunDetails(const vec3< F32 > &sunDirection, const FColour3 &colour, const F32 altitude, const F32 azimuth) noexcept
void waitForAllTasks(bool flushCallbacks)
Definition: TaskPool.cpp:246
vec3< T > getForwardDirection() const noexcept
Returns normalized(getForwardVec())
vec3 direction(const vec3 &u) const noexcept
get the direction vector to the specified point
T distance(const vec3 &v) const noexcept
compute the vector's distance to another specified vector
vec3< T > rgb
Definition: MathVectors.h:1378
constexpr T RadiansToDegrees(T angleRadians) noexcept
Return the degree equivalent of the given radian value.
Definition: MathHelper.inl:436
constexpr DEGREES< T > to_VerticalFoV(DEGREES< T > horizontalFoV, D64 aspectRatio) noexcept
Definition: MathHelper.inl:352
constexpr bool ENABLE_EDITOR
Definition: config.h:66
constexpr bool IS_DEBUG_BUILD
Definition: config.h:55
constexpr bool IS_EDITOR_BUILD
Definition: config.h:65
constexpr U8 MAX_LOCAL_PLAYER_COUNT
Maximum number of players we support locally. We store per-player data such as key-bindings,...
Definition: config.h:144
constexpr char DELETED_FOLDER_NAME[]
Definition: config.h:199
constexpr char DEFAULT_PROJECT_NAME[]
Definition: config.h:197
constexpr char DEFAULT_SCENE_NAME[]
Definition: config.h:198
FColour4 WHITE
Random stuff added for convenience.
Definition: Colours.cpp:8
constexpr Optick::Category::Type Scene
Definition: Profiler.h:66
constexpr T SecondsToMicroseconds(U a) noexcept
Definition: MathHelper.inl:767
ProfileTimer & ADD_TIMER(const char *timerName)
const char * RenderStageToString(const RenderStage stage) noexcept
Definition: GFXDevice.cpp:54
Str StringFormat(const char *fmt, Args &&...args)
bool CompareIgnoreCase(const char *a, const char *b) noexcept
void readXML(const ResourcePath &path, boost::property_tree::ptree &tree)
Handle console commands that start with a forward slash.
Definition: AIProcessor.cpp:7
FileError removeDirectory(const ResourcePath &path)
DELEGATE_STD< Ret, Args... > DELEGATE
constexpr U32 to_U32(const T value)
void Wait(const Task &task, TaskPool &pool)
Definition: Task.cpp:20
vector< ProjectID > ProjectIDs
uint8_t U8
@ RES_LOADED
The resource is available for usage.
@ RES_LOADING
The resource is loading, creating data, parsing scripts, etc.
Task * CreateTask(Predicate &&threadedFunction, bool allowedInIdle=true)
Definition: TaskPool.inl:45
constexpr F32 to_F32(const T value)
bool Finished(const Task &task) noexcept
Definition: Task.inl:38
constexpr D64 to_D64(const T value)
SceneNodeType
ToDo: Move particle emitter to components (it will make them way more dynamic) - Ionut.
Definition: SceneNodeFwd.h:47
vec3< U8 > UColour3
Definition: MathHelper.h:69
constexpr U16 BYTE_BUFFER_VERSION
eastl::vector< Type > vector
Definition: Vector.h:42
bool IsSet(const SwitchSceneTarget &target) noexcept
std::shared_lock< mutex > SharedLock
Definition: SharedMutex.h:49
FileError copyFile(const ResourcePath &sourcePath, const std::string_view sourceName, const ResourcePath &targetPath, const std::string_view targetName, const bool overwrite)
@ REALTIME
not threaded
constexpr F32 F32_MAX
uint16_t U16
constexpr U64 _ID(const char *const str, const U64 value=val_64_const) noexcept
void efficient_clear(eastl::fixed_vector< T, nodeCount, bEnableOverflow, OverflowAllocator > &fixed_vector)
Definition: Vector.h:52
constexpr U8 to_U8(const T value)
static const vec3< F32 > WORLD_Z_NEG_AXIS
Definition: MathVectors.h:1444
FORCE_INLINE constexpr bool Is3DObject(const SceneNodeType type) noexcept
Definition: SceneNodeFwd.h:98
void Start(Task &task, TaskPool &pool, TaskPriority priority=TaskPriority::DONT_CARE, const DELEGATE< void > &onCompletionFunction={})
Definition: Task.cpp:9
FileError copyDirectory(const ResourcePath &sourcePath, const ResourcePath &targetPath, bool recursively, bool overwrite)
bool operator==(const DisplayManager::OutputDisplayProperties &lhs, const DisplayManager::OutputDisplayProperties &rhs) noexcept
Definition: Application.inl:37
FileError deleteFile(const ResourcePath &filePath, const std::string_view fileName)
bool fileExists(const ResourcePath &filePathAndName)
constexpr I32 to_I32(const T value)
bool pathExists(const ResourcePath &filePath)
static const vec3< F32 > VECTOR3_ZERO
Definition: MathVectors.h:1434
int64_t I64
FORCE_INLINE T * Get(const Handle< T > handle)
uint32_t U32
uint64_t U64
constexpr auto to_base(const Type value) -> Type
static NO_INLINE void errorfn(const char *format, T &&... args)
static NO_INLINE void warnfn(const char *format, T &&... args)
static NO_INLINE void printfn(const char *format, T &&... args)
vec4< F32 > _colourAndDensity
Definition: SceneState.h:74
vec4< F32 > _colourSunScatter
Definition: SceneState.h:75
const Frustum * _frustum
static void FrustumCull(const NodeCullParams &params, U16 cullFlags, const SceneGraph &sceneGraph, const SceneState &sceneState, PlatformContext &context, VisibleNodeList<> &nodesOut)
static void ToVisibleNodes(const Camera *camera, const vector< SceneGraphNode * > &nodes, VisibleNodeList<> &nodesOut)
StringReturnType< N > string() const noexcept
Definition: ResourcePath.h:64
const SceneNodeType * _ignoredTypes
Definition: SceneNodeFwd.h:80
DirectionalLightComponent * _sunLight
Definition: Scene.h:136
Definition: Scene.h:112
Str< 256 > _name
Definition: Scene.h:113
U16 width
The new width and height.
Angle::RADIANS< F32 > azimuth
Definition: Sun.h:45
Angle::RADIANS< F32 > altitude
Definition: Sun.h:44
Angle::DEGREES< F32 > altitudeMax
Definition: Sun.h:46
SceneGraphNode * _node
void append(const VisibleNodeList &other) noexcept
size_t size() const noexcept
const T & node(const size_t idx) const noexcept