From f64a3e13df12ee32927d0bebc65b93f145d6edc2 Mon Sep 17 00:00:00 2001 From: devZoGok Date: Tue, 1 Mar 2022 20:51:40 +0200 Subject: [PATCH] Animation controller uses now the singleton pattern --- animationChannelTest.cpp | 4 ++-- animationController.cpp | 13 +++++++++++++ animationController.h | 4 ++-- animationControllerTest.cpp | 4 ++-- boneTest.cpp | 2 +- driverSample.cpp | 4 ++-- ikSolverTest.cpp | 2 +- lightSample.cpp | 4 ++-- morphAnimationSample.cpp | 2 +- node.cpp | 5 +---- node.h | 5 +---- root.cpp | 3 +++ skeletalAnimationSample.cpp | 2 +- skeleton.cpp | 4 +--- skeleton.h | 5 +---- textSample.cpp | 4 ++-- vbModelReader.cpp | 19 ++++++++----------- vbModelReader.h | 2 +- vbModelReaderTest.cpp | 2 +- 19 files changed, 46 insertions(+), 44 deletions(-) diff --git a/animationChannelTest.cpp b/animationChannelTest.cpp index 60f33e6..b32db68 100644 --- a/animationChannelTest.cpp +++ b/animationChannelTest.cpp @@ -12,9 +12,9 @@ using namespace std; namespace vb01{ void AnimationChannelTest::setUp(){ Bone *bone = new Bone("bone", 1, Vector3(0, 0, 0), Quaternion::QUAT_I, Vector3::VEC_IJK); - skeleton = new Skeleton(new AnimationController()); + skeleton = new Skeleton(); skeleton->addBone(bone, nullptr); - AnimationController *controller = skeleton->getAnimationController(); + AnimationController *controller = AnimationController::getSingleton(); Keyframe k1, k2; k1.frame = 0; diff --git a/animationController.cpp b/animationController.cpp index e0dd0b1..2778836 100644 --- a/animationController.cpp +++ b/animationController.cpp @@ -5,6 +5,15 @@ using namespace std; namespace vb01{ + static AnimationController *animationController = nullptr; + + AnimationController* AnimationController::getSingleton(){ + if(!animationController) + animationController = new AnimationController(); + + return animationController; + } + void AnimationController::update(){ for(AnimationChannel *channel : channels){ channel->update(); @@ -14,8 +23,10 @@ namespace vb01{ void AnimationController::transform(AnimationChannel *channel){ Animation *animation = getAnimation(channel->getAnimationName()); + for(Animatable *animatable : channel->getAnimatables()){ vector keyframeChannels = animation->getKeyframeChannelsByAnimatable(animatable); + for(KeyframeChannel keyframeChannel : keyframeChannels){ int currentFrame = channel->getCurrentFrame(); Keyframe pastKeyframe = KeyframeChannel::findKeyframe(currentFrame, keyframeChannel, true); @@ -33,11 +44,13 @@ namespace vb01{ Animation* AnimationController::getAnimation(string name){ Animation *anim = nullptr; + for(Animation *a : animations) if(a->getName() == name){ anim = a; break; } + return anim; } diff --git a/animationController.h b/animationController.h index f93bed8..0063344 100644 --- a/animationController.h +++ b/animationController.h @@ -15,8 +15,7 @@ namespace vb01{ class AnimationController{ public: - AnimationController(){} - ~AnimationController(){} + static AnimationController* getSingleton(); void update(); Animation* getAnimation(std::string); void addAnimationChannel(AnimationChannel *channel); @@ -26,6 +25,7 @@ namespace vb01{ std::vector animations; std::vector channels; + AnimationController(){} void transform(AnimationChannel*); protected: void onAnimationEnd(std::string){} diff --git a/animationControllerTest.cpp b/animationControllerTest.cpp index cfececb..8198e2c 100644 --- a/animationControllerTest.cpp +++ b/animationControllerTest.cpp @@ -31,7 +31,7 @@ namespace vb01{ kg.bone = bone; kg.keyframeChannels = vector({ch0, ch1}); - controller = skeleton->getAnimationController(); + controller = AnimationController::getSingleton(); Animation *anim = new Animation("anim"); anim->addKeyframeGroup(kg); controller->addAnimation(anim); @@ -45,7 +45,7 @@ namespace vb01{ void AnimationControllerTest::setUp(){ Node *rootNode = Root::getSingleton()->getRootNode(); - skeleton = new Skeleton(new AnimationController()); + skeleton = new Skeleton(); Bone *bone = new Bone("bone", 1.f, Vector3::VEC_ZERO, Quaternion::QUAT_W, Vector3::VEC_IJK); skeleton->addBone(bone, (Bone*)rootNode); diff --git a/boneTest.cpp b/boneTest.cpp index b972687..c3373e1 100644 --- a/boneTest.cpp +++ b/boneTest.cpp @@ -15,7 +15,7 @@ namespace vb01{ rootNode->attachChild(modelNodeParent); modelNodeParent->attachChild(modelNode); - skeleton = new Skeleton(new AnimationController()); + skeleton = new Skeleton(); Bone *rootBone = new Bone("rootBone", 1, Vector3::VEC_ZERO, Quaternion::QUAT_W, Vector3::VEC_IJK); Bone *pelvis = new Bone("pelvis", 1, Vector3(0, 2, 0), Quaternion::QUAT_W, Vector3::VEC_IJK); diff --git a/driverSample.cpp b/driverSample.cpp index 9c01391..e5fbb6f 100644 --- a/driverSample.cpp +++ b/driverSample.cpp @@ -40,7 +40,7 @@ int main(){ * Populate the scene with cubes */ Box *driverBox = new Box(Vector3(1, 1, 1) * .25); - Node *driver = new Node(Vector3::VEC_ZERO, Quaternion::QUAT_W, Vector3::VEC_IJK, "", new AnimationController()); + Node *driver = new Node(Vector3::VEC_ZERO, Quaternion::QUAT_W, Vector3::VEC_IJK, ""); Material *driverMat = new Material(PATH + "texture"); driverMat->addBoolUniform("texturingEnabled", false); driverMat->addVec4Uniform("diffuseColor", Vector4(0, 1, 0, 1)); @@ -113,7 +113,7 @@ int main(){ * The AnimationController plays the animations set in the AnimationChannel objects. * AnimationChannel objects require an animation and animatable objects, e.g. textures to work. */ - AnimationController *controller = driver->getAnimationController(); + AnimationController *controller = AnimationController::getSingleton(); controller->addAnimation(anim); AnimationChannel *channel = new AnimationChannel(); controller->addAnimationChannel(channel); diff --git a/ikSolverTest.cpp b/ikSolverTest.cpp index d4daf1e..73c9aef 100644 --- a/ikSolverTest.cpp +++ b/ikSolverTest.cpp @@ -7,7 +7,7 @@ namespace vb01{ void IkSolverTest::setUp(){ rootNode = Root::getSingleton()->getRootNode(); - skeleton = new Skeleton(new AnimationController()); + skeleton = new Skeleton(); Bone *boneA = new Bone("A", 1, Vector3::VEC_ZERO, Quaternion::QUAT_W, Vector3::VEC_IJK); Bone *boneB = new Bone("B", 1, Vector3::VEC_J, Quaternion::QUAT_W, Vector3::VEC_IJK); diff --git a/lightSample.cpp b/lightSample.cpp index 58ea8cc..2ed6cc5 100644 --- a/lightSample.cpp +++ b/lightSample.cpp @@ -74,7 +74,7 @@ int main(){ Light *light = new Light(Light::SPOT); light->setColor(Vector3(1, 1, 1)); - Node *lightNode = new Node(Vector3::VEC_ZERO, Quaternion::QUAT_W, Vector3::VEC_IJK, "", new AnimationController()); + Node *lightNode = new Node(Vector3::VEC_ZERO, Quaternion::QUAT_W, Vector3::VEC_IJK, ""); lightNode->addLight(light); rootNode->attachChild(lightNode); lightNode->setOrientation(Quaternion(.7, Vector3(1, 0, 0))); @@ -111,7 +111,7 @@ int main(){ * The AnimationController plays the animations set in the AnimationChannel objects. * AnimationChannel objects require an animation and animatable objects, e.g. textures to work. */ - AnimationController *controller = lightNode->getAnimationController(); + AnimationController *controller = AnimationController::getSingleton(); controller->addAnimation(animation); AnimationChannel *channel = new AnimationChannel(); controller->addAnimationChannel(channel); diff --git a/morphAnimationSample.cpp b/morphAnimationSample.cpp index 2f6684b..48e525e 100644 --- a/morphAnimationSample.cpp +++ b/morphAnimationSample.cpp @@ -58,7 +58,7 @@ int main(){ * The AnimationController plays the animations set in the AnimationChannel objects. * AnimationChannel objects require an animation and animatable objects, e.g. textures to work. */ - AnimationController *controller = skeleton->getAnimationController(); + AnimationController *controller = AnimationController::getSingleton(); AnimationChannel *channel = new AnimationChannel(); controller->addAnimationChannel(channel); channel->addAnimatable(skeleton->getBone("bone")); diff --git a/node.cpp b/node.cpp index b9eb8b0..49a273c 100755 --- a/node.cpp +++ b/node.cpp @@ -15,12 +15,11 @@ using namespace std; using namespace glm; namespace vb01{ - Node::Node(Vector3 pos, Quaternion orientation, Vector3 scale, string name, AnimationController *controller) : Animatable(){ + Node::Node(Vector3 pos, Quaternion orientation, Vector3 scale, string name) : Animatable(){ this->pos = pos; this->scale = scale; this->orientation = orientation; this->name = name; - this->controller = controller; globalAxis[0] = Vector3::VEC_I; globalAxis[1] = Vector3::VEC_J; @@ -54,8 +53,6 @@ namespace vb01{ c->update(); for(ParticleEmitter *p : emitters) p->update(); - if(controller) - controller->update(); } for(Driver *driver : drivers) driver->drive(getDriverValue(driver->getType())); diff --git a/node.h b/node.h index 1ae1f7a..fc82d75 100755 --- a/node.h +++ b/node.h @@ -16,11 +16,10 @@ namespace vb01{ class Light; class ParticleEmitter; class Text; - class AnimationController; class Node : public Animatable{ public: - Node(Vector3 = Vector3::VEC_ZERO, Quaternion = Quaternion::QUAT_W, Vector3 = Vector3::VEC_IJK, std::string = "", AnimationController *c = nullptr); + Node(Vector3 = Vector3::VEC_ZERO, Quaternion = Quaternion::QUAT_W, Vector3 = Vector3::VEC_IJK, std::string = ""); virtual ~Node(); void attachMesh(Mesh*); void attachParticleEmitter(ParticleEmitter*); @@ -63,14 +62,12 @@ namespace vb01{ inline std::string getName(){return name;} inline void setVisible(bool v){this->visible = v;} inline void addDriver(Driver *d){drivers.push_back(d);} - inline AnimationController* getAnimationController(){return controller;} private: void adjustUp(Vector3); void adjustDir(Vector3); void updateShaders(); Quaternion adjustRot(std::vector, Quaternion, bool); - AnimationController *controller = nullptr; std::vector drivers; protected: virtual void animate(float, KeyframeChannel); diff --git a/root.cpp b/root.cpp index bc04e57..9aa0328 100755 --- a/root.cpp +++ b/root.cpp @@ -5,6 +5,7 @@ #include "box.h" #include "quad.h" #include "lineRenderer.h" +#include "animationController.h" #include "glad.h" #include @@ -150,6 +151,8 @@ namespace vb01{ glCullFace(GL_BACK); } + AnimationController::getSingleton()->update(); + rootNode->update(); LineRenderer::getSingleton()->drawLines(); diff --git a/skeletalAnimationSample.cpp b/skeletalAnimationSample.cpp index 3c4c57d..42a9f3e 100644 --- a/skeletalAnimationSample.cpp +++ b/skeletalAnimationSample.cpp @@ -58,7 +58,7 @@ int main(){ * The AnimationController plays the animations set in the AnimationChannel objects. * AnimationChannel objects require an animation and animatable objects, e.g. textures to work. */ - AnimationController *controller = skeleton->getAnimationController(); + AnimationController *controller = AnimationController::getSingleton(); AnimationChannel *channel = new AnimationChannel(); controller->addAnimationChannel(channel); channel->addAnimatable(skeleton->getBone("handIK.R")); diff --git a/skeleton.cpp b/skeleton.cpp index ac4dc35..617a338 100644 --- a/skeleton.cpp +++ b/skeleton.cpp @@ -11,14 +11,12 @@ using namespace std; using namespace glm; namespace vb01{ - Skeleton::Skeleton(AnimationController *controller, string name){ + Skeleton::Skeleton(string name){ this->name = name; - this->controller = controller; } void Skeleton::update(){ updateIk(); - controller->update(); } void Skeleton::updateIk(){ diff --git a/skeleton.h b/skeleton.h index ce4bdde..9674347 100644 --- a/skeleton.h +++ b/skeleton.h @@ -8,15 +8,13 @@ namespace vb01{ class Animation; - class AnimationController; class Skeleton{ public: - Skeleton(AnimationController*, std::string = ""); + Skeleton(std::string = ""); void update(); void addBone(Bone*, Bone*); Bone* getBone(std::string); - inline AnimationController* getAnimationController(){return controller;} inline Bone* getBone(int i){return bones[i];} inline Bone* getRootBone(){return bones[0];} inline std::vector& getBones(){return bones;} @@ -30,7 +28,6 @@ namespace vb01{ std::string name; std::vector bones; - AnimationController *controller = nullptr; }; } diff --git a/textSample.cpp b/textSample.cpp index e6d4c93..c113e3a 100644 --- a/textSample.cpp +++ b/textSample.cpp @@ -65,7 +65,7 @@ int main(){ text->setHorizontal(horizontal[i]); text->setMaterial(textMat); - Node *textNode = new Node(Vector3(0, 50 * (i + 1), 0), Quaternion::QUAT_W, Vector3::VEC_IJK, "", new AnimationController()); + Node *textNode = new Node(Vector3(0, 50 * (i + 1), 0), Quaternion::QUAT_W, Vector3::VEC_IJK, ""); textNode->addText(text); guiNode->attachChild(textNode); @@ -103,7 +103,7 @@ int main(){ * The AnimationController plays the animations set in the AnimationChannel objects. * AnimationChannel objects require an animation and animatable objects, e.g. textures to work. */ - AnimationController *controller = textNode->getAnimationController(); + AnimationController *controller = AnimationController::getSingleton(); controller->addAnimation(anim); AnimationChannel *channel = new AnimationChannel(); controller->addAnimationChannel(channel); diff --git a/vbModelReader.cpp b/vbModelReader.cpp index b307c1b..06fd1a0 100644 --- a/vbModelReader.cpp +++ b/vbModelReader.cpp @@ -268,7 +268,7 @@ namespace vb01{ return keyframeChannel; } - void VbModelReader::readAnimations(Animatable *animatable, AnimationController *controller, vector &animationData){ + void VbModelReader::readAnimations(Animatable *animatable, vector &animationData){ int numAnimations = atoi(animationData[0].substr(animationData[0].find_first_of(':') + 2).c_str()); int animStartLine = 1; @@ -279,7 +279,7 @@ namespace vb01{ currentAnim = data[0]; Animation *animation = new Animation(currentAnim); - controller->addAnimation(animation); + AnimationController::getSingleton()->addAnimation(animation); int numKeyframeChannels = atoi(data[1].c_str()); int keyframeChannelStartLine = animStartLine + 1; @@ -331,8 +331,7 @@ namespace vb01{ int animationStartLine = boneStartLine + numBones; int driverStartLine = findDriverStartLine(skeletonData, animationStartLine); - AnimationController *controller = new AnimationController(); - Skeleton *skeleton = new Skeleton(controller, name); + Skeleton *skeleton = new Skeleton(name); currentSkeleton = skeleton; vector skeletonSubData = vector(skeletonData.begin() + boneStartLine, skeletonData.begin() + boneStartLine + numBones); @@ -340,7 +339,7 @@ namespace vb01{ skeletonSubData.clear(); skeletonSubData = vector(skeletonData.begin() + animationStartLine, skeletonData.begin() + driverStartLine); - readAnimations(nullptr, controller, skeletonSubData); + readAnimations(nullptr, skeletonSubData); skeletonSubData.clear(); skeletonSubData = vector(skeletonData.begin() + driverStartLine, skeletonData.end()); @@ -536,12 +535,11 @@ namespace vb01{ getLineData(meshData[3].substr(meshData[3].find_first_of(':') + 2), data, 3); Vector3 scale = Vector3(atof(data[0].c_str()), atof(data[1].c_str()), atof(data[2].c_str())); - AnimationController *controller = new AnimationController(); - Node *node = new Node(pos, rot, scale, name, controller); + Node *node = new Node(pos, rot, scale, name); nodes.push_back(node); meshSubData = vector(meshData.begin() + animationStartLine, meshData.begin() + driverStartLine); - readAnimations(node, controller, meshSubData); + readAnimations(node, meshSubData); meshSubData.clear(); meshSubData = vector(meshData.begin() + driverStartLine, meshData.end()); @@ -604,15 +602,14 @@ namespace vb01{ light->setInnerAngle(innerAngle); currentLight = light; - AnimationController *controller = new AnimationController(); - Node *node = new Node(pos, rot, scale, name, controller); + Node *node = new Node(pos, rot, scale, name); node->addLight(light); nodes.push_back(node); int animationStartLine = 9; int driverStartLine = findDriverStartLine(lightData, animationStartLine); vector lightSubData = vector(lightData.begin() + animationStartLine, lightData.begin() + driverStartLine); - readAnimations(node, controller, lightSubData); + readAnimations(node, lightSubData); lightSubData.clear(); lightSubData = vector(lightData.begin() + driverStartLine, lightData.end()); diff --git a/vbModelReader.h b/vbModelReader.h index 65fbeee..3572a36 100644 --- a/vbModelReader.h +++ b/vbModelReader.h @@ -27,7 +27,7 @@ namespace vb01{ int findDriverStartLine(std::vector&, int); void createBones(Skeleton*, std::vector&); KeyframeChannel readKeyframeChannel(Animatable*, std::vector&, int&); - void readAnimations(Animatable*, AnimationController*, std::vector&); + void readAnimations(Animatable*, std::vector&); Skeleton* readSkeleton(std::vector&); void readVertices(std::vector&, std::vector&, std::vector&, std::vector&, int); void readFaces(std::vector&, std::vector&, std::vector&, std::vector&, std::vector&, int, Mesh::Vertex*, u32*); diff --git a/vbModelReaderTest.cpp b/vbModelReaderTest.cpp index 5f391eb..322d06a 100644 --- a/vbModelReaderTest.cpp +++ b/vbModelReaderTest.cpp @@ -176,7 +176,7 @@ namespace vb01{ else CPPUNIT_ASSERT(bones[i].parent == "-"); } - AnimationController *controller = skeleton->getAnimationController(); + AnimationController *controller = AnimationController::getSingleton(); string animNames[]{"Action", "open"}; CPPUNIT_ASSERT(controller->getAnimation(animNames[0])); CPPUNIT_ASSERT(controller->getAnimation(animNames[1]));