From bc17c53ef558e666d3c4c926e6989cc306d11c46 Mon Sep 17 00:00:00 2001 From: "C. J. Howard" Date: Sat, 23 Sep 2017 01:27:59 +0800 Subject: [PATCH] Refactor forceps code and add support for animated pinching --- CMakeLists.txt | 1 + data | 2 +- lib/emergent | 2 +- src/application.cpp | 17 +-- src/application.hpp | 3 +- src/game/ant.cpp | 75 +++++--------- src/game/ant.hpp | 7 +- src/game/colony.cpp | 10 +- src/game/colony.hpp | 7 ++ src/game/tool.cpp | 212 ++++++++++++++++++++++++++++++++++++++ src/game/tool.hpp | 165 +++++++++++++++++++++++++++-- src/states/play-state.cpp | 106 +++---------------- src/states/play-state.hpp | 4 - 13 files changed, 440 insertions(+), 171 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 46d7461..b35465a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -231,6 +231,7 @@ set(EXECUTABLE_SOURCES ${EXECUTABLE_SOURCE_DIR}/game/level.cpp ${EXECUTABLE_SOURCE_DIR}/game/biome.hpp ${EXECUTABLE_SOURCE_DIR}/game/biome.cpp + ${EXECUTABLE_SOURCE_DIR}/game/tool.cpp ${EXECUTABLE_SOURCE_DIR}/debug.hpp ${EXECUTABLE_SOURCE_DIR}/debug.cpp ${EXECUTABLE_SOURCE_DIR}/camera-controller.hpp diff --git a/data b/data index ce902f8..a9efe78 160000 --- a/data +++ b/data @@ -1 +1 @@ -Subproject commit ce902f8e1c8ad4b204689711ea9bdb3fe7f3b585 +Subproject commit a9efe788f89a3b1bf6381d1be2ffec4d3adc52bc diff --git a/lib/emergent b/lib/emergent index f07060a..0fb5711 160000 --- a/lib/emergent +++ b/lib/emergent @@ -1 +1 @@ -Subproject commit f07060a2fd956170b046bf412fa3b9b73b06f320 +Subproject commit 0fb571191709569af7e342e281721ffa8cafd736 diff --git a/src/application.cpp b/src/application.cpp index fa1c0e8..21360f9 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -28,6 +28,7 @@ #include "states/level-select-state.hpp" #include "states/play-state.hpp" #include "game/colony.hpp" +#include "game/tool.hpp" #include "ui/toolbar.hpp" #include "ui/pie-menu.hpp" #include "debug.hpp" @@ -602,7 +603,6 @@ bool Application::loadModels() antHillModelInstance.setModel(antHillModel); antHillModelInstance.setRotation(glm::angleAxis(glm::radians(90.0f), Vector3(1, 0, 0))); nestModelInstance.setModel(nestModel); - forcepsModelInstance.setModel(forcepsModel); biomeFloorModelInstance.setModel(biomeFloorModel); return true; @@ -988,18 +988,18 @@ bool Application::loadUI() // Create pause/play button elements pauseButtonImage = new UIImage(); - pauseButtonImage->setAnchor(Vector2(0.0f, 1.0f)); + pauseButtonImage->setAnchor(Vector2(0.5f, 1.0f)); pauseButtonImage->setDimensions(Vector2(pauseButtonTexture->getWidth(), pauseButtonTexture->getHeight())); - pauseButtonImage->setTranslation(Vector2(16.0f, -16.0f)); + pauseButtonImage->setTranslation(Vector2(0.0f, -16.0f)); pauseButtonImage->setTexture(pauseButtonTexture); pauseButtonImage->setVisible(false); pauseButtonImage->setActive(false); uiRootElement->addChild(pauseButtonImage); playButtonImage = new UIImage(); - playButtonImage->setAnchor(Vector2(0.0f, 1.0f)); + playButtonImage->setAnchor(Vector2(0.5f, 1.0f)); playButtonImage->setDimensions(Vector2(playButtonTexture->getWidth(), playButtonTexture->getHeight())); - playButtonImage->setTranslation(Vector2(16.0f, -16.0f)); + playButtonImage->setTranslation(Vector2(0.0f, -16.0f)); playButtonImage->setTexture(playButtonTexture); playButtonImage->setVisible(false); playButtonImage->setActive(false); @@ -1055,7 +1055,7 @@ bool Application::loadUI() toolbar->setButtonDepressedTexture(toolbarButtonDepressedTexture); toolbar->addButton(toolBrushTexture, std::bind(&std::printf, "0\n"), std::bind(&std::printf, "0\n")); toolbar->addButton(toolLensTexture, std::bind(&std::printf, "1\n"), std::bind(&std::printf, "1\n")); - toolbar->addButton(toolForcepsTexture, std::bind(&SceneObject::setActive, &forcepsModelInstance, true), std::bind(&SceneObject::setActive, &forcepsModelInstance, false)); + toolbar->addButton(toolForcepsTexture, std::bind(&std::printf, "2\n"), std::bind(&std::printf, "2\n")); toolbar->addButton(toolTrowelTexture, std::bind(&std::printf, "3\n"), std::bind(&std::printf, "3\n")); toolbar->resize(); //uiRootElement->addChild(toolbar->getContainer()); @@ -1403,6 +1403,11 @@ bool Application::loadGame() colony = new Colony(); colony->setAntModel(antModel); + // Create tools + forceps = new Forceps(forcepsModel); + forceps->setColony(colony); + forceps->setCameraController(surfaceCam); + return true; } diff --git a/src/application.hpp b/src/application.hpp index 47f1d44..eefddf9 100644 --- a/src/application.hpp +++ b/src/application.hpp @@ -52,6 +52,7 @@ class ModelLoader; class MaterialLoader; class Toolbar; class PieMenu; +class Forceps; /** * Encapsulates the state of the application. @@ -382,8 +383,8 @@ public: bool cameraOverheadView; bool cameraNestView; int toolIndex; + Forceps* forceps; bool simulationPaused; - bool forcepsClosed; // Debug LineBatcher* lineBatcher; diff --git a/src/game/ant.cpp b/src/game/ant.cpp index fc60e93..59750a6 100644 --- a/src/game/ant.cpp +++ b/src/game/ant.cpp @@ -34,10 +34,7 @@ Ant::Ant(Colony* colony): pose(nullptr) { pose = new Pose(colony->getAntModel()->getSkeleton()); - for (std::size_t i = 0; i < pose->getSkeleton()->getBoneCount(); ++i) - { - pose->setRelativeTransform(i, pose->getSkeleton()->getBindPose()->getRelativeTransform(i)); - } + pose->reset(); pose->concatenate(); modelInstance.setModel(colony->getAntModel()); @@ -51,44 +48,18 @@ Ant::~Ant() delete pose; } -void Ant::rotateHead() +void Ant::animate() { - /* - const Bone* headBone = pose->getSkeleton()->getBone("left-flagellum"); - if (headBone != nullptr) - { - std::size_t boneIndex = headBone->getIndex(); - - Transform transform = pose->getRelativeTransform(boneIndex); - transform.rotation = glm::normalize(transform.rotation * glm::angleAxis(glm::radians(5.0f), Vector3(0.0f, 1.0f, 0.0f))); - - pose->setRelativeTransform(boneIndex, transform); - pose->concatenate(); - } - */ - - const Animation* animation = pose->getSkeleton()->getAnimation("tripod-gait"); - if (animation != nullptr) - { - for (std::size_t i = 0; i < animation->getChannelCount(); ++i) - { - const AnimationChannel* channel = animation->getChannel(i); - - std::size_t boneIndex = channel->getChannelID(); - Transform transform = channel->interpolateBoundingKeyFrames(animationTime); - - pose->setRelativeTransform(channel->getChannelID(), transform); - } - pose->concatenate(); - - animationTime = fwrap(animationTime + 2.0f, animation->getEndTime()); - - /* - if (animationTime > animation->getEndTime()) - { - animationTime = animation->getStartTime(); - }*/ - } + colony->getTripodGaitAnimation()->animate(pose, animationTime); + pose->concatenate(); + animationTime = fwrap(animationTime + 2.0f, colony->getTripodGaitAnimation()->getEndTime()); +} + +void Ant::suspend(const Vector3& suspensionPoint) +{ + transform.translation = suspensionPoint; + transform.rotation = getRotation(); + modelInstance.setTransform(transform); } void Ant::move(const Vector3& velocity) @@ -127,7 +98,7 @@ void Ant::update(float dt) float probeLateralOffset = 0.1f; float probeForwardOffset = 0.3f; - rotateHead(); + animate(); // Steering if (state == Ant::State::WANDER) @@ -185,6 +156,16 @@ void Ant::update(float dt) move(velocity); } + // Update transform + if (state == Ant::State::WANDER || state == Ant::State::IDLE) + { + transform.translation = getPosition(); + transform.rotation = getRotation(); + + // Update model instance + modelInstance.setTransform(transform); + } + // Locomotion /* @@ -198,16 +179,6 @@ void Ant::update(float dt) when a grounded leg enters the swing phases, its current pose is saved as the liftoff pose, then an animation is created using the liftoff pose, midswing pose, and touchdown pose. */ - - // Update transform - if (state != Ant::State::DEAD) - { - transform.translation = getPosition(); - transform.rotation = getRotation(); - - // Update model instance - modelInstance.setTransform(transform); - } } Vector3 Ant::forage(const Vector3& leftReceptor, const Vector3& rightReceptor) diff --git a/src/game/ant.hpp b/src/game/ant.hpp index 12c43ac..67fccc5 100644 --- a/src/game/ant.hpp +++ b/src/game/ant.hpp @@ -58,7 +58,8 @@ public: { IDLE, WANDER, - DEAD + DEAD, + SUSPENDED }; /** @@ -67,7 +68,9 @@ public: Ant(Colony* colony); ~Ant(); - void rotateHead(); + void animate(); + + void suspend(const Vector3& suspensionPoint); void move(const Vector3& velocity); diff --git a/src/game/colony.cpp b/src/game/colony.cpp index 8b4b1e4..e7c34e3 100644 --- a/src/game/colony.cpp +++ b/src/game/colony.cpp @@ -23,7 +23,8 @@ #include "../configuration.hpp" Colony::Colony(): - antModel(nullptr) + antModel(nullptr), + tripodGaitAnimation(nullptr) { Vector3 octreeMin = Vector3(-ANTKEEPER_TERRAIN_WIDTH, -ANTKEEPER_TERRAIN_BASE_HEIGHT, -ANTKEEPER_TERRAIN_DEPTH) * 0.5f - Vector3(ANTKEEPER_OCTREE_PADDING); Vector3 octreeMax = Vector3( ANTKEEPER_TERRAIN_WIDTH, ANTKEEPER_TERRAIN_BASE_HEIGHT, ANTKEEPER_TERRAIN_DEPTH) * 0.5f + Vector3(ANTKEEPER_OCTREE_PADDING); @@ -73,6 +74,13 @@ void Colony::update(float dt) void Colony::setAntModel(Model* model) { this->antModel = model; + + // Find tripod gait animation + tripodGaitAnimation = model->getSkeleton()->getAnimation("tripod-gait"); + if (!tripodGaitAnimation) + { + std::cerr << "Ant tripod gait animation not found" << std::endl; + } } void Colony::queryAnts(const BoundingVolume& volume, std::list* results) const diff --git a/src/game/colony.hpp b/src/game/colony.hpp index a853f53..8d0284e 100644 --- a/src/game/colony.hpp +++ b/src/game/colony.hpp @@ -47,6 +47,7 @@ public: void setAntModel(Model* model); const Model* getAntModel() const; Model* getAntModel(); + const Animation* getTripodGaitAnimation() const; void queryAnts(const BoundingVolume& volume, std::list* results) const; @@ -63,6 +64,7 @@ public: private: // Rendering Model* antModel; + const Animation* tripodGaitAnimation; // Locomotion float walkSpeed; @@ -89,6 +91,11 @@ inline Model* Colony::getAntModel() return antModel; } +inline const Animation* Colony::getTripodGaitAnimation() const +{ + return tripodGaitAnimation; +} + inline std::size_t Colony::getAntCount() const { return ants.size(); diff --git a/src/game/tool.cpp b/src/game/tool.cpp index ee0674f..55a2fa5 100644 --- a/src/game/tool.cpp +++ b/src/game/tool.cpp @@ -1,2 +1,214 @@ #include "tool.hpp" +#include "ant.hpp" +#include "colony.hpp" +#include "../camera-controller.hpp" +#include +#include +Forceps::Forceps(const Model* model) +{ + // Allocate pose and initialize to bind pose + pose = new Pose(model->getSkeleton()); + pose->reset(); + pose->concatenate(); + + // Setup model instance + modelInstance.setModel(model); + modelInstance.setPose(pose); + + // Find pinch animation + pinchAnimation = model->getSkeleton()->getAnimation("pinch"); + if (!pinchAnimation) + { + std::cerr << "Forceps pinch animation not found" << std::endl; + } + + // Find release animation + releaseAnimation = model->getSkeleton()->getAnimation("release"); + if (!releaseAnimation) + { + std::cerr << "Forceps release animation not found" << std::endl; + } + + // Allocate tweener and and setup tweens + tweener = new Tweener(); + descentTween = new Tween(EaseFunction::OUT_CUBIC, 0.0f, 0.0667f, 1.0f, -1.0f); + ascentTween = new Tween(EaseFunction::IN_CUBIC, 0.0f, 0.0667f, 0.0f, 1.0f); + descentTween->setEndCallback(std::bind(&TweenBase::start, ascentTween)); + tweener->addTween(descentTween); + tweener->addTween(ascentTween); + + // Setup initial state + state = Forceps::State::RELEASED; + animationTime = 0.0f; + colony = nullptr; + targetedAnt = nullptr; + suspendedAnt = nullptr; + cameraController = nullptr; + pick = Vector3(0.0f); +} + +Forceps::~Forceps() +{ + delete pose; + delete descentTween; + delete ascentTween; + delete tweener; +} + +void Forceps::update(float dt) +{ + // Update tweener + tweener->update(dt); + + // Determine distance from pick point + float forcepsDistance = descentTween->getStartValue(); + if (!ascentTween->isStopped()) + { + forcepsDistance = ascentTween->getTweenValue(); + } + else if (!descentTween->isStopped()) + { + forcepsDistance = descentTween->getTweenValue(); + } + + Quaternion rotation = glm::angleAxis(cameraController->getAzimuth(), Vector3(0, 1, 0)) * + glm::angleAxis(glm::radians(15.0f), Vector3(0, 0, -1)); + Vector3 translation = pick + rotation * Vector3(0, forcepsDistance, 0); + + // Set tool position + modelInstance.setTranslation(translation); + modelInstance.setRotation(rotation); + + if (state == Forceps::State::RELEASED) + { + + } + else if (state == Forceps::State::RELEASING) + { + // Perform release animation + releaseAnimation->animate(pose, animationTime); + pose->concatenate(); + + // If release animation is finished + if (animationTime >= releaseAnimation->getEndTime()) + { + // Changed to released state + state = Forceps::State::RELEASED; + } + } + else if (state == Forceps::State::PINCHED) + { + if (suspendedAnt != nullptr) + { + // Suspend ant + suspendedAnt->suspend(modelInstance.getTranslation()); + } + } + else if (state == Forceps::State::PINCHING) + { + // Perform pinch animation + pinchAnimation->animate(pose, animationTime); + pose->concatenate(); + + // If pinch animation is finished + if (animationTime >= pinchAnimation->getEndTime()) + { + // If an ant was targeted + if (targetedAnt != nullptr) + { + // Suspend targeted ant + suspendedAnt = targetedAnt; + suspendedAnt->setState(Ant::State::SUSPENDED); + suspendedAnt->suspend(modelInstance.getTranslation()); + targetedAnt = nullptr; + } + + // Change to pinched state + state = Forceps::State::PINCHED; + } + } + + // Increment animation time + //animationTime += dt; + animationTime += 2.5f; +} + +void Forceps::setColony(Colony* colony) +{ + this->colony = colony; +} + +void Forceps::setCameraController(const SurfaceCameraController* cameraController) +{ + this->cameraController = cameraController; +} + +void Forceps::setPick(const Vector3& pick) +{ + this->pick = pick; +} + +void Forceps::pinch() +{ + // Change state to pinching + state = Forceps::State::PINCHING; + animationTime = 0.0f; + + if (colony != nullptr) + { + // Target nearest ant in pinching radius + Sphere pinchingBounds = Sphere(pick, 0.35f); + + // Build a list of ants which intersect the pinching bounds + std::list ants; + colony->queryAnts(pinchingBounds, &ants); + + // Target ant closest to the center of the pinching bounds + float closestDistance = std::numeric_limits::infinity(); + for (Agent* agent: ants) + { + Ant* ant = static_cast(agent); + + Vector3 difference = ant->getPosition() - pinchingBounds.getCenter(); + float distanceSquared = glm::dot(difference, difference); + if (distanceSquared < closestDistance) + { + closestDistance = distanceSquared; + targetedAnt = ant; + } + } + } + + // Start descent tweener + descentTween->start(); +} + +void Forceps::release() +{ + // Change state to releasing + state = Forceps::State::RELEASING; + animationTime = 0.0f; + + if (suspendedAnt != nullptr) + { + /* + auto result = intersects(pickingRay, pickTriangle); + if (std::get<0>(result)) + { + Vector3 barycentricPosition = Vector3(std::get<2>(result), std::get<3>(result), 1.0f - std::get<2>(result) - std::get<3>(result)); + pickAnt->setPosition(pickTriangle, barycentricPosition); + } + */ + + // Release suspended ant + suspendedAnt->setState(Ant::State::WANDER); + suspendedAnt = nullptr; + } + + // Reset tweens + descentTween->reset(); + descentTween->stop(); + ascentTween->reset(); + ascentTween->stop(); +} diff --git a/src/game/tool.hpp b/src/game/tool.hpp index b1c215f..1ef5a50 100644 --- a/src/game/tool.hpp +++ b/src/game/tool.hpp @@ -1,3 +1,33 @@ +/* + * Copyright (C) 2017 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 TOOL_HPP +#define TOOL_HPP + +#include "../ui/tween.hpp" + +#include +using namespace Emergent; + +class Ant; +class Colony; +class SurfaceCameraController; /** * Abstract base class for tools. Tools are the only way for the user to interact with the world. @@ -5,28 +35,141 @@ class Tool { public: - - - -private: - Vector3 translation; + virtual void update(float dt) = 0; }; + +/** + * The forceps tool can pick up ants and place them anywhere in the world. + */ class Forceps: public Tool { public: - -private: + enum class State + { + RELEASED, + RELEASING, + PINCHED, + PINCHING + }; + + /** + * Creates an instance of Forceps. + * + * @param model Forceps model + */ + Forceps(const Model* model); + + /** + * Destroys an instance of Forceps. + */ + ~Forceps(); + + /** + * Updates the forceps. + */ + virtual void update(float dt); + + /** + * Pinches the forceps. + */ void pinch(); + + /** + * Releases the forceps. + */ void release(); - ModelInstance forcepsModelInstance; + /** + * Associates a colony with this forceps. + * + * @param colony Colony with which to associate. + */ + void setColony(Colony* colony); + + /** + * Sets the camera. + * + * @param camera Pointer to the camera. + */ + void setCameraController(const SurfaceCameraController* cameraController); + + /** + * Sets the picking position. + * + * @param pick Picking position + */ + void setPick(const Vector3& pick); + + /** + * Returns the current state of the forceps. + */ + Forceps::State getState() const; + + /** + * Returns the suspended ant, if any. + */ + Ant* getSuspendedAnt() const; + + /** + * Returns the model instance. + */ + const ModelInstance* getModelInstance() const; + ModelInstance* getModelInstance(); + +private: + Forceps::State state; + ModelInstance modelInstance; + Pose* pose; + const Animation* pinchAnimation; + const Animation* releaseAnimation; + float animationTime; + Tweener* tweener; + Tween* descentTween; + Tween* ascentTween; + Colony* colony; + Ant* targetedAnt; + Ant* suspendedAnt; + const SurfaceCameraController* cameraController; + Vector3 pick; +}; + +inline Forceps::State Forceps::getState() const +{ + return state; +} + +inline Ant* Forceps::getSuspendedAnt() const +{ + return suspendedAnt; +} + +inline const ModelInstance* Forceps::getModelInstance() const +{ + return &modelInstance; +} + +inline ModelInstance* Forceps::getModelInstance() +{ + return &modelInstance; +} + +/** + * The lens tool can be used to burn ants. + */ +class Lens: public Tool +{ +public: + virtual void update(float dt); }; +/** + * The brush tool can paint pheromones on the terrain. + */ class Brush: public Tool { public: + virtual void update(float dt); +}; -private: - void paint(); -}; \ No newline at end of file +#endif // TOOL_HPP diff --git a/src/states/play-state.cpp b/src/states/play-state.cpp index e7465d3..18650c3 100644 --- a/src/states/play-state.cpp +++ b/src/states/play-state.cpp @@ -23,6 +23,7 @@ #include "../camera-controller.hpp" #include "../game/colony.hpp" #include "../game/ant.hpp" +#include "../game/tool.hpp" #include "../ui/toolbar.hpp" #include @@ -46,24 +47,17 @@ void PlayState::enter() application->toolbar->getContainer()->setActive(true); // Setup tools - application->forcepsClosed = false; + application->forceps->setColony(application->colony); + + // Add tools to scene + application->defaultLayer->addObject(application->forceps->getModelInstance()); // Add terrain to scene application->defaultLayer->addObject(&application->currentLevel->terrainSurface); application->defaultLayer->addObject(&application->currentLevel->terrainSubsurface); application->defaultLayer->addObject(&application->biomeFloorModelInstance); - // Add forceps to scene - application->defaultLayer->addObject(&application->forcepsModelInstance); - forcepsPose = new Pose(application->forcepsModelInstance.getModel()->getSkeleton()); - for (std::size_t i = 0; i < forcepsPose->getSkeleton()->getBoneCount(); ++i) - { - forcepsPose->setRelativeTransform(i, forcepsPose->getSkeleton()->getBindPose()->getRelativeTransform(i)); - } - forcepsPose->concatenate(); - application->forcepsModelInstance.setPose(forcepsPose); - forcepsAnimation = nullptr; - forcepsAnimationTime = 0.0f; + // Spawn ants Navmesh* navmesh = application->currentLevel->terrain.getSurfaceNavmesh(); @@ -96,8 +90,6 @@ void PlayState::enter() application->simulationPaused = false; application->mouse->addMouseButtonObserver(this); - - pickAnt = nullptr; } void PlayState::execute() @@ -188,6 +180,7 @@ void PlayState::execute() std::size_t triangleIndex = std::get<3>(result); pickTriangle = (*application->currentLevel->terrain.getSurfaceNavmesh()->getTriangles())[triangleIndex]; + /* float forcepsDistance = application->forcepsSwoopTween->getTweenValue(); //Quaternion rotation = glm::rotation(Vector3(0, 1, 0), triangle->normal); @@ -199,29 +192,12 @@ void PlayState::execute() // Set tool position application->forcepsModelInstance.setTranslation(translation); application->forcepsModelInstance.setRotation(rotation); + */ } - if (forcepsAnimation != nullptr) - { - for (std::size_t i = 0; i < forcepsAnimation->getChannelCount(); ++i) - { - const AnimationChannel* channel = forcepsAnimation->getChannel(i); - - std::size_t boneIndex = channel->getChannelID(); - Transform transform = channel->interpolateBoundingKeyFrames(forcepsAnimationTime); - - forcepsPose->setRelativeTransform(channel->getChannelID(), transform); - } - forcepsPose->concatenate(); - - forcepsAnimationTime += 2.5f; - } - - if (pickAnt != nullptr) - { - pickAnt->getModelInstance()->setTranslation(pick); - pickAnt->rotateHead(); - } + // Update tools + application->forceps->setPick(pick); + application->forceps->update(application->dt); // Update colony if (!application->simulationPaused) @@ -252,7 +228,7 @@ void PlayState::exit() application->defaultLayer->removeObject(&application->currentLevel->terrainSurface); application->defaultLayer->removeObject(&application->currentLevel->terrainSubsurface); application->defaultLayer->removeObject(&application->biomeFloorModelInstance); - application->defaultLayer->removeObject(&application->forcepsModelInstance); + application->defaultLayer->removeObject(application->forceps->getModelInstance()); for (std::size_t i = 0; i < application->colony->getAntCount(); ++i) { Ant* ant = application->colony->getAnt(i); @@ -277,40 +253,7 @@ void PlayState::mouseButtonPressed(int button, int x, int y) { if (button == 1) { - application->forcepsClosed = true; - forcepsAnimation = forcepsPose->getSkeleton()->getAnimation("pinch"); - forcepsAnimationTime = 0.0f; - - application->forcepsSwoopTween->setDuration(0.10f); - application->forcepsSwoopTween->setStartValue(1.0f); - application->forcepsSwoopTween->setDeltaValue(-1.0f); - application->forcepsSwoopTween->reset(); - application->forcepsSwoopTween->start(); - - Sphere forcepsSphere = Sphere(pick, 0.35f); - - std::list ants; - pickAnt = nullptr; - float closestDistance = std::numeric_limits::infinity(); - - application->colony->queryAnts(forcepsSphere, &ants); - for (Agent* agent: ants) - { - Ant* ant = static_cast(agent); - - Vector3 difference = ant->getPosition() - pick; - float distanceSquared = glm::dot(difference, difference); - if (distanceSquared < closestDistance) - { - closestDistance = distanceSquared; - pickAnt = ant; - } - } - - if (pickAnt != nullptr) - { - pickAnt->setState(Ant::State::DEAD); - } + application->forceps->pinch(); } } @@ -318,27 +261,6 @@ void PlayState::mouseButtonReleased(int button, int x, int y) { if (button == 1) { - application->forcepsClosed = false; - forcepsAnimation = forcepsPose->getSkeleton()->getAnimation("release"); - forcepsAnimationTime = 0.0f; - - application->forcepsSwoopTween->setDuration(0.10f); - application->forcepsSwoopTween->setStartValue(0.0f); - application->forcepsSwoopTween->setDeltaValue(1.0f); - application->forcepsSwoopTween->reset(); - application->forcepsSwoopTween->start(); - - if (pickAnt != nullptr) - { - auto result = intersects(pickingRay, pickTriangle); - if (std::get<0>(result)) - { - Vector3 barycentricPosition = Vector3(std::get<2>(result), std::get<3>(result), 1.0f - std::get<2>(result) - std::get<3>(result)); - pickAnt->setPosition(pickTriangle, barycentricPosition); - } - - pickAnt->setState(Ant::State::WANDER); - pickAnt = nullptr; - } + application->forceps->release(); } } diff --git a/src/states/play-state.hpp b/src/states/play-state.hpp index ce94a64..b26ecbe 100644 --- a/src/states/play-state.hpp +++ b/src/states/play-state.hpp @@ -47,10 +47,6 @@ private: Vector3 pick; Ray pickingRay; Navmesh::Triangle* pickTriangle; - Ant* pickAnt; - Pose* forcepsPose; - float forcepsAnimationTime; - const Animation* forcepsAnimation; }; #endif // PLAY_STATE_HPP \ No newline at end of file