Merge branch 'main' of https://github.com/antopilo/Nuake
This commit is contained in:
@@ -27,5 +27,5 @@ void main()
|
||||
vec4 a = texture(u_Source, UV);
|
||||
vec4 b = texture(u_Source2, UV);
|
||||
|
||||
FragColor = vec4(vec3(a.rgb + b.rgb / 2.0), a.a * b.a);
|
||||
FragColor = vec4(vec3(a.rgb + (b.rgb) / 2.0), a.a);
|
||||
}
|
||||
@@ -180,7 +180,7 @@ float ShadowCalculation(Light light, vec3 FragPos, vec3 normal)
|
||||
float bias = max(0.005 * (1.0 - dot(normal, light.Direction)), 0.0005);
|
||||
//float pcfDepth = texture(ShadowMaps[shadowmap], vec3(projCoords.xy, currentDepth), bias);
|
||||
|
||||
if (shadowmap <= 3)
|
||||
if (shadowmap <= 4)
|
||||
{
|
||||
const float NUM_SAMPLES = 4.f;
|
||||
const float SAMPLES_START = (NUM_SAMPLES - 1.0f) / 2.0f;
|
||||
@@ -272,7 +272,7 @@ void main()
|
||||
|
||||
// scale light by NdotL
|
||||
float NdotL = max(dot(N, L), 0.0);
|
||||
Lo += (kD * albedo / PI) * radiance * NdotL;// note that we already multiplied the BRDF by the Fresnel (kS) so we won't multiply by kS again
|
||||
Lo += (kD * albedo / PI + specular) * radiance * NdotL;// note that we already multiplied the BRDF by the Fresnel (kS) so we won't multiply by kS again
|
||||
}
|
||||
|
||||
/// ambient lighting (we now use IBL as the ambient term)
|
||||
@@ -282,7 +282,7 @@ void main()
|
||||
vec3 kD = 1.0 - kS;
|
||||
kD *= 1.0 - metallic;
|
||||
|
||||
vec3 ambient = (kD * albedo) * (ao) * ssao;
|
||||
vec3 ambient = (vec3(0.5) * albedo) * (ao)*ssao;
|
||||
vec3 color = (ambient) + Lo;
|
||||
|
||||
// Display CSM splits..
|
||||
|
||||
45
Editor/resources/Shaders/shadowMap_skinned.shader
Normal file
45
Editor/resources/Shaders/shadowMap_skinned.shader
Normal file
@@ -0,0 +1,45 @@
|
||||
#shader vertex
|
||||
#version 460 core
|
||||
|
||||
layout(location = 0) in vec3 Position;
|
||||
layout(location = 1) in vec2 UVPosition;
|
||||
layout(location = 2) in vec3 Normal;
|
||||
layout(location = 3) in vec3 Tangent;
|
||||
layout(location = 4) in vec3 Bitangent;
|
||||
layout(location = 5) in ivec4 BoneIDs;
|
||||
layout(location = 6) in vec4 Weights;
|
||||
|
||||
uniform mat4 u_LightTransform;
|
||||
|
||||
const int MAX_BONES = 200;
|
||||
const int MAX_BONES_INFLUENCE = 4;
|
||||
uniform mat4 u_FinalBonesMatrice[MAX_BONES];
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 totalPosition = vec4(0.0f);
|
||||
for (int i = 0; i < MAX_BONES_INFLUENCE; i++)
|
||||
{
|
||||
if (BoneIDs[i] == -1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (BoneIDs[i] >= MAX_BONES)
|
||||
{
|
||||
totalPosition = vec4(Position, 1.0f);
|
||||
break;
|
||||
}
|
||||
|
||||
vec4 localPosition = u_FinalBonesMatrice[BoneIDs[i]] * vec4(Position, 1.0f);
|
||||
totalPosition += localPosition * Weights[i];
|
||||
// vec3 localNormal = mat3(u_FinalBonesMatrice[BoneIDs[i]]) * Normal;
|
||||
}
|
||||
|
||||
gl_Position = u_LightTransform * totalPosition;
|
||||
}
|
||||
|
||||
#shader fragment
|
||||
#version 460 core
|
||||
|
||||
void main() { }
|
||||
@@ -46,6 +46,7 @@
|
||||
#include "src/Rendering/SceneRenderer.h"
|
||||
#include <dependencies/glfw/include/GLFW/glfw3.h>
|
||||
#include <src/Rendering/Buffers/Framebuffer.h>
|
||||
#include "UIDemoWindow.h"
|
||||
|
||||
namespace Nuake {
|
||||
Ref<UI::UserInterface> userInterface;
|
||||
@@ -1544,6 +1545,7 @@ namespace Nuake {
|
||||
|
||||
bool isLoadingProject = false;
|
||||
bool isLoadingProjectQueue = false;
|
||||
UIDemoWindow m_DemoWindow;
|
||||
|
||||
int frameCount = 2;
|
||||
void EditorInterface::Draw()
|
||||
@@ -1610,6 +1612,8 @@ namespace Nuake {
|
||||
|
||||
pInterface.m_CurrentProject = Engine::GetProject();
|
||||
|
||||
m_DemoWindow.Draw();
|
||||
|
||||
_audioWindow->Draw();
|
||||
|
||||
DrawMenuBar();
|
||||
|
||||
@@ -62,9 +62,9 @@ namespace Nuake
|
||||
void FileSystemUI::DrawDirectory(Ref<Directory> directory, uint32_t drawId)
|
||||
{
|
||||
ImGui::PushFont(FontManager::GetFont(Icons));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 4.0f);
|
||||
const char* icon = ICON_FA_FOLDER;
|
||||
const std::string id = ICON_FA_FOLDER + std::string("##") + directory->name;
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 4.0f);
|
||||
if (ImGui::Button(id.c_str(), ImVec2(100, 100)))
|
||||
{
|
||||
m_CurrentDirectory = directory;
|
||||
|
||||
20
Editor/src/Windows/UIDemoWindow.cpp
Normal file
20
Editor/src/Windows/UIDemoWindow.cpp
Normal file
@@ -0,0 +1,20 @@
|
||||
#include "UIDemoWindow.h"
|
||||
|
||||
#include "src/UI/ImUI.h"
|
||||
|
||||
float floatSlider = 0.6f;
|
||||
bool checkbox = false;
|
||||
|
||||
void UIDemoWindow::Draw()
|
||||
{
|
||||
using namespace Nuake;
|
||||
|
||||
UI::BeginWindow("UI Demo");
|
||||
{
|
||||
UI::PrimaryButton("Primary Button");
|
||||
UI::SecondaryButton("Secondary Button");
|
||||
UI::FloatSlider("Float slider", floatSlider);
|
||||
UI::CheckBox("Checkbox", checkbox);
|
||||
}
|
||||
UI::EndWindow();
|
||||
}
|
||||
13
Editor/src/Windows/UIDemoWindow.h
Normal file
13
Editor/src/Windows/UIDemoWindow.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
class UIDemoWindow
|
||||
{
|
||||
public:
|
||||
UIDemoWindow() = default;
|
||||
~UIDemoWindow() = default;
|
||||
|
||||
void Draw();
|
||||
};
|
||||
|
||||
|
||||
@@ -174,12 +174,12 @@ namespace Nuake
|
||||
fileWriter.close();
|
||||
}
|
||||
|
||||
int FileSystem::DeleteFileFromPath(const std::string& path)
|
||||
uintmax_t FileSystem::DeleteFileFromPath(const std::string& path)
|
||||
{
|
||||
return std::remove(path.c_str());
|
||||
}
|
||||
|
||||
int FileSystem::DeleteFolder(const std::string& path)
|
||||
uintmax_t FileSystem::DeleteFolder(const std::string& path)
|
||||
{
|
||||
return std::filesystem::remove_all(path.c_str());
|
||||
}
|
||||
|
||||
@@ -47,8 +47,8 @@ namespace Nuake
|
||||
static bool BeginWriteFile(const std::string path);
|
||||
static bool WriteLine(const std::string line);
|
||||
static void EndWriteFile();
|
||||
static int DeleteFileFromPath(const std::string& path);
|
||||
static int DeleteFolder(const std::string& path);
|
||||
static uintmax_t DeleteFileFromPath(const std::string& path);
|
||||
static uintmax_t DeleteFolder(const std::string& path);
|
||||
};
|
||||
|
||||
class File
|
||||
|
||||
@@ -49,8 +49,12 @@ namespace Nuake
|
||||
|
||||
for (auto& m : i.second)
|
||||
{
|
||||
if (!depthOnly)
|
||||
{
|
||||
shader->SetUniform1i(entityIdUniformLocation, m.entityId + 1);
|
||||
}
|
||||
|
||||
shader->SetUniformMat4f(modelMatrixUniformLocation, m.transform);
|
||||
shader->SetUniform1i(entityIdUniformLocation, m.entityId + 1);
|
||||
m.Mesh->Draw(shader, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -262,6 +262,43 @@ namespace Nuake
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Shader* gBufferSkinnedMeshShader = ShaderManager::GetShader("resources/Shaders/shadowMap_skinned.shader");
|
||||
gBufferSkinnedMeshShader->Bind();
|
||||
const uint32_t modelMatrixUniformLocation = gBufferSkinnedMeshShader->FindUniformLocation("u_Model");
|
||||
gBufferSkinnedMeshShader->SetUniformMat4f(modelMatrixUniformLocation, Matrix4(1.0f));
|
||||
|
||||
auto skinnedView = scene.m_Registry.view<TransformComponent, SkinnedModelComponent, VisibilityComponent>();
|
||||
for (auto l : view)
|
||||
{
|
||||
auto [lightTransform, light, visibility] = view.get<TransformComponent, LightComponent, VisibilityComponent>(l);
|
||||
if (light.Type != LightType::Directional || !light.CastShadows || !visibility.Visible)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int i = 0; i < CSM_AMOUNT; i++)
|
||||
{
|
||||
light.m_Framebuffers[i]->Bind();
|
||||
{
|
||||
gBufferSkinnedMeshShader->SetUniformMat4f("u_LightTransform", light.mViewProjections[i]);
|
||||
for (auto e : skinnedView)
|
||||
{
|
||||
auto [transform, mesh, visibility] = skinnedView.get<TransformComponent, SkinnedModelComponent, VisibilityComponent>(e);
|
||||
if (mesh.ModelResource != nullptr && visibility.Visible)
|
||||
{
|
||||
auto& rootBoneNode = mesh.ModelResource->GetSkeletonRootNode();
|
||||
SetSkeletonBoneTransformRecursive(rootBoneNode, gBufferSkinnedMeshShader);
|
||||
|
||||
for (auto& m : mesh.ModelResource->GetMeshes())
|
||||
{
|
||||
m->Draw(gBufferSkinnedMeshShader, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SceneRenderer::GBufferPass(Scene& scene)
|
||||
@@ -293,10 +330,8 @@ namespace Nuake
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Renderer::Flush(gBufferShader, false);
|
||||
|
||||
|
||||
// Quake BSPs
|
||||
auto quakeView = scene.m_Registry.view<TransformComponent, BSPBrushComponent, VisibilityComponent>();
|
||||
for (auto e : quakeView)
|
||||
@@ -311,9 +346,9 @@ namespace Nuake
|
||||
Renderer::SubmitMesh(b, transform.GetGlobalTransform(), (uint32_t)e);
|
||||
}
|
||||
}
|
||||
|
||||
Renderer::Flush(gBufferShader, false);
|
||||
|
||||
RenderCommand::Disable(RendererEnum::FACE_CULL);
|
||||
// Sprites
|
||||
auto spriteView = scene.m_Registry.view<TransformComponent, SpriteComponent, VisibilityComponent>();
|
||||
for (auto& e : spriteView)
|
||||
@@ -399,7 +434,6 @@ namespace Nuake
|
||||
if (meshResource && visibility.Visible)
|
||||
{
|
||||
auto& rootBoneNode = meshResource->GetSkeletonRootNode();
|
||||
|
||||
SetSkeletonBoneTransformRecursive(rootBoneNode, gBufferSkinnedMeshShader);
|
||||
|
||||
for (auto& m : mesh.ModelResource->GetMeshes())
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace Nuake
|
||||
}
|
||||
}
|
||||
|
||||
Texture::Texture(glm::vec2 size, GLenum format, GLenum format2, GLenum format3, void* data)
|
||||
Texture::Texture(Vector2 size, GLenum format, GLenum format2, GLenum format3, void* data)
|
||||
{
|
||||
m_RendererId = 0;
|
||||
m_Format = format;
|
||||
@@ -67,24 +67,20 @@ namespace Nuake
|
||||
//glGenerateMipmap(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
Texture::Texture(Vector2 size, unsigned char* data, int len)
|
||||
Texture::Texture(unsigned char* data, int len)
|
||||
{
|
||||
m_RendererId = 0;
|
||||
m_Width = size.x;
|
||||
m_Height = size.y;
|
||||
int channels = 0;
|
||||
m_LocalBuffer = stbi_load_from_memory(data, len, &m_Width, &m_Height, &channels, 0);
|
||||
glGenTextures(1, &m_RendererId);
|
||||
glBindTexture(GL_TEXTURE_2D, m_RendererId);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, -1.0f);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, m_Width, m_Height, 0, GL_RGB, GL_UNSIGNED_BYTE, m_LocalBuffer);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_Width, m_Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_LocalBuffer);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
|
||||
if (m_LocalBuffer)
|
||||
@@ -93,12 +89,12 @@ namespace Nuake
|
||||
}
|
||||
else
|
||||
{
|
||||
const std::string msg = "failed to load texture buffer";
|
||||
const std::string msg = "Failed to load texture from buffer";
|
||||
Logger::Log(msg, "texture", WARNING);
|
||||
}
|
||||
}
|
||||
|
||||
Texture::Texture(glm::vec2 size, msdfgen::BitmapConstRef<unsigned char, 4>& bitmap, bool t)
|
||||
Texture::Texture(Vector2 size, msdfgen::BitmapConstRef<unsigned char, 4>& bitmap, bool t)
|
||||
{
|
||||
m_RendererId = 0;
|
||||
m_Width = size.x;
|
||||
@@ -110,7 +106,6 @@ namespace Nuake
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
|
||||
auto pixel = bitmap(0, bitmap.height - 0 - 1);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_Width, m_Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (unsigned char*)bitmap.pixels);
|
||||
}
|
||||
|
||||
@@ -28,10 +28,11 @@ namespace Nuake
|
||||
int m_BPP; // byte per pixel.
|
||||
|
||||
public:
|
||||
Texture(const std::string& path);
|
||||
Texture(glm::vec2 size, msdfgen::BitmapConstRef<unsigned char, 4>& bitmap, bool t);
|
||||
Texture(glm::vec2 size, GLenum format, GLenum format2 = 0, GLenum format3 = 0, void* data = NULL);
|
||||
Texture(Vector2 size, unsigned char* data, int len);
|
||||
Texture(const std::string& path); // Load texture from file
|
||||
Texture(unsigned char* data, int len); // Used to load texture from a memory buffer
|
||||
|
||||
Texture(Vector2 size, GLenum format, GLenum format2 = 0, GLenum format3 = 0, void* data = 0); // Used to load texture from memeory with known size
|
||||
Texture(Vector2 size, msdfgen::BitmapConstRef<unsigned char, 4>& bitmap, bool t); // Used internally for MSDF fonts
|
||||
~Texture();
|
||||
|
||||
void Resize(glm::vec2 size);
|
||||
|
||||
@@ -522,9 +522,19 @@ namespace Nuake
|
||||
uint32_t textureIndex = std::atoi(String::Split(path, '*')[1].c_str());
|
||||
const aiTexture* aitexture = scene->GetEmbeddedTexture(path.c_str());
|
||||
|
||||
Vector2 textureSize = Vector2(aitexture->mWidth, aitexture->mHeight);
|
||||
auto texture = CreateRef<Texture>(textureSize, (unsigned char*)aitexture->pcData, textureSize.x);
|
||||
return texture;
|
||||
Ref<Texture> nuakeTexture;
|
||||
if (aitexture->mHeight == 0)
|
||||
{
|
||||
// We are using a compression like jpeg, where width is the size of the buffer in bytes.
|
||||
nuakeTexture = CreateRef<Texture>((unsigned char*)aitexture->pcData, aitexture->mWidth);
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector2 textureSize = Vector2(aitexture->mWidth, aitexture->mHeight);
|
||||
nuakeTexture = CreateRef<Texture>((unsigned char*)aitexture->pcData, textureSize.x);
|
||||
}
|
||||
|
||||
return nuakeTexture;
|
||||
}
|
||||
|
||||
std::string texturePath = modelDir + path;
|
||||
|
||||
@@ -34,6 +34,27 @@ p = j[#p]; \
|
||||
#define DESERIALIZE_VEC2(v, p) \
|
||||
p = Vector2(v["x"], v["y"]);
|
||||
|
||||
#define SERIALIZE_MAT4(lbl, m) \
|
||||
{ \
|
||||
int i = 0; \
|
||||
for (int l = 0; l < 4; l++) { \
|
||||
for (int k = 0; k < 4; k++) { \
|
||||
j[lbl][i] = m[l][k]; \
|
||||
i++; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
#define DESERIALIZE_MAT4(lbl, m) \
|
||||
{ \
|
||||
int i = 0; \
|
||||
for(int l = 0; l < 4; l++) { \
|
||||
for(int k = 0; k < 4; k++) { \
|
||||
m[l][k] = j[lbl][i];\
|
||||
i++; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
#define SERIALIZE_OBJECT(v) j[#v] = v->Serialize();
|
||||
#define SERIALIZE_OBJECT_REF(v) j[#v] = v.Serialize();
|
||||
|
||||
@@ -11,6 +11,11 @@ namespace Nuake
|
||||
m_PositionTimestamps = std::vector<float>();
|
||||
m_RotationTimestamps = std::vector<float>();
|
||||
m_ScaleTimestamps = std::vector<float>();
|
||||
|
||||
m_PositionTransform = Matrix4(1.0f);
|
||||
m_RotationTransform = Matrix4(1.0f);
|
||||
m_ScaleTransform = Matrix4(1.0f);
|
||||
m_FinalTransform = Matrix4(1.0f);
|
||||
}
|
||||
|
||||
float BoneTransformTrack::GetScaleFactor(float lastTime, float nextTime, float animationTime)
|
||||
@@ -22,7 +27,7 @@ namespace Nuake
|
||||
return scaleFactor;
|
||||
}
|
||||
|
||||
Nuake::Matrix4 BoneTransformTrack::InterpolatePosition(float time)
|
||||
Matrix4 BoneTransformTrack::InterpolatePosition(float time)
|
||||
{
|
||||
if (m_Positions.size() == 0)
|
||||
{
|
||||
@@ -34,14 +39,20 @@ namespace Nuake
|
||||
return glm::translate(Matrix4(1.0f), m_Positions[0]);
|
||||
}
|
||||
|
||||
// This returns the last position when we are at the last keyframe
|
||||
int p0Index = GetPositionIndex(time);
|
||||
if (p0Index == m_Positions.size() - 1)
|
||||
{
|
||||
return glm::translate(Matrix4(1.0f), m_Positions[p0Index]);
|
||||
}
|
||||
|
||||
int p1Index = p0Index + 1;
|
||||
float scaleFactor = GetScaleFactor(m_PositionTimestamps[p0Index], m_PositionTimestamps[p1Index], time);
|
||||
glm::vec3 finalPosition = glm::mix(m_Positions[p0Index], m_Positions[p1Index], scaleFactor);
|
||||
Vector3 finalPosition = glm::mix(m_Positions[p0Index], m_Positions[p1Index], scaleFactor);
|
||||
return glm::translate(Matrix4(1.0f), finalPosition);
|
||||
}
|
||||
|
||||
Nuake::Matrix4 BoneTransformTrack::InterpolateRotation(float time)
|
||||
Matrix4 BoneTransformTrack::InterpolateRotation(float time)
|
||||
{
|
||||
if (m_Rotations.size() == 0)
|
||||
{
|
||||
@@ -54,17 +65,21 @@ namespace Nuake
|
||||
return glm::toMat4(rotation);
|
||||
}
|
||||
|
||||
// This returns the last rotation when we are at the last keyframe
|
||||
int p0Index = GetRotationIndex(time);
|
||||
if (p0Index == m_Rotations.size() - 1)
|
||||
{
|
||||
return glm::toMat4(m_Rotations[p0Index]);
|
||||
}
|
||||
|
||||
int p1Index = p0Index + 1;
|
||||
float scaleFactor = GetScaleFactor(m_RotationTimestamps[p0Index],
|
||||
m_RotationTimestamps[p1Index], time);
|
||||
glm::quat finalRotation = glm::slerp(m_Rotations[p0Index],
|
||||
m_Rotations[p1Index], scaleFactor);
|
||||
float scaleFactor = GetScaleFactor(m_RotationTimestamps[p0Index], m_RotationTimestamps[p1Index], time);
|
||||
Quat finalRotation = glm::slerp(m_Rotations[p0Index],m_Rotations[p1Index], scaleFactor);
|
||||
finalRotation = glm::normalize(finalRotation);
|
||||
return glm::toMat4(finalRotation);
|
||||
}
|
||||
|
||||
Nuake::Matrix4 BoneTransformTrack::InterpolateScale(float time)
|
||||
Matrix4 BoneTransformTrack::InterpolateScale(float time)
|
||||
{
|
||||
if (m_Scales.size() == 0)
|
||||
{
|
||||
@@ -72,14 +87,21 @@ namespace Nuake
|
||||
}
|
||||
|
||||
if (1 == m_Scales.size())
|
||||
{
|
||||
return glm::scale(glm::mat4(1.0f), m_Scales[0]);
|
||||
}
|
||||
|
||||
// This returns the last rotation when we are at the last keyframe
|
||||
int p0Index = GetScaleIndex(time);
|
||||
if (p0Index == m_Scales.size() - 1)
|
||||
{
|
||||
return glm::scale(Matrix4(1.0f), m_Scales[p0Index]);
|
||||
}
|
||||
|
||||
int p1Index = p0Index + 1;
|
||||
float scaleFactor = GetScaleFactor(m_ScaleTimestamps[p0Index],
|
||||
m_ScaleTimestamps[p1Index], time);
|
||||
glm::vec3 finalScale = glm::mix(m_Scales[p0Index], m_Scales[p1Index], scaleFactor);
|
||||
return glm::scale(glm::mat4(1.0f), finalScale);
|
||||
float scaleFactor = GetScaleFactor(m_ScaleTimestamps[p0Index], m_ScaleTimestamps[p1Index], time);
|
||||
Vector3 finalScale = glm::mix(m_Scales[p0Index], m_Scales[p1Index], scaleFactor);
|
||||
return glm::scale(Matrix4(1.0f), finalScale);
|
||||
}
|
||||
|
||||
json BoneTransformTrack::Serialize()
|
||||
|
||||
@@ -59,25 +59,11 @@ namespace Nuake
|
||||
m_Scales.push_back(scale);
|
||||
}
|
||||
|
||||
int GetPositionIndex(float animationTime)
|
||||
{
|
||||
if (m_Positions.size() == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (int index = 0; index < m_Positions.size() - 1; index++)
|
||||
{
|
||||
if (animationTime < m_PositionTimestamps[index + 1])
|
||||
{
|
||||
return index;
|
||||
}
|
||||
}
|
||||
assert(0);
|
||||
}
|
||||
|
||||
void Update(float time)
|
||||
{
|
||||
// We cannot use const reference here because we would compare the reference to previous pos
|
||||
// to the m_PositionTransform and previous pos always equale.
|
||||
// Making the hasChanged always false. We would end up comparing the same values always.
|
||||
const Matrix4 previousPos = m_PositionTransform;
|
||||
const Matrix4 previousRot = m_RotationTransform;
|
||||
const Matrix4 previousSca = m_ScaleTransform;
|
||||
@@ -97,6 +83,24 @@ namespace Nuake
|
||||
return m_FinalTransform;
|
||||
}
|
||||
|
||||
int GetPositionIndex(float animationTime)
|
||||
{
|
||||
if (m_Positions.size() == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (int index = 0; index < m_Positions.size() - 1; index++)
|
||||
{
|
||||
if (animationTime < m_PositionTimestamps[index + 1])
|
||||
{
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
return static_cast<int>(m_Positions.size()) - 1;
|
||||
}
|
||||
|
||||
/* Gets the current index on mKeyRotations to interpolate to based on the
|
||||
current animation time*/
|
||||
int GetRotationIndex(float animationTime)
|
||||
@@ -108,7 +112,8 @@ namespace Nuake
|
||||
return index;
|
||||
}
|
||||
}
|
||||
assert(0);
|
||||
|
||||
return static_cast<int>(m_Rotations.size()) - 1;
|
||||
}
|
||||
|
||||
/* Gets the current index on mKeyScalings to interpolate to based on the
|
||||
@@ -122,7 +127,8 @@ namespace Nuake
|
||||
return index;
|
||||
}
|
||||
}
|
||||
assert(0);
|
||||
|
||||
return static_cast<int>(m_Scales.size()) - 1;
|
||||
}
|
||||
|
||||
float GetScaleFactor(float lastTime, float nextTime, float animationTime);
|
||||
@@ -158,7 +164,7 @@ namespace Nuake
|
||||
}
|
||||
else
|
||||
{
|
||||
m_CurrentTime = time;
|
||||
m_CurrentTime = std::max(time, m_Duration);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
#include "src/Core/Core.h"
|
||||
#include "src/Core/Maths.h"
|
||||
#include "src/Resource/Serializable.h"
|
||||
|
||||
namespace Nuake
|
||||
{
|
||||
@@ -14,5 +15,47 @@ namespace Nuake
|
||||
Matrix4 FinalTransform = Matrix4(1.0f);
|
||||
int32_t Id = -1;
|
||||
int32_t EntityHandle = 0;
|
||||
|
||||
json Serialize()
|
||||
{
|
||||
BEGIN_SERIALIZE();
|
||||
SERIALIZE_MAT4("Transform", Transform);
|
||||
SERIALIZE_MAT4("Offset", Offset);
|
||||
SERIALIZE_VAL(Name);
|
||||
SERIALIZE_VAL(ChildrenCount);
|
||||
SERIALIZE_VAL(Id);
|
||||
SERIALIZE_VAL(EntityHandle);
|
||||
|
||||
uint32_t i = 0;
|
||||
for (auto& c : Children)
|
||||
{
|
||||
j["Children"][i] = c.Serialize();
|
||||
i++;
|
||||
}
|
||||
|
||||
END_SERIALIZE();
|
||||
}
|
||||
|
||||
bool Deserialize(json j)
|
||||
{
|
||||
DESERIALIZE_MAT4("Transform", Transform);
|
||||
DESERIALIZE_MAT4("Offset", Offset);
|
||||
DESERIALIZE_VAL(Name);
|
||||
DESERIALIZE_VAL(ChildrenCount);
|
||||
DESERIALIZE_VAL(Id);
|
||||
DESERIALIZE_VAL(EntityHandle);
|
||||
|
||||
if (j.contains("Children"))
|
||||
{
|
||||
for (uint32_t i = 0; i < ChildrenCount; i++)
|
||||
{
|
||||
SkeletonNode newChildren;
|
||||
newChildren.Deserialize(j["Children"][i]);
|
||||
Children.push_back(std::move(newChildren));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -71,6 +71,7 @@ namespace Nuake
|
||||
if (this->Path != "")
|
||||
{
|
||||
j["Path"] = this->Path;
|
||||
j["SkeletonNode"] = m_SkeletonRoot.Serialize();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -86,10 +87,9 @@ namespace Nuake
|
||||
for (auto& animation : m_Animations)
|
||||
{
|
||||
j["m_Animations"][a] = animation->Serialize();
|
||||
a++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
END_SERIALIZE();
|
||||
}
|
||||
@@ -108,6 +108,13 @@ namespace Nuake
|
||||
m_NumAnimation = m_Animations.size();
|
||||
m_CurrentAnimation = 0;
|
||||
|
||||
if (j.contains("SkeletonNode"))
|
||||
{
|
||||
SkeletonNode skeletonNode;
|
||||
skeletonNode.Deserialize(j["SkeletonNode"]);
|
||||
m_SkeletonRoot = std::move(skeletonNode);
|
||||
}
|
||||
|
||||
this->Path = j["Path"];
|
||||
}
|
||||
else
|
||||
|
||||
@@ -35,6 +35,7 @@ namespace Nuake
|
||||
bool Deserialize(const json& j)
|
||||
{
|
||||
ModelPath = j["ModelPath"];
|
||||
|
||||
ModelResource = CreateRef<SkinnedModel>();
|
||||
|
||||
if (j.contains("ModelResource"))
|
||||
|
||||
@@ -486,7 +486,6 @@ namespace Nuake
|
||||
skeletonRoot.EntityHandle = skeletonRootEntity.GetID();
|
||||
entity.AddChild(skeletonRootEntity);
|
||||
|
||||
|
||||
Vector3 bonePosition;
|
||||
Quat boneRotation;
|
||||
Vector3 boneScale;
|
||||
|
||||
@@ -36,28 +36,24 @@ namespace Nuake
|
||||
{
|
||||
float newAnimationTime = animation->GetCurrentTime() + (ts * animation->GetTicksPerSecond());
|
||||
animation->SetCurrentTime(newAnimationTime);
|
||||
|
||||
auto& rootBone = model->GetSkeletonRootNode();
|
||||
UpdateBonePositionTraversal(rootBone, animation, animation->GetCurrentTime());
|
||||
}
|
||||
|
||||
auto& rootBone = model->GetSkeletonRootNode();
|
||||
UpdateBonePositionTraversal(rootBone, animation, animation->GetCurrentTime(), model->IsPlaying);
|
||||
}
|
||||
}
|
||||
|
||||
void AnimationSystem::UpdateBonePositionTraversal(SkeletonNode& bone, Ref<SkeletalAnimation> animation, float time)
|
||||
void AnimationSystem::UpdateBonePositionTraversal(SkeletonNode& bone, Ref<SkeletalAnimation> animation, float time, bool isPlaying)
|
||||
{
|
||||
const std::string& boneName = bone.Name;
|
||||
|
||||
auto& animationTrack = animation->GetTrack(boneName);
|
||||
auto& animationTrack = animation->GetTrack(bone.Name);
|
||||
|
||||
Entity& boneEntity = m_Scene->GetEntity(boneName);
|
||||
Entity& boneEnt = m_Scene->GetEntityByID(bone.EntityHandle);
|
||||
///assert(boneEnt.GetHandle() == boneEntity.GetHandle());
|
||||
if (boneEnt.IsValid())
|
||||
{
|
||||
auto& transformComponent = boneEnt.GetComponent<TransformComponent>();
|
||||
bone.FinalTransform = transformComponent.GetGlobalTransform() * bone.Offset;
|
||||
|
||||
//if (!animationTrack.IsEmpty())
|
||||
if (!animationTrack.IsEmpty() && isPlaying)
|
||||
{
|
||||
// Get Update transform
|
||||
animationTrack.Update(time);
|
||||
@@ -76,10 +72,10 @@ namespace Nuake
|
||||
transformComponent.Dirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (auto& childBone : bone.Children)
|
||||
{
|
||||
UpdateBonePositionTraversal(childBone, animation, time);
|
||||
UpdateBonePositionTraversal(childBone, animation, time, isPlaying);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,6 @@ namespace Nuake
|
||||
void Exit() override;
|
||||
|
||||
private:
|
||||
void UpdateBonePositionTraversal(SkeletonNode& bone, Ref<SkeletalAnimation> animation, float time);
|
||||
void UpdateBonePositionTraversal(SkeletonNode& bone, Ref<SkeletalAnimation> animation, float time, bool isPlaying);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -78,8 +78,9 @@ namespace Nuake
|
||||
Quat globalOrientation = transform.GetLocalRotation();
|
||||
Vector3 globalScale = transform.GetLocalScale();
|
||||
|
||||
#ifndef FRAME_PERFECT_TRANSFORM
|
||||
ParentComponent parentComponent = currentParent.GetComponent<ParentComponent>();
|
||||
#define FRAME_PERFECT_TRANSFORM
|
||||
#ifndef FRAME_PERFECT_TRANSFORM
|
||||
if (parentComponent.HasParent)
|
||||
{
|
||||
TransformComponent& transformComponent = parentComponent.Parent.GetComponent<TransformComponent>();
|
||||
|
||||
154
Nuake/src/UI/ImUI.h
Normal file
154
Nuake/src/UI/ImUI.h
Normal file
@@ -0,0 +1,154 @@
|
||||
#pragma once
|
||||
#include "src/Core/Core.h"
|
||||
#include "src/Core/Maths.h"
|
||||
|
||||
#include "imgui/imgui.h"
|
||||
#include "../../../Editor/src/Misc/InterfaceFonts.h"
|
||||
|
||||
#include "src/Resource/FontAwesome5.h"
|
||||
|
||||
namespace Nuake
|
||||
{
|
||||
namespace UI
|
||||
{
|
||||
static uint32_t PrimaryCol = IM_COL32(97, 0, 255, 255);
|
||||
static uint32_t GrabCol = IM_COL32(97, 0, 255, 255);
|
||||
|
||||
static ImVec2 ButtonPadding = ImVec2(16.0f, 8.0f);
|
||||
static ImVec2 IconButtonPadding = ImVec2(8.0f, 8.0f);
|
||||
|
||||
void BeginWindow(const std::string& name)
|
||||
{
|
||||
ImGui::Begin(name.c_str());
|
||||
}
|
||||
|
||||
void EndWindow()
|
||||
{
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
bool PrimaryButton(const std::string& name)
|
||||
{
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, IM_COL32(97, 0, 255, 255));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, IM_COL32(97, 0, 255, 200));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonActive, IM_COL32(97, 0, 255, 255));
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 4.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ButtonPadding);
|
||||
|
||||
UIFont boldFont(Bold);
|
||||
const bool buttonPressed = ImGui::Button(name.c_str());
|
||||
|
||||
ImGui::PopStyleColor(3);
|
||||
|
||||
ImGui::PopStyleVar(2);
|
||||
|
||||
return buttonPressed;
|
||||
}
|
||||
|
||||
bool SecondaryButton(const std::string& name)
|
||||
{
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, IM_COL32(0, 0, 0, 0));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, IM_COL32(97, 0, 255, 200));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonActive, IM_COL32(97, 0, 255, 255));
|
||||
ImGui::PushStyleColor(ImGuiCol_Border, PrimaryCol);
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 2.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 4.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ButtonPadding);
|
||||
|
||||
UIFont boldFont(Bold);
|
||||
const bool buttonPressed = ImGui::Button(name.c_str());
|
||||
|
||||
ImGui::PopStyleVar(3);
|
||||
|
||||
ImGui::PopStyleColor(4);
|
||||
|
||||
return buttonPressed;
|
||||
}
|
||||
|
||||
bool IconButton(const std::string& icon)
|
||||
{
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 4.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, IconButtonPadding);
|
||||
|
||||
const float height = ImGui::GetTextLineHeight() + ButtonPadding.y * 2.0;
|
||||
const bool isPressed = ImGui::Button(icon.c_str(), ImVec2(height, height));
|
||||
|
||||
ImGui::PopStyleVar(2);
|
||||
|
||||
return isPressed;
|
||||
}
|
||||
|
||||
bool FloatSlider(const std::string& name, float& input, float min = 0.0f, float max = 1.0f, float speed = 0.01f)
|
||||
{
|
||||
//ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, { 0, ImGui::GetStyle().ItemSpacing.y });
|
||||
//IconButton(ICON_FA_ANGLE_UP);
|
||||
//
|
||||
//ImGui::SameLine();
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 4.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ButtonPadding);
|
||||
|
||||
const bool isUsing = ImGui::DragFloat(("##" + name).c_str(), &input, speed, min, max);
|
||||
|
||||
ImGui::PopStyleVar(2);
|
||||
|
||||
//ImGui::PopStyleColor();
|
||||
|
||||
return isUsing;
|
||||
}
|
||||
|
||||
bool CheckBox(const std::string& name, bool& value)
|
||||
{
|
||||
const float height = ImGui::GetTextLineHeight() + ButtonPadding.y * 2.0;
|
||||
|
||||
if (value)
|
||||
{
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, IM_COL32(0, 0, 0, 0));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, IM_COL32(97, 0, 255, 200));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonActive, PrimaryCol);
|
||||
ImGui::PushStyleColor(ImGuiCol_Border, PrimaryCol);
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 2.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 4.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ButtonPadding);
|
||||
|
||||
const bool buttonPressed = ImGui::Button(("##" + name).c_str(), ImVec2(height, height));
|
||||
|
||||
ImGui::PopStyleVar(3);
|
||||
|
||||
ImGui::PopStyleColor(4);
|
||||
|
||||
if (buttonPressed)
|
||||
{
|
||||
value = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, PrimaryCol);
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, PrimaryCol);
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonActive, PrimaryCol);
|
||||
ImGui::PushStyleColor(ImGuiCol_Border, IM_COL32(97, 0, 255, 200));
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 2.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 4.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ButtonPadding);
|
||||
|
||||
const bool buttonPressed = ImGui::Button(("##" + name).c_str(), ImVec2(height, height));
|
||||
|
||||
ImGui::PopStyleVar(3);
|
||||
|
||||
ImGui::PopStyleColor(4);
|
||||
|
||||
if (buttonPressed)
|
||||
{
|
||||
value = true;
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user