neco to dela

This commit is contained in:
det-fys 2023-12-22 16:10:48 +01:00
parent 3f33390ad7
commit 87db261a10
12 changed files with 536 additions and 169 deletions

View File

@ -1,4 +1,5 @@
#include "entity_model.hpp"
#include "window.hpp"
using namespace TSR;
@ -14,36 +15,45 @@ 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<AnimationComponent>(ent);
else
reg.erase<AnimationComponent>(ent);
//if (comp.model->HasAnimations())
// reg.emplace_or_replace<AnimationComponent>(ent);
//else
// reg.erase<AnimationComponent>(ent);
comp.ctx.model_matrix = glm::mat4(1.0f);
for (int i = 0; i < TSR_NUM_COLORS; ++i)
comp.ctx.colors[i] = glm::vec4(1.0f);
comp.spawned_at = Game::FrameNum();
auto& bone_transforms = comp.bone_transforms[Game::FrameNum() % 2];
for (auto& t : bone_transforms) {
t.pos = glm::vec3(0.0f);
t.rot = glm::quat(glm::mat4(1.0f));
t.scl = glm::vec3(1.0f);
//auto& bone_transforms = comp.bone_transforms[1 - (Game::FrameNum() % 2)];
for (auto& t : comp.bone_transforms[0])
IdentityTransform(t);
for (auto& t : comp.bone_transforms[1])
IdentityTransform(t);
IdentityTransform(comp.trans[0]);
IdentityTransform(comp.trans[1]);
for (auto& mat : comp.bone_transforms_mat) {
mat = glm::mat4(1.0f);
}
}
void TSR::ModelSystem::RemoveModel(entt::entity ent) {
auto& reg = Game::Registry();
reg.erase<ModelComponent>(ent);
reg.erase<AnimationComponent>(ent);
//reg.erase<AnimationComponent>(ent);
}
void ModelSystem::Anim(entt::entity ent, const std::string& anim_name) {
void ModelSystem::Anim(entt::entity ent, const std::string& anim_name, float t) {
auto& comp = Game::Registry().get<ModelComponent>(ent);
auto id = comp.model->GetAnimId(anim_name);
auto& anim = comp.animations[id];
anim.t = 0.0f;
anim.t = t;
}
@ -59,10 +69,17 @@ void ModelSystem::Animate() {
float frame_time = 1.0f / (float)Game::TPS();
auto v = Game::Registry().view<AnimationComponent, ModelComponent>();
for (auto [ent, model] : v.each()) {
auto v = Game::Registry().view<ModelComponent, TransformComponent>();
for (auto [ent, model, trans] : v.each()) {
model.trans[frame_idx] = trans.trans;
auto& anims = model.animations;
auto& bone_transforms = model.bone_transforms[frame_idx];
auto& bone_transforms_prev = model.bone_transforms[1 - frame_idx];
for (int i = 0; i < bone_transforms.size(); ++i) {
bone_transforms[i] = bone_transforms_prev[i];
}
for (auto it = anims.begin(); it != anims.end(); ) {
bool remove = false;
@ -81,6 +98,8 @@ void ModelSystem::Animate() {
}
}
// events
if (anim.skel) {
auto& skel_anim = *anim.skel;
@ -93,10 +112,12 @@ 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);
//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);
}
}
@ -106,9 +127,55 @@ void ModelSystem::Animate() {
++it;
}
}
}
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;
float w = trans.rot.w;
float x2 = x + x;
float y2 = y + y;
float z2 = z + z;
float xx = x * x2;
float xy = x * y2;
float xz = x * z2;
float yy = y * y2;
float yz = y * z2;
float zz = z * z2;
float wx = w * x2;
float wy = w * y2;
float wz = w * z2;
float sx = trans.scl.x;
float sy = trans.scl.y;
float sz = trans.scl.z;
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) {
@ -124,12 +191,61 @@ void ModelSystem::Render(TSR::Renderer& renderer) {
//}
auto frame_t = Game::FrameT();
auto frame_idx1 = Game::FrameNum() % 2;
auto frame_idx0 = 1 - frame_idx1;
auto frame_idx0 = Game::FrameNum() % 2;
auto frame_idx1 = 1 - frame_idx0;
//glm::mat4 identity(1.0f);
auto v = Game::Registry().view<ModelComponent, TransformComponent>();
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));
if (model.model->IsSkeletal() && !Window::KeyDown(GLFW_KEY_V)) {
auto& sk_bones = model.model->GetSkeleton().Bones();
auto& bone_transforms0 = model.bone_transforms[frame_idx0];
auto& bone_transforms1 = model.bone_transforms[frame_idx1];
for (int i = 0; i < model.bone_transforms_mat.size(); ++i) {
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)
model.bone_transforms_mat[i] = model.bone_transforms_mat[sk_bones[i].parent_idx] * model.bone_transforms_mat[i];
}
}
model.ctx.bone_transforms = model.bone_transforms_mat.data();
if (!Window::KeyDown(GLFW_KEY_X))
model.model->Draw(renderer, &model.ctx);
}

View File

@ -14,6 +14,7 @@ namespace TSR {
struct ModelComponent {
AssetPtr<Model> model;
TSR::DrawCtx ctx;
Transform trans[2];
std::vector<glm::mat4> bone_transforms_mat;
std::vector<BoneTransform> bone_transforms[2];
std::map<AnimationId, ModelAnimation> animations;
@ -26,7 +27,7 @@ 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);
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 Animate();

View File

@ -1,8 +1,165 @@
#include "game.hpp"
#include "entity_model.hpp"
#include "window.hpp"
#include "camera.hpp"
#include "worldmap.hpp"
using namespace TSR;
entt::registry Game::s_registry;
uint64_t Game::s_sv_frame = 0;
float Game::s_frame_t = 0.0f;
int Game::s_tps = 50;
float Game::s_frame_t = 0.0f;
int Game::s_tps = 50;
static Camera cam;
static entt::entity ent1;
static WorldMap* s_map;
void Game::Run() {
Filesystem::Init("main");
WindowWrapper ww("TSR test", 640, 480);
////Audio::Init();
Renderer renderer;
WorldMap map("maps/kalbatest1.mapproject.json");
while (!map.Loaded())
map.LoadNext();
s_map = &map;
for (int i = 0; i < 20; ++i) {
auto ent = Game::Registry().create();
ModelSystem::AddModel(ent, "models/test_skeletal.mdl.json");
ModelSystem::Anim(ent, "init");
ModelSystem::Anim(ent, "ruce");
glm::vec3 pos(2.0f * (i / 10), 0.0f, 2.0f * (i % 10));
auto& trans = Registry().emplace_or_replace<TransformComponent>(ent);
trans.trans.pos = pos;
trans.trans.rot = glm::quat(glm::vec3(0.0f));
trans.trans.scl = glm::vec3(1.0f);
}
ent1 = Game::Registry().create();
ModelSystem::AddModel(ent1, "models/skrin.mdl.json");
ModelSystem::Anim(ent1, "init");
ModelSystem::Anim(ent1, "open_left");
ModelSystem::Anim(ent1, "open_right");
auto& trans = Registry().emplace_or_replace<TransformComponent>(ent1);
glm::vec3 pos(0.0f, 5.0f, 0.0f);
trans.trans.pos = pos;
trans.trans.rot = glm::quat(glm::vec3(0.0f));
trans.trans.scl = glm::vec3(1.0f);
Window::SetInputMode(GLFW_CURSOR, GLFW_CURSOR_DISABLED);
Window::SetCursorPosCallback([](GLFWwindow* window, double xpos, double ypos) {
static float last_mouse_x = 0.0f, last_mouse_y = 0.0f;
double xoffset = xpos - last_mouse_x;
double yoffset = last_mouse_y - ypos; // reversed since y-coordinates range from bottom to top
cam.ProcessMouse(xoffset, yoffset);
last_mouse_x = xpos;
last_mouse_y = ypos;
});
Window::SetKeyCallback([](GLFWwindow* window, int key, int scancode, int action, int mods) {
if (action == GLFW_PRESS) {
switch (key) {
case GLFW_KEY_E:
ModelSystem::Anim(ent1, "open_left");
ModelSystem::Anim(ent1, "open_right");
break;
case GLFW_KEY_Q:
ModelSystem::Anim(ent1, "close_left");
ModelSystem::Anim(ent1, "close_right");
break;
}
}
});
cam.movement_speed *= 0.1f;
Window::Show();
auto start_t = std::chrono::steady_clock::now();
uint32_t time = 0U;
uint32_t real_time = 0U;
uint32_t frame_time_ms = 1000U / s_tps;
glfwSwapInterval(0);
while (!Window::ShouldClose()) {
auto diff = std::chrono::steady_clock::now() - start_t;
real_time = std::chrono::duration_cast<std::chrono::milliseconds>(diff).count();
if (!Window::KeyDown(GLFW_KEY_C)) {
while (time < real_time) {
SvFrame();
time += frame_time_ms;
}
}
s_frame_t = (float)(real_time - time + frame_time_ms) / (float)frame_time_ms;
ClFrame(renderer, 0.0f);
}
}
void Game::SvFrame() {
ModelSystem::Animate();
++s_sv_frame;
float time = 1.0f / (float)s_tps;
if (Window::KeyDown(GLFW_KEY_W))
cam.ProcessMovement(Camera::Movement::FORWARD, time);
if (Window::KeyDown(GLFW_KEY_S))
cam.ProcessMovement(Camera::Movement::BACKWARD, time);
if (Window::KeyDown(GLFW_KEY_A))
cam.ProcessMovement(Camera::Movement::LEFT, time);
if (Window::KeyDown(GLFW_KEY_D))
cam.ProcessMovement(Camera::Movement::RIGHT, time);
if (Window::KeyDown(GLFW_KEY_SPACE))
cam.ProcessMovement(Camera::Movement::UP, time);
if (Window::KeyDown(GLFW_KEY_LEFT_SHIFT))
cam.ProcessMovement(Camera::Movement::DOWN, time);
}
void Game::ClFrame(Renderer& renderer, float frame_t) {
int w, h;
Window::GetFramebufferSize(w, h);
renderer.SetProjection((float)w / (float)h, 90.0f, 0.1f, 1000.0f);
//r.SetViewMatrix(glm::lookAt(glm::vec3(-1.0f, 2.0f, 2.0f), glm::vec3(0.0f, 1.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f)));
renderer.SetViewMatrix(cam.GetViewMatrix());
//r.SetViewMatrix(glm::lookAt(glm::vec3(10.0f, 5.0f, 3.0f), glm::vec3(0.0f), glm::vec3(0.0f, 1.0f, 0.0f)));
ModelSystem::Render(renderer);
s_map->Draw(renderer);
renderer.Render(w, h);
Window::PollEvents();
Window::SwapBuffers();
}

View File

@ -5,13 +5,10 @@
#include <glm/gtx/quaternion.hpp>
#include <memory>
#include <entt/entt.hpp>
#include "renderer.hpp"
namespace TSR {
struct TransformComponent {
glm::vec3 pos[2];
glm::quat rot[2];
};
class Game {
static entt::registry s_registry;
@ -20,8 +17,9 @@ namespace TSR {
static int s_tps;
public:
static void Run();
static void SvFrame();
static void ClFrame(float frame_t);
static void ClFrame(Renderer& renderer, float frame_t);
static entt::registry& Registry() { return s_registry; }
static uint64_t FrameNum() { return s_sv_frame; }
@ -29,6 +27,9 @@ namespace TSR {
static int TPS() { return s_tps; }
};
struct TransformComponent {
Transform trans;
};
}

View File

@ -1,7 +1,7 @@
#pragma once
#include "tsr.hpp"
#include "transform.hpp"
// PARSERS
namespace TSR {
@ -22,11 +22,7 @@ namespace TSR {
glm::mat4 offset;
};
struct BoneTransform {
glm::vec3 pos;
glm::quat rot;
glm::vec3 scl;
};
using BoneTransform = Transform;
struct SkAnimChannel {
std::string name;

View File

@ -104,32 +104,34 @@ Model::Model(const std::string& name) {
m_part_names.insert({ part_json.at("name").get<std::string>(), m_parts.size() - 1 });
}
const auto& anims_json = model_json.at("animations");
for (const auto& anim_json : anims_json) {
m_animations.push_back(Animation());
auto idx = m_animations.size() - 1;
auto& anim = m_animations[idx];
m_anim_names.insert({ anim_json.at("name").get<std::string>(), idx });
if (model_json.contains("animations")) {
const auto& anims_json = model_json.at("animations");
for (const auto& anim_json : anims_json) {
m_animations.push_back(Animation());
auto idx = m_animations.size() - 1;
auto& anim = m_animations[idx];
m_anim_names.insert({ anim_json.at("name").get<std::string>(), idx });
if (anim_json.contains("skel")) {
if (!m_skeleton) Throw("Skeletal animation in a model with no skeleton");
anim.skel = AssetMap::Get<SkAnim>(anim_json.at("skel").get<std::string>());
for (const auto& chan : anim.skel->Channels())
anim.bone_ids.push_back(m_skeleton->GetBoneIdByName(chan.name));
if (anim_json.contains("skel")) {
if (!m_skeleton) Throw("Skeletal animation in a model with no skeleton");
anim.skel = AssetMap::Get<SkAnim>(anim_json.at("skel").get<std::string>());
for (const auto& chan : anim.skel->Channels())
anim.bone_ids.push_back(m_skeleton->GetBoneIdByName(chan.name));
anim.duration = anim.skel->Duration();
anim.tps = anim.skel->TPS();
}
else {
anim.duration = anim_json.at("duration").get<float>();
anim.tps = anim_json.at("tps").get<float>();
}
anim.duration = anim.skel->Duration();
anim.tps = anim.skel->TPS();
}
else {
anim.duration = anim_json.at("duration").get<float>();
anim.tps = anim_json.at("tps").get<float>();
}
anim.is_cyclic = false;
if (anim_json.contains("cyclic"))
anim.is_cyclic = anim_json.at("cyclic").get<bool>();
anim.is_cyclic = false;
if (anim_json.contains("cyclic"))
anim.is_cyclic = anim_json.at("cyclic").get<bool>();
// events
// events
}
}
}
catch (nlohmann::json::exception ex) {

23
src/tsr/transform.hpp Normal file
View File

@ -0,0 +1,23 @@
#pragma once
#include <glm/glm.hpp>
#include <glm/gtc/quaternion.hpp>
struct Transform {
glm::vec3 pos;
glm::quat rot;
glm::vec3 scl;
};
inline Transform MixTransforms(const Transform& t1, const Transform& t2, float t) {
Transform ret;
ret.pos = glm::mix(t1.pos, t2.pos, t);
ret.rot = glm::slerp(t1.rot, t2.rot, t);
ret.scl = glm::mix(t1.scl, t2.scl, t);
return ret;
}
inline void IdentityTransform(Transform& t) {
t.pos = glm::vec3(0.0f);
t.rot = glm::quat(1.0f, 0.0f, 0.0f, 0.0f);
t.scl = glm::vec3(1.0f);
}

109
src/tsr/worldmap.cpp Normal file
View File

@ -0,0 +1,109 @@
#include "worldmap.hpp"
using namespace TSR;
static const char* color_strs[] = { "color1", "color2", "color3", "color4" };
WorldMap::WorldMap(const std::string& map_path) : m_loading_phase(LoadingPhase::FIRST), m_map_path(map_path), m_loaded_models(0) {}
int WorldMap::LoadNext() {
switch (m_loading_phase) {
case LoadingPhase::FIRST:
m_loading_phase = LoadingPhase::PARSE;
return 0;
break;
case LoadingPhase::PARSE:
{
auto j_map = nlohmann::json::parse(Filesystem::Read(m_map_path));
//if (j_map.contains(""))
auto j_objects = j_map.at("objects");
for (const auto& j_object : j_objects) {
auto model_name = j_object.at("model").get<std::string>();
auto& model_instances = m_loading_obj_data[model_name];
//MapObject obj;
//obj.m_model = s;
BasicDrawCtx ctx;
auto pos = JsonGetVec<3>(j_object.at("pos"));
auto rot = j_object.at("angle").get<float>();
float scale = 1.0f;
if (j_object.contains("scale"))
j_object.at("scale").get_to(scale);
ctx.model_matrix = glm::scale(glm::rotate(glm::translate(glm::mat4(1.0f), pos), glm::radians(rot), glm::vec3(0.0f, 1.0f, 0.0f)), glm::vec3(scale));
for (int i = 0; i < 4; ++i) {
auto& cns = color_strs[i];
if (j_object.contains(cns))
ctx.colors[i] = JsonGetVec<4>(j_object.at(cns));
}
model_instances.m_contexts.push_back(ctx);
}
m_loading_iter = m_loading_obj_data.cbegin();
m_loading_phase = LoadingPhase::MODELS;
return 10;
break;
}
case LoadingPhase::MODELS:
{
if (m_loading_iter == m_loading_obj_data.cend()) {
m_loading_phase = LoadingPhase::FINISHED;
m_loading_obj_data.clear();
return 100;
}
const auto& models = *(m_loading_iter++);
++m_loaded_models;
auto s = AssetMap::Get<Model>(models.first);
if (models.second.m_contexts.size() > 4) {
MapObject obj;
obj.m_model = s;
obj.m_ctx.ssbo = std::make_unique<InstancedSSBO>(models.second.m_contexts);
m_objects_instanced.push_back(std::move(obj));
}
else {
for (const auto& instance : models.second.m_contexts) {
MapObject obj;
obj.m_model = s;
obj.m_ctx.model_matrix = instance.model_matrix;
for (int i = 0; i < 4; i++)
obj.m_ctx.colors[i] = instance.colors[i];
m_objects.push_back(std::move(obj));
}
}
return 10 + (90 * m_loaded_models / m_loading_obj_data.size());
break;
}
case LoadingPhase::FINISHED:
return 100;
break;
}
return 0;
}

59
src/tsr/worldmap.hpp Normal file
View File

@ -0,0 +1,59 @@
#pragma once
#include <vector>
#include "model.hpp"
//#include "audio.hpp"
#include "window.hpp"
#include "tsr.hpp"
namespace TSR {
class WorldMap {
// general
std::string m_map_path;
// loading
enum class LoadingPhase {
FIRST,
PARSE,
MODELS,
FINISHED,
} m_loading_phase;
struct ModelInstances {
std::vector<BasicDrawCtx> m_contexts;
};
using LoadingObjData = std::map<std::string, ModelInstances>;
LoadingObjData m_loading_obj_data;
LoadingObjData::const_iterator m_loading_iter;
int m_loaded_models;
// final
struct MapObject {
DrawCtx m_ctx;
AssetPtr<Model> m_model;
};
std::vector<MapObject> m_objects;
std::vector<MapObject> m_objects_instanced;
public:
WorldMap(const std::string& map_path);
bool Loaded() const { return m_loading_phase == LoadingPhase::FINISHED; }
const std::string& Name() { return m_map_path; }
int LoadNext();
void Draw(Renderer& r) const {
for (const auto& obj : m_objects)
obj.m_model->Draw(r, &obj.m_ctx);
for (const auto& obj : m_objects_instanced)
obj.m_model->DrawInstanced(r, &obj.m_ctx);
}
};
}

View File

@ -5,6 +5,8 @@
#include "tsr/renderer.hpp"
#include "tsr/model.hpp"
#include "tsr/camera.hpp"
#include "tsr/game.hpp"
#include "tsr/entity_model.hpp"
#include <windows.h>
using namespace TSR;
@ -14,118 +16,7 @@ int main() {
TsrPrintf("Hello (client)\n");
try {
Filesystem::Init("main");
WindowWrapper ww("TSR test", 640, 480);
////Audio::Init();
Renderer r;
auto model = AssetMap::Get<Model>("models/test_skeletal.mdl.json");
DrawCtx draw_ctx;
draw_ctx.model_matrix = glm::mat4(1.0f);
std::vector<glm::mat4> bone_transforms;
bone_transforms.resize(model->GetSkeleton().Bones().size());
draw_ctx.bone_transforms = &bone_transforms[0];
auto anim_id = model->GetAnimId("ruce");
const auto& anim = model->GetAnim(anim_id);
const auto& skel = model->GetSkeleton();
const auto& sk_bones = skel.Bones();
//glfwSwapInterval(0);
Window::SetInputMode(GLFW_CURSOR, GLFW_CURSOR_DISABLED);
Window::SetCursorPosCallback([](GLFWwindow* window, double xpos, double ypos) {
static float last_mouse_x = 0.0f, last_mouse_y = 0.0f;
double xoffset = xpos - last_mouse_x;
double yoffset = last_mouse_y - ypos; // reversed since y-coordinates range from bottom to top
cam.ProcessMouse(xoffset, yoffset);
last_mouse_x = xpos;
last_mouse_y = ypos;
});
cam.movement_speed *= 0.1f;
Window::Show();
while (!Window::ShouldClose()) {
float time = 1.0f / 75.0f;
if (Window::KeyDown(GLFW_KEY_W))
cam.ProcessMovement(Camera::Movement::FORWARD, time);
if (Window::KeyDown(GLFW_KEY_S))
cam.ProcessMovement(Camera::Movement::BACKWARD, time);
if (Window::KeyDown(GLFW_KEY_A))
cam.ProcessMovement(Camera::Movement::LEFT, time);
if (Window::KeyDown(GLFW_KEY_D))
cam.ProcessMovement(Camera::Movement::RIGHT, time);
if (Window::KeyDown(GLFW_KEY_SPACE))
cam.ProcessMovement(Camera::Movement::UP, time);
if (Window::KeyDown(GLFW_KEY_LEFT_SHIFT))
cam.ProcessMovement(Camera::Movement::DOWN, time);
int w, h;
Window::GetFramebufferSize(w, h);
r.SetProjection((float)w / (float)h, 90.0f, 0.1f, 1000.0f);
//r.SetViewMatrix(glm::lookAt(glm::vec3(-1.0f, 2.0f, 2.0f), glm::vec3(0.0f, 1.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f)));
r.SetViewMatrix(cam.GetViewMatrix());
//r.SetViewMatrix(glm::lookAt(glm::vec3(10.0f, 5.0f, 3.0f), glm::vec3(0.0f), glm::vec3(0.0f, 1.0f, 0.0f)));
// reset bones
for (int i = 0; i < bone_transforms.size(); ++i) {
bone_transforms[i] = sk_bones[i].transform;
}
// animation
float cur_frame = glm::mod((float)(glfwGetTime() * anim.skel->TPS()), (float)anim.skel->Duration());
//float cur_frame = glm::mod(1.0f, 3.0f);
for (int i = 0; i < anim.skel->Channels().size(); ++i) {
int fr1 = glm::floor(cur_frame);
int fr2 = glm::ceil(cur_frame);
float t = glm::fract(cur_frame);
const auto& frame1 = anim.skel->Channels()[i].frames[fr1];
const auto& frame2 = anim.skel->Channels()[i].frames[fr2];
auto translation = glm::translate(glm::mat4(1.0f), glm::mix(frame1.pos, frame2.pos, t));
auto rotation = glm::toMat4(glm::normalize(glm::slerp(frame1.rot, frame2.rot, t)));
auto scale = glm::scale(glm::mat4(1.0f), glm::mix(frame1.scl, frame2.scl, t));
bone_transforms[anim.bone_ids[i]] = translation * rotation * scale;
}
// apply parents
for (int i = 0; i < bone_transforms.size(); ++i) {
if (sk_bones[i].parent_idx != TSR_NO_BONE)
bone_transforms[i] = bone_transforms[sk_bones[i].parent_idx] * bone_transforms[i];
}
model->Draw(r, &draw_ctx);
r.Render(w, h);
Window::PollEvents();
Window::SwapBuffers();
}
Game::Run();
//Client::Run();

View File

@ -139,6 +139,7 @@
<ClCompile Include="src\tsr\renderer.cpp" />
<ClCompile Include="src\tsr\window.cpp" />
<ClCompile Include="src\tsrecs.cpp" />
<ClCompile Include="src\tsr\worldmap.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\tsr\camera.hpp" />
@ -150,8 +151,10 @@
<ClInclude Include="src\tsr\filesystem.hpp" />
<ClInclude Include="src\tsr\ia.hpp" />
<ClInclude Include="src\tsr\renderer.hpp" />
<ClInclude Include="src\tsr\transform.hpp" />
<ClInclude Include="src\tsr\tsr.hpp" />
<ClInclude Include="src\tsr\window.hpp" />
<ClInclude Include="src\tsr\worldmap.hpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">

View File

@ -45,6 +45,9 @@
<ClCompile Include="src\tsr\camera.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\tsr\worldmap.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\tsr\window.hpp">
@ -80,5 +83,11 @@
<ClInclude Include="src\tsr\camera.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\tsr\transform.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\tsr\worldmap.hpp">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>