Browse Source

Refactor forceps code and add support for animated pinching

master
C. J. Howard 7 years ago
parent
commit
bc17c53ef5
13 changed files with 440 additions and 171 deletions
  1. +1
    -0
      CMakeLists.txt
  2. +1
    -1
      data
  3. +1
    -1
      lib/emergent
  4. +11
    -6
      src/application.cpp
  5. +2
    -1
      src/application.hpp
  6. +23
    -52
      src/game/ant.cpp
  7. +5
    -2
      src/game/ant.hpp
  8. +9
    -1
      src/game/colony.cpp
  9. +7
    -0
      src/game/colony.hpp
  10. +212
    -0
      src/game/tool.cpp
  11. +154
    -11
      src/game/tool.hpp
  12. +14
    -92
      src/states/play-state.cpp
  13. +0
    -4
      src/states/play-state.hpp

+ 1
- 0
CMakeLists.txt View File

@ -231,6 +231,7 @@ set(EXECUTABLE_SOURCES
${EXECUTABLE_SOURCE_DIR}/game/level.cpp ${EXECUTABLE_SOURCE_DIR}/game/level.cpp
${EXECUTABLE_SOURCE_DIR}/game/biome.hpp ${EXECUTABLE_SOURCE_DIR}/game/biome.hpp
${EXECUTABLE_SOURCE_DIR}/game/biome.cpp ${EXECUTABLE_SOURCE_DIR}/game/biome.cpp
${EXECUTABLE_SOURCE_DIR}/game/tool.cpp
${EXECUTABLE_SOURCE_DIR}/debug.hpp ${EXECUTABLE_SOURCE_DIR}/debug.hpp
${EXECUTABLE_SOURCE_DIR}/debug.cpp ${EXECUTABLE_SOURCE_DIR}/debug.cpp
${EXECUTABLE_SOURCE_DIR}/camera-controller.hpp ${EXECUTABLE_SOURCE_DIR}/camera-controller.hpp

+ 1
- 1
data

@ -1 +1 @@
Subproject commit ce902f8e1c8ad4b204689711ea9bdb3fe7f3b585
Subproject commit a9efe788f89a3b1bf6381d1be2ffec4d3adc52bc

+ 1
- 1
lib/emergent

@ -1 +1 @@
Subproject commit f07060a2fd956170b046bf412fa3b9b73b06f320
Subproject commit 0fb571191709569af7e342e281721ffa8cafd736

+ 11
- 6
src/application.cpp View File

@ -28,6 +28,7 @@
#include "states/level-select-state.hpp" #include "states/level-select-state.hpp"
#include "states/play-state.hpp" #include "states/play-state.hpp"
#include "game/colony.hpp" #include "game/colony.hpp"
#include "game/tool.hpp"
#include "ui/toolbar.hpp" #include "ui/toolbar.hpp"
#include "ui/pie-menu.hpp" #include "ui/pie-menu.hpp"
#include "debug.hpp" #include "debug.hpp"
@ -602,7 +603,6 @@ bool Application::loadModels()
antHillModelInstance.setModel(antHillModel); antHillModelInstance.setModel(antHillModel);
antHillModelInstance.setRotation(glm::angleAxis(glm::radians(90.0f), Vector3(1, 0, 0))); antHillModelInstance.setRotation(glm::angleAxis(glm::radians(90.0f), Vector3(1, 0, 0)));
nestModelInstance.setModel(nestModel); nestModelInstance.setModel(nestModel);
forcepsModelInstance.setModel(forcepsModel);
biomeFloorModelInstance.setModel(biomeFloorModel); biomeFloorModelInstance.setModel(biomeFloorModel);
return true; return true;
@ -988,18 +988,18 @@ bool Application::loadUI()
// Create pause/play button elements // Create pause/play button elements
pauseButtonImage = new UIImage(); 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->setDimensions(Vector2(pauseButtonTexture->getWidth(), pauseButtonTexture->getHeight()));
pauseButtonImage->setTranslation(Vector2(16.0f, -16.0f));
pauseButtonImage->setTranslation(Vector2(0.0f, -16.0f));
pauseButtonImage->setTexture(pauseButtonTexture); pauseButtonImage->setTexture(pauseButtonTexture);
pauseButtonImage->setVisible(false); pauseButtonImage->setVisible(false);
pauseButtonImage->setActive(false); pauseButtonImage->setActive(false);
uiRootElement->addChild(pauseButtonImage); uiRootElement->addChild(pauseButtonImage);
playButtonImage = new UIImage(); 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->setDimensions(Vector2(playButtonTexture->getWidth(), playButtonTexture->getHeight()));
playButtonImage->setTranslation(Vector2(16.0f, -16.0f));
playButtonImage->setTranslation(Vector2(0.0f, -16.0f));
playButtonImage->setTexture(playButtonTexture); playButtonImage->setTexture(playButtonTexture);
playButtonImage->setVisible(false); playButtonImage->setVisible(false);
playButtonImage->setActive(false); playButtonImage->setActive(false);
@ -1055,7 +1055,7 @@ bool Application::loadUI()
toolbar->setButtonDepressedTexture(toolbarButtonDepressedTexture); toolbar->setButtonDepressedTexture(toolbarButtonDepressedTexture);
toolbar->addButton(toolBrushTexture, std::bind(&std::printf, "0\n"), std::bind(&std::printf, "0\n")); 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(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->addButton(toolTrowelTexture, std::bind(&std::printf, "3\n"), std::bind(&std::printf, "3\n"));
toolbar->resize(); toolbar->resize();
//uiRootElement->addChild(toolbar->getContainer()); //uiRootElement->addChild(toolbar->getContainer());
@ -1403,6 +1403,11 @@ bool Application::loadGame()
colony = new Colony(); colony = new Colony();
colony->setAntModel(antModel); colony->setAntModel(antModel);
// Create tools
forceps = new Forceps(forcepsModel);
forceps->setColony(colony);
forceps->setCameraController(surfaceCam);
return true; return true;
} }

+ 2
- 1
src/application.hpp View File

@ -52,6 +52,7 @@ class ModelLoader;
class MaterialLoader; class MaterialLoader;
class Toolbar; class Toolbar;
class PieMenu; class PieMenu;
class Forceps;
/** /**
* Encapsulates the state of the application. * Encapsulates the state of the application.
@ -382,8 +383,8 @@ public:
bool cameraOverheadView; bool cameraOverheadView;
bool cameraNestView; bool cameraNestView;
int toolIndex; int toolIndex;
Forceps* forceps;
bool simulationPaused; bool simulationPaused;
bool forcepsClosed;
// Debug // Debug
LineBatcher* lineBatcher; LineBatcher* lineBatcher;

+ 23
- 52
src/game/ant.cpp View File

@ -34,10 +34,7 @@ Ant::Ant(Colony* colony):
pose(nullptr) pose(nullptr)
{ {
pose = new Pose(colony->getAntModel()->getSkeleton()); 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(); pose->concatenate();
modelInstance.setModel(colony->getAntModel()); modelInstance.setModel(colony->getAntModel());
@ -51,44 +48,18 @@ Ant::~Ant()
delete pose; 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) void Ant::move(const Vector3& velocity)
@ -127,7 +98,7 @@ void Ant::update(float dt)
float probeLateralOffset = 0.1f; float probeLateralOffset = 0.1f;
float probeForwardOffset = 0.3f; float probeForwardOffset = 0.3f;
rotateHead();
animate();
// Steering // Steering
if (state == Ant::State::WANDER) if (state == Ant::State::WANDER)
@ -185,6 +156,16 @@ void Ant::update(float dt)
move(velocity); 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 // 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. 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) Vector3 Ant::forage(const Vector3& leftReceptor, const Vector3& rightReceptor)

+ 5
- 2
src/game/ant.hpp View File

@ -58,7 +58,8 @@ public:
{ {
IDLE, IDLE,
WANDER, WANDER,
DEAD
DEAD,
SUSPENDED
}; };
/** /**
@ -67,7 +68,9 @@ public:
Ant(Colony* colony); Ant(Colony* colony);
~Ant(); ~Ant();
void rotateHead();
void animate();
void suspend(const Vector3& suspensionPoint);
void move(const Vector3& velocity); void move(const Vector3& velocity);

+ 9
- 1
src/game/colony.cpp View File

@ -23,7 +23,8 @@
#include "../configuration.hpp" #include "../configuration.hpp"
Colony::Colony(): 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 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); 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) void Colony::setAntModel(Model* model)
{ {
this->antModel = 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<Agent*>* results) const void Colony::queryAnts(const BoundingVolume& volume, std::list<Agent*>* results) const

+ 7
- 0
src/game/colony.hpp View File

@ -47,6 +47,7 @@ public:
void setAntModel(Model* model); void setAntModel(Model* model);
const Model* getAntModel() const; const Model* getAntModel() const;
Model* getAntModel(); Model* getAntModel();
const Animation* getTripodGaitAnimation() const;
void queryAnts(const BoundingVolume& volume, std::list<Agent*>* results) const; void queryAnts(const BoundingVolume& volume, std::list<Agent*>* results) const;
@ -63,6 +64,7 @@ public:
private: private:
// Rendering // Rendering
Model* antModel; Model* antModel;
const Animation* tripodGaitAnimation;
// Locomotion // Locomotion
float walkSpeed; float walkSpeed;
@ -89,6 +91,11 @@ inline Model* Colony::getAntModel()
return antModel; return antModel;
} }
inline const Animation* Colony::getTripodGaitAnimation() const
{
return tripodGaitAnimation;
}
inline std::size_t Colony::getAntCount() const inline std::size_t Colony::getAntCount() const
{ {
return ants.size(); return ants.size();

+ 212
- 0
src/game/tool.cpp View File

@ -1,2 +1,214 @@
#include "tool.hpp" #include "tool.hpp"
#include "ant.hpp"
#include "colony.hpp"
#include "../camera-controller.hpp"
#include <iostream>
#include <list>
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<float>(EaseFunction::OUT_CUBIC, 0.0f, 0.0667f, 1.0f, -1.0f);
ascentTween = new Tween<float>(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<Agent*> ants;
colony->queryAnts(pinchingBounds, &ants);
// Target ant closest to the center of the pinching bounds
float closestDistance = std::numeric_limits<float>::infinity();
for (Agent* agent: ants)
{
Ant* ant = static_cast<Ant*>(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();
}

+ 154
- 11
src/game/tool.hpp View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#ifndef TOOL_HPP
#define TOOL_HPP
#include "../ui/tween.hpp"
#include <emergent/emergent.hpp>
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. * Abstract base class for tools. Tools are the only way for the user to interact with the world.
@ -5,28 +35,141 @@
class Tool class Tool
{ {
public: 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 class Forceps: public Tool
{ {
public: 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(); void pinch();
/**
* Releases the forceps.
*/
void release(); 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<float>* descentTween;
Tween<float>* 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 class Brush: public Tool
{ {
public: public:
virtual void update(float dt);
};
private:
void paint();
};
#endif // TOOL_HPP

+ 14
- 92
src/states/play-state.cpp View File

@ -23,6 +23,7 @@
#include "../camera-controller.hpp" #include "../camera-controller.hpp"
#include "../game/colony.hpp" #include "../game/colony.hpp"
#include "../game/ant.hpp" #include "../game/ant.hpp"
#include "../game/tool.hpp"
#include "../ui/toolbar.hpp" #include "../ui/toolbar.hpp"
#include <cmath> #include <cmath>
@ -46,24 +47,17 @@ void PlayState::enter()
application->toolbar->getContainer()->setActive(true); application->toolbar->getContainer()->setActive(true);
// Setup tools // Setup tools
application->forcepsClosed = false;
application->forceps->setColony(application->colony);
// Add tools to scene
application->defaultLayer->addObject(application->forceps->getModelInstance());
// Add terrain to scene // Add terrain to scene
application->defaultLayer->addObject(&application->currentLevel->terrainSurface); application->defaultLayer->addObject(&application->currentLevel->terrainSurface);
application->defaultLayer->addObject(&application->currentLevel->terrainSubsurface); application->defaultLayer->addObject(&application->currentLevel->terrainSubsurface);
application->defaultLayer->addObject(&application->biomeFloorModelInstance); 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 // Spawn ants
Navmesh* navmesh = application->currentLevel->terrain.getSurfaceNavmesh(); Navmesh* navmesh = application->currentLevel->terrain.getSurfaceNavmesh();
@ -96,8 +90,6 @@ void PlayState::enter()
application->simulationPaused = false; application->simulationPaused = false;
application->mouse->addMouseButtonObserver(this); application->mouse->addMouseButtonObserver(this);
pickAnt = nullptr;
} }
void PlayState::execute() void PlayState::execute()
@ -188,6 +180,7 @@ void PlayState::execute()
std::size_t triangleIndex = std::get<3>(result); std::size_t triangleIndex = std::get<3>(result);
pickTriangle = (*application->currentLevel->terrain.getSurfaceNavmesh()->getTriangles())[triangleIndex]; pickTriangle = (*application->currentLevel->terrain.getSurfaceNavmesh()->getTriangles())[triangleIndex];
/*
float forcepsDistance = application->forcepsSwoopTween->getTweenValue(); float forcepsDistance = application->forcepsSwoopTween->getTweenValue();
//Quaternion rotation = glm::rotation(Vector3(0, 1, 0), triangle->normal); //Quaternion rotation = glm::rotation(Vector3(0, 1, 0), triangle->normal);
@ -199,29 +192,12 @@ void PlayState::execute()
// Set tool position // Set tool position
application->forcepsModelInstance.setTranslation(translation); application->forcepsModelInstance.setTranslation(translation);
application->forcepsModelInstance.setRotation(rotation); 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 // Update colony
if (!application->simulationPaused) if (!application->simulationPaused)
@ -252,7 +228,7 @@ void PlayState::exit()
application->defaultLayer->removeObject(&application->currentLevel->terrainSurface); application->defaultLayer->removeObject(&application->currentLevel->terrainSurface);
application->defaultLayer->removeObject(&application->currentLevel->terrainSubsurface); application->defaultLayer->removeObject(&application->currentLevel->terrainSubsurface);
application->defaultLayer->removeObject(&application->biomeFloorModelInstance); 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) for (std::size_t i = 0; i < application->colony->getAntCount(); ++i)
{ {
Ant* ant = application->colony->getAnt(i); Ant* ant = application->colony->getAnt(i);
@ -277,40 +253,7 @@ void PlayState::mouseButtonPressed(int button, int x, int y)
{ {
if (button == 1) 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<Agent*> ants;
pickAnt = nullptr;
float closestDistance = std::numeric_limits<float>::infinity();
application->colony->queryAnts(forcepsSphere, &ants);
for (Agent* agent: ants)
{
Ant* ant = static_cast<Ant*>(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) 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();
} }
} }

+ 0
- 4
src/states/play-state.hpp View File

@ -47,10 +47,6 @@ private:
Vector3 pick; Vector3 pick;
Ray pickingRay; Ray pickingRay;
Navmesh::Triangle* pickTriangle; Navmesh::Triangle* pickTriangle;
Ant* pickAnt;
Pose* forcepsPose;
float forcepsAnimationTime;
const Animation* forcepsAnimation;
}; };
#endif // PLAY_STATE_HPP #endif // PLAY_STATE_HPP

Loading…
Cancel
Save