Divide Framework 0.1
A free and open-source 3D Framework under heavy development
Loading...
Searching...
No Matches
WarScene.cpp
Go to the documentation of this file.
1
2
3#include "Headers/WarScene.h"
5
9
12#include "Core/Headers/Kernel.h"
16
27
29
36
38
39namespace Divide {
40
41WarScene::WarScene(PlatformContext& context, Project& parent, const SceneEntry& entry)
42 : Scene(context, parent, entry),
45{
46 const size_t idx = parent.parent().addSelectionCallback([&](PlayerIndex /*idx*/, const vector<SceneGraphNode*>& node)
47 {
48 string selectionText;
49 for (SceneGraphNode* it : node)
50 {
51 selectionText.append("\n");
52 selectionText.append(it->name().c_str());
53 }
54
55 _GUI->modifyText("entityState", selectionText, true);
56 });
57
58 _selectionCallbackIndices.push_back(idx);
59}
60
61WarScene::~WarScene()
62{
63 if (_targetLines && !_context.gfx().destroyIMP(_targetLines) )
64 {
65 DebugBreak();
66 }
67}
68
69void WarScene::toggleTerrainMode() {
71}
72
73void WarScene::debugDraw(GFX::CommandBuffer& bufferInOut,
74 GFX::MemoryBarrierCommand& memCmdInOut )
75{
76 if (state()->renderState().isEnabledOption(SceneRenderState::RenderOptions::RENDER_CUSTOM_PRIMITIVES))
77 {
78 if (!_targetLines)
79 {
80 _targetLines = _context.gfx().newIMP("WarScene Target Lines");
81 PipelineDescriptor pipelineDescriptor = {};
82 pipelineDescriptor._shaderProgramHandle = _context.gfx().imShaders()->imWorldShaderNoTexture();
83
84 pipelineDescriptor._stateBlock = _context.gfx().getNoDepthTestBlock();
85 _targetLines->setPipelineDescriptor(pipelineDescriptor);
86 }
87 else
88 {
89 _targetLines->getCommandBuffer(bufferInOut, memCmdInOut);
90 }
91 }
92 else if (_targetLines)
93 {
94 if (!_context.gfx().destroyIMP(_targetLines))
95 {
96 DebugBreak();
97 }
98 }
99 Scene::debugDraw(bufferInOut, memCmdInOut);
100}
101
102namespace {
103 constexpr bool g_enableOldGameLogic = false;
104 F32 phi = 0.0f;
106 bool initPosSet = false;
107}
108
109namespace{
111}
112
113void WarScene::updateSceneStateInternal(const U64 deltaTimeUS) {
114 PROFILE_SCOPE_AUTO( Profiler::Category::GameLogic );
115
116 if (!_sceneReady) {
117 return;
118 }
119
120 if (_terrainMode) {
121 if (g_terrain == nullptr) {
122 auto objects = sceneGraph()->getNodesByType(SceneNodeType::TYPE_TERRAIN);
123 if (!objects.empty())
124 {
125 g_terrain = objects.front();
126 }
127 } else {
128 vec3<F32> camPos = playerCamera()->snapshot()._eye;
129 if (g_terrain->get<BoundsComponent>()->getBoundingBox().containsPoint(camPos)) {
130 const Terrain& ter = g_terrain->getNode<Terrain>();
131
132 F32 headHeight = state()->playerState(state()->playerPass())._headHeight;
133 camPos -= g_terrain->get<TransformComponent>()->getWorldPosition();
134 playerCamera()->setEye(ter.getVertFromGlobal(camPos.x, camPos.z, true)._position + vec3<F32>(0.0f, headHeight, 0.0f));
135 }
136 }
137 }
138
139 if constexpr(g_enableOldGameLogic) {
140 if (_resetUnits) {
141 resetUnits();
142 _resetUnits = false;
143 }
144
145 SceneGraphNode* particles = _particleEmitter;
146 const F32 radius = 200;
147
148 if (particles) {
149 phi += 0.001f;
150 if (phi > 360.0f) {
151 phi = 0.0f;
152 }
153
154 TransformComponent* tComp = particles->get<TransformComponent>();
155 if (!initPosSet) {
156 initPos.set(tComp->getWorldPosition());
157 initPosSet = true;
158 }
159
160 tComp->setPosition(radius * std::cos(phi) + initPos.x,
161 (radius * 0.5f) * std::sin(phi) + initPos.y,
162 radius * std::sin(phi) + initPos.z);
163 tComp->rotateY(phi);
164 }
165
166 if (!_aiManager->getNavMesh(_armyNPCs[0][0]->get<UnitComponent>()->getUnit<NPC>()->getAIEntity()->getAgentRadiusCategory())) {
167 return;
168 }
169
170 // renderState().drawDebugLines(true);
171 vec3<F32> tempDestination;
172 UColour4 redLine(255, 0, 0, 128);
173 UColour4 blueLine(0, 0, 255, 128);
174 vector<Line> paths;
175 paths.reserve(_armyNPCs[0].size() + _armyNPCs[1].size());
176 for (U8 i = 0; i < 2; ++i) {
177 for (SceneGraphNode* node : _armyNPCs[i]) {
178 AI::AIEntity* const character = node->get<UnitComponent>()->getUnit<NPC>()->getAIEntity();
179 if (!node->IsActive()) {
180 continue;
181 }
182 tempDestination.set(character->getDestination());
183 if (!tempDestination.isZeroLength()) {
184 paths.emplace_back(
185 character->getPosition(),
186 tempDestination,
187 i == 0 ? blueLine : redLine,
188 i == 0 ? blueLine / 2 : redLine / 2);
189 }
190 }
191 }
192 if (_targetLines) {
193 _targetLines->fromLines(paths.data(), paths.size());
194 }
195
196 if (!_aiManager->updatePaused()) {
197 _elapsedGameTime += deltaTimeUS;
199 }
200 }
201}
202
203bool WarScene::load() {
204 // Load scene resources
205 const bool loadState = Scene::load();
206 setDayNightCycleTimeFactor(24);
207
208 // Position camera
209 Camera::GetUtilityCamera(Camera::UtilityCamera::DEFAULT)->setEye(vec3<F32>(43.13f, 147.09f, -4.41f));
210 Camera::GetUtilityCamera(Camera::UtilityCamera::DEFAULT)->setGlobalRotation(-90.0f /*yaw*/, 59.21f /*pitch*/);
211
212 // Add some obstacles
213
214 /*
215 constexpr U32 lightMask = to_base(ComponentType::TRANSFORM) |
216 to_base(ComponentType::BOUNDS) |
217 to_base(ComponentType::RENDERING);
218
219 constexpr U32 normalMask = lightMask |
220 to_base(ComponentType::RIGID_BODY) |
221 to_base(ComponentType::NAVIGATION) |
222 to_base(ComponentType::NETWORKING);
223
224 SceneGraphNode* cylinder[5];
225 cylinder[0] = _sceneGraph->findNode("cylinderC");
226 cylinder[1] = _sceneGraph->findNode("cylinderNW");
227 cylinder[2] = _sceneGraph->findNode("cylinderNE");
228 cylinder[3] = _sceneGraph->findNode("cylinderSW");
229 cylinder[4] = _sceneGraph->findNode("cylinderSE");
230
231 for (U8 i = 0; i < 5; ++i) {
232 RenderingComponent* const renderable = cylinder[i]->getChild(0).get<RenderingComponent>();
233 renderable->getMaterialInstance()->setDoubleSided(true);
234 cylinder[i]->getChild(0).getNode().getMaterialTpl()->setDoubleSided(true);
235 }
236
237 // Make the center cylinder reflective
238 const Material_ptr& matInstance = cylinder[0]->getChild(0).get<RenderingComponent>()->getMaterialInstance();
239 matInstance->shininess(Material::MAX_SHININESS);
240 */
241 string currentName;
242#if 0
243 SceneNode_ptr cylinderMeshNW = cylinder[1]->getNode();
244 SceneNode_ptr cylinderMeshNE = cylinder[2]->getNode();
245 SceneNode_ptr cylinderMeshSW = cylinder[3]->getNode();
246 SceneNode_ptr cylinderMeshSE = cylinder[4]->getNode();
247
248 SceneNode_ptr currentMesh;
249 SceneGraphNode* baseNode;
250
251 SceneGraphNodeDescriptor sceneryNodeDescriptor;
252 sceneryNodeDescriptor._serialize = false;
253 sceneryNodeDescriptor._componentMask = normalMask;
254
255 U8 locationFlag = 0;
256 vec2<I32> currentPos;
257 for (U8 i = 0; i < 40; ++i) {
258 if (i < 10) {
259 baseNode = cylinder[1];
260 currentMesh = cylinderMeshNW;
261 currentName = "Cylinder_NW_" + Util::to_string((I32)i);
262 currentPos.x = -200 + 40 * i + 50;
263 currentPos.y = -200 + 40 * i + 50;
264 } else if (i >= 10 && i < 20) {
265 baseNode = cylinder[2];
266 currentMesh = cylinderMeshNE;
267 currentName = "Cylinder_NE_" + Util::to_string((I32)i);
268 currentPos.x = 200 - 40 * (i % 10) - 50;
269 currentPos.y = -200 + 40 * (i % 10) + 50;
270 locationFlag = 1;
271 } else if (i >= 20 && i < 30) {
272 baseNode = cylinder[3];
273 currentMesh = cylinderMeshSW;
274 currentName = "Cylinder_SW_" + Util::to_string((I32)i);
275 currentPos.x = -200 + 40 * (i % 20) + 50;
276 currentPos.y = 200 - 40 * (i % 20) - 50;
277 locationFlag = 2;
278 } else {
279 baseNode = cylinder[4];
280 currentMesh = cylinderMeshSE;
281 currentName = "Cylinder_SE_" + Util::to_string((I32)i);
282 currentPos.x = 200 - 40 * (i % 30) - 50;
283 currentPos.y = 200 - 40 * (i % 30) - 50;
284 locationFlag = 3;
285 }
286
287
288
289 sceneryNodeDescriptor._node = currentMesh;
290 sceneryNodeDescriptor._name = currentName;
291 sceneryNodeDescriptor._usageContext = baseNode->usageContext();
292 sceneryNodeDescriptor._physicsGroup = baseNode->get<RigidBodyComponent>()->physicsGroup();
293
294 SceneGraphNode* crtNode = _sceneGraph->getRoot().addNode(sceneryNodeDescriptor);
295
296 TransformComponent* tComp = crtNode->get<TransformComponent>();
297 NavigationComponent* nComp = crtNode->get<NavigationComponent>();
298 nComp->navigationContext(baseNode->get<NavigationComponent>()->navigationContext());
299 nComp->navigationDetailOverride(baseNode->get<NavigationComponent>()->navMeshDetailOverride());
300
301 vec3<F32> position(to_F32(currentPos.x), -0.01f, to_F32(currentPos.y));
302 tComp->setScale(baseNode->get<TransformComponent>()->getScale());
303 tComp->setPosition(position);
304 {
305 ResourceDescriptor<Light> tempLight(Util::StringFormat("Light_point_random_1", currentName.c_str()));
306 tempLight.setEnumValue(to_base(LightType::POINT));
307 tempLight.setUserPtr(_lightPool);
308 std::shared_ptr<Light> light = CreateResource(_resCache, tempLight);
309 light->setDrawImpostor(false);
310 light->setRange(25.0f);
311 //light->setCastShadows(i == 0 ? true : false);
312 light->setCastShadows(false);
313 light->setDiffuseColour(DefaultColours::RANDOM());
314 SceneGraphNode* lightSGN = _sceneGraph->getRoot().addNode(light, lightMask);
315 lightSGN->get<TransformComponent>()->setPosition(position + vec3<F32>(0.0f, 8.0f, 0.0f));
316 }
317 {
318 ResourceDescriptor<Light> tempLight(Util::StringFormat("Light_point_{}_2", currentName.c_str()));
319 tempLight.setEnumValue(to_base(LightType::POINT));
320 tempLight.setUserPtr(_lightPool);
321 std::shared_ptr<Light> light = CreateResource(_resCache, tempLight);
322 light->setDrawImpostor(false);
323 light->setRange(35.0f);
324 light->setCastShadows(false);
325 light->setDiffuseColour(DefaultColours::RANDOM());
326 SceneGraphNode* lightSGN = _sceneGraph->getRoot().addNode(light, lightMask);
327 lightSGN->get<TransformComponent>()->setPosition(position + vec3<F32>(0.0f, 8.0f, 0.0f));
328 }
329 {
330 ResourceDescriptor<Light> tempLight(Util::StringFormat("Light_spot_{}", currentName.c_str()));
331 tempLight.setEnumValue(to_base(LightType::SPOT));
332 tempLight.setUserPtr(_lightPool);
333 std::shared_ptr<Light> light = CreateResource(_resCache, tempLight);
334 light->setDrawImpostor(false);
335 light->setRange(55.0f);
336 //light->setCastShadows(i == 1 ? true : false);
337 light->setCastShadows(false);
338 light->setDiffuseColour(DefaultColours::RANDOM());
339 SceneGraphNode* lightSGN = _sceneGraph->getRoot().addNode(light, lightMask);
340 lightSGN->get<TransformComponent>()->setPosition(position + vec3<F32>(0.0f, 10.0f, 0.0f));
341 lightSGN->get<TransformComponent>()->rotateX(-20);
342 }
343 }
344
345 SceneGraphNode* flag;
346 flag = _sceneGraph->findNode("flag");
347 RenderingComponent* const renderable = flag->getChild(0).get<RenderingComponent>();
348 renderable->getMaterialInstance()->setDoubleSided(true);
349 const Material_ptr& mat = flag->getChild(0).getNode()->getMaterialTpl();
350 mat->setDoubleSided(true);
351 flag->setActive(false);
352 SceneNode_ptr flagNode = flag->getNode();
353
354 sceneryNodeDescriptor._usageContext = NodeUsageContext::NODE_DYNAMIC;
355 sceneryNodeDescriptor._node = flagNode;
356 sceneryNodeDescriptor._physicsGroup = flag->get<RigidBodyComponent>()->physicsGroup();
357 sceneryNodeDescriptor._name = "Team1Flag";
358
359 _flag[0] = _sceneGraph->getRoot().addNode(sceneryNodeDescriptor);
360
361 SceneGraphNode* flag0(_flag[0]);
362
363 TransformComponent* flagtComp = flag0->get<TransformComponent>();
364 NavigationComponent* flagNComp = flag0->get<NavigationComponent>();
365 RenderingComponent* flagRComp = flag0->getChild(0).get<RenderingComponent>();
366
367 flagtComp->setScale(flag->get<TransformComponent>()->getScale());
368 flagtComp->setPosition(vec3<F32>(25.0f, 0.1f, -206.0f));
369
370 flagNComp->navigationContext(NavigationComponent::NavigationContext::NODE_IGNORE);
371
372 flagRComp->getMaterialInstance()->setDiffuse(DefaultColours::BLUE);
373
374 sceneryNodeDescriptor._name = "Team2Flag";
375 _flag[1] = _sceneGraph->getRoot().addNode(sceneryNodeDescriptor);
376 SceneGraphNode* flag1(_flag[1]);
377 flag1->usageContext(flag->usageContext());
378
379 flagtComp = flag1->get<TransformComponent>();
380 flagNComp = flag1->get<NavigationComponent>();
381 flagRComp = flag1->getChild(0).get<RenderingComponent>();
382
383 flagtComp->setPosition(vec3<F32>(25.0f, 0.1f, 206.0f));
384 flagtComp->setScale(flag->get<TransformComponent>()->getScale());
385
386 flagNComp->navigationContext(NavigationComponent::NavigationContext::NODE_IGNORE);
387
388 flagRComp->getMaterialInstance()->setDiffuse(DefaultColours::RED);
389
390 sceneryNodeDescriptor._name = "FirstPersonFlag";
391 SceneGraphNode* firstPersonFlag = _sceneGraph->getRoot().addNode(sceneryNodeDescriptor);
392 firstPersonFlag->lockVisibility(true);
393
394 flagtComp = firstPersonFlag->get<TransformComponent>();
395 flagtComp->setScale(0.0015f);
396 flagtComp->setPosition(1.25f, -1.5f, 0.15f);
397 flagtComp->rotate(-20.0f, -70.0f, 50.0f);
398
399 auto collision = [this](const RigidBodyComponent& collider) {
400 weaponCollision(collider);
401 };
402 RigidBodyComponent* rComp = firstPersonFlag->get<RigidBodyComponent>();
403 rComp->onCollisionCbk(collision);
404 flagRComp = firstPersonFlag->getChild(0).get<RenderingComponent>();
405 flagRComp->getMaterialInstance()->setDiffuse(DefaultColours::GREEN);
406
407 firstPersonFlag->get<RigidBodyComponent>()->physicsGroup(PhysicsGroup::GROUP_KINEMATIC);
408
409 _firstPersonWeapon = firstPersonFlag;
410
411 AI::WarSceneAIProcessor::registerFlags(_flag[0], _flag[1]);
412
413 AI::WarSceneAIProcessor::registerScoreCallback([&](U8 teamID, const string& unitName) {
414 registerPoint(teamID, unitName);
415 });
416
417 AI::WarSceneAIProcessor::registerMessageCallback([&](U8 eventID, const string& unitName) {
418 printMessage(eventID, unitName);
419 });
420#endif
421
422 //state().renderState().generalVisibility(state().renderState().generalVisibility() * 2);
423
424 ResourceDescriptor<TransformNode> transformDescriptor("LightTransform");
425
426 SceneGraphNodeDescriptor lightParentNodeDescriptor;
427 lightParentNodeDescriptor._nodeHandle = FromHandle( CreateResource( transformDescriptor ) );
428 lightParentNodeDescriptor._serialize = false;
429 lightParentNodeDescriptor._name = "Point Lights";
430 lightParentNodeDescriptor._usageContext = NodeUsageContext::NODE_STATIC;
431 lightParentNodeDescriptor._componentMask = to_base(ComponentType::TRANSFORM) |
432 to_base(ComponentType::BOUNDS) |
433 to_base(ComponentType::NETWORKING);
434 SceneGraphNode* pointLightNode = _sceneGraph->getRoot()->addChildNode(lightParentNodeDescriptor);
435 pointLightNode->get<BoundsComponent>()->collisionsEnabled(false);
436
437 SceneGraphNodeDescriptor lightNodeDescriptor;
438 lightNodeDescriptor._serialize = false;
439 lightNodeDescriptor._usageContext = NodeUsageContext::NODE_DYNAMIC;
440 lightNodeDescriptor._componentMask = to_base(ComponentType::TRANSFORM) |
441 to_base(ComponentType::BOUNDS) |
442 to_base(ComponentType::NETWORKING) |
443 to_base(ComponentType::POINT_LIGHT);
444
445 constexpr U8 rowCount = 10;
446 constexpr U8 colCount = 10;
447 for (U8 row = 0; row < rowCount; row++)
448 {
449 for (U8 col = 0; col < colCount; col++)
450 {
451 Util::StringFormat( lightNodeDescriptor._name, "Light_point_{}_{}", row, col);
452 lightNodeDescriptor._nodeHandle = FromHandle( CreateResource( transformDescriptor ) );
453
454 SceneGraphNode* lightSGN = pointLightNode->addChildNode(lightNodeDescriptor);
455
456 PointLightComponent* pointLight = lightSGN->get<PointLightComponent>();
457 pointLight->castsShadows(false);
458 pointLight->range(50.0f);
459 pointLight->setDiffuseColour(DefaultColours::RANDOM().rgb);
460
461 TransformComponent* tComp = lightSGN->get<TransformComponent>();
462 tComp->setPosition(vec3<F32>(-21.0f + 115 * row, 20.0f, -21.0f + 115 * col));
463
464 lightSGN->get<BoundsComponent>()->collisionsEnabled(false);
465
466 _lightNodeTransforms.push_back(tComp);
467 }
468 }
469
470 Camera::GetUtilityCamera(Camera::UtilityCamera::DEFAULT)->setHorizontalFoV(110);
471
472 _sceneReady = true;
473 if (loadState) {
474 return initializeAI(true);
475 }
476 return false;
477}
478
479
480bool WarScene::unload() {
481 deinitializeAI(true);
482 return Scene::unload();
483}
484
485U16 WarScene::registerInputActions() {
486 U16 actionID = Scene::registerInputActions();
487
488 //ToDo: Move these to per-scene XML file
489 {
490 PressReleaseActions::Entry actionEntry = {};
491 actionEntry.releaseIDs().insert(actionID);
492 if (!_input->actionList().registerInputAction(actionID, [this](const InputParams& param) {toggleCamera(param); })) {
494 }
495 _input->addKeyMapping(Input::KeyCode::KC_TAB, actionEntry);
496 actionID++;
497 }
498 {
499 PressReleaseActions::Entry actionEntry = {};
500 if (!_input->actionList().registerInputAction(actionID, [this](const InputParams& /*param*/) {registerPoint(0u, ""); })) {
502 }
503 actionEntry.releaseIDs().insert(actionID);
504 _input->addKeyMapping(Input::KeyCode::KC_1, actionEntry);
505 actionID++;
506 }
507 {
508 PressReleaseActions::Entry actionEntry = {};
509 if (!_input->actionList().registerInputAction(actionID, [this](const InputParams& /*param*/) {registerPoint(1u, ""); })) {
511 }
512 actionEntry.releaseIDs().insert(actionID);
513 _input->addKeyMapping(Input::KeyCode::KC_2, actionEntry);
514 actionID++;
515 }
516 {
517 PressReleaseActions::Entry actionEntry = {};
518 if (!_input->actionList().registerInputAction(actionID, [this](InputParams /*param*/) {
520 const bool dir = _lightPool->lightTypeEnabled(LightType::DIRECTIONAL);
521 const bool point = _lightPool->lightTypeEnabled(LightType::POINT);
522 const bool spot = _lightPool->lightTypeEnabled(LightType::SPOT);
523 if (dir && point && spot) {
524 _lightPool->toggleLightType(LightType::SPOT, false);
525 } else if (dir && point && !spot) {
526 _lightPool->toggleLightType(LightType::POINT, false);
527 } else if (dir && !point && !spot) {
528 _lightPool->toggleLightType(LightType::DIRECTIONAL, false);
529 _lightPool->toggleLightType(LightType::SPOT, true);
530 } else if (!dir && !point && spot) {
531 _lightPool->toggleLightType(LightType::POINT, true);
532 } else if (!dir && point && spot) {
533 _lightPool->toggleLightType(LightType::DIRECTIONAL, true);
534 _lightPool->toggleLightType(LightType::POINT, false);
535 } else {
536 _lightPool->toggleLightType(LightType::POINT, true);
537 }
538 })) {
540 }
541 actionEntry.releaseIDs().insert(actionID);
542 _input->addKeyMapping(Input::KeyCode::KC_L, actionEntry);
543 }
544
545 return actionID++;
546}
547
548void WarScene::toggleCamera(const InputParams param) {
549 // None of this works with multiple players
550 static bool tpsCameraActive = false;
551 static bool flyCameraActive = true;
552 static Camera* tpsCamera = nullptr;
553
554 if (!tpsCamera) {
555 tpsCamera = Camera::FindCamera(_ID("tpsCamera"));
556 }
557
558 const PlayerIndex idx = getPlayerIndexForDevice(param._deviceIndex);
559 if (_currentSelection[idx]._selectionCount > 0u) {
560 SceneGraphNode* node = sceneGraph()->findNode(_currentSelection[idx]._selections[0]);
561 if (node != nullptr) {
562 if (flyCameraActive) {
563 state()->playerState(idx).overrideCamera(tpsCamera);
564 tpsCamera->setTarget(node->get<TransformComponent>(), vec3<F32>(0.f, 0.75f, 1.f));
565 flyCameraActive = false;
566 tpsCameraActive = true;
567 return;
568 }
569 }
570 }
571 if (tpsCameraActive) {
572 state()->playerState(idx).overrideCamera(nullptr);
573 tpsCameraActive = false;
574 flyCameraActive = true;
575 }
576}
577
578void WarScene::postLoadMainThread() {
579 const vec2<U16> screenResolution = _context.gfx().renderTargetPool().getRenderTarget(RenderTargetNames::SCREEN)->getResolution();
580 const Rect<U16> targetRenderViewport = { 0u, 0u, screenResolution.width, screenResolution.height };
581
582 GUIButton* btn = _GUI->addButton("Simulate",
583 "Simulate",
584 pixelPosition(targetRenderViewport.sizeX - 220, 60),
585 pixelScale(100, 25));
586 btn->setEventCallback(GUIButton::Event::MouseClick, [this](const I64 btnGUID) { startSimulation(btnGUID); });
587
588 btn = _GUI->addButton("TerrainMode",
589 "Terrain Mode Toggle",
590 pixelPosition(targetRenderViewport.sizeX - 240, 90),
591 pixelScale(120, 25));
592 btn->setEventCallback(GUIButton::Event::MouseClick,
593 [this](I64 /*btnID*/) { toggleTerrainMode(); });
594
595 _GUI->addText("RenderBinCount",
596 pixelPosition(60, 83),
597 Font::DIVIDE_DEFAULT,
598 UColour4(164, 50, 50, 255),
599 Util::StringFormat("Number of items in Render Bin: {}", 0));
600
601 _GUI->addText("camPosition", pixelPosition(60, 103),
602 Font::DIVIDE_DEFAULT,
603 UColour4(50, 192, 50, 255),
604 Util::StringFormat("Position [ X: {:5.0f} | Y: {:5.0f} | Z: {:5.0f} ] [Pitch: {:5.2f} | Yaw: {:5.2f}]",
605 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
606
607
608 _GUI->addText("scoreDisplay",
609 pixelPosition(60, 123), // Position
610 Font::DIVIDE_DEFAULT, // Font
611 UColour4(50, 192, 50, 255),// Colour
612 Util::StringFormat("Score: A - {} B - {}", 0, 0)); // Text and arguments
613
614 _GUI->addText("terrainInfoDisplay",
615 pixelPosition(60, 163), // Position
616 Font::DIVIDE_DEFAULT, // Font
617 UColour4(128, 0, 0, 255),// Colour
618 "Terrain Data"); // Text and arguments
619
620 _GUI->addText("entityState",
621 pixelPosition(60, 223),
622 Font::DIVIDE_DEFAULT,
623 UColour4(0, 0, 0, 255),
624 "",
625 true);
626
627 _infoBox = _GUI->addMsgBox("infoBox", "Info", "Blabla");
628
629 // Add a first person camera
630 {
631 Camera* cam = Camera::CreateCamera("fpsCamera", Camera::Mode::FIRST_PERSON );
632 cam->fromCamera(*Camera::GetUtilityCamera(Camera::UtilityCamera::DEFAULT));
633 cam->speedFactor().move = 10.f;
634 cam->speedFactor().turn = 10.f;
635 }
636 // Add a third person camera
637 {
638 Camera* cam = Camera::CreateCamera("tpsCamera", Camera::Mode::THIRD_PERSON );
639 cam->fromCamera(*Camera::GetUtilityCamera(Camera::UtilityCamera::DEFAULT));
640 cam->speedFactor().move = 0.02f;
641 cam->speedFactor().turn = 0.01f;
642 }
643
644 /*
645 addTaskTimer(TimerClass::GAME_TIME,
646 Time::SecondsToMicroseconds( 5.0 ),
647 [this]( [[maybe_unused]] const U64 elapsedTimeUS )
648 {
649 for (SceneGraphNode* npc : _armyNPCs[0]) {
650 assert(npc);
651 npc->get<UnitComponent>()->getUnit<NPC>()->playNextAnimation();
652
653 } );
654
655 addTaskTimer( TimerClass::GAME_TIME,
656 Time::SecondsToMicroseconds( 10.0 ),
657 [this]( [[maybe_unused]] const U64 elapsedTimeUS )
658 {
659 for (SceneGraphNode* npc : _armyNPCs[1]) {
660 assert(npc);
661 npc->get<UnitComponent>()->getUnit<NPC>()->playNextAnimation();
662 }
663 });
664 */
665
666 addTaskTimer( TimerClass::GAME_TIME,
667 Time::MillisecondsToMicroseconds( 33 ),
668 [this]( [[maybe_unused]] const U64 elapsedTimeUS )
669 {
670 thread_local F32 phiLight = 0.0f;
671 thread_local bool initPosSetLight = false;
672 NO_DESTROY thread_local vector<vec3<F32>> initPosLight;
673
674 if ( !initPosSetLight )
675 {
676 const size_t lightCount = _lightNodeTransforms.size();
677 initPosLight.resize( lightCount );
678 for ( size_t i = 0u; i < lightCount; ++i )
679 {
680 initPosLight[i].set( _lightNodeTransforms[i]->getWorldPosition() );
681 }
682 initPosSetLight = true;
683 }
684
685 const size_t lightCount = _lightNodeTransforms.size();
686 constexpr F32 radius = 150.f;
687 constexpr F32 height = 25.f;
688
689 phiLight += 0.01f;
690 if (phiLight > 360.0f)
691 {
692 phiLight = 0.0f;
693 }
694
695 const F32 s1 = std::sin( phiLight);
696 const F32 c1 = std::cos( phiLight);
697 const F32 s2 = std::sin(-phiLight);
698 const F32 c2 = std::cos(-phiLight);
699
700 for ( size_t i = 0u; i < lightCount; ++i )
701 {
702 const F32 c = i % 2 == 0 ? c1 : c2;
703 const F32 s = i % 2 == 0 ? s1 : s2;
704
705 _lightNodeTransforms[i]->setPosition(
706 radius * c + initPosLight[i].x,
707 height * s + initPosLight[i].y,
708 radius * s + initPosLight[i].z
709 );
710 }
711 });
712
713 addGuiTimer( TimerClass::APP_TIME,
714 Time::SecondsToMicroseconds( 0.25),
715 [this]( [[maybe_unused]] const U64 elapsedTimeUS )
716 {
717 const Camera& cam = *_scenePlayers.front()->camera();
718 vec3<F32> eyePos = cam.snapshot()._eye;
719 const vec3<F32>& euler = cam.euler();
720
721 _GUI->modifyText("RenderBinCount",
722 Util::StringFormat("Number of items in Render Bin: {}.",
723 _context.kernel().renderPassManager()->getLastTotalBinSize(RenderStage::DISPLAY)), false);
724
725 _GUI->modifyText("camPosition",
726 Util::StringFormat("Position [ X: {:5.2f} | Y: {:5.2f} | Z: {:5.2f} ] [Pitch: {:5.2f} | Yaw: {:5.2f}]",
727 eyePos.x, eyePos.y, eyePos.z, euler.pitch, euler.yaw), false);
728
729 static SceneGraphNode* terrain = nullptr;
730 if ( terrain == nullptr )
731 {
732 vector<SceneGraphNode*> terrains = _sceneGraph->getNodesByType( SceneNodeType::TYPE_TERRAIN );
733 if ( !terrains.empty() )
734 {
735 terrain = terrains.front();
736 }
737 }
738
739 if (terrain != nullptr)
740 {
741 const Terrain& ter = terrain->getNode<Terrain>();
742 CLAMP<F32>(eyePos.x,
743 ter.getDimensions().width * 0.5f * -1.0f,
744 ter.getDimensions().width * 0.5f);
745 CLAMP<F32>(eyePos.z,
746 ter.getDimensions().height * 0.5f * -1.0f,
747 ter.getDimensions().height * 0.5f);
748 mat4<F32> mat = MAT4_IDENTITY;
749 terrain->get<TransformComponent>()->getWorldMatrix(mat);
750 Terrain::Vert terVert = ter.getVertFromGlobal(eyePos.x, eyePos.z, true);
751 const vec3<F32> terPos = mat * terVert._position;
752 const vec3<F32>& terNorm = terVert._normal;
753 const vec3<F32>& terTan = terVert._tangent;
754 _GUI->modifyText("terrainInfoDisplay",
755 Util::StringFormat("Position [ X: {:5.2f} | Y: {:5.2f} | Z: {:5.2f} ]\nNormal [ X: {:5.2f} | Y: {:5.2f} | Z: {:5.2f} ]\nTangent [ X: {:5.2f} | Y: {:5.2f} | Z: {:5.2f} ]",
756 terPos.x, terPos.y, terPos.z,
757 terNorm.x, terNorm.y, terNorm.z,
758 terTan.x, terTan.y, terTan.z),
759 true);
760 }
761 });
762
763 addGuiTimer( TimerClass::GAME_TIME,
764 Time::SecondsToMicroseconds( 1.0 ),
765 [this]( [[maybe_unused]] const U64 elapsedTimeUS )
766 {
767 string selectionText;
768 const Selections& selections = _currentSelection[0];
769 for (U8 i = 0u; i < selections._selectionCount; ++i) {
770 SceneGraphNode* node = sceneGraph()->findNode(selections._selections[i]);
771 if (node != nullptr) {
772 AI::AIEntity* entity = findAI(node);
773 if (entity) {
774 selectionText.append("\n");
775 selectionText.append(entity->toString());
776 }
777 }
778 }
779 if (!selectionText.empty()) {
780 _GUI->modifyText("entityState", selectionText, true);
781 }
782 });
783
784 addGuiTimer( TimerClass::GAME_TIME,
785 Time::SecondsToMicroseconds( 5.0 ),
786 [this]( [[maybe_unused]] const U64 elapsedTimeUS )
787 {
788 U32 elapsedTimeMinutes = Time::MicrosecondsToSeconds<U32>(_elapsedGameTime) / 60 % 60;
789 U32 elapsedTimeSeconds = Time::MicrosecondsToSeconds<U32>(_elapsedGameTime) % 60;
790 U32 elapsedTimeMilliseconds = Time::MicrosecondsToMilliseconds<U32>(_elapsedGameTime) % 1000;
791
792
793 U32 limitTimeMinutes = _timeLimitMinutes;
794 U32 limitTimeSeconds = 0;
795 U32 limitTimeMilliseconds = 0;
796
797 _GUI->modifyText("scoreDisplay",
798 Util::StringFormat("Score: A - {} B - {} [Limit: {}]\nElapsed game time [ {}:{}:{} / {}:{}:{}]",
799 AI::WarSceneAIProcessor::getScore(0),
800 AI::WarSceneAIProcessor::getScore(1),
801 _scoreLimit,
802 elapsedTimeMinutes,
803 elapsedTimeSeconds,
804 elapsedTimeMilliseconds,
805 limitTimeMinutes,
806 limitTimeSeconds,
807 limitTimeMilliseconds),
808 true);
809 });
810
811 Scene::postLoadMainThread();
812}
813
814void WarScene::onSetActive() {
815 Scene::onSetActive();
816 //playerCamera()->lockToObject(_firstPersonWeapon);
817}
818
819void WarScene::weaponCollision(const RigidBodyComponent& collider) {
820 Console::d_printfn("Weapon touched [ {} ]", collider.parentSGN()->name().c_str());
821}
822
823}
#define NO_DESTROY
#define DIVIDE_UNEXPECTED_CALL()
#define PROFILE_SCOPE_AUTO(CATEGORY)
Definition: Profiler.h:87
void setTarget(TransformComponent *tComp, const vec3< F32 > &offsetDirection=VECTOR3_ZERO) noexcept
Offset direction is a (eventually normalized) vector that is scaled by curRadius and applied to the c...
Definition: Camera.cpp:348
void getCommandBuffer(GFX::CommandBuffer &commandBufferInOut, GFX::MemoryBarrierCommand &memCmdInOut)
void setPipelineDescriptor(const PipelineDescriptor &descriptor)
void fromLines(const IM::LineDescriptor &lines)
ProjectManager & parent() noexcept
size_t addSelectionCallback(const DELEGATE< void, U8, const vector< SceneGraphNode * > & > &selectionCallback)
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
void set(const T *v) noexcept
set the 3 components of the vector manually using a source pointer to a (large enough) array
Definition: MathVectors.h:707
constexpr Optick::Category::Type Scene
Definition: Profiler.h:66
Handle console commands that start with a forward slash.
Definition: AIProcessor.cpp:7
void weaponCollision(const RigidBodyComponent &collider)
Definition: WarScene.cpp:819
U64 _elapsedGameTime
Definition: WarScene.h:88
SceneGraphNode * _firstPersonWeapon
Definition: WarScene.h:98
bool deinitializeAI(bool continueOnErrors)
Definition: WarSceneAI.cpp:436
uint8_t U8
bool DebugBreak(const bool condition) noexcept
vector< TransformComponent * > _lightNodeTransforms
Definition: WarScene.h:82
constexpr F32 to_F32(const T value)
SceneGraphNode * _particleEmitter
Definition: WarScene.h:97
U32 _scoreLimit
Definition: WarScene.h:86
bool _sceneReady
Definition: WarScene.h:89
RelativePosition2D pixelPosition(const I32 x, const I32 y)
Definition: Dimension.h:61
Project & parent
Definition: DefaultScene.h:41
uint16_t U16
constexpr U64 _ID(const char *const str, const U64 value=val_64_const) noexcept
FORCE_INLINE Handle< T > CreateResource(const ResourceDescriptor< T > &descriptor, bool &wasInCache, std::atomic_uint &taskCounter)
SceneGraphNode * _flag[2]
Definition: WarScene.h:96
IMPrimitive * _targetLines
Definition: WarScene.h:95
bool _resetUnits
Definition: WarScene.h:90
bool initializeAI(bool continueOnErrors)
Definition: WarSceneAI.cpp:138
SceneNodeHandle FromHandle(const Handle< T > handle)
RelativeScale2D pixelScale(const I32 x, const I32 y)
Definition: Dimension.h:76
bool _terrainMode
Definition: WarScene.h:91
void startSimulation(I64 btnGUID)
Definition: WarSceneAI.cpp:457
void toggleTerrainMode()
Definition: WarScene.cpp:69
AI::AIEntity * findAI(SceneGraphNode *node)
Definition: WarSceneAI.cpp:412
U32 _timeLimitMinutes
Definition: WarScene.h:85
void registerPoint(U16 teamID, const string &unitName)
Definition: WarSceneAI.cpp:113
GUIMessageBox * _infoBox
Definition: WarScene.h:81
vec4< U8 > UColour4
Definition: MathHelper.h:72
bool resetUnits()
Definition: WarSceneAI.cpp:426
void checkGameCompletion()
Definition: WarSceneAI.cpp:45
uint32_t U32
Project const SceneEntry & entry
Definition: DefaultScene.h:41
void printMessage(U8 eventId, const string &unitName) const
Definition: WarSceneAI.cpp:25
uint64_t U64
constexpr auto to_base(const Type value) -> Type