Skip to content

Commit

Permalink
Entity animation
Browse files Browse the repository at this point in the history
  • Loading branch information
LazyJazz committed Dec 26, 2023
1 parent 49ce86a commit 8b4f454
Show file tree
Hide file tree
Showing 10 changed files with 144 additions and 26 deletions.
2 changes: 1 addition & 1 deletion external/grassland
Submodule grassland updated 0 files
26 changes: 16 additions & 10 deletions src/GameBall/main/world.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ World::World(GameX::Base::Core *core) : Module(core) {
camera_ = scene_->CreateCamera(glm::vec3{0.0f, 0.0f, 3.0f},
glm::vec3{0.0f, 0.0f, 0.0f}, 45.0f, aspect,
0.1f, 100.0f);
cube_ = core_->AnimationManager()->CreateMesh("models/lucy.obj");
cube_ = core_->AnimationManager()->CreateMesh("models/sphere.obj");
static_model_ = core_->AnimationManager()->CreateStaticModel(cube_);
dynamic_model_ = core_->AnimationManager()->CreateDynamicModel(cube_);
static_entity_ = scene_->CreateEntity(static_model_);
Expand All @@ -38,6 +38,9 @@ World::World(GameX::Base::Core *core) : Module(core) {
dynamic_model_->SyncMeshData();

core_->AnimationManager()->SetPrimarySceneCamera(scene_, camera_);

dynamic_entity_->SetScale(glm::vec3{0.5f});
static_entity_->SetScale(glm::vec3{0.5f});
}

World::~World() {
Expand All @@ -55,15 +58,18 @@ World::~World() {

void World::Update() {
static float omega = 0.0f;
dynamic_entity_->SetEntitySettings(GameX::Animation::Entity::EntitySettings{
glm::translate(glm::mat4{1.0f}, glm::vec3{0.5f, 0.0f, 0.0f}) *
glm::rotate(glm::mat4{1.0f}, omega, glm::vec3{1.0f, 1.0f, 1.0f}) *
glm::scale(glm::mat4{1.0f}, glm::vec3{0.0025f})});

static_entity_->SetEntitySettings(GameX::Animation::Entity::EntitySettings{
glm::translate(glm::mat4{1.0f}, glm::vec3{-0.5f, 0.0f, 0.0f}) *
glm::rotate(glm::mat4{1.0f}, omega, glm::vec3{1.0f, -1.0f, -1.0f}) *
glm::scale(glm::mat4{1.0f}, glm::vec3{0.0025f})});
static_entity_->SetMotion(
glm::vec3{-0.5f, 0.0f, 0.0f}, glm::vec3{0.0f, 0.0f, 0.0f},
glm::vec3{0.0f, 0.0f, 0.0f},
glm::mat3{
glm::rotate(glm::mat4{1.0f}, omega, glm::vec3{1.0f, -1.0f, -1.0f})},
glm::vec3{1.0f, -1.0f, -1.0f}, glm::radians(180.0f));
dynamic_entity_->SetMotion(
glm::vec3{0.5f, 0.0f, 0.0f}, glm::vec3{0.0f, 0.0f, 0.0f},
glm::vec3{0.0f, 0.0f, 0.0f},
glm::mat3{
glm::rotate(glm::mat4{1.0f}, omega, glm::vec3{1.0f, 1.0f, 1.0f})},
glm::vec3{1.0f, 1.0f, 1.0f}, glm::radians(180.0f));
omega += glm::radians(180.0f) / 64.0f;
}

Expand Down
2 changes: 2 additions & 0 deletions src/GameX/animation/command_buffer.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#pragma once
#include <chrono>
#include <functional>
#include <queue>
#include <set>
Expand All @@ -12,5 +13,6 @@ struct CommandBuffer {
std::queue<DynamicObject *> new_dynamic_objects;
std::queue<std::function<void()>> commands;
std::queue<Object *> delete_objects;
std::chrono::steady_clock::time_point time_point;
};
} // namespace GameX::Animation
64 changes: 61 additions & 3 deletions src/GameX/animation/entity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,31 @@ Entity::~Entity() {
}

void Entity::Update(float delta_time) {
accumulated_time_ += delta_time;
glm::vec3 x = x_ + v_ * accumulated_time_ +
0.5f * a_ * accumulated_time_ * accumulated_time_;
glm::vec3 omega = R_ * I_inv_ * ((L_ + accumulated_time_ * tau_) * R_);
float theta = glm::length(omega);
glm::mat4 R{1.0f};
if (theta > 0.0f) {
R = glm::rotate(glm::mat4{1.0f}, theta * delta_time, omega);
}
R_ = glm::mat3{R} * R_;
EntitySettings settings;
auto R_final = glm::mat4{R_};
R_final[3][3] = 1.0f;
settings.model = glm::translate(glm::mat4{1.0f}, x) * R_final * affine_;
// R_final = R_final;
// printf("accumulated_time: %f\n", delta_time);
// printf("%f %f %f %f\n", R_final[0][0], R_final[0][1], R_final[0][2],
// R_final[0][3]); printf("%f %f %f %f\n", R_final[1][0],
// R_final[1][1], R_final[1][2], R_final[1][3]); printf("%f %f %f
// %f\n", R_final[2][0], R_final[2][1], R_final[2][2], R_final[2][3]);
// printf("%f %f %f %f\n", R_final[3][0], R_final[3][1], R_final[3][2],
// R_final[3][3]); spdlog::info("Entity position: ({}, {}, {})", x.x,
// x.y, x.z); spdlog::info("Entity scale: ({}, {}, {})", affine_[0][0],
// affine_[1][1], affine_[2][2]);
entity_->SetEntitySettings(settings);
}

Entity::Entity(struct Scene *scene, Model *model)
Expand All @@ -16,8 +41,41 @@ Entity::Entity(struct Scene *scene, Model *model)
});
}

void Entity::SetEntitySettings(const Entity::EntitySettings &settings) {
manager_->RecordCommand(
[this, settings]() { entity_->SetEntitySettings(settings); });
void Entity::SetMotion(glm::vec3 x,
glm::vec3 v,
glm::vec3 a,
glm::mat3 R,
glm::vec3 axis,
float omega) {
axis = glm::normalize(axis);
SetMotion(x, v, a, R, axis * omega, glm::vec3{0.0f}, glm::mat3{1.0f});
}

void Entity::SetMotion(glm::vec3 x,
glm::vec3 v,
glm::vec3 a,
glm::mat3 R,
glm::vec3 L,
glm::vec3 tau,
glm::mat3 I) {
manager_->RecordCommand([this, x, v, a, R, L, tau, I]() {
x_ = x;
v_ = v;
a_ = a;
R_ = R;
L_ = L;
tau_ = tau;
I_ = I;
I_inv_ = glm::inverse(I_);
accumulated_time_ = 0.0f;
});
}

void Entity::SetScale(glm::vec3 scale) {
SetAffine(glm::scale(glm::mat4{1.0f}, scale));
}

void Entity::SetAffine(glm::mat4 affine) {
manager_->RecordCommand([this, affine]() { affine_ = affine; });
}
} // namespace GameX::Animation
26 changes: 25 additions & 1 deletion src/GameX/animation/entity.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,33 @@ class Entity : public DynamicObject {
Entity(class Scene *scene, Model *model);
virtual ~Entity();
void Update(float delta_time) override;
void SetEntitySettings(const EntitySettings &settings);
void SetMotion(glm::vec3 x,
glm::vec3 v = glm::vec3{0.0f},
glm::vec3 a = glm::vec3{0.0f},
glm::mat3 R = glm::mat3{1.0f},
glm::vec3 axis = glm::vec3{0.0f},
float omega = 0.0f);
void SetMotion(glm::vec3 x,
glm::vec3 v,
glm::vec3 a,
glm::mat3 R,
glm::vec3 L,
glm::vec3 tau,
glm::mat3 I);
void SetScale(glm::vec3 scale);
void SetAffine(glm::mat4 affine);

private:
std::unique_ptr<Base::Entity> entity_;
glm::mat4 affine_{1.0f}; // scale
glm::vec3 x_{}; // position
glm::vec3 v_{}; // velocity
glm::vec3 a_{}; // acceleration
glm::mat3 R_{1.0f}; // rotation matrix
glm::vec3 L_{}; // angular momentum
glm::vec3 tau_{}; // torque
glm::mat3 I_{1.0f}; // inertia tensor
glm::mat3 I_inv_{1.0f}; // inverse of inertia tensor
float accumulated_time_{0.0f};
};
} // namespace GameX::Animation
9 changes: 8 additions & 1 deletion src/GameX/animation/manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,20 @@ namespace GameX::Animation {
Manager::Manager(Base::Renderer *renderer) : renderer_(renderer) {
auto extent = renderer_->App()->VkCore()->SwapChain()->Extent();
film_ = renderer_->RenderPipeline()->CreateFilm(extent.width, extent.height);
last_time_point_ = std::chrono::steady_clock::now();
}

Manager::~Manager() {
ProcessCommandBufferQueue();
film_.reset();
}

void Manager::Update(float delta_time) {
void Manager::Update(std::chrono::steady_clock::time_point time_point) {
ProcessCommandBufferQueue();
auto delta_time = std::chrono::duration<float, std::chrono::seconds::period>(
time_point - last_time_point_)
.count();
last_time_point_ = time_point;
for (auto &object : dynamic_objects_) {
object->Update(delta_time);
}
Expand Down Expand Up @@ -46,7 +51,9 @@ void Manager::ProcessCommandBufferQueue() {
std::lock_guard<std::mutex> lock(cmd_buffer_queue_mutex_);

while (!cmd_buffer_queue_.empty()) {
LAND_INFO("Processing command buffer queue");
auto &cmd_buffer = cmd_buffer_queue_.front();
last_time_point_ = cmd_buffer.time_point;

while (!cmd_buffer.new_dynamic_objects.empty()) {
dynamic_objects_.insert(cmd_buffer.new_dynamic_objects.front());
Expand Down
12 changes: 9 additions & 3 deletions src/GameX/animation/manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,21 @@ class Manager {

~Manager();

void Update(float delta_time);
void Update(std::chrono::steady_clock::time_point time_point);

void SetWorkingCommandBuffer(CommandBuffer *cmd_buffer) {
working_cmd_buffer_ = cmd_buffer;
}

void RecordCommand(const std::function<void()> &command);

void ExecuteCommandBuffer(CommandBuffer &&cmd_buffer) {
bool ExecuteCommandBuffer(CommandBuffer &&cmd_buffer, bool force_push) {
std::lock_guard<std::mutex> lock(cmd_buffer_queue_mutex_);
cmd_buffer_queue_.push(std::move(cmd_buffer));
if (cmd_buffer_queue_.size() < 3 || force_push) {
cmd_buffer_queue_.push(std::move(cmd_buffer));
return true;
}
return false;
}

void RegisterDynamicObject(DynamicObject *object);
Expand Down Expand Up @@ -81,5 +85,7 @@ class Manager {

Scene *primary_scene_{};
Camera *primary_camera_{};

std::chrono::steady_clock::time_point last_time_point_;
};
} // namespace GameX::Animation
11 changes: 7 additions & 4 deletions src/GameX/application/application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,13 @@ void Application::Cleanup() {

void Application::Update() {
OnUpdate();
static auto last_time = glfwGetTime();
auto current_time = glfwGetTime();
auto delta_time = current_time - last_time;
animation_manager_->Update(delta_time);
static auto last_time = std::chrono::steady_clock::now();
auto current_time = std::chrono::steady_clock::now();
auto delta_time = std::chrono::duration<float, std::chrono::seconds::period>(
current_time - last_time)
.count();
last_time = current_time;
animation_manager_->Update(current_time);
renderer_->SyncObjects();
}

Expand Down
14 changes: 12 additions & 2 deletions src/GameX/core/core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Core::~Core() {
}

void Core::Start() {
thread_start_time_ = std::chrono::steady_clock::now();
logic_thread_ = std::thread(&Core::LogicThread, this);
}

Expand All @@ -21,8 +22,14 @@ void Core::Stop() {
}

void Core::LogicThread() {
auto start_time = std::chrono::steady_clock::now();
LAND_INFO("Thread time offset: {}",
std::chrono::duration<float, std::chrono::seconds::period>(
start_time - thread_start_time_)
.count());
while (!stop_logic_thread_) {
Animation::CommandBuffer command_buffer;
command_buffer.time_point = std::chrono::steady_clock::now();
animation_manager->SetWorkingCommandBuffer(&command_buffer);

std::lock_guard<std::mutex> lock(load_queue_mutex_);
Expand All @@ -34,17 +41,20 @@ void Core::LogicThread() {
UpdateSubordinates();

animation_manager->SetWorkingCommandBuffer(nullptr);
animation_manager->ExecuteCommandBuffer(std::move(command_buffer));
while (!animation_manager->ExecuteCommandBuffer(std::move(command_buffer),
stop_logic_thread_))
;
metronome_.Tick();
}

Animation::CommandBuffer command_buffer;
command_buffer.time_point = std::chrono::steady_clock::now();
animation_manager->SetWorkingCommandBuffer(&command_buffer);
std::set<Object *> release_modules = GetSubordinates();
for (auto &module : release_modules) {
delete module;
}
animation_manager->SetWorkingCommandBuffer(nullptr);
animation_manager->ExecuteCommandBuffer(std::move(command_buffer));
animation_manager->ExecuteCommandBuffer(std::move(command_buffer), true);
}
} // namespace GameX::Base
4 changes: 3 additions & 1 deletion src/GameX/core/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,14 @@ class Core : public ObjectManager {
Animation::Manager *animation_manager;
std::unique_ptr<Physics::World> physics_world_;

Metronome metronome_;
Metronome metronome_{std::chrono::microseconds(15625)};

std::thread logic_thread_;
bool stop_logic_thread_{false};

std::mutex load_queue_mutex_;
std::queue<std::function<void()>> load_queue_;

std::chrono::steady_clock::time_point thread_start_time_;
};
} // namespace GameX::Base

0 comments on commit 8b4f454

Please sign in to comment.