diff --git a/src/entity/components/camera-component.cpp b/src/entity/components/camera-component.cpp
new file mode 100644
index 0000000..2f4f81f
--- /dev/null
+++ b/src/entity/components/camera-component.cpp
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2017-2019 Christopher J. Howard
+ *
+ * This file is part of Antkeeper Source Code.
+ *
+ * Antkeeper Source Code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Antkeeper Source Code is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Antkeeper Source Code. If not, see .
+ */
+
+#include "camera-component.hpp"
+
+ComponentBase* CameraComponent::clone() const
+{
+ CameraComponent* component = new CameraComponent();
+ component->camera = camera;
+
+ return component;
+}
+
diff --git a/src/entity/components/camera-component.hpp b/src/entity/components/camera-component.hpp
new file mode 100644
index 0000000..de2f60e
--- /dev/null
+++ b/src/entity/components/camera-component.hpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2017-2019 Christopher J. Howard
+ *
+ * This file is part of Antkeeper Source Code.
+ *
+ * Antkeeper Source Code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Antkeeper Source Code is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Antkeeper Source Code. If not, see .
+ */
+
+#ifndef CAMERA_COMPONENT_HPP
+#define CAMERA_COMPONENT_HPP
+
+#include "../component.hpp"
+#include "component-type.hpp"
+
+#include
+using namespace Emergent;
+
+class CameraComponent: public Component
+{
+public:
+ virtual ComponentBase* clone() const;
+
+ Camera camera;
+};
+
+#endif // CAMERA_COMPONENT_HPP
+
diff --git a/src/entity/components/component-type.hpp b/src/entity/components/component-type.hpp
index 9c03646..910659d 100644
--- a/src/entity/components/component-type.hpp
+++ b/src/entity/components/component-type.hpp
@@ -25,6 +25,7 @@ enum class ComponentType
ANIMATION,
ANT_HILL,
BEHAVIOR,
+ CAMERA,
COLLISION,
LEGGED_LOCOMOTION,
MODEL,
diff --git a/src/entity/systems/camera-system.cpp b/src/entity/systems/camera-system.cpp
new file mode 100644
index 0000000..adae601
--- /dev/null
+++ b/src/entity/systems/camera-system.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2017-2019 Christopher J. Howard
+ *
+ * This file is part of Antkeeper Source Code.
+ *
+ * Antkeeper Source Code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Antkeeper Source Code is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Antkeeper Source Code. If not, see .
+ */
+
+#include "camera-system.hpp"
+
+CameraSystem::CameraSystem(ComponentManager* componentManager):
+ System(componentManager),
+ cameraGroup(componentManager)
+{
+ cameraGroup.addGroupObserver(this);
+}
+
+CameraSystem::~CameraSystem()
+{}
+
+void CameraSystem::update(float t, float dt)
+{
+ auto members = cameraGroup.getMembers();
+ for (const CameraGroup::Member* member: *members)
+ {
+ CameraComponent* camera = std::get<0>(member->components);
+ TransformComponent* transform = std::get<1>(member->components);
+ }
+}
+
+void CameraSystem::memberRegistered(const CameraGroup::Member* member)
+{}
+
+void CameraSystem::memberUnregistered(const CameraGroup::Member* member)
+{}
+
+void CameraSystem::handleEvent(const MouseMovedEvent& event)
+{}
+
diff --git a/src/entity/systems/camera-system.hpp b/src/entity/systems/camera-system.hpp
new file mode 100644
index 0000000..8f0388d
--- /dev/null
+++ b/src/entity/systems/camera-system.hpp
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2017-2019 Christopher J. Howard
+ *
+ * This file is part of Antkeeper Source Code.
+ *
+ * Antkeeper Source Code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Antkeeper Source Code is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Antkeeper Source Code. If not, see .
+ */
+
+#ifndef CAMERA_SYSTEM_HPP
+#define CAMERA_SYSTEM_HPP
+
+#include "../entity-group.hpp"
+#include "../components/camera-component.hpp"
+#include "../components/model-component.hpp"
+#include "../components/transform-component.hpp"
+#include "../system.hpp"
+
+#include
+using namespace Emergent;
+
+typedef EntityGroup CameraGroup;
+
+class CameraSystem:
+ public System,
+ public CameraGroup::Observer,
+ public EventHandler
+{
+public:
+ CameraSystem(ComponentManager* componentManager);
+ virtual ~CameraSystem();
+
+ virtual void update(float t, float dt);
+
+private:
+ virtual void memberRegistered(const CameraGroup::Member* member);
+ virtual void memberUnregistered(const CameraGroup::Member* member);
+ virtual void handleEvent(const MouseMovedEvent& event);
+ CameraGroup cameraGroup;
+};
+
+#endif // CAMERA_SYSTEM_HPP
+
diff --git a/src/entity/systems/render-system.cpp b/src/entity/systems/render-system.cpp
index 86416f5..a5a2fc1 100644
--- a/src/entity/systems/render-system.cpp
+++ b/src/entity/systems/render-system.cpp
@@ -21,10 +21,12 @@
RenderSystem::RenderSystem(ComponentManager* componentManager, SceneLayer* scene):
System(componentManager),
- modelEntityGroup(componentManager),
+ cameraGroup(componentManager),
+ modelGroup(componentManager),
scene(scene)
{
- modelEntityGroup.addGroupObserver(this);
+ cameraGroup.addGroupObserver(this);
+ modelGroup.addGroupObserver(this);
}
RenderSystem::~RenderSystem()
@@ -32,8 +34,17 @@ RenderSystem::~RenderSystem()
void RenderSystem::update(float t, float dt)
{
- auto members = modelEntityGroup.getMembers();
- for (const ModelEntityGroup::Member* member: *members)
+ // Update transform of all cameras
+ for (const CameraGroup::Member* member: *cameraGroup.getMembers())
+ {
+ CameraComponent* camera = std::get<0>(member->components);
+ TransformComponent* transform = std::get<1>(member->components);
+
+ camera->camera.setTransform(transform->transform);
+ }
+
+ // Update transform of all model instances
+ for (const ModelGroup::Member* member: *modelGroup.getMembers())
{
ModelComponent* model = std::get<0>(member->components);
TransformComponent* transform = std::get<1>(member->components);
@@ -42,13 +53,25 @@ void RenderSystem::update(float t, float dt)
}
}
-void RenderSystem::memberRegistered(const ModelEntityGroup::Member* member)
+void RenderSystem::memberRegistered(const CameraGroup::Member* member)
+{
+ CameraComponent* camera = std::get<0>(member->components);
+ scene->addObject(&camera->camera);
+}
+
+void RenderSystem::memberUnregistered(const CameraGroup::Member* member)
+{
+ CameraComponent* camera = std::get<0>(member->components);
+ scene->removeObject(&camera->camera);
+}
+
+void RenderSystem::memberRegistered(const ModelGroup::Member* member)
{
ModelComponent* model = std::get<0>(member->components);
scene->addObject(&model->model);
}
-void RenderSystem::memberUnregistered(const ModelEntityGroup::Member* member)
+void RenderSystem::memberUnregistered(const ModelGroup::Member* member)
{
ModelComponent* model = std::get<0>(member->components);
scene->removeObject(&model->model);
diff --git a/src/entity/systems/render-system.hpp b/src/entity/systems/render-system.hpp
index 444ad3f..0bb24eb 100644
--- a/src/entity/systems/render-system.hpp
+++ b/src/entity/systems/render-system.hpp
@@ -20,6 +20,7 @@
#ifndef RENDER_SYSTEM_HPP
#define RENDER_SYSTEM_HPP
+#include "../components/camera-component.hpp"
#include "../components/model-component.hpp"
#include "../components/transform-component.hpp"
#include "../entity-group.hpp"
@@ -28,14 +29,16 @@
#include
using namespace Emergent;
-typedef EntityGroup ModelEntityGroup;
+typedef EntityGroup CameraGroup;
+typedef EntityGroup ModelGroup;
/**
* Abstract base class for entity systems.
*/
-class RenderSystem: public
- System,
- ModelEntityGroup::Observer
+class RenderSystem:
+ public System,
+ public CameraGroup::Observer,
+ public ModelGroup::Observer
{
public:
RenderSystem(ComponentManager* componentManager, SceneLayer* scene);
@@ -44,11 +47,14 @@ public:
virtual void update(float t, float dt);
private:
- ModelEntityGroup modelEntityGroup;
+ CameraGroup cameraGroup;
+ ModelGroup modelGroup;
SceneLayer* scene;
- virtual void memberRegistered(const ModelEntityGroup::Member* member);
- virtual void memberUnregistered(const ModelEntityGroup::Member* member);
+ virtual void memberRegistered(const CameraGroup::Member* member);
+ virtual void memberUnregistered(const CameraGroup::Member* member);
+ virtual void memberRegistered(const ModelGroup::Member* member);
+ virtual void memberUnregistered(const ModelGroup::Member* member);
};
#endif // RENDER_SYSTEM_HPP
diff --git a/src/entity/systems/tool-system.cpp b/src/entity/systems/tool-system.cpp
index 91311ea..9a28b3b 100644
--- a/src/entity/systems/tool-system.cpp
+++ b/src/entity/systems/tool-system.cpp
@@ -21,10 +21,10 @@
ToolSystem::ToolSystem(ComponentManager* componentManager):
System(componentManager),
- tools(componentManager),
+ toolGroup(componentManager),
picked(false)
{
- tools.addGroupObserver(this);
+ toolGroup.addGroupObserver(this);
}
ToolSystem::~ToolSystem()
@@ -34,7 +34,7 @@ void ToolSystem::update(float t, float dt)
{
pick();
- auto members = tools.getMembers();
+ auto members = toolGroup.getMembers();
for (const ToolGroup::Member* member: *members)
{
ModelComponent* model = std::get<0>(member->components);
@@ -83,7 +83,6 @@ void ToolSystem::pick()
void ToolSystem::memberRegistered(const ToolGroup::Member* member)
{
ToolComponent* tool = std::get<1>(member->components);
- tool->active = false;
}
void ToolSystem::memberUnregistered(const ToolGroup::Member* member)
diff --git a/src/entity/systems/tool-system.hpp b/src/entity/systems/tool-system.hpp
index 1b9e214..0adc9b5 100644
--- a/src/entity/systems/tool-system.hpp
+++ b/src/entity/systems/tool-system.hpp
@@ -31,9 +31,6 @@ using namespace Emergent;
typedef EntityGroup ToolGroup;
-/**
- * Abstract base class for entity systems.
- */
class ToolSystem:
public System,
public ToolGroup::Observer,
@@ -59,7 +56,7 @@ private:
const Camera* pickingCamera;
Vector4 pickingViewport;
bool picked;
- ToolGroup tools;
+ ToolGroup toolGroup;
};
#endif // TOOL_SYSTEM_HPP
diff --git a/src/game.cpp b/src/game.cpp
index b7541f2..dbbc274 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -18,6 +18,7 @@
*/
#include "game.hpp"
+#include "resources/csv-table.hpp"
#include "states/game-state.hpp"
#include "states/splash-state.hpp"
#include "states/sandbox-state.hpp"
@@ -45,6 +46,7 @@
#include "entity/systems/sound-system.hpp"
#include "entity/systems/collision-system.hpp"
#include "entity/systems/render-system.hpp"
+#include "entity/systems/camera-system.hpp"
#include "entity/systems/tool-system.hpp"
#include "entity/systems/locomotion-system.hpp"
#include "entity/systems/behavior-system.hpp"
@@ -243,145 +245,30 @@ void Game::setup()
// Load settings
loadSettings();
- // Load strings
- loadStrings();
-
- // Determine number of available languages
- languageCount = (*stringTable)[0].size() - 1;
-
- // Match language code with language index
- languageIndex = 0;
- CSVRow* languageCodes = &(*stringTable)[0];
- for (std::size_t i = 1; i < languageCodes->size(); ++i)
- {
- if (language == (*languageCodes)[i])
- {
- languageIndex = i - 1;
- break;
- }
- }
+ // Setup localization (load strings, select language, ...)
+ setupLocalization();
- // Get display resolution
- const Display* display = deviceManager->getDisplays()->front();
- int displayWidth = std::get<0>(display->getDimensions());
- int displayHeight = std::get<1>(display->getDimensions());
+ setupWindow();
- if (fullscreen)
- {
- w = static_cast(fullscreenResolution.x);
- h = static_cast(fullscreenResolution.y);
- }
- else
- {
- w = static_cast(windowedResolution.x);
- h = static_cast(windowedResolution.y);
- }
+ setupGraphics();
- // Determine window position
- int x = std::get<0>(display->getPosition()) + displayWidth / 2 - w / 2;
- int y = std::get<1>(display->getPosition()) + displayHeight / 2 - h / 2;
+ setupUI();
- // Read title string
- std::string title = getString(getLanguageIndex(), "title");
+ setupControls();
- // Create window
- window = windowManager->createWindow(title.c_str(), x, y, w, h, fullscreen, WindowFlag::RESIZABLE);
- if (!window)
- {
- throw std::runtime_error("Game::Game(): Failed to create window.");
- }
+ setupGameplay();
- // Set v-sync mode
- window->setVSync(vsync);
+ setupDebugging();
- // Setup step scheduler
- double maxFrameDuration = 0.25;
- double stepFrequency = 60.0;
- stepScheduler.setMaxFrameDuration(maxFrameDuration);
- stepScheduler.setStepFrequency(stepFrequency);
- timestep = stepScheduler.getStepPeriod();
- // Setup performance sampling
- performanceSampler.setSampleSize(15);
- // Get DPI and convert font size to pixels
- dpi = display->getDPI();
- fontSizePX = fontSizePT * (1.0f / 72.0f) * dpi;
- // Setup control profile
- keyboard = deviceManager->getKeyboards()->front();
- mouse = deviceManager->getMice()->front();
- closeControl.bindKey(keyboard, Scancode::ESCAPE);
- closeControl.setActivatedCallback(std::bind(&Application::close, this, EXIT_SUCCESS));
- fullscreenControl.bindKey(keyboard, Scancode::F11);
- fullscreenControl.setActivatedCallback(std::bind(&Game::toggleFullscreen, this));
- openRadialMenuControl.bindKey(keyboard, Scancode::LSHIFT);
- moveForwardControl.bindKey(keyboard, Scancode::W);
- moveBackControl.bindKey(keyboard, Scancode::S);
- moveLeftControl.bindKey(keyboard, Scancode::A);
- moveRightControl.bindKey(keyboard, Scancode::D);
- //rotateCCWControl.bindKey(keyboard, Scancode::Q);
- //rotateCWControl.bindKey(keyboard, Scancode::E);
- moveRightControl.bindKey(keyboard, Scancode::D);
- zoomInControl.bindKey(keyboard, Scancode::EQUALS);
- zoomInControl.bindMouseWheelAxis(mouse, MouseWheelAxis::POSITIVE_Y);
- zoomOutControl.bindKey(keyboard, Scancode::MINUS);
- zoomOutControl.bindMouseWheelAxis(mouse, MouseWheelAxis::NEGATIVE_Y);
- adjustCameraControl.bindMouseButton(mouse, 2);
- dragCameraControl.bindMouseButton(mouse, 3);
- toggleNestViewControl.bindKey(keyboard, Scancode::N);
- toggleWireframeControl.bindKey(keyboard, Scancode::V);
- screenshotControl.bindKey(keyboard, Scancode::F12);
- toggleEditModeControl.bindKey(keyboard, Scancode::TAB);
- controlProfile.registerControl("close", &closeControl);
- controlProfile.registerControl("fullscreen", &fullscreenControl);
- controlProfile.registerControl("open-radial-menu", &openRadialMenuControl);
- controlProfile.registerControl("move-forward", &moveForwardControl);
- controlProfile.registerControl("move-back", &moveBackControl);
- controlProfile.registerControl("move-left", &moveLeftControl);
- controlProfile.registerControl("move-right", &moveRightControl);
- controlProfile.registerControl("rotate-ccw", &rotateCCWControl);
- controlProfile.registerControl("rotate-cw", &rotateCWControl);
- controlProfile.registerControl("zoom-in", &zoomInControl);
- controlProfile.registerControl("zoom-out", &zoomOutControl);
- controlProfile.registerControl("adjust-camera", &adjustCameraControl);
- controlProfile.registerControl("drag-camera", &dragCameraControl);
- controlProfile.registerControl("toggle-nest-view", &toggleNestViewControl);
- controlProfile.registerControl("toggle-wireframe", &toggleWireframeControl);
- controlProfile.registerControl("screenshot", &screenshotControl);
- controlProfile.registerControl("toggle-edit-mode", &toggleEditModeControl);
- // Save default control bindings
- std::string bindingsPath = getConfigPath() + "/bindings/";
- if (!pathExists(bindingsPath))
- {
- createDirectory(bindingsPath);
- }
- controlProfile.save(bindingsPath + "default.csv");
-
- // Load control bindings
- std::string controlProfileFilename = getConfigPath() + "/bindings/" + controlProfileName + ".csv";
- controlProfile.load(controlProfileFilename, deviceManager);
-
- wireframe = false;
- toggleWireframeControl.setActivatedCallback(std::bind(&Game::toggleWireframe, this));
- screenshotControl.setActivatedCallback(std::bind(&Game::queueScreenshot, this));
screenshotQueued = false;
// Create scene
scene = new Scene(&stepInterpolator);
- TestEvent event1, event2, event3;
- event1.id = 1;
- event2.id = 2;
- event3.id = 3;
-
-
- eventDispatcher.subscribe(this);
- eventDispatcher.schedule(event1, 1.0);
- eventDispatcher.schedule(event2, 10.0);
- eventDispatcher.schedule(event3, 1.0);
-
// Load model resources
try
{
@@ -471,27 +358,6 @@ void Game::setup()
Shader* shader = resourceManager->load("depth-pass.glsl");
- /*
- VertexFormat format;
- format.addAttribute(0);
- format.addAttribute(1);
- format.addAttribute(2);
-
- VertexBuffer* vb = graphicsContext->createVertexBuffer(format);
- vb->resize(1000);
- vb->setData(bla, 0, 1000);
-
- IndexBuffer* ib = graphicsContext->createIndexBuffer();
- ib->resize(300);
- ib->setData(bla, 0, 300);
-
- graphicsContext->bind(framebuffer);
- graphicsContext->bind(shader);
- graphicsContext->bind(vb);
- graphicsContext->bind(ib);
- graphicsContext->draw(100, TRIANGLES);
- */
-
cameraRig = nullptr;
orbitCam = new OrbitCam();
orbitCam->attachCamera(&camera);
@@ -780,71 +646,7 @@ void Game::setup()
antLabelPinHole->setTexture(hudSpriteSheetTexture);
antLabelPinHole->setTextureBounds(normalizeTextureBounds(hudTextureAtlas.getBounds("label-pin-hole"), hudTextureAtlasBounds));
antLabelContainer->addChild(antLabelPinHole);
-
- notificationBoxImage = new UIImage();
- notificationBoxImage->setTexture(hudSpriteSheetTexture);
- notificationBoxImage->setTextureBounds(normalizeTextureBounds(hudTextureAtlas.getBounds("notification-box"), hudTextureAtlasBounds));
- notificationBoxImage->setVisible(false);
- hudContainer->addChild(notificationBoxImage);
-
- // Construct show notification animation clip
- notificationCount = 0;
- AnimationChannel* channel2;
- showNotificationClip.setInterpolator(easeOutQuint);
- channel2 = showNotificationClip.addChannel(0);
- channel2->insertKeyframe(0.0f, Vector2(0.0f, 0.0f));
- channel2->insertKeyframe(0.5f, Vector2(32.0f, 1.0f));
- showNotificationAnimation.setClip(&showNotificationClip);
- showNotificationAnimation.setSpeed(1.0f);
- showNotificationAnimation.setTimeFrame(showNotificationClip.getTimeFrame());
- animator.addAnimation(&showNotificationAnimation);
-
- showNotificationAnimation.setAnimateCallback
- (
- [this](std::size_t id, const Vector2& values)
- {
- notificationBoxImage->setVisible(true);
- notificationBoxImage->setTintColor(Vector4(Vector3(1.0f), values.y));
- //notificationBoxImage->setTranslation(Vector2(0.0f, -32.0f + values.x));
- }
- );
- showNotificationAnimation.setEndCallback
- (
- [this]()
- {
- hideNotificationAnimation.rewind();
- hideNotificationAnimation.play();
- }
- );
-
- // Construct hide notification animation clip
- hideNotificationClip.setInterpolator(easeOutQuint);
- AnimationChannel* channel;
- channel = hideNotificationClip.addChannel(0);
- channel->insertKeyframe(0.0f, 1.0f);
- channel->insertKeyframe(10.5f, 1.0f);
- channel->insertKeyframe(12.0f, 0.0f);
- hideNotificationAnimation.setClip(&hideNotificationClip);
- hideNotificationAnimation.setSpeed(1.0f);
- hideNotificationAnimation.setTimeFrame(hideNotificationClip.getTimeFrame());
- animator.addAnimation(&hideNotificationAnimation);
- hideNotificationAnimation.setAnimateCallback
- (
- [this](std::size_t id, float opacity)
- {
- notificationBoxImage->setTintColor(Vector4(Vector3(1.0f), opacity));
- }
- );
- hideNotificationAnimation.setEndCallback
- (
- [this]()
- {
- notificationBoxImage->setVisible(false);
- --notificationCount;
- popNotification();
- }
- );
-
+
// Construct box selection
boxSelectionImageBackground = new UIImage();
boxSelectionImageBackground->setAnchor(Anchor::CENTER);
@@ -911,6 +713,7 @@ void Game::setup()
// Construct fade-in animation clip
fadeInClip.setInterpolator(easeOutCubic);
+ AnimationChannel* channel;
channel = fadeInClip.addChannel(0);
channel->insertKeyframe(0.0f, 1.0f);
channel->insertKeyframe(1.0f, 0.0f);
@@ -1004,10 +807,6 @@ void Game::setup()
);
animator.addAnimation(&cameraFlashAnimation);
- // Setup default compositor
- {
- defaultCompositor.load(nullptr);
- }
// Setup shadow map pass and compositor
{
@@ -1160,7 +959,6 @@ void Game::setup()
brush->setOrbitCam(orbitCam);
defaultLayer->addObject(brush->getModelInstance());
- glEnable(GL_MULTISAMPLE);
//
performanceSampler.setSampleSize(30);
@@ -1174,6 +972,7 @@ void Game::setup()
// Initialize systems
soundSystem = new SoundSystem(componentManager);
collisionSystem = new CollisionSystem(componentManager);
+ cameraSystem = new CameraSystem(componentManager);
renderSystem = new RenderSystem(componentManager, defaultLayer);
toolSystem = new ToolSystem(componentManager);
toolSystem->setPickingCamera(&camera);
@@ -1200,6 +999,7 @@ void Game::setup()
systemManager->addSystem(collisionSystem);
systemManager->addSystem(toolSystem);
systemManager->addSystem(particleSystem);
+ systemManager->addSystem(cameraSystem);
systemManager->addSystem(renderSystem);
EntityID sidewalkPanel;
@@ -1211,7 +1011,7 @@ void Game::setup()
EntityID antNest = createInstanceOf("ant-nest");
setTranslation(antNest, Vector3(20, 0, 40));
- lollipop = createInstanceOf("lollipop");
+ EntityID lollipop = createInstanceOf("lollipop");
setTranslation(lollipop, Vector3(30.0f, 3.5f * 0.5f, -30.0f));
setRotation(lollipop, glm::angleAxis(glm::radians(8.85f), Vector3(1.0f, 0.0f, 0.0f)));
@@ -1260,10 +1060,6 @@ void Game::setup()
changeState(splashState);
}
-void Game::input()
-{
-}
-
void Game::update(float t, float dt)
{
this->time = t;
@@ -1283,14 +1079,27 @@ void Game::update(float t, float dt)
// Update animations
animator.animate(dt);
- std::stringstream stream;
- stream.precision(2);
- stream << std::fixed << (performanceSampler.getMeanFrameDuration() * 1000.0f);
- fpsLabel->setText(stream.str());
+ if (fpsLabel->isVisible())
+ {
+ std::stringstream stream;
+ stream.precision(2);
+ stream << std::fixed << (performanceSampler.getMeanFrameDuration() * 1000.0f);
+ fpsLabel->setText(stream.str());
+ }
uiRootElement->update();
+}
- controlProfile.update();
+void Game::input()
+{
+ /*
+ if (useToolControl.isActive() && !useToolControl.wasActive())
+ {
+ intentSystem.queueIntent(Intent::USE_TOOL);
+ }
+ */
+
+ controls.update();
}
void Game::render()
@@ -1341,9 +1150,217 @@ void Game::handleEvent(const WindowResizedEvent& event)
resizeUI(event.width, event.height);
}
-void Game::handleEvent(const TestEvent& event)
+void Game::setupLocalization()
{
- std::cout << "Event received!!! ID: " << event.id << std::endl;
+ // Load strings
+ loadStrings();
+
+ // Determine number of available languages
+ languageCount = (*stringTable)[0].size() - 1;
+
+ // Match language code with language index
+ languageIndex = 0;
+ CSVRow* languageCodes = &(*stringTable)[0];
+ for (std::size_t i = 1; i < languageCodes->size(); ++i)
+ {
+ if (language == (*languageCodes)[i])
+ {
+ languageIndex = i - 1;
+ break;
+ }
+ }
+}
+
+void Game::setupWindow()
+{
+ // Get display resolution
+ const Display* display = deviceManager->getDisplays()->front();
+ int displayWidth = std::get<0>(display->getDimensions());
+ int displayHeight = std::get<1>(display->getDimensions());
+
+ if (fullscreen)
+ {
+ w = static_cast(fullscreenResolution.x);
+ h = static_cast(fullscreenResolution.y);
+ }
+ else
+ {
+ w = static_cast(windowedResolution.x);
+ h = static_cast(windowedResolution.y);
+ }
+
+ // Determine window position
+ int x = std::get<0>(display->getPosition()) + displayWidth / 2 - w / 2;
+ int y = std::get<1>(display->getPosition()) + displayHeight / 2 - h / 2;
+
+ // Read title string
+ std::string title = getString(getLanguageIndex(), "title");
+
+ // Create window
+ window = windowManager->createWindow(title.c_str(), x, y, w, h, fullscreen, WindowFlag::RESIZABLE);
+ if (!window)
+ {
+ throw std::runtime_error("Game::Game(): Failed to create window.");
+ }
+
+ // Set v-sync mode
+ window->setVSync(vsync);
+}
+
+void Game::setupGraphics()
+{
+
+ glEnable(GL_MULTISAMPLE);
+}
+
+void Game::setupUI()
+{
+ // Get DPI and convert font size to pixels
+ const Display* display = deviceManager->getDisplays()->front();
+ dpi = display->getDPI();
+ fontSizePX = fontSizePT * (1.0f / 72.0f) * dpi;
+}
+
+void Game::setupControls()
+{
+ // Get keyboard and mouse
+ keyboard = deviceManager->getKeyboards()->front();
+ mouse = deviceManager->getMice()->front();
+
+ // Build the master control set
+ controls.addControl(&toggleFullscreenControl);
+ controls.addControl(&screenshotControl);
+ controls.addControl(&exitControl);
+ controls.addControl(&menuUpControl);
+ controls.addControl(&menuDownControl);
+ controls.addControl(&menuLeftControl);
+ controls.addControl(&menuRightControl);
+ controls.addControl(&menuBackControl);
+ controls.addControl(&moveForwardControl);
+ controls.addControl(&moveBackControl);
+ controls.addControl(&moveLeftControl);
+ controls.addControl(&moveRightControl);
+ controls.addControl(&zoomInControl);
+ controls.addControl(&zoomOutControl);
+ controls.addControl(&orbitCCWControl);
+ controls.addControl(&orbitCWControl);
+ controls.addControl(&adjustCameraControl);
+ controls.addControl(&dragCameraControl);
+ controls.addControl(&openToolMenuControl);
+ controls.addControl(&useToolControl);
+ controls.addControl(&toggleEditModeControl);
+ controls.addControl(&toggleWireframeControl);
+
+ // Build the system control set
+ systemControls.addControl(&exitControl);
+ systemControls.addControl(&toggleFullscreenControl);
+ systemControls.addControl(&screenshotControl);
+
+ // Build the menu control set
+ menuControls.addControl(&menuUpControl);
+ menuControls.addControl(&menuDownControl);
+ menuControls.addControl(&menuLeftControl);
+ menuControls.addControl(&menuRightControl);
+ menuControls.addControl(&menuSelectControl);
+ menuControls.addControl(&menuBackControl);
+
+ // Build the camera control set
+ cameraControls.addControl(&moveForwardControl);
+ cameraControls.addControl(&moveBackControl);
+ cameraControls.addControl(&moveLeftControl);
+ cameraControls.addControl(&moveRightControl);
+ cameraControls.addControl(&zoomInControl);
+ cameraControls.addControl(&zoomOutControl);
+ cameraControls.addControl(&orbitCCWControl);
+ cameraControls.addControl(&orbitCWControl);
+ cameraControls.addControl(&adjustCameraControl);
+ cameraControls.addControl(&dragCameraControl);
+
+ // Build the tool control set
+ toolControls.addControl(&openToolMenuControl);
+ toolControls.addControl(&useToolControl);
+
+ // Build the editor control set
+ editorControls.addControl(&toggleEditModeControl);
+
+ // Setup control callbacks
+ exitControl.setActivatedCallback(std::bind(&Application::close, this, EXIT_SUCCESS));
+ toggleFullscreenControl.setActivatedCallback(std::bind(&Game::toggleFullscreen, this));
+ screenshotControl.setActivatedCallback(std::bind(&Game::queueScreenshot, this));
+ toggleWireframeControl.setActivatedCallback(std::bind(&Game::toggleWireframe, this));
+
+ // Map controls
+ inputMapper->map(&exitControl, keyboard, Scancode::ESCAPE);
+ inputMapper->map(&toggleFullscreenControl, keyboard, Scancode::F11);
+ inputMapper->map(&screenshotControl, keyboard, Scancode::F12);
+ inputMapper->map(&openToolMenuControl, keyboard, Scancode::LSHIFT);
+ inputMapper->map(&moveForwardControl, keyboard, Scancode::W);
+ inputMapper->map(&moveBackControl, keyboard, Scancode::S);
+ inputMapper->map(&moveLeftControl, keyboard, Scancode::A);
+ inputMapper->map(&moveRightControl, keyboard, Scancode::D);
+ inputMapper->map(&orbitCCWControl, keyboard, Scancode::Q);
+ inputMapper->map(&orbitCWControl, keyboard, Scancode::E);
+ inputMapper->map(&zoomInControl, mouse, MouseWheelAxis::POSITIVE_Y);
+ inputMapper->map(&zoomInControl, keyboard, Scancode::EQUALS);
+ inputMapper->map(&zoomOutControl, mouse, MouseWheelAxis::NEGATIVE_Y);
+ inputMapper->map(&zoomOutControl, keyboard, Scancode::MINUS);
+ inputMapper->map(&adjustCameraControl, mouse, 2);
+ inputMapper->map(&dragCameraControl, mouse, 3);
+ inputMapper->map(&toggleWireframeControl, keyboard, Scancode::V);
+ inputMapper->map(&toggleEditModeControl, keyboard, Scancode::TAB);
+
+ /*
+ controlProfile.registerControl("exit", &exitControl);
+ controlProfile.registerControl("toggle-fullscreen", &toggleFullscreenControl);
+ controlProfile.registerControl("open-tool-menu", &openToolMenuControl);
+ controlProfile.registerControl("move-forward", &moveForwardControl);
+ controlProfile.registerControl("move-back", &moveBackControl);
+ controlProfile.registerControl("move-left", &moveLeftControl);
+ controlProfile.registerControl("move-right", &moveRightControl);
+ controlProfile.registerControl("orbit-ccw", &orbitCCWControl);
+ controlProfile.registerControl("orbit-cw", &orbitCWControl);
+ controlProfile.registerControl("zoom-in", &zoomInControl);
+ controlProfile.registerControl("zoom-out", &zoomOutControl);
+ controlProfile.registerControl("adjust-camera", &adjustCameraControl);
+ controlProfile.registerControl("drag-camera", &dragCameraControl);
+ controlProfile.registerControl("toggle-wireframe", &toggleWireframeControl);
+ controlProfile.registerControl("screenshot", &screenshotControl);
+ controlProfile.registerControl("toggle-edit-mode", &toggleEditModeControl);
+ */
+
+ /*
+ // Save default control bindings
+ std::string bindingsPath = getConfigPath() + "/bindings/";
+ if (!pathExists(bindingsPath))
+ {
+ createDirectory(bindingsPath);
+ }
+ controlProfile.save(bindingsPath + "default.csv");
+
+ // Load control bindings
+ std::string controlProfileFilename = getConfigPath() + "/bindings/" + controlProfileName + ".csv";
+ controlProfile.load(controlProfileFilename, deviceManager);
+ */
+
+}
+
+void Game::setupGameplay()
+{
+ // Setup step scheduler
+ double maxFrameDuration = 0.25;
+ double stepFrequency = 60.0;
+ stepScheduler.setMaxFrameDuration(maxFrameDuration);
+ stepScheduler.setStepFrequency(stepFrequency);
+ timestep = stepScheduler.getStepPeriod();
+}
+
+void Game::setupDebugging()
+{
+ // Setup performance sampling
+ performanceSampler.setSampleSize(15);
+
+ // Disable wireframe drawing
+ wireframe = false;
}
void Game::resetSettings()
@@ -1580,10 +1597,6 @@ void Game::resizeUI(int w, int h)
antTag->setAnchor(Anchor::CENTER);
antTag->setDimensions(Vector2(antLabelContainer->getDimensions().x, antPin->getDimensions().y));
- Rect notificationBoxBounds = hudTextureAtlas.getBounds("notification-box");
- notificationBoxImage->setDimensions(Vector2(notificationBoxBounds.getWidth(), notificationBoxBounds.getHeight()));
- notificationBoxImage->setAnchor(Vector2(0.5f, 0.0f));
-
float cameraGridLineWidth = 2.0f;
float cameraReticleDiameter = 6.0f;
cameraGridContainer->setDimensions(Vector2(w, h));
@@ -1820,10 +1833,6 @@ void Game::selectTool(int toolIndex)
{
currentTool->setActive(true);
}
- else
- {
- pushNotification("Invalid tool.");
- }
}
if (1)
@@ -1837,24 +1846,9 @@ void Game::selectTool(int toolIndex)
}
}
-void Game::pushNotification(const std::string& text)
-{
- std::cout << text << std::endl;
- ++notificationCount;
-
- if (notificationCount == 1)
- {
- popNotification();
- }
-}
-
-void Game::popNotification()
+EntityID Game::createInstance()
{
- if (notificationCount > 0)
- {
- showNotificationAnimation.rewind();
- showNotificationAnimation.play();
- }
+ return entityManager->createEntity();
}
EntityID Game::createInstanceOf(const std::string& templateName)
@@ -1873,6 +1867,17 @@ void Game::destroyInstance(EntityID entity)
entityManager->destroyEntity(entity);
}
+void Game::addComponent(EntityID entity, ComponentBase* component)
+{
+ componentManager->addComponent(entity, component);
+}
+
+void Game::removeComponent(EntityID entity, ComponentType type)
+{
+ ComponentBase* component = componentManager->removeComponent(entity, type);
+ delete component;
+}
+
void Game::setTranslation(EntityID entity, const Vector3& translation)
{
TransformComponent* component = static_cast(componentManager->getComponent(entity, ComponentType::TRANSFORM));
diff --git a/src/game.hpp b/src/game.hpp
index f6c7460..b987ac3 100644
--- a/src/game.hpp
+++ b/src/game.hpp
@@ -24,7 +24,6 @@
using namespace Emergent;
#include "entity/entity-id.hpp"
-#include "resources/csv-table.hpp"
#include