diff --git a/src/tsr/entity_model.cpp b/src/tsr/entity_model.cpp index 4b5e67a..3427493 100644 --- a/src/tsr/entity_model.cpp +++ b/src/tsr/entity_model.cpp @@ -15,11 +15,6 @@ void ModelSystem::AddModel(entt::entity ent, const std::string& name) { comp.bone_transforms[1].resize(num_bones); } - //if (comp.model->HasAnimations()) - // reg.emplace_or_replace(ent); - //else - // reg.erase(ent); - comp.ctx.model_matrix = glm::mat4(1.0f); for (int i = 0; i < TSR_NUM_COLORS; ++i) @@ -27,7 +22,6 @@ void ModelSystem::AddModel(entt::entity ent, const std::string& name) { comp.spawned_at = Game::FrameNum(); - //auto& bone_transforms = comp.bone_transforms[1 - (Game::FrameNum() % 2)]; for (auto& t : comp.bone_transforms[0]) IdentityTransform(t); @@ -48,20 +42,35 @@ void TSR::ModelSystem::RemoveModel(entt::entity ent) { //reg.erase(ent); } -void ModelSystem::Anim(entt::entity ent, const std::string& anim_name, float t) { +void ModelSystem::Anim(entt::entity ent, const std::string& anim_name, float t, float fade_in_time) { auto& comp = Game::Registry().get(ent); auto id = comp.model->GetAnimId(anim_name); auto& anim = comp.animations[id]; anim.t = t; + if (fade_in_time > 0.0f) { + anim.state = AS_FADING_IN; + anim.fade_time = fade_in_time; + anim.weight = 0.0f; + } + else { + anim.state = AS_PLAYING; + anim.weight = 1.0f; + } } -void ModelSystem::StopAnim(entt::entity ent, const std::string& anim_name) { +void ModelSystem::StopAnim(entt::entity ent, const std::string& anim_name, float fade_out_time) { auto& comp = Game::Registry().get(ent); auto id = comp.model->GetAnimId(anim_name); - comp.animations.erase(id); + if (fade_out_time > 0.0f) { + auto& anim = comp.animations[id]; + anim.state = AS_FADING_OUT; + anim.fade_time = fade_out_time; + } + else + comp.animations.erase(id); } void ModelSystem::Animate() { @@ -86,6 +95,21 @@ void ModelSystem::Animate() { const auto& anim = model.model->GetAnim(it->first); auto& anim_data = it->second; + if (anim_data.state == AS_FADING_IN) { + anim_data.weight += frame_time / anim_data.fade_time; + if (anim_data.weight >= 1.0f) { + anim_data.weight = 1.0f; + anim_data.state = AS_PLAYING; + } + } + else if (anim_data.state == AS_FADING_OUT) { + anim_data.weight -= frame_time / anim_data.fade_time; + if (anim_data.weight <= 0.0f) { + anim_data.weight = 0.0f; + remove = true; + } + } + anim_data.t += anim.tps * frame_time; if (anim_data.t > anim.duration) { @@ -112,12 +136,9 @@ void ModelSystem::Animate() { const auto& frame1 = anim.skel->Channels()[i].frames[fr1]; const auto& frame2 = anim.skel->Channels()[i].frames[fr2]; - //auto& trans = bone_transforms[anim.bone_ids[i]]; - //trans.pos = glm::mix(frame1.pos, frame2.pos, t); - //trans.rot = glm::slerp(frame1.rot, frame2.rot, t); - //trans.scl = glm::mix(frame1.scl, frame2.scl, t); - - bone_transforms[anim.bone_ids[i]] = MixTransforms(frame1, frame2, t); + auto& cur_transform = bone_transforms[anim.bone_ids[i]]; + cur_transform = MixTransforms(cur_transform, MixTransforms(frame1, frame2, t), anim_data.weight); + } } @@ -131,8 +152,6 @@ void ModelSystem::Animate() { } static void CreateTransMatFast(glm::mat4& trans_mat, const Transform& trans) { - //glm::mat4 trans_mat(1.0f); - float x = trans.rot.x; float y = trans.rot.y; float z = trans.rot.z; @@ -158,63 +177,38 @@ static void CreateTransMatFast(glm::mat4& trans_mat, const Transform& trans) { trans_mat[0][0] = (1.0f - (yy + zz)) * sx; trans_mat[0][1] = (xy + wz) * sx; trans_mat[0][2] = (xz - wy) * sx; - //trans_mat[0][2] = 0.0f; trans_mat[1][0] = (xy - wz) * sy; trans_mat[1][1] = (1.0f - (xx + zz)) * sy; trans_mat[1][2] = (yz + wx) * sy; - //trans_mat[1][3] = 0.0f; trans_mat[2][0] = (xz + wy) * sz; trans_mat[2][1] = (yz - wx) * sz; trans_mat[2][2] = (1.0f - (xx + yy)) * sz; - //trans_mat[2][3] = 0.0f; trans_mat[3][0] = trans.pos.x; trans_mat[3][1] = trans.pos.y; trans_mat[3][2] = trans.pos.z; - //trans_mat[3][3] = 1.0f; - - //return trans_mat; } void ModelSystem::Render(TSR::Renderer& renderer) { - //auto v = World::Registry().view(); - //for (auto [ent, mesh, render, trans] : v.each()) { - // render.ctx.m_model_matrix = glm::toMat4(trans.rot) * glm::translate(glm::mat4(1.0f), trans.pos); - // - // for (auto& drawable : mesh.parts) - // renderer.Add(TSR::DrawRef(&drawable, &render.ctx)); - - - //} - auto frame_t = Game::FrameT(); auto frame_idx0 = Game::FrameNum() % 2; auto frame_idx1 = 1 - frame_idx0; - //glm::mat4 identity(1.0f); - auto v = Game::Registry().view(); for (auto [ent, model, trans] : v.each()) { // no second buffer if (model.spawned_at >= Game::FrameNum() - 1) continue; - - //auto translation = glm::translate(glm::mat4(1.0f), glm::mix(trans.pos[frame_idx0], trans.pos[frame_idx1], frame_t)); - //auto rotation = glm::toMat4(glm::normalize(glm::slerp(trans.rot[frame_idx0], trans.rot[frame_idx1], frame_t))); - //model.ctx.model_matrix = translation * rotation; const auto& trans1 = model.trans[frame_idx0]; const auto& trans2 = model.trans[frame_idx1]; CreateTransMatFast(model.ctx.model_matrix, MixTransforms(trans1, trans2, frame_t)); - // temp - renderer.AddDebugLine(model.ctx.model_matrix[3], model.ctx.model_matrix[3] + glm::vec4(0.0f, 1.0f, 0.0f, 0.0f), glm::vec3(1.0f, 0.0f, 0.0f)); - if (model.model->IsSkeletal() && !Window::KeyDown(GLFW_KEY_V)) { auto& sk_bones = model.model->GetSkeleton().Bones(); @@ -225,18 +219,6 @@ void ModelSystem::Render(TSR::Renderer& renderer) { const auto& frame1 = bone_transforms0[i]; const auto& frame2 = bone_transforms1[i]; - //auto pos = glm::mix(frame1.pos, frame2.pos, frame_t); - //auto rot = glm::slerp(frame1.rot, frame2.rot, frame_t); - //auto scl = glm::mix(frame1.scl, frame2.scl, frame_t); - - //auto translation = glm::translate(glm::mat4(1.0f), glm::mix(frame1.pos, frame2.pos, frame_t)); - //auto rotation = glm::toMat4(glm::normalize(glm::slerp(frame1.rot, frame2.rot, frame_t))); - //auto scale = glm::scale(glm::mat4(1.0f), glm::mix(frame1.scl, frame2.scl, frame_t)); - - //model.bone_transforms_mat[i] = translation * rotation * scale; - - //model.bone_transforms_mat[i] = glm::translate(identity, pos) * glm::mat4_cast(glm::normalize(rot)) * glm::scale(identity, scl); - //model.bone_transforms_mat[i] = CreateTransMatFast(pos, rot, scl); CreateTransMatFast(model.bone_transforms_mat[i], MixTransforms(frame1, frame2, frame_t)); if (sk_bones[i].parent_idx != TSR_NO_BONE) diff --git a/src/tsr/entity_model.hpp b/src/tsr/entity_model.hpp index 5269543..b49e3ee 100644 --- a/src/tsr/entity_model.hpp +++ b/src/tsr/entity_model.hpp @@ -7,8 +7,18 @@ namespace TSR { + enum AnimState { + AS_FADING_IN, + AS_PLAYING, + AS_FADING_OUT, + AS_STOPPED + }; + struct ModelAnimation { - float t; + AnimState state = AS_PLAYING; + float weight = 0.0f; + float fade_time = 0.0f; + float t = 0.0f; }; struct ModelComponent { @@ -27,8 +37,8 @@ namespace TSR { public: static void AddModel(entt::entity ent, const std::string& name); static void RemoveModel(entt::entity ent); - static void Anim(entt::entity ent, const std::string& anim_name, float t = 0.0f); - static void StopAnim(entt::entity ent, const std::string& anim_name); + static void Anim(entt::entity ent, const std::string& anim_name, float t = 0.0f, float fade_in_time = 0.0f); + static void StopAnim(entt::entity ent, const std::string& anim_name, float fade_out_time = 0.0f); static void Animate(); static void Render(Renderer& renderer); diff --git a/src/tsr/game.cpp b/src/tsr/game.cpp index 0d2b001..f27747d 100644 --- a/src/tsr/game.cpp +++ b/src/tsr/game.cpp @@ -23,6 +23,8 @@ static Camera cam; static entt::entity ent1; static entt::entity player; +static AssetPtr s_skybox_model; + void Game::StartGame(const std::string& map_name) { s_sv_frame = 0; s_frame_t = 0.0f; @@ -55,14 +57,17 @@ void Game::Run() { while (!s_map->Loaded()) s_map->LoadNext(); + s_skybox_model = AssetMap::Get("models/skybox.mdl.json"); //s_physics_scene->EnableDebug(false); - for (int i = 0; i < 20; ++i) { + for (int i = 0; i < 10; ++i) { auto ent = Game::Registry().create(); ModelSystem::AddModel(ent, "models/test_skeletal.mdl.json"); ModelSystem::Anim(ent, "init"); ModelSystem::Anim(ent, "ruce"); + //ModelSystem::Anim(ent, "stand"); + //ModelSystem::Anim(ent, "walk2", i * 13.0f); glm::vec3 pos(2.0f * (i / 10), 0.0f, 2.0f * (i % 10)); @@ -90,7 +95,7 @@ void Game::Run() { player = Game::Registry().create(); ModelSystem::AddModel(player, "models/test_skeletal.mdl.json"); ModelSystem::Anim(player, "init"); - ModelSystem::Anim(player, "ruce"); + ModelSystem::Anim(player, "stand"); auto& trans = Registry().emplace_or_replace(player); glm::vec3 pos(0.0f, 5.0f, 0.0f); trans.trans.pos = pos; @@ -206,6 +211,8 @@ void Game::SvFrame() { if (Window::KeyDown(GLFW_KEY_D)) move_right += 1.0f; + static bool walking = false; + if (move_forward != 0.0f || move_right != 0.0f) { auto move_vector = cam.forward_backward_vector * move_forward + cam.right_vector * move_right; @@ -216,8 +223,34 @@ void Game::SvFrame() { auto& cctcomp = Registry().get(player); glm::vec3 forward_vector(std::sin(cctcomp.angle), -1.0f, std::cos(cctcomp.angle)); - CCTSystem::Move(player, forward_vector * (5.0f / TPS()), time); + CCTSystem::Move(player, forward_vector * (3.0f / TPS()), time); + + if (!walking) { + walking = true; + ModelSystem::Anim(player, "walk2", 6.0f, 0.2f); + } } + else { + if (walking) { + walking = false; + ModelSystem::StopAnim(player, "walk2", 0.1f); + } + } + + static bool aiming = false; + + if (Window::KeyDown(GLFW_KEY_E)) { + if (!aiming) { + aiming = true; + ModelSystem::Anim(player, "ruce", 0.0f, 0.2f); + } + } + else { + if (aiming) { + aiming = false; + ModelSystem::StopAnim(player, "ruce", 0.2f); + } + } CCTSystem::Update(); ModelSystem::Animate(); @@ -239,6 +272,9 @@ void Game::ClFrame(Renderer& renderer, float frame_t) { if (s_debug_draw) s_physics_scene->DrawDebug(renderer); + if (s_skybox_model) + s_skybox_model->Draw(renderer, nullptr); + cam.position = glm::vec3(Registry().get(player).ctx.model_matrix[3]) + glm::vec3(0.0f, 1.0f, 0.0f); renderer.SetViewMatrix(cam.GetViewMatrix()); diff --git a/src/tsr/model.cpp b/src/tsr/model.cpp index 2589cc5..baadca1 100644 --- a/src/tsr/model.cpp +++ b/src/tsr/model.cpp @@ -83,6 +83,9 @@ Model::Model(const std::string& name) : else if (type_str == "SKELETAL") { d.type = RT_SKELETAL; } + else if (type_str == "SKYBOX") { + d.type = RT_SKYBOX; + } // BONE if (part_json.contains("bone")) { diff --git a/src/tsr/renderer.cpp b/src/tsr/renderer.cpp index 58ed642..17ebb3c 100644 --- a/src/tsr/renderer.cpp +++ b/src/tsr/renderer.cpp @@ -18,6 +18,7 @@ RenderType Renderer::s_rt_instanced_map[RT_COUNT] = { RT_NONE, //RT_XZ_XZ_MASK_UV RT_NONE, //RT_SKELETAL RT_NONE, //RT_TRANSLUCENT + RT_NONE, //RT_SKYBOX }; const char* Shader::s_uniform_names[SU_COUNT] = { @@ -345,6 +346,7 @@ Renderer::Renderer() : m_shader_xz_xz_mask_uv(Filesystem::Read("shaders/basic.vs"), Filesystem::Read("shaders/xz_xz_mask_uv.fs"), "XZ_XZ_MASK_UV"), m_shader_skeletal(Filesystem::Read("shaders/skeletal.vs"), Filesystem::Read("shaders/skeletal.fs"), "SKELETAL"), m_shader_debug(Filesystem::Read("shaders/debug.vs"), Filesystem::Read("shaders/debug.fs"), "DEBUG"), + m_shader_skybox(Filesystem::Read("shaders/skybox.vs"), Filesystem::Read("shaders/skybox.fs"), "SKYBOX"), m_proj_matrix(1.0f), m_view_matrix(1.0f), m_viewport_buf(AssetMap::Get("viewport.ia2")), @@ -370,7 +372,14 @@ void Renderer::Render(int width, int height) { //glm::vec3 ambient_color = sun_color * 0.6f;//(1.0f, 1.0f, 0.8f); //glm::vec3 farplane_color(0.1f, 0.1f, 0.2f); - glm::vec3 sun_color(1.0f, 1.0f, 0.8f); + //glm::vec3 sun_color(1.0f, 1.0f, 0.8f); + //glm::vec3 sun_direction(0.0f, 1.0f, 0.0f); + //glm::vec3 ambient_color = sun_color * 0.6f;//(1.0f, 1.0f, 0.8f); + //glm::vec3 farplane_color(0.7f, 0.8f, 0.9f); + + + glm::vec3 sun_color(1.0f, 0.95f, 0.8f); + sun_color *= 1.0f; glm::vec3 sun_direction(0.0f, 1.0f, 0.0f); glm::vec3 ambient_color = sun_color * 0.6f;//(1.0f, 1.0f, 0.8f); glm::vec3 farplane_color(0.7f, 0.8f, 0.9f); @@ -577,11 +586,30 @@ void Renderer::Render(int width, int height) { m_debug_vao.Draw(m_debug_lines, true); } - //glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); - //glStencilFunc(GL_EQUAL, 0, 0xFF); - //glStencilMask(0x00); + // SKYBOX + if (!m_draw_lists[RT_SKYBOX].empty()) { + m_shader_skybox.Use(); + + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + glStencilFunc(GL_EQUAL, 0, 0xFF); + glStencilMask(0x00); + + auto inv_view = glm::inverse(m_view_matrix); + auto skybox_mat = mat_vp * glm::translate(glm::mat4(1.0f), glm::vec3(inv_view[3])); + + + + glUniformMatrix4fv(m_shader_skybox.U(SU_VP), 1, GL_FALSE, glm::value_ptr(skybox_mat)); + glUniform1i(m_shader_skybox.U(SU_TEX), 0); + + for (const auto& d : m_draw_lists[RT_SKYBOX]) { + glActiveTexture(GL_TEXTURE0); + d.drawable->texture->Bind(); + + d.drawable->mesh->Draw(); + } + } - // draw skybox glDisable(GL_CULL_FACE); glDisable(GL_STENCIL_TEST); diff --git a/src/tsr/renderer.hpp b/src/tsr/renderer.hpp index 26cc1df..14c708c 100644 --- a/src/tsr/renderer.hpp +++ b/src/tsr/renderer.hpp @@ -24,6 +24,7 @@ namespace TSR { RT_XZ_XZ_MASK_UV, RT_SKELETAL, RT_TRANSLUCENT, + RT_SKYBOX, RT_COUNT }; @@ -297,6 +298,7 @@ namespace TSR { Shader m_shader_screen; Shader m_shader_skeletal; Shader m_shader_debug; + Shader m_shader_skybox; //float m_aspect_ratio; std::unique_ptr m_fbs;