Skip to content

Commit

Permalink
Last from lenovo
Browse files Browse the repository at this point in the history
  • Loading branch information
Dante-666 committed Jun 23, 2021
1 parent df132bf commit d89070f
Show file tree
Hide file tree
Showing 10 changed files with 408 additions and 58 deletions.
24 changes: 24 additions & 0 deletions AnimNavMeshAgent.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include "AnimNavMeshAgent.h"
#include <new>

NS_CC_BEGIN

AnimNavMeshAgent* AnimNavMeshAgent::create(const NavMeshAgentParam &param) {
auto agent = new (std::nothrow) AnimNavMeshAgent();
if(agent && agent->initWith(param)) {
agent->autorelease();
return agent;
}
CC_SAFE_DELETE(agent);
return nullptr;
}

const Vec3 &AnimNavMeshAgent::getDestination() { return _destination; }
const Vec3 &AnimNavMeshAgent::getOrigination() { return _origination; }

const Vec3 &AnimNavMeshAgent::getPosition() {
auto agent = _crowd->getAgent(_agentID);
_position = Vec3(agent->npos);
return _position;
}
NS_CC_END
18 changes: 18 additions & 0 deletions AnimNavMeshAgent.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#pragma once

#include "navmesh/CCNavMeshAgent.h"

NS_CC_BEGIN

/** I had to modify the original class since all its memebers were private and
* makes the callback pretty much useless
*/
class AnimNavMeshAgent : public NavMeshAgent {
Vec3 _position;
public:
static AnimNavMeshAgent *create(const NavMeshAgentParam &);
const Vec3 &getDestination();
const Vec3 &getOrigination();
const Vec3 &getPosition();
};
NS_CC_END
80 changes: 80 additions & 0 deletions AnimatedSprite3D.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#include "AnimatedSprite3D.h"
#include "ccMacros.h"
#include <functional>
#include <iostream>
#include <ratio>

NS_CC_BEGIN

AnimatedSprite3D::AnimatedSprite3D() : AnimationManager{}, AnimationMSM{this} {};

AnimatedSprite3D *AnimatedSprite3D::create(const std::string &modelPath) {

auto sprite = new (std::nothrow) AnimatedSprite3D();

std::unordered_map<AnimationType, const std::string> anim2strMap;
anim2strMap.insert({AnimationType::IDLE, "CharacterArmature|Idle"});
anim2strMap.insert({AnimationType::WALK, "CharacterArmature|Walk"});
anim2strMap.insert({AnimationType::RUN, "CharacterArmature|Run"});

sprite->initAnimations(modelPath, anim2strMap);

NavMeshAgentParam param;
param.radius = 0.5;
param.height = 8;
param.maxSpeed = 10;
param.maxAcceleration = 100;
auto agent = AnimNavMeshAgent::create(param);

if (sprite && sprite->initWithFile(modelPath) &&
sprite->addComponent(agent)) {
sprite->_contentSize = sprite->getBoundingBox().size;
sprite->autorelease();
sprite->setRotation3D(Vec3{0, M_PI / 2, 0});
sprite->setScale(1. / 5);
sprite->setCameraMask((unsigned int)CameraFlag::USER1);

return sprite;
}
CC_SAFE_DELETE(sprite);
return nullptr;
}

bool AnimatedSprite3D::addComponent(Component *agent) {
auto navAgent = static_cast<AnimNavMeshAgent *>(agent);
CCASSERT(navAgent != nullptr,
"AnimatedSprite3D only supports AnimNavMeshAgent");
if (Node::addComponent(agent)) {
_agent = navAgent;
return true;
}
return false;
}

void AnimatedSprite3D::move(const Vec3 &target) {
// it is here that we must define the animation interpolations
if (_agent) {
_agent->move(target,
std::bind(&AnimatedSprite3D::moveCallback, this,
std::placeholders::_1, std::placeholders::_2));
}
}

void AnimatedSprite3D::moveCallback(NavMeshAgent *agent,
float totalTimeAfterMove) {
auto navAgent = static_cast<AnimNavMeshAgent *>(agent);
auto origin = navAgent->getOrigination();
auto dest = navAgent->getDestination();
auto pos = navAgent->getPosition();
static float startBound = 1.0f;
static float stopBound = 0.35f;
if (pos.distance(origin) < startBound) {
// std::cout << "close to origin" << std::endl;
} else if (pos.distance(dest) < startBound &&
(pos - dest).length() > stopBound) {
// std::cout << "close to dest" << std::endl;
} else {
}
}

NS_CC_END
36 changes: 36 additions & 0 deletions AnimatedSprite3D.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#pragma once

#include "AnimNavMeshAgent.h"
#include "AnimationManager.h"
#include "cocos2d.h"

NS_CC_BEGIN

/** This sprite is the base class for all different types of characters. The
* primary functionality of this class is to support animations and different
* texture maps for the main character and their weapons.
*
* The final children classes would handle character level ups and other RPG
* interactions like collision and who hit who should belong to some other
* class.
*/
class AnimatedSprite3D : public Sprite3D,
public AnimationMSM,
public AnimationManager {
AnimNavMeshAgent *_agent = nullptr;

public:
AnimatedSprite3D();

static AnimatedSprite3D *create(const std::string &);

virtual bool addComponent(Component *) override;

void move(const Vec3 &);

void moveCallback(NavMeshAgent *, float);

friend class AnimationMSM;
};

NS_CC_END
74 changes: 74 additions & 0 deletions AnimationMSM.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#include "AnimationMSM.h"

#include <functional>
#include <iostream>
#include <utility>

NS_CC_BEGIN

using State = AnimationMSM::State;

State &State::operator=(State &&other) { return other; }

const State &State::onTrigger(const AnimationTrigger &trigger,
const AnimationMSM &msm) const {
auto it = _outMap.find(trigger);
if (it != _outMap.end()) {
it->second.first(msm._sprite);
return it->second.second;
} else {
return *this;
}
};

void State::registerTransition(const AnimationTrigger &trigger,
transition &&trans, const State &state) {
std::reference_wrapper<State> rs = const_cast<State &>(state);
std::reference_wrapper<transition> rtrans = trans;
_outMap.emplace(trigger, std::make_pair(rtrans, rs));
}

AnimationMSM::AnimationMSM(Sprite3D *const sprite) : _sprite(sprite) {

// vector doesn't hold references
// fix this?
_states.emplace_back(State(AnimationType::DEFAULT));
_states.emplace_back(State(AnimationType::IDLE));
_states.emplace_back(State(AnimationType::WALK));
_states.emplace_back(State(AnimationType::RUN));

_curr = &_states[0];

_states[0].registerTransition(
AnimationTrigger::DEFAULT2IDLE, std::move([](Sprite3D *animSprite) {
std::cout << "starting to idle" << std::endl;
}),
_states[1]);
_states[1].registerTransition(
AnimationTrigger::IDLE2WALK, std::move([](Sprite3D *animSprite) {
std::cout << "starting to walk" << std::endl;
}),
_states[2]);
/*
_states[2].registerTransition(
AnimationTrigger::WALK2RUN,
Transition([](int x) { std::cout << "starting to run" << std::endl; },
_states[3]));
_states[3].registerTransition(
AnimationTrigger::RUN2IDLE,
Transition([](int x) { std::cout << "starting to idle" << std::endl; },
_states[1]));*/

_sprite->retain();
};

AnimationMSM::~AnimationMSM() {
_sprite->release();
_curr = nullptr;
_states.clear();
}

void AnimationMSM::switchState(const AnimationTrigger &trigger) {
_curr = &const_cast<State &>(_curr->onTrigger(trigger, *this));
}
NS_CC_END
66 changes: 66 additions & 0 deletions AnimationMSM.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#pragma once

#include "cocos2d.h"
#include <unordered_map>
#include <vector>

NS_CC_BEGIN

enum class AnimationType { DEFAULT, IDLE, WALK, RUN };

enum class AnimationTrigger { DEFAULT2IDLE, IDLE2WALK, WALK2RUN, RUN2IDLE };

typedef std::function<void(Sprite3D *)> transition;

class AnimationMSM {

public:
AnimationMSM(Sprite3D *const);
~AnimationMSM();

void switchState(const AnimationTrigger &trigger);

/* This class is meant to store the state of the object and the
* actions will be performed when state transitions happen via a
* callback
*/
class State {
AnimationType _type;
std::unordered_map<AnimationTrigger, std::pair<transition, State &>>
_outMap;

public:
State(const AnimationType &type) : _type(type){};
~State() = default;

/* Delete any copy supporting operations */
State(const State &) = delete;
State &operator=(const State &other) = delete;

/* Move should still be supported */
State(State &&) = default;
State &operator=(State &&other);

const AnimationType &getType() const { return _type; }
const State &onTrigger(const AnimationTrigger &,
const AnimationMSM &) const;
void registerTransition(const AnimationTrigger &, transition &&,
const State &);
};

/* These states are temporary and they work not on user given trigger, but
* rather a time based trigger. When the required time has elapsed, we
* transition to the next required state
*/
class QuasiState : State {
public:
QuasiState(const AnimationType &type) : State(type){};
};

private:
std::vector<State> _states;
const State *_curr;
Sprite3D *const _sprite;
};

NS_CC_END
49 changes: 49 additions & 0 deletions AnimationManager.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#include "AnimationManager.h"
#include "AnimatedSprite3D.h"

NS_CC_BEGIN

AnimationManager::AnimationManager() {};

AnimationManager::~AnimationManager() {
// Decrement the reference count for auto-deletion
for (auto item : _animationMap) {
item.second->release();
}
_animationMap.clear();
}

bool AnimationManager::initAnimations(
const std::string &modelPath,
const std::unordered_map<AnimationType, const std::string> &type2strMap) {
_modelPath = modelPath;

std::string fullPath =
FileUtils::getInstance()->fullPathForFilename(modelPath);

auto bundle = Bundle3D::createBundle();
bool retVal = true;

for (auto type2str : type2strMap) {
Animation3DData animationData;
Animation3D *animation = new Animation3D();

if (bundle->load(fullPath) &&
bundle->loadAnimationData(type2str.second, &animationData) &&
animation->init(animationData)) {
// Do this or else it will be cleaned up immediately
animation->retain();
// If everything loads correctly, insert it into the map
_animationMap.insert({type2str.first, animation});
} else {
retVal = false;
}
}
return retVal;
};

Animation3D* AnimationManager::getAnimation(AnimationType type) {
return _animationMap[type];
}

NS_CC_END
26 changes: 26 additions & 0 deletions AnimationManager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#pragma once

#include "3d/CCBundle3D.h"
#include "AnimationMSM.h"
#include "ccMacros.h"
#include "cocos2d.h"
#include <unordered_map>

NS_CC_BEGIN

class AnimationManager {
std::string _modelPath;
std::unordered_map<AnimationType, Animation3D *> _animationMap;

public:
AnimationManager();
~AnimationManager();

bool initAnimations(
const std::string &,
const std::unordered_map<AnimationType, const std::string> &);

Animation3D *getAnimation(AnimationType);
};

NS_CC_END
Loading

0 comments on commit d89070f

Please sign in to comment.