From 9f831c7a6fc067e1fa86dacf6fa0da1941a24579 Mon Sep 17 00:00:00 2001 From: h4570 Date: Tue, 23 Aug 2022 22:18:53 +0200 Subject: [PATCH] finished 5 tutorial --- ROADMAP.txt | 3 +- tutorials/02-sprite/bin/tyra.png | Bin 0 -> 34899 bytes tutorials/05-animation/inc/tutorial_05.hpp | 11 +++ tutorials/05-animation/src/tutorial_05.cpp | 87 ++++++++++++++++++++- 4 files changed, 98 insertions(+), 3 deletions(-) create mode 100644 tutorials/02-sprite/bin/tyra.png diff --git a/ROADMAP.txt b/ROADMAP.txt index 3a242f4..a6f2a85 100644 --- a/ROADMAP.txt +++ b/ROADMAP.txt @@ -5,7 +5,7 @@ - [Tutorials] 7 - [Tutorials] 8 - [Tutorials] 9. -- [Renderer] Check ee clipping on de_dust2, add decimate to de_dust2? + - [General] Check all left TODOs -> Github issues - [General] Readme Credits: clipping, obj loader - [Video] How to setup environment @@ -19,6 +19,7 @@ - [Demo] BBox constructors - [General] Add cpp lint checker in GitHub / static code analysis - [General] Smart pointers and std::array instead of raw pointers +- [Renderer] Check ee clipping on de_dust2, add decimate to de_dust2? - [General] Control generated id to avoid duplication. Maybe Just increment from 0? Add interface IIdentificable? - [renderer] fog - [General] CI in Github via docker image diff --git a/tutorials/02-sprite/bin/tyra.png b/tutorials/02-sprite/bin/tyra.png new file mode 100644 index 0000000000000000000000000000000000000000..016f830bbd4de3a83d88f204415277ecc0db3c10 GIT binary patch literal 34899 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 UOVFVdQ&MBb@034l-j{pDw literal 0 HcmV?d00001 diff --git a/tutorials/05-animation/inc/tutorial_05.hpp b/tutorials/05-animation/inc/tutorial_05.hpp index 60a6289..21c7bc3 100644 --- a/tutorials/05-animation/inc/tutorial_05.hpp +++ b/tutorials/05-animation/inc/tutorial_05.hpp @@ -23,7 +23,18 @@ class Tutorial05 : public Game { void loop(); private: + void loadZombieMesh(); + void loadWarriorMesh(); + void warriorAnimationCallback(const AnimationSequenceCallback& callback); + Engine* engine; + + Vec4 cameraPosition, cameraLookAt; + + std::unique_ptr warriorMesh; + std::unique_ptr zombieMesh; + DynamicPipeline dynpip; + DynPipOptions renderOptions; }; } // namespace Tyra diff --git a/tutorials/05-animation/src/tutorial_05.cpp b/tutorials/05-animation/src/tutorial_05.cpp index 3eb49b6..b0ae989 100644 --- a/tutorials/05-animation/src/tutorial_05.cpp +++ b/tutorials/05-animation/src/tutorial_05.cpp @@ -17,8 +17,91 @@ Tutorial05::Tutorial05(Engine* t_engine) : engine(t_engine) {} Tutorial05::~Tutorial05() {} -void Tutorial05::init() {} +void Tutorial05::init() { + dynpip.setRenderer(&engine->renderer.core); -void Tutorial05::loop() {} + cameraPosition = Vec4(0.0F, 0.0F, -10.0F); + cameraLookAt.unit(); + + loadZombieMesh(); + loadWarriorMesh(); +} + +void Tutorial05::loop() { + zombieMesh->update(); // update animation state + warriorMesh->update(); + + engine->renderer.beginFrame(CameraInfo3D(&cameraPosition, &cameraLookAt)); + { + engine->renderer.renderer3D.usePipeline(dynpip); + + dynpip.render(zombieMesh.get(), renderOptions); + dynpip.render(warriorMesh.get(), renderOptions); + } + engine->renderer.endFrame(); +} + +void Tutorial05::loadZombieMesh() { + ObjLoaderOptions options; + options.scale = 20.0F; + options.flipUVs = true; + + /** If count is > 1, loader will automatically add _00000X suffix */ + options.animation.count = 6; + + /** Starting file suffix index. It means that 1 will start from _000001.obj */ + options.animation.startingIndex = 1; + + /** If you want to know how to cook this file, please watch tutorial video */ + auto data = ObjLoader::load(FileUtils::fromCwd("zombie/zombie.obj"), options); + + zombieMesh = std::make_unique(data.get()); + + zombieMesh->translation.translate(Vec4(-3.0F, -5.0F, 0.0F)); + zombieMesh->rotation.rotateY(3.0F); + + /** + * Tyra will play all frames by default. + * If you want to arrange animation frames by yourself, you can use this + * method. + */ + zombieMesh->animation.setSequence({3, 4, 5}); // fight animation + // zombieMesh->animation.setSequence({0, 1, 2}); // walk animation + + zombieMesh->animation.loop = true; + + engine->renderer.getTextureRepository().addByMesh( + zombieMesh.get(), FileUtils::fromCwd("zombie/"), "png"); +} + +void Tutorial05::loadWarriorMesh() { + MD2LoaderOptions options; + options.scale = .08F; + + auto data = + MD2Loader::load(FileUtils::fromCwd("warrior/warrior.md2"), options); + + warriorMesh = std::make_unique(data.get()); + + warriorMesh->translation.translate(Vec4(3.0F, -4.0F, 0.0F)); + warriorMesh->rotation.rotateX(-1.566F); + warriorMesh->rotation.rotateY(1.566F); + + warriorMesh->animation.speed = 0.2F; + + /** Callback can return useful animation informations */ + warriorMesh->animation.setCallback(std::bind( + &Tutorial05::warriorAnimationCallback, this, std::placeholders::_1)); + + engine->renderer.getTextureRepository().addByMesh( + warriorMesh.get(), FileUtils::fromCwd("warrior/"), "png"); +} + +void Tutorial05::warriorAnimationCallback( + const AnimationSequenceCallback& callback) { + if (callback == AnimationSequenceCallback_Loop) { + TYRA_LOG("Warrior animation sequence is starting from beginning!"); + } +} } // namespace Tyra