This commit is contained in:
Antoine Pilote
2023-09-18 08:38:26 -04:00
25 changed files with 456 additions and 80 deletions

View File

@@ -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);
}

View File

@@ -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..

View 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() { }

View File

@@ -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();

View File

@@ -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;

View 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();
}

View File

@@ -0,0 +1,13 @@
#pragma once
class UIDemoWindow
{
public:
UIDemoWindow() = default;
~UIDemoWindow() = default;
void Draw();
};

View File

@@ -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());
}

View File

@@ -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

View 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);
}
}

View File

@@ -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())

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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;

View File

@@ -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();

View File

@@ -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()

View File

@@ -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);
}
}

View File

@@ -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;
}
};
}

View File

@@ -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

View File

@@ -35,6 +35,7 @@ namespace Nuake
bool Deserialize(const json& j)
{
ModelPath = j["ModelPath"];
ModelResource = CreateRef<SkinnedModel>();
if (j.contains("ModelResource"))

View File

@@ -486,7 +486,6 @@ namespace Nuake
skeletonRoot.EntityHandle = skeletonRootEntity.GetID();
entity.AddChild(skeletonRootEntity);
Vector3 bonePosition;
Quat boneRotation;
Vector3 boneScale;

View File

@@ -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);
}
}

View File

@@ -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);
};
}

View File

@@ -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
View 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;
}
}
}