From 786b7a4cfec1940cb83ce3620912b42d26649d53 Mon Sep 17 00:00:00 2001 From: "C. J. Howard" Date: Tue, 12 Dec 2017 18:51:57 +0800 Subject: [PATCH] Rename CameraController to CameraRig and add FreeCam rig --- CMakeLists.txt | 4 +- data | 2 +- src/application.cpp | 23 ++- src/application.hpp | 10 +- src/{camera-controller.cpp => camera-rig.cpp} | 140 +++++++++---- src/{camera-controller.hpp => camera-rig.hpp} | 184 ++++++++++++------ src/game/tool.cpp | 21 +- src/game/tool.hpp | 6 +- src/materials.hpp | 2 +- src/states/game-state.cpp | 170 ++++++++++------ src/states/game-state.hpp | 6 +- src/states/title-state.cpp | 24 +-- 12 files changed, 395 insertions(+), 197 deletions(-) rename src/{camera-controller.cpp => camera-rig.cpp} (53%) rename src/{camera-controller.hpp => camera-rig.hpp} (51%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 591faef..12dda07 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -232,8 +232,8 @@ set(EXECUTABLE_SOURCES ${EXECUTABLE_SOURCE_DIR}/game/tool.cpp ${EXECUTABLE_SOURCE_DIR}/debug.hpp ${EXECUTABLE_SOURCE_DIR}/debug.cpp - ${EXECUTABLE_SOURCE_DIR}/camera-controller.hpp - ${EXECUTABLE_SOURCE_DIR}/camera-controller.cpp + ${EXECUTABLE_SOURCE_DIR}/camera-rig.hpp + ${EXECUTABLE_SOURCE_DIR}/camera-rig.cpp ${EXECUTABLE_SOURCE_DIR}/model-loader.hpp ${EXECUTABLE_SOURCE_DIR}/model-loader.cpp ${EXECUTABLE_SOURCE_DIR}/material-loader.hpp diff --git a/data b/data index 463807e..539e0fb 160000 --- a/data +++ b/data @@ -1 +1 @@ -Subproject commit 463807e1e360d62997874f3a5b185f93c9999b50 +Subproject commit 539e0fb8dd911630199af903257c8dfe7f70de9f diff --git a/src/application.cpp b/src/application.cpp index 2acca75..f9d5e50 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -32,7 +32,7 @@ #include "ui/toolbar.hpp" #include "ui/pie-menu.hpp" #include "debug.hpp" -#include "camera-controller.hpp" +#include "camera-rig.hpp" #include "configuration.hpp" #include #include @@ -407,7 +407,9 @@ Application::Application(int argc, char* argv[]): modelLoader->setMaterialLoader(materialLoader); // Allocate game variables - surfaceCam = new SurfaceCameraController(); + orbitCam = new OrbitCam(); + freeCam = new FreeCam(); + activeRig = orbitCam; // Enter loading state state = nextState = loadingState; @@ -896,6 +898,9 @@ bool Application::loadScene() pheromoneTexture.setTextureID(pheromoneTextureID); } + // Enable seamless cubemap filtering + glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); + // Setup skybox pass skyboxPass.setRenderTarget(&framebufferARenderTarget); @@ -933,7 +938,7 @@ bool Application::loadScene() defaultCompositor.addPass(&clearDepthPass); defaultCompositor.addPass(&skyboxPass); - defaultCompositor.addPass(&soilPass); + //defaultCompositor.addPass(&soilPass); defaultCompositor.addPass(&lightingPass); defaultCompositor.addPass(&horizontalBlurPass); defaultCompositor.addPass(&verticalBlurPass); @@ -1579,6 +1584,7 @@ bool Application::loadControls() gameControlProfile->registerControl("toggle-pause", &togglePause); gameControlProfile->registerControl("toggle-pause-menu", &togglePauseMenu); gameControlProfile->registerControl("fast-forward", &fastForward); + gameControlProfile->registerControl("switch-rig", &switchRig); cameraMoveForward.bindKey(keyboard, SDL_SCANCODE_W); cameraMoveBack.bindKey(keyboard, SDL_SCANCODE_S); @@ -1599,6 +1605,7 @@ bool Application::loadControls() togglePause.bindKey(keyboard, SDL_SCANCODE_SPACE); togglePauseMenu.bindKey(keyboard, SDL_SCANCODE_ESCAPE); fastForward.bindKey(keyboard, SDL_SCANCODE_F); + switchRig.bindKey(keyboard, SDL_SCANCODE_TAB); return true; } @@ -1626,15 +1633,15 @@ bool Application::loadGame() // Create tools forceps = new Forceps(forcepsModel); forceps->setColony(colony); - forceps->setCameraController(surfaceCam); + forceps->setOrbitCam(orbitCam); lens = new Lens(lensModel); - lens->setCameraController(surfaceCam); + lens->setOrbitCam(orbitCam); lens->setSunDirection(glm::normalize(-sunlightCamera.getTranslation())); brush = new Brush(brushModel); brush->setColony(colony); - brush->setCameraController(surfaceCam); + brush->setOrbitCam(orbitCam); loadWorld(0); loadLevel(0); @@ -2073,7 +2080,9 @@ void Application::loadLevel(std::size_t index) currentLevel->load(*levelParams); PhysicalMaterial* material = materialLoader->load("data/materials/debug-terrain-surface.mtl"); - //material->albedoOpacityMap = &pheromoneTexture; + material->albedoOpacityMap = &pheromoneTexture; + material->shadowCaster = false; + material->flags |= (unsigned int)PhysicalMaterial::Flags::TRANSLUCENT; currentLevel->terrain.getSurfaceModel()->getGroup(0)->material = material; } diff --git a/src/application.hpp b/src/application.hpp index 7a7fb5d..4db623a 100644 --- a/src/application.hpp +++ b/src/application.hpp @@ -43,8 +43,9 @@ class LoadingState; class SplashState; class TitleState; class GameState; -class CameraController; -class SurfaceCameraController; +class CameraRig; +class OrbitCam; +class FreeCam; class LineBatcher; class ModelLoader; class MaterialLoader; @@ -252,6 +253,7 @@ public: Control togglePause; Control togglePauseMenu; Control fastForward; + Control switchRig; Arcball arcball; // Misc @@ -398,7 +400,9 @@ public: Level* currentLevel; Colony* colony; - SurfaceCameraController* surfaceCam; + OrbitCam* orbitCam; + FreeCam* freeCam; + CameraRig* activeRig; bool cameraOverheadView; bool cameraNestView; int toolIndex; diff --git a/src/camera-controller.cpp b/src/camera-rig.cpp similarity index 53% rename from src/camera-controller.cpp rename to src/camera-rig.cpp index 0f41086..46a8b14 100644 --- a/src/camera-controller.cpp +++ b/src/camera-rig.cpp @@ -17,25 +17,109 @@ * along with Antkeeper Source Code. If not, see . */ -#include "camera-controller.hpp" +#include "camera-rig.hpp" +#include +#include + +CameraRig::CameraRig(): + camera(nullptr), + translation(0.0f), + rotation(1.0f, 0.0f, 0.0f, 0.0f), + forward(0.0f, 0.0f, -1.0f), + right(1.0f, 0.0f, 0.0f), + up(0.0f, 1.0f, 0.0f) +{} + +void CameraRig::attachCamera(Camera* camera) +{ + this->camera = camera; + if (camera != nullptr) + { + camera->lookAt(translation, translation + forward, up); + } +} + +void CameraRig::detachCamera() +{ + camera = nullptr; +} + +void CameraRig::setTranslation(const Vector3& translation) +{ + this->translation = translation; +} + +void CameraRig::setRotation(const Quaternion& rotation) +{ + this->rotation = rotation; + + // Calculate orthonormal basis + forward = glm::normalize(rotation * Vector3(0.0f, 0.0f, -1.0f)); + up = glm::normalize(rotation * Vector3(0.0f, 1.0f, 0.0f)); + right = glm::normalize(glm::cross(forward, up)); +} + +FreeCam::FreeCam(): + pitchRotation(1.0f, 0.0f, 0.0f, 0.0f), + yawRotation(1.0f, 0.0f, 0.0f, 0.0f), + pitch(0.0f), + yaw(0.0f) +{} -CameraController::CameraController(): - camera(nullptr) +FreeCam::~FreeCam() {} -SurfaceCameraController::SurfaceCameraController(): +void FreeCam::update(float dt) +{ + if (getCamera() != nullptr) + { + getCamera()->lookAt(getTranslation(), getTranslation() + getForward(), getUp()); + } +} + +void FreeCam::move(const Vector2& velocity) +{ + setTranslation(getTranslation() + getForward() * velocity.x + getRight() * velocity.y); +} + +float wrapAngle(float x) +{ + x = std::fmod(x + glm::pi(), glm::pi() * 2.0f); + if (x < 0.0f) + { + x += glm::pi() * 2.0f; + } + + return x - glm::pi(); +} + +void FreeCam::rotate(float pan, float tilt) +{ + pitch = wrapAngle(pitch + tilt); + yaw = wrapAngle(yaw + pan); + + pitch = std::min(std::max(glm::radians(-89.0f), pitch), glm::radians(89.0f)); + + // Form quaternions from pan and tilt angles + pitchRotation = glm::angleAxis(pitch,Vector3(1.0f, 0.0f, 0.0f)); + yawRotation = glm::angleAxis(yaw, Vector3(0.0f, 1.0f, 0.0f)); + + // Rotate camera + setRotation(glm::normalize(yawRotation * pitchRotation)); +} + +OrbitCam::OrbitCam(): elevationRotation(1, 0, 0, 0), azimuthRotation(1, 0, 0, 0), - rotation(1, 0, 0, 0), targetElevationRotation(1, 0, 0, 0), targetAzimuthRotation(1, 0, 0, 0), targetRotation(1, 0, 0, 0) {} -SurfaceCameraController::~SurfaceCameraController() +OrbitCam::~OrbitCam() {} -void SurfaceCameraController::update(float dt) +void OrbitCam::update(float dt) { float interpolationFactor = 0.25f / (1.0 / 60.0f) * dt; @@ -54,15 +138,14 @@ void SurfaceCameraController::update(float dt) setAzimuth(glm::mix(azimuth, targetAzimuth, interpolationFactor)); // Calculate rotation - rotation = azimuthRotation * elevationRotation; + setRotation(azimuthRotation * elevationRotation); // Interpolate focal point and focal distance focalPoint = glm::mix(focalPoint, targetFocalPoint, interpolationFactor); focalDistance = glm::mix(focalDistance, targetFocalDistance, interpolationFactor); // Caluclate translation - translation = focalPoint + rotation * Vector3(0.0f, 0.0f, focalDistance); - + setTranslation(focalPoint + getRotation() * Vector3(0.0f, 0.0f, focalDistance)); /* // Recalculate azimuth azimuthRotation = rotation; @@ -80,78 +163,67 @@ void SurfaceCameraController::update(float dt) */ // Update camera - if (camera != nullptr) + if (getCamera() != nullptr) { - camera->lookAt(translation, focalPoint, Vector3(0.0f, 1.0f, 0.0f)); + getCamera()->lookAt(getTranslation(), getTranslation() + getForward(), getUp()); } } -void SurfaceCameraController::move(Vector2 direction) +void OrbitCam::move(Vector2 direction) { targetFocalPoint += azimuthRotation * Vector3(direction.x, 0.0f, direction.y); } -void SurfaceCameraController::rotate(float angle) +void OrbitCam::rotate(float angle) { setTargetAzimuth(targetAzimuth + angle); } -void SurfaceCameraController::zoom(float distance) +void OrbitCam::zoom(float distance) { setTargetFocalDistance(targetFocalDistance - distance); } -void SurfaceCameraController::setFocalPoint(const Vector3& point) +void OrbitCam::setFocalPoint(const Vector3& point) { focalPoint = point; } -void SurfaceCameraController::setFocalDistance(float distance) +void OrbitCam::setFocalDistance(float distance) { focalDistance = distance; } -void SurfaceCameraController::setElevation(float angle) +void OrbitCam::setElevation(float angle) { elevation = angle; elevationRotation = glm::angleAxis(elevation, Vector3(-1.0f, 0.0f, 0.0f)); } -void SurfaceCameraController::setAzimuth(float angle) +void OrbitCam::setAzimuth(float angle) { azimuth = angle; azimuthRotation = glm::angleAxis(azimuth, Vector3(0.0f, 1.0f, 0.0f)); } -void SurfaceCameraController::setTargetFocalPoint(const Vector3& point) +void OrbitCam::setTargetFocalPoint(const Vector3& point) { targetFocalPoint = point; } -void SurfaceCameraController::setTargetFocalDistance(float distance) +void OrbitCam::setTargetFocalDistance(float distance) { targetFocalDistance = distance; } -void SurfaceCameraController::setTargetElevation(float angle) +void OrbitCam::setTargetElevation(float angle) { targetElevation = angle; targetElevationRotation = glm::angleAxis(targetElevation, Vector3(-1.0f, 0.0f, 0.0f)); } -void SurfaceCameraController::setTargetAzimuth(float angle) +void OrbitCam::setTargetAzimuth(float angle) { targetAzimuth = angle; targetAzimuthRotation = glm::angleAxis(targetAzimuth, Vector3(0.0f, 1.0f, 0.0f)); } - -TunnelCameraController::TunnelCameraController() -{} - -TunnelCameraController::~TunnelCameraController() -{} - -void TunnelCameraController::update(float dt) -{ - -} \ No newline at end of file diff --git a/src/camera-controller.hpp b/src/camera-rig.hpp similarity index 51% rename from src/camera-controller.hpp rename to src/camera-rig.hpp index 2ee28b8..3269c79 100644 --- a/src/camera-controller.hpp +++ b/src/camera-rig.hpp @@ -17,48 +17,147 @@ * along with Antkeeper Source Code. If not, see . */ -#ifndef CAMERA_CONTROLLER_HPP -#define CAMERA_CONTROLLER_HPP +#ifndef CAMERA_RIG_HPP +#define CAMERA_RIG_HPP #include using namespace Emergent; -class CameraController +/** + * Abstract base class for camera rigs which control the movement of cameras. + */ +class CameraRig { public: - CameraController(); + CameraRig(); + + /** + * Updates the rig. + */ virtual void update(float dt) = 0; - void setCamera(Camera* camera); + /** + * Attaches a camera to the rig. + * + * @param camera Camera to attach. + */ + void attachCamera(Camera* camera); + + /** + * Detaches a camera from the rig. + */ + void detachCamera(); + /** + * Sets the translation of the camera rig. + */ + void setTranslation(const Vector3& translation); + + /** + * Sets the rotation of the camera rig. + */ + void setRotation(const Quaternion& rotation); + + /** + * Returns the attached camera. + */ const Camera* getCamera() const; + + /// @copydoc CameraRig::getCamera() const Camera* getCamera(); + + const Vector3& getTranslation() const; + const Quaternion& getRotation() const; + const Vector3& getForward() const; + const Vector3& getRight() const; + const Vector3& getUp() const; -protected: +private: Camera* camera; + Vector3 translation; + Quaternion rotation; + Vector3 forward; + Vector3 right; + Vector3 up; }; -inline void CameraController::setCamera(Camera* camera) +inline const Camera* CameraRig::getCamera() const { - this->camera = camera; + return camera; } -inline const Camera* CameraController::getCamera() const +inline Camera* CameraRig::getCamera() { return camera; } -inline Camera* CameraController::getCamera() +inline const Vector3& CameraRig::getTranslation() const { - return camera; + return translation; } -class SurfaceCameraController: public CameraController +inline const Quaternion& CameraRig::getRotation() const +{ + return rotation; +} + +inline const Vector3& CameraRig::getForward() const +{ + return forward; +} + +inline const Vector3& CameraRig::getRight() const +{ + return right; +} + +inline const Vector3& CameraRig::getUp() const +{ + return up; +} + +/** + * Rig which can freely move around the scene. + */ +class FreeCam: public CameraRig +{ +public: + FreeCam(); + virtual ~FreeCam(); + + /** + * Moves the camera. + * + * @param velocity Specifies the movement velocity on the local forward-right plane. + */ + void move(const Vector2& velocity); + + /** + * Rotates the camera. + * + * @param pan Specifies the angle (in radians) to rotate around the global Y-axis. + * @param tilt Specifies the angle (in radians) to rotate around the local X-axis. + */ + void rotate(float pan, float tilt); + + virtual void update(float dt); + +private: + Quaternion pitchRotation; + Quaternion yawRotation; + float pitch; + float yaw; +}; + +/** + * Rig which orbits around a focal point. + */ +class OrbitCam: public CameraRig { public: - SurfaceCameraController(); - virtual ~SurfaceCameraController(); + OrbitCam(); + virtual ~OrbitCam(); virtual void update(float dt); /// @param direction Specifies the movement direction and speed scale on the XZ plane @@ -83,8 +182,6 @@ public: float getTargetFocalDistance() const; float getTargetElevation() const; float getTargetAzimuth() const; - const Vector3& getTranslation() const; - const glm::quat& getRotation() const; const Vector3& getTargetTranslation() const; const glm::quat& getTargetRotation() const; @@ -101,93 +198,60 @@ private: glm::quat elevationRotation; glm::quat azimuthRotation; - glm::quat rotation; glm::quat targetElevationRotation; glm::quat targetAzimuthRotation; glm::quat targetRotation; - Vector3 translation; Vector3 targetTranslation; }; -inline const Vector3& SurfaceCameraController::getFocalPoint() const +inline const Vector3& OrbitCam::getFocalPoint() const { return focalPoint; } -inline float SurfaceCameraController::getFocalDistance() const +inline float OrbitCam::getFocalDistance() const { return focalDistance; } -inline float SurfaceCameraController::getElevation() const +inline float OrbitCam::getElevation() const { return elevation; } -inline float SurfaceCameraController::getAzimuth() const +inline float OrbitCam::getAzimuth() const { return azimuth; } -inline const Vector3& SurfaceCameraController::getTargetFocalPoint() const +inline const Vector3& OrbitCam::getTargetFocalPoint() const { return targetFocalPoint; } -inline float SurfaceCameraController::getTargetFocalDistance() const +inline float OrbitCam::getTargetFocalDistance() const { return targetFocalDistance; } -inline float SurfaceCameraController::getTargetElevation() const +inline float OrbitCam::getTargetElevation() const { return targetElevation; } -inline float SurfaceCameraController::getTargetAzimuth() const +inline float OrbitCam::getTargetAzimuth() const { return targetAzimuth; } -inline const Vector3& SurfaceCameraController::getTranslation() const -{ - return translation; -} - -inline const glm::quat& SurfaceCameraController::getRotation() const -{ - return rotation; -} - -inline const Vector3& SurfaceCameraController::getTargetTranslation() const +inline const Vector3& OrbitCam::getTargetTranslation() const { return targetTranslation; } -inline const glm::quat& SurfaceCameraController::getTargetRotation() const +inline const glm::quat& OrbitCam::getTargetRotation() const { return targetRotation; } -/** - * Note, when mouseover tunnel, highlight (in red?) the entire path from the end of the tunnel to the entrance of the nest. - */ -class TunnelCameraController: public CameraController -{ -public: - TunnelCameraController(); - virtual ~TunnelCameraController(); - - virtual void update(float dt); - - void rotateCW(float scale); - void rotateCCW(float scale); - - // Ascends the tunnel system in the direction of the entrance - void ascend(float scale); - - // Descends along the current tunnel - void descend(float scale); -}; - -#endif \ No newline at end of file +#endif // CAMERA_RIG_HPP \ No newline at end of file diff --git a/src/game/tool.cpp b/src/game/tool.cpp index 8024171..0b3e29d 100644 --- a/src/game/tool.cpp +++ b/src/game/tool.cpp @@ -3,7 +3,7 @@ #include "colony.hpp" #include "navmesh.hpp" #include "pheromone-matrix.hpp" -#include "../camera-controller.hpp" +#include "../camera-rig.hpp" #include "../configuration.hpp" #include #include @@ -11,7 +11,7 @@ Tool::Tool(): active(false), pick(0.0f), - cameraController(nullptr) + orbitCam(nullptr) { modelInstance.setActive(active); } @@ -28,9 +28,9 @@ void Tool::setActive(bool active) } } -void Tool::setCameraController(const SurfaceCameraController* cameraController) +void Tool::setOrbitCam(const OrbitCam* orbitCam) { - this->cameraController = cameraController; + this->orbitCam = orbitCam; } Forceps::Forceps(const Model* model) @@ -79,7 +79,6 @@ Forceps::Forceps(const Model* model) colony = nullptr; targetedAnt = nullptr; suspendedAnt = nullptr; - cameraController = nullptr; pick = Vector3(0.0f); // Open forceps @@ -113,7 +112,7 @@ void Forceps::update(float dt) forcepsDistance = descentTween->getTweenValue(); } - Quaternion alignment = glm::angleAxis(cameraController->getAzimuth(), Vector3(0, 1, 0)); + Quaternion alignment = glm::angleAxis(orbitCam->getAzimuth(), Vector3(0, 1, 0)); Quaternion tilt = glm::angleAxis(glm::radians(15.0f), Vector3(0, 0, -1)); Quaternion rotation = glm::normalize(alignment * tilt); Vector3 translation = pick + rotation * Vector3(0, forcepsDistance, 0); @@ -151,13 +150,13 @@ void Forceps::update(float dt) tilt = glm::angleAxis(glm::radians(15.0f), Vector3(0, 0, -1)); // Project camera forward onto XZ plane - Vector3 cameraForwardXZ = cameraController->getCamera()->getForward(); + Vector3 cameraForwardXZ = orbitCam->getCamera()->getForward(); cameraForwardXZ.y = 0.0f; cameraForwardXZ = glm::normalize(cameraForwardXZ); // Form alignment quaternion //Quaternion alignment = glm::rotation(Vector3(0, 0, -1), cameraForwardXZ); - alignment = glm::angleAxis(cameraController->getAzimuth(), Vector3(0, 1, 0)); + alignment = glm::angleAxis(orbitCam->getAzimuth(), Vector3(0, 1, 0)); // Calculate target rotation at the top of the ascentTween rotationTop = glm::normalize(alignment * tilt); @@ -209,7 +208,7 @@ void Forceps::update(float dt) Vector3 interpolatedTranslation = glm::lerp(translationTop, translationBottom, interpolationFactor); // Project camera forward onto XZ plane - Vector3 cameraForwardXZ = cameraController->getCamera()->getForward(); + Vector3 cameraForwardXZ = orbitCam->getCamera()->getForward(); cameraForwardXZ.y = 0.0f; cameraForwardXZ = glm::normalize(cameraForwardXZ); @@ -312,7 +311,7 @@ void Forceps::pinch() antForwardXZ = glm::normalize(antForwardXZ); // Project camera forward onto XZ plane - Vector3 cameraForwardXZ = cameraController->getCamera()->getForward(); + Vector3 cameraForwardXZ = orbitCam->getCamera()->getForward(); cameraForwardXZ.y = 0.0f; cameraForwardXZ = glm::normalize(cameraForwardXZ); @@ -606,7 +605,7 @@ void Brush::update(float dt) Quaternion tilt = glm::angleAxis(tiltAngle, tiltAxis); - Quaternion alignment = glm::angleAxis(cameraController->getAzimuth(), Vector3(0, 1, 0)); + Quaternion alignment = glm::angleAxis(orbitCam->getAzimuth(), Vector3(0, 1, 0)); Quaternion rotation = glm::normalize(tilt); Vector3 translation = pick + Vector3(0, brushDistance, 0); diff --git a/src/game/tool.hpp b/src/game/tool.hpp index e0525ef..7f1f7b2 100644 --- a/src/game/tool.hpp +++ b/src/game/tool.hpp @@ -28,7 +28,7 @@ using namespace Emergent; class Ant; class Colony; class Navmesh; -class SurfaceCameraController; +class OrbitCam; /** * Abstract base class for tools. Tools are the only way for the user to interact with the world. @@ -70,7 +70,7 @@ public: * * @param camera Pointer to the camera. */ - void setCameraController(const SurfaceCameraController* cameraController); + void setOrbitCam(const OrbitCam* orbitCam); bool isActive() const; @@ -84,7 +84,7 @@ protected: ModelInstance modelInstance; bool active; Vector3 pick; - const SurfaceCameraController* cameraController; + const OrbitCam* orbitCam; }; inline bool Tool::isActive() const diff --git a/src/materials.hpp b/src/materials.hpp index 3d2e8a7..50ec213 100644 --- a/src/materials.hpp +++ b/src/materials.hpp @@ -86,4 +86,4 @@ inline unsigned int PhysicalMaterial::getMaterialFormatID() const return static_cast(MaterialFormat::PHYSICAL); } -#endif // MATERIALS \ No newline at end of file +#endif // MATERIALS diff --git a/src/states/game-state.cpp b/src/states/game-state.cpp index 714bcc1..f9a5882 100644 --- a/src/states/game-state.cpp +++ b/src/states/game-state.cpp @@ -20,7 +20,7 @@ #include "game-state.hpp" #include "title-state.hpp" #include "../application.hpp" -#include "../camera-controller.hpp" +#include "../camera-rig.hpp" #include "../game/colony.hpp" #include "../game/ant.hpp" #include "../game/tool.hpp" @@ -79,7 +79,8 @@ void GameState::enter() // Add terrain to scene - //application->defaultLayer->addObject(&application->currentLevel->terrainSurface); + application->defaultLayer->addObject(&application->currentLevel->terrainSurface); + application->currentLevel->terrainSurface.setTranslation(Vector3(0.0f, 0.01f, 0.0f)); //application->defaultLayer->addObject(&application->currentLevel->terrainSubsurface); application->defaultLayer->addObject(&application->sidewalkPanelInstance); application->defaultLayer->addObject(&application->sidewalkPanelInstance1); @@ -104,16 +105,16 @@ void GameState::enter() } // Setup camera controller - application->surfaceCam->setCamera(&application->camera); - //application->surfaceCam->setFocalPoint(Vector3(0.0f)); - //application->surfaceCam->setFocalDistance(250.0f); - //application->surfaceCam->setElevation(glm::radians(35.0f)); - //application->surfaceCam->setAzimuth(glm::radians(-45.0f)); - application->surfaceCam->setTargetFocalPoint(Vector3(0.0f)); - application->surfaceCam->setTargetFocalDistance(250.0f); - application->surfaceCam->setTargetElevation(glm::radians(35.0f)); - //application->surfaceCam->setTargetAzimuth(glm::radians(-45.0f)); - application->surfaceCam->update(0.0f); + application->orbitCam->attachCamera(&application->camera); + //application->orbitCam->setFocalPoint(Vector3(0.0f)); + //application->orbitCam->setFocalDistance(250.0f); + //application->orbitCam->setElevation(glm::radians(35.0f)); + //application->orbitCam->setAzimuth(glm::radians(-45.0f)); + application->orbitCam->setTargetFocalPoint(Vector3(0.0f)); + application->orbitCam->setTargetFocalDistance(250.0f); + application->orbitCam->setTargetElevation(glm::radians(35.0f)); + //application->orbitCam->setTargetAzimuth(glm::radians(-45.0f)); + application->orbitCam->update(0.0f); application->simulationPaused = false; @@ -135,6 +136,7 @@ void GameState::enter() application->fadeInTween->start(); application->mouse->addMouseButtonObserver(this); + application->mouse->addMouseMotionObserver(this); } void GameState::execute() @@ -222,61 +224,82 @@ void GameState::execute() } else { - // Move camera - Vector2 movementVector(0.0f); - if (application->cameraMoveLeft.isTriggered()) - movementVector.x -= application->cameraMoveLeft.getCurrentValue(); - if (application->cameraMoveRight.isTriggered()) - movementVector.x += application->cameraMoveRight.getCurrentValue(); - if (application->cameraMoveForward.isTriggered()) - movementVector.y -= application->cameraMoveForward.getCurrentValue(); - if (application->cameraMoveBack.isTriggered()) - movementVector.y += application->cameraMoveBack.getCurrentValue(); - if (movementVector.x != 0.0f || movementVector.y != 0.0f) + // Select rig + if (application->switchRig.isTriggered() && !application->switchRig.wasTriggered()) { - movementVector *= 0.005f * application->surfaceCam->getFocalDistance() * application->dt / (1.0f / 60.0f); - application->surfaceCam->move(movementVector); - - Vector3 focal = application->surfaceCam->getFocalPoint(); + if (application->activeRig == application->orbitCam) + { + application->freeCam->setTranslation(application->orbitCam->getTranslation()); + //application->freeCam->setRotation(application->orbitCam->getRotation()); + + application->orbitCam->detachCamera(); + application->freeCam->attachCamera(&application->camera); + application->activeRig = application->freeCam; + } + else if (application->activeRig == application->freeCam) + { + application->freeCam->detachCamera(); + application->orbitCam->attachCamera(&application->camera); + application->activeRig = application->orbitCam; + } } - // Zoom camera - float zoomFactor = application->surfaceCam->getFocalDistance() / 10.0f * application->dt / (1.0f / 60.0f); - if (application->cameraZoomIn.isTriggered()) - application->surfaceCam->zoom(zoomFactor * application->cameraZoomIn.getCurrentValue()); - if (application->cameraZoomOut.isTriggered()) - application->surfaceCam->zoom(-zoomFactor * application->cameraZoomOut.getCurrentValue()); - - // Rotate camera - if (application->cameraRotateCW.isTriggered() && !application->cameraRotateCW.wasTriggered()) + // Move camera + if (application->activeRig == application->orbitCam) { - application->surfaceCam->rotate(glm::radians(-45.0f)); + Vector2 movementVector(0.0f); + if (application->cameraMoveLeft.isTriggered()) + movementVector.x -= application->cameraMoveLeft.getCurrentValue(); + if (application->cameraMoveRight.isTriggered()) + movementVector.x += application->cameraMoveRight.getCurrentValue(); + if (application->cameraMoveForward.isTriggered()) + movementVector.y -= application->cameraMoveForward.getCurrentValue(); + if (application->cameraMoveBack.isTriggered()) + movementVector.y += application->cameraMoveBack.getCurrentValue(); + if (movementVector.x != 0.0f || movementVector.y != 0.0f) + { + movementVector *= 0.005f * application->orbitCam->getFocalDistance() * application->dt / (1.0f / 60.0f); + application->orbitCam->move(movementVector); + } + + // Zoom camera + float zoomFactor = application->orbitCam->getFocalDistance() / 10.0f * application->dt / (1.0f / 60.0f); + if (application->cameraZoomIn.isTriggered()) + application->orbitCam->zoom(zoomFactor * application->cameraZoomIn.getCurrentValue()); + if (application->cameraZoomOut.isTriggered()) + application->orbitCam->zoom(-zoomFactor * application->cameraZoomOut.getCurrentValue()); + + // Rotate camera + if (application->cameraRotateCW.isTriggered() && !application->cameraRotateCW.wasTriggered()) + { + application->orbitCam->rotate(glm::radians(-45.0f)); + } + if (application->cameraRotateCCW.isTriggered() && !application->cameraRotateCCW.wasTriggered()) + { + application->orbitCam->rotate(glm::radians(45.0f)); + } } - if (application->cameraRotateCCW.isTriggered() && !application->cameraRotateCCW.wasTriggered()) + else if (application->activeRig == application->freeCam) { - application->surfaceCam->rotate(glm::radians(45.0f)); + Vector2 movementVector(0.0f); + if (application->cameraMoveForward.isTriggered()) + movementVector.x += application->cameraMoveForward.getCurrentValue(); + if (application->cameraMoveBack.isTriggered()) + movementVector.x -= application->cameraMoveBack.getCurrentValue(); + if (application->cameraMoveLeft.isTriggered()) + movementVector.y -= application->cameraMoveLeft.getCurrentValue(); + if (application->cameraMoveRight.isTriggered()) + movementVector.y += application->cameraMoveRight.getCurrentValue(); + if (movementVector.x != 0.0f || movementVector.y != 0.0f) + { + movementVector = glm::normalize(movementVector) * 0.15f; + application->freeCam->move(movementVector); + } } } - - - /* - else - { - Plane plane; - plane.set(Vector3(0, 1, 0), Vector3(0.0f)); - auto result = pickingRay.intersects(plane); - pick = pickingRay.extrapolate(std::get<1>(result)); - } - */ - - - - - - - // Update camera - application->surfaceCam->update(application->dt); + // Update camera rig + application->activeRig->update(application->dt); // Picking if (!application->simulationPaused) @@ -305,7 +328,7 @@ void GameState::execute() float forcepsDistance = application->forcepsSwoopTween->getTweenValue(); //Quaternion rotation = glm::rotation(Vector3(0, 1, 0), triangle->normal); - Quaternion rotation = glm::angleAxis(application->surfaceCam->getAzimuth(), Vector3(0, 1, 0)) * + Quaternion rotation = glm::angleAxis(application->orbitCam->getAzimuth(), Vector3(0, 1, 0)) * glm::angleAxis(glm::radians(15.0f), Vector3(0, 0, -1)); Vector3 translation = pick + rotation * Vector3(0, forcepsDistance, 0); @@ -358,8 +381,8 @@ void GameState::execute() { for (int x = 0; x < application->pheromoneTexture.getWidth(); ++x) { - float concentrationH = std::min(1.0f, bufferH[index]) * 0.35f; - float concentrationR = std::min(1.0f, bufferR[index]) * 0.35f; + float concentrationH = std::min(1.0f, bufferH[index]); + float concentrationR = std::min(1.0f, bufferR[index]); cmyk[0] = std::min(1.0f, concentrationH * HOMING_PHEROMONE_COLOR[0] + concentrationR * RECRUITMENT_PHEROMONE_COLOR[0]); cmyk[1] = std::min(1.0f, concentrationH * HOMING_PHEROMONE_COLOR[1] + concentrationR * RECRUITMENT_PHEROMONE_COLOR[1]); @@ -371,11 +394,12 @@ void GameState::execute() GLubyte b = static_cast(std::min(255.0f, rgb[2] * 255.0f)); GLubyte g = static_cast(std::min(255.0f, rgb[1] * 255.0f)); GLubyte r = static_cast(std::min(255.0f, rgb[0] * 255.0f)); + GLubyte a = static_cast(std::min(255.0f, std::max(concentrationH, concentrationR) * 64.0f)); *(channel++) = b; *(channel++) = g; *(channel++) = r; - *(channel++) = 255; + *(channel++) = a; ++index; } @@ -394,6 +418,7 @@ void GameState::exit() { // Remove input observers application->mouse->removeMouseButtonObserver(this); + application->mouse->removeMouseMotionObserver(this); // Clear scene //application->defaultLayer->removeObject(&application->currentLevel->terrainSurface); @@ -435,6 +460,8 @@ void GameState::mouseButtonPressed(int button, int x, int y) { application->lens->focus(); } + + dragging = true; } } @@ -455,5 +482,24 @@ void GameState::mouseButtonReleased(int button, int x, int y) { application->lens->unfocus(); } + + dragging = false; + } +} + +void GameState::mouseMoved(int x, int y) +{ + oldMousePosition = mousePosition; + mousePosition = Vector2(x, y); + + if (application->activeRig == application->freeCam && dragging) + { + float rotationScale = glm::radians(180.0f) / application->resolution.y; + Vector2 difference = mousePosition - oldMousePosition; + + float pan = -difference.x * rotationScale; + float tilt = -difference.y * rotationScale; + + application->freeCam->rotate(pan, tilt); } } diff --git a/src/states/game-state.hpp b/src/states/game-state.hpp index 02566aa..da4e4dc 100644 --- a/src/states/game-state.hpp +++ b/src/states/game-state.hpp @@ -28,7 +28,7 @@ #include using namespace Emergent; -class GameState: public ApplicationState, public MouseButtonObserver +class GameState: public ApplicationState, public MouseButtonObserver, public MouseMotionObserver { public: GameState(Application* application); @@ -40,6 +40,7 @@ public: virtual void mouseButtonPressed(int button, int x, int y); virtual void mouseButtonReleased(int button, int x, int y); + virtual void mouseMoved(int x, int y); private: ModelInstance terrainSurface; @@ -47,6 +48,9 @@ private: Vector3 pick; Ray pickingRay; Navmesh::Triangle* pickTriangle; + bool dragging; + Vector2 oldMousePosition; + Vector2 mousePosition; }; #endif // GAME_STATE_HPP \ No newline at end of file diff --git a/src/states/title-state.cpp b/src/states/title-state.cpp index 6cd3cc7..3c38807 100644 --- a/src/states/title-state.cpp +++ b/src/states/title-state.cpp @@ -19,7 +19,7 @@ #include "title-state.hpp" #include "../application.hpp" -#include "../camera-controller.hpp" +#include "../camera-rig.hpp" #include "../ui/menu.hpp" #include #include @@ -42,20 +42,20 @@ void TitleState::enter() application->camera.setPerspective( glm::radians(30.0f), application->resolution.x / application->resolution.y, - 0.1f, + 0.5f, 1000.0f); // Setup camera controller - application->surfaceCam->setCamera(&application->camera); - application->surfaceCam->setFocalPoint(Vector3(0.0f)); - application->surfaceCam->setFocalDistance(50.0f); - application->surfaceCam->setElevation(glm::radians(-30.0f)); - application->surfaceCam->setAzimuth(glm::radians(180.0f)); - application->surfaceCam->setTargetFocalPoint(application->surfaceCam->getFocalPoint()); - application->surfaceCam->setTargetFocalDistance(application->surfaceCam->getFocalDistance()); - application->surfaceCam->setTargetElevation(application->surfaceCam->getElevation()); - application->surfaceCam->setTargetAzimuth(application->surfaceCam->getAzimuth()); - application->surfaceCam->update(0.0f); + application->orbitCam->attachCamera(&application->camera); + application->orbitCam->setFocalPoint(Vector3(0.0f)); + application->orbitCam->setFocalDistance(50.0f); + application->orbitCam->setElevation(glm::radians(-30.0f)); + application->orbitCam->setAzimuth(glm::radians(180.0f)); + application->orbitCam->setTargetFocalPoint(application->orbitCam->getFocalPoint()); + application->orbitCam->setTargetFocalDistance(application->orbitCam->getFocalDistance()); + application->orbitCam->setTargetElevation(application->orbitCam->getElevation()); + application->orbitCam->setTargetAzimuth(application->orbitCam->getAzimuth()); + application->orbitCam->update(0.0f); // Dim background application->darkenImage->setVisible(true);