Commit 13adfd11 authored by Florian Oetke's avatar Florian Oetke
Browse files

basic working animations

parent 09cff367
......@@ -10,6 +10,7 @@ vert_shader:shadow_model = shader/bin/shadow_model.vert.spv
frag_shader:shadow_model = shader/bin/shadow_model.frag.spv
vert_shader:model = shader/bin/model.vert.spv
vert_shader:model_animated = shader/bin/model_animated.vert.spv
frag_shader:model = shader/bin/model.frag.spv
frag_shader:model_emissive = shader/bin/model_emissive.frag.spv
frag_shader:model_alphatest = shader/bin/model_alphatest.frag.spv
......
......@@ -7,10 +7,9 @@
layout(early_fragment_tests) in;
layout(location = 0) in vec3 world_pos;
layout(location = 1) in vec3 view_pos;
layout(location = 2) in vec3 normal;
layout(location = 3) in vec2 tex_coords;
layout(location = 0) in vec3 view_pos;
layout(location = 1) in vec3 normal;
layout(location = 2) in vec2 tex_coords;
layout(location = 0) out vec4 depth_out;
......@@ -47,10 +46,6 @@ void main() {
depth_out = vec4(-view_pos.z / global_uniforms.proj_planes.y, 0,0,1);
albedo_mat_id_out = vec4(albedo.rgb, 0.0);
mat_data_out = vec4(encode_normal(normal), roughness, metallic);
float disect = model_uniforms.options.x;
if(disect>0 && world_pos.z>=disect)
discard;
}
vec3 decode_tangent_normal(vec2 tn) {
......
......@@ -9,13 +9,12 @@ layout(location = 0) in vec3 position;
layout(location = 1) in vec3 normal;
layout(location = 2) in vec2 tex_coords;
layout(location = 0) out vec3 out_world_pos;
layout(location = 1) out vec3 out_view_pos;
layout(location = 2) out vec3 out_normal;
layout(location = 3) out vec2 out_tex_coords;
layout(location = 0) out vec3 out_view_pos;
layout(location = 1) out vec3 out_normal;
layout(location = 2) out vec2 out_tex_coords;
layout(push_constant) uniform Per_model_uniforms {
mat4 model;
mat4 model_to_view;
vec4 light_color;
vec4 options;
} model_uniforms;
......@@ -26,15 +25,11 @@ out gl_PerVertex {
void main() {
mat4 model_to_view = global_uniforms.view_mat * model_uniforms.model;
vec4 world_pos = model_uniforms.model * vec4(position, 1.0);
vec4 view_pos = model_to_view * vec4(position, 1.0);
vec4 view_pos = model_uniforms.model_to_view * vec4(position, 1.0);
out_world_pos = world_pos.xyz / world_pos.w;
out_view_pos = view_pos.xyz / view_pos.w;
gl_Position = global_uniforms.proj_mat * view_pos;
out_normal = (model_to_view * vec4(normal, 0.0)).xyz;
out_normal = (model_uniforms.model_to_view * vec4(normal, 0.0)).xyz;
out_tex_coords = tex_coords;
gl_Position = global_uniforms.proj_mat * view_pos;
}
......@@ -5,10 +5,9 @@
#include "global_uniforms.glsl"
#include "normal_encoding.glsl"
layout(location = 0) in vec3 world_pos;
layout(location = 1) in vec3 view_pos;
layout(location = 2) in vec3 normal;
layout(location = 3) in vec2 tex_coords;
layout(location = 0) in vec3 view_pos;
layout(location = 1) in vec3 normal;
layout(location = 2) in vec2 tex_coords;
layout(location = 0) out vec4 depth_out;
......@@ -48,10 +47,6 @@ void main() {
depth_out = vec4(-view_pos.z / global_uniforms.proj_planes.y, 0,0,1);
albedo_mat_id_out = vec4(albedo.rgb, 0.0);
mat_data_out = vec4(encode_normal(normal), roughness, metallic);
float disect = model_uniforms.options.x;
if(disect>0 && world_pos.z>=disect)
discard;
}
vec3 decode_tangent_normal(vec2 tn) {
......
#version 450
#extension GL_ARB_separate_shader_objects : enable
#extension GL_ARB_shading_language_420pack : enable
#include "global_uniforms.glsl"
layout(location = 0) in vec3 position;
layout(location = 1) in vec3 normal;
layout(location = 2) in vec2 tex_coords;
layout(location = 3) in ivec4 bone_ids;
layout(location = 4) in vec4 bone_weights;
layout(location = 0) out vec3 out_view_pos;
layout(location = 1) out vec3 out_normal;
layout(location = 2) out vec2 out_tex_coords;
layout(set=2, binding = 0) uniform Bone_uniforms {
mat4 offset[64];
} bones;
layout(push_constant) uniform Per_model_uniforms {
mat4 model_to_view;
vec4 light_color;
vec4 options;
} model_uniforms;
out gl_PerVertex {
vec4 gl_Position;
};
void main() {
float unused_weight = 1.0 - dot(bone_weights, vec4(1.0));
vec4 p = bones.offset[bone_ids[0]] * vec4(position, 1.0) * bone_weights[0]
+ bones.offset[bone_ids[1]] * vec4(position, 1.0) * bone_weights[1]
+ bones.offset[bone_ids[2]] * vec4(position, 1.0) * bone_weights[2]
+ bones.offset[bone_ids[3]] * vec4(position, 1.0) * bone_weights[3]
+ vec4(position, 1.0) * unused_weight ;
vec4 n = bones.offset[bone_ids[0]] * vec4(normal, 0.0) * bone_weights[0]
+ bones.offset[bone_ids[1]] * vec4(normal, 0.0) * bone_weights[1]
+ bones.offset[bone_ids[2]] * vec4(normal, 0.0) * bone_weights[2]
+ bones.offset[bone_ids[3]] * vec4(normal, 0.0) * bone_weights[3]
+ vec4(normal, 0.0) * unused_weight ;
vec4 view_pos = model_uniforms.model_to_view * p;
out_view_pos = view_pos.xyz / view_pos.w;
out_normal = (model_uniforms.model_to_view * n).xyz;
out_tex_coords = tex_coords;
gl_Position = global_uniforms.proj_mat * view_pos;
}
......@@ -5,10 +5,9 @@
#include "global_uniforms.glsl"
#include "normal_encoding.glsl"
layout(location = 0) in vec3 world_pos;
layout(location = 1) in vec3 view_pos;
layout(location = 2) in vec3 normal;
layout(location = 3) in vec2 tex_coords;
layout(location = 0) in vec3 view_pos;
layout(location = 1) in vec3 normal;
layout(location = 2) in vec2 tex_coords;
layout(location = 0) out vec4 depth_out;
......
Subproject commit 6a57dbf0c2fcdbaa9d36671da65dbdde2377a741
Subproject commit 26cc9aa8881064c6f43caac653d809d8717f4c4e
#include "game_engine.hpp"
#include <mirrage/renderer/deferred_renderer.hpp>
#include <mirrage/renderer/pass/animation_pass.hpp>
#include <mirrage/renderer/pass/blit_pass.hpp>
#include <mirrage/renderer/pass/bloom_pass.hpp>
#include <mirrage/renderer/pass/deferred_pass.hpp>
......@@ -29,6 +30,7 @@ namespace mirrage {
*this,
window(),
util::make_vector(renderer::make_pass_factory<renderer::Frustum_culling_pass_factory>(),
renderer::make_pass_factory<renderer::Animation_pass_factory>(),
renderer::make_pass_factory<renderer::Shadowmapping_pass_factory>(),
renderer::make_pass_factory<renderer::Deferred_pass_factory>(),
renderer::make_pass_factory<renderer::Gen_mipmap_pass_factory>(),
......
......@@ -4,6 +4,7 @@
#include "meta_system.hpp"
#include "systems/nim_system.hpp"
#include <mirrage/renderer/animation_comp.hpp>
#include <mirrage/renderer/light_comp.hpp>
#include <mirrage/renderer/model_comp.hpp>
#include <mirrage/renderer/pass/gui_pass.hpp>
......@@ -71,6 +72,23 @@ namespace mirrage {
, _window_fullscreen(engine.window().fullscreen() != graphic::Fullscreen::no)
{
auto monk = _meta_system.entities().emplace("monk");
monk.get<Transform_comp>().process([](auto& transform) {
transform.position = {-8, 0, -0.5f};
transform.orientation = glm::quatLookAt(glm::vec3{-1, 0, 0}, glm::vec3{0, 1, 0});
});
monk.get<renderer::Animation_comp>().process([](auto& anim) { anim.animation("dance"_strid); });
auto chest = _meta_system.entities().emplace("chest");
chest.get<Transform_comp>().process([](auto& transform) {
transform.position = {-6, 0, -0.5f};
transform.orientation = glm::quatLookAt(glm::vec3{-1, 0, 0}, glm::vec3{0, 1, 0});
});
chest.get<renderer::Animation_comp>().process([](auto& anim) { anim.animation("close"_strid); });
_camera = _meta_system.entities().emplace("camera");
auto cornell = _meta_system.entities().emplace("cornell");
......
......@@ -4,13 +4,19 @@ project(mirrage_mesh_converter LANGUAGES CXX)
add_executable(mesh_converter
animation_parser.cpp
animation_parser.hpp
common.hpp
filesystem.cpp
filesystem.hpp
main.cpp
model_parser.hpp
model_parser.cpp
material_parser.hpp
material_parser.cpp
filesystem.hpp
filesystem.cpp
material_parser.hpp
model_parser.cpp
model_parser.hpp
skeleton_parser.cpp
skeleton_parser.hpp
${BACKWARD_ENABLE}
)
add_backward(mesh_converter)
......
#include "animation_parser.hpp"
#include "common.hpp"
#include "filesystem.hpp"
#include "skeleton_parser.hpp"
#include <mirrage/renderer/animation.hpp>
#include <mirrage/utils/log.hpp>
#include <assimp/scene.h>
#include <gsl/gsl>
#include <fstream>
#include <iostream>
#include <vector>
namespace mirrage {
namespace {
auto invalid_char(char c) { return !std::isalnum(c); }
auto to_our_behaviour(aiAnimBehaviour b)
{
using renderer::detail::Behaviour;
switch(b) {
case aiAnimBehaviour_DEFAULT: return Behaviour::node_transform;
case aiAnimBehaviour_CONSTANT: return Behaviour::nearest;
case aiAnimBehaviour_LINEAR: return Behaviour::extrapolate;
case aiAnimBehaviour_REPEAT: return Behaviour::repeat;
case _aiAnimBehaviour_Force32Bit: break;
}
MIRRAGE_FAIL("Invalid/Unexpected aiAnimBehaviour: " << static_cast<int>(b));
}
} // namespace
void parse_animations(const std::string& model_name,
const std::string& output,
const aiScene& scene,
const Mesh_converted_config& cfg,
const Skeleton_data& skeleton)
{
if(!scene.HasAnimations())
return;
create_directory(output + "/animations");
auto base_dir = output + "/animations/";
auto animations = gsl::span(scene.mAnimations, scene.mNumAnimations);
if(cfg.print_animations) {
for(auto anim : animations) {
LOG(plog::info) << "Animation for model " << model_name << ": " << anim->mName.C_Str();
}
}
for(auto anim : animations) {
using namespace renderer::detail;
auto name = std::string(anim->mName.C_Str());
name.erase(std::remove_if(name.begin(), name.end(), invalid_char), name.end());
auto animation_data = Animation_data();
animation_data.duration = static_cast<float>(anim->mDuration / anim->mTicksPerSecond);
animation_data.bones.resize(skeleton.bones.size(), Bone_animation{});
auto channels = gsl::span(anim->mChannels, anim->mNumChannels);
for(auto channel : channels) {
auto bone_idx = skeleton.bones_by_name.find(channel->mNodeName.C_Str());
if(bone_idx == skeleton.bones_by_name.end()) {
LOG(plog::warning) << "Couldn't find bone '" << channel->mNodeName.C_Str()
<< "' referenced by animation: " << anim->mName.C_Str();
continue;
}
auto& per_bone_data = animation_data.bones.at(std::size_t(bone_idx->second));
per_bone_data.pre_behaviour = to_our_behaviour(channel->mPreState);
per_bone_data.post_behaviour = to_our_behaviour(channel->mPostState);
per_bone_data.positions.reserve(channel->mNumPositionKeys);
for(auto i = 0; i < int(channel->mNumPositionKeys); i++) {
auto& p = channel->mPositionKeys[i];
per_bone_data.positions.emplace_back(static_cast<float>(p.mTime / anim->mTicksPerSecond),
p.mValue.x,
p.mValue.y,
p.mValue.z);
}
per_bone_data.scales.reserve(channel->mNumScalingKeys);
for(auto i = 0; i < int(channel->mNumScalingKeys); i++) {
auto& p = channel->mScalingKeys[i];
per_bone_data.scales.emplace_back(static_cast<float>(p.mTime / anim->mTicksPerSecond),
p.mValue.x,
p.mValue.y,
p.mValue.z);
}
per_bone_data.rotations.reserve(channel->mNumRotationKeys);
for(auto i = 0; i < int(channel->mNumRotationKeys); i++) {
auto& p = channel->mRotationKeys[i];
per_bone_data.rotations.emplace_back(static_cast<float>(p.mTime / anim->mTicksPerSecond),
p.mValue.w,
p.mValue.x,
p.mValue.y,
p.mValue.z);
}
}
auto filename = base_dir + name + ".maf";
util::to_lower_inplace(filename);
auto file = std::ofstream(filename);
MIRRAGE_INVARIANT(file, "Couldn't open output animation file for: " << name);
sf2::serialize_json(file, animation_data);
}
}
} // namespace mirrage
#pragma once
#include <string>
struct aiScene;
namespace mirrage {
struct Skeleton_data;
struct Mesh_converted_config;
extern void parse_animations(const std::string& model_name,
const std::string& output,
const aiScene& scene,
const Mesh_converted_config& cfg,
const Skeleton_data&);
} // namespace mirrage
#pragma once
#include <assimp/scene.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <sf2/sf2.hpp>
#include <iostream>
#include <string>
#include <type_traits>
#include <unordered_map>
#include <vector>
namespace mirrage {
sf2_enum(Texture_type, albedo, metalness, roughness, normal, emission);
using Texture_mapping = std::unordered_map<Texture_type, std::vector<int>>;
struct Mesh_converted_config {
Texture_mapping texture_mappings{
{Texture_type::albedo, {1}}, // aiTextureType_DIFFUSE
{Texture_type::metalness, {3}}, // aiTextureType_AMBIENT
{Texture_type::roughness, {7, 2}}, // aiTextureType_SHININESS, aiTextureType_SPECULAR
{Texture_type::normal, {6, 5}}, // aiTextureType_NORMALS, aiTextureType_HEIGHT
{Texture_type::emission, {4}}, // aiTextureType_EMISSIVE
};
std::unordered_map<std::string, std::unordered_map<Texture_type, std::string>>
material_texture_override;
std::vector<std::string> empty_bones_to_keep;
std::string default_output_directory = "output";
bool print_material_info = false;
bool print_animations = true;
};
sf2_structDef(Mesh_converted_config,
texture_mappings,
material_texture_override,
empty_bones_to_keep,
default_output_directory,
print_material_info,
print_animations);
template <typename T>
void write(std::ostream& out, const T& value)
{
static_assert(!std::is_pointer<T>::value, "T is a pointer. That is DEFINITLY not what you wanted!");
out.write(reinterpret_cast<const char*>(&value), sizeof(T));
}
template <typename T>
void write(std::ostream& out, const std::vector<T>& value)
{
static_assert(!std::is_pointer<T>::value, "T is a pointer. That is DEFINITLY not what you wanted!");
out.write(reinterpret_cast<const char*>(value.data()), value.size() * sizeof(T));
}
inline auto to_glm(aiMatrix4x4 in) -> glm::mat4
{
/*
return glm::transpose(glm::mat4{{in.a1, in.a2, in.a3, in.a4},
{in.b1, in.b2, in.b3, in.b4},
{in.c1, in.c2, in.c3, in.c4},
{in.d1, in.d2, in.d3, in.d4}});
*/
return glm::transpose(glm::make_mat4(&in.a1));
;
}
inline auto to_glm(aiVector3D v) { return glm::vec3(v.x, v.y, v.z); }
} // namespace mirrage
......@@ -4,7 +4,9 @@
#ifdef _WIN32
#include <direct.h>
#include <io.h>
#include <windows.h>
#define access _access_s
#else
#include <sys/stat.h>
#include <unistd.h>
......@@ -23,4 +25,7 @@ namespace mirrage {
"Couldn't create directory \"" << dir << "\": " << int(errno));
#endif
}
auto exists(const std::string& name) -> bool { return access(name.c_str(), 0) == 0; }
} // namespace mirrage
......@@ -6,4 +6,7 @@
namespace mirrage {
extern void create_directory(const std::string& name);
}
extern auto exists(const std::string& name) -> bool;
} // namespace mirrage
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment