Merge pull request #28 from antopilo/NK-48-Dynamic-physics-gizmo

NK-48 Physics gizmo
This commit is contained in:
Antoine Pilote
2023-07-16 13:48:12 -04:00
committed by GitHub
28 changed files with 588 additions and 122 deletions

View File

@@ -1,3 +1,5 @@
#include <dependencies/GLEW/include/GL/glew.h>
#include <Engine.h>
#include <src/Core/Input.h>
@@ -28,6 +30,9 @@
#include "src/Windows/FileSystemUI.h"
#include <src/Core/Maths.h>
#include <src/Rendering/SceneRenderer.h>
const std::string WindowTitle = "Nuake Editor";
@@ -184,9 +189,27 @@ int main(int argc, char* argv[])
camera = currentScene->m_EditorCamera;
}
if (currentScene && !Nuake::Engine::IsPlayMode() && editor.ShouldDrawAxis())
if (currentScene && !Nuake::Engine::IsPlayMode())
{
gizmoDrawer.DrawGizmos(currentScene);
auto& gBuffer = currentScene->mSceneRenderer->GetGBuffer();
auto& depthTexture = gBuffer.GetTexture(GL_DEPTH_ATTACHMENT);
float nearZ = 0.1f;
float farZ = 1000.0f;
gizmoDrawer.GetLineShader().SetUniformTex("u_Depth", depthTexture.get(), 3);
gizmoDrawer.GetLineShader().SetUniformVec2("u_Resolution", depthTexture->GetSize());
glEnable(GL_LINE_SMOOTH);
glEnable(GL_BLEND);
glDepthRange(0.1f, 1000.0f);
if (editor.ShouldDrawAxis())
{
gizmoDrawer.DrawAxis(currentScene);
}
if (editor.ShouldDrawCollision())
{
gizmoDrawer.DrawGizmos(currentScene);
}
}
}
sceneFramebuffer->Unbind();

View File

@@ -20,9 +20,15 @@ public:
ImGui::Text("Size");
ImGui::TableNextColumn();
ImGuiHelper::DrawVec3("BoxSize", &component.Size);
ImGuiHelper::DrawVec3("BoxSize", &component.Size, 0.5f, 100.0, 0.01f);
component.Size = glm::abs(component.Size);
component.Size.x = std::max(component.Size.x, 0.0001f);
component.Size.y = std::max(component.Size.y, 0.0001f);
component.Size.z = std::max(component.Size.z, 0.0001f);
ImGui::TableNextColumn();
ComponentTableReset(component.Size, glm::vec3(1, 1, 1));
ComponentTableReset(component.Size, glm::vec3(0.5f, 0.5f, 0.5f));
}
ImGui::TableNextColumn();
{

View File

@@ -23,7 +23,8 @@ public:
{
ImGui::Text("Radius");
ImGui::TableNextColumn();
ImGui::DragFloat("##Radius", &Radius);
ImGui::DragFloat("##Radius", &Radius, 0.01f, 0.001f);
Radius = std::max(Radius, 0.001f);
ImGui::TableNextColumn();
ComponentTableReset(Radius, 0.5f)
}
@@ -31,8 +32,8 @@ public:
{
ImGui::Text("Height");
ImGui::TableNextColumn();
ImGui::DragFloat("##Height", &Height);
ImGui::DragFloat("##Height", &Height, 0.01f, 0.001f);
Height = std::max(Height, 0.001f);
ImGui::TableNextColumn();
ComponentTableReset(Height, 1.0f)
}

View File

@@ -0,0 +1,43 @@
#pragma once
#include "ComponentPanel.h"
#include <src/Scene/Components/CylinderColliderComponent.h>
class CylinderColliderPanel : ComponentPanel
{
public:
CylinderColliderPanel() = default;
void Draw(Nuake::Entity entity) override
{
using namespace Nuake;
if (!entity.HasComponent<CylinderColliderComponent>())
{
return;
}
auto& [Cylinder, Radius, Height, IsTrigger] = entity.GetComponent<CylinderColliderComponent>();
BeginComponentTable(CYLINDER COLLIDER, CylinderColliderComponent)
{
{
ImGui::Text("Radius");
ImGui::TableNextColumn();
ImGui::DragFloat("##Radius", &Radius, 0.01f, 0.001f);
Radius = std::max(Radius, 0.001f);
ImGui::TableNextColumn();
ComponentTableReset(Radius, 0.5f)
}
ImGui::TableNextColumn();
{
ImGui::Text("Height");
ImGui::TableNextColumn();
ImGui::DragFloat("##Height", &Height, 0.01f, 0.0001f);
Height = std::max(Height, 0.001f);
ImGui::TableNextColumn();
ComponentTableReset(Height, 1.0f)
}
}
EndComponentTable()
}
};

View File

@@ -31,7 +31,10 @@ public:
ImGui::Text("Model");
ImGui::TableNextColumn();
ImGui::DragInt("##Submesh", &component.SubMesh, 0, 255);
int editorValue = component.SubMesh;
ImGui::DragInt("##Submesh", &editorValue, 0.1f, 0, 255);
component.SubMesh = editorValue;
ImGui::TableNextColumn();
ComponentTableReset(component.SubMesh, 0);
}

View File

@@ -20,7 +20,8 @@ public:
ImGui::Text("Mass");
ImGui::TableNextColumn();
ImGui::DragFloat("##Mass", &component.Mass, 0.1f, 0.1f);
ImGui::DragFloat("##Mass", &component.Mass, 0.01f, 0.1f);
component.Mass = std::max(component.Mass, 0.0f);
ImGui::TableNextColumn();
ComponentTableReset(component.Mass, 0.0f);
}

View File

@@ -19,7 +19,9 @@ public:
{
ImGui::Text("Size");
ImGui::TableNextColumn();
ImGui::DragFloat("##Radius", &component.Radius);
ImGui::DragFloat("##Radius", &component.Radius, 0.01f, 0.001f);
component.Radius = std::max(component.Radius, 0.001f);
ImGui::TableNextColumn();
ComponentTableReset(component.Radius, 0.5f);
}

View File

@@ -13,6 +13,10 @@
#include <dependencies/GLEW/include/GL/glew.h>
#include "src/Scene/Components/CapsuleColliderComponent.h"
#include <src/Scene/Components/CylinderColliderComponent.h>
#include <src/Scene/Components/MeshCollider.h>
#include <src/Scene/Components/ModelComponent.h>
GizmoDrawer::GizmoDrawer()
{
@@ -29,7 +33,46 @@ GizmoDrawer::GizmoDrawer()
mAxisLineBuffer->AddBuffer(*mAxisLineVertexBuffer, *vblayout);
GenerateSphereGizmo();
GenerateCapsuleGizmo();
// Box
const Color cubeColor = Color(1, 0, 0, 1);
std::vector<LineVertex> mBoxVertices =
{
LineVertex{Vector3(-1.f, -1.f, -1.f), cubeColor},
LineVertex{Vector3(1.0f, -1.f, -1.f), cubeColor},
LineVertex{Vector3(-1.f, -1.f, 1.f), cubeColor},
LineVertex{Vector3(1.0f, -1.f, 1.f), cubeColor},
LineVertex{Vector3(-1.f, 1.f, -1.f), cubeColor},
LineVertex{Vector3(1.0f, 1.f, -1.f), cubeColor},
LineVertex{Vector3(-1.f, 1.f, 1.f), cubeColor},
LineVertex{Vector3(1.0f, 1.f, 1.f), cubeColor},
LineVertex{Vector3(-1.f, -1.f, -1.f), cubeColor},
LineVertex{Vector3(-1.0f, -1.f, 1.f), cubeColor},
LineVertex{Vector3(1.f, -1.f, -1.f), cubeColor},
LineVertex{Vector3(1.0f, -1.f, 1.f), cubeColor},
LineVertex{Vector3(-1.f, 1.f, -1.f), cubeColor},
LineVertex{Vector3(-1.0f, 1.f, 1.f), cubeColor},
LineVertex{Vector3(1.f, 1.f, -1.f), cubeColor},
LineVertex{Vector3(1.0f, 1.f, 1.f), cubeColor},
LineVertex{Vector3(-1.0f, -1.0f, -1.f), cubeColor},
LineVertex{Vector3(-1.f, 1.0f, -1.f), cubeColor},
LineVertex{Vector3(1.0f, -1.0f, -1.f), cubeColor},
LineVertex{Vector3(1.f, 1.0f, -1.f), cubeColor},
LineVertex{Vector3(-1.0f, -1.0f, 1.f), cubeColor},
LineVertex{Vector3(-1.f, 1.0f, 1.f), cubeColor},
LineVertex{Vector3(1.0f, -1.0f, 1.f), cubeColor},
LineVertex{Vector3(1.0f, 1.0f, 1.f), cubeColor}
};
mBoxBuffer = CreateRef<Nuake::VertexArray>();
mBoxBuffer->Bind();
mBoxVertexBuffer = CreateRef<VertexBuffer>(mBoxVertices.data(), mBoxVertices.size() * sizeof(Nuake::LineVertex));
mBoxBuffer->AddBuffer(*mBoxVertexBuffer, *vblayout);
// Load gizmos
ModelLoader loader;
@@ -66,8 +109,9 @@ void GizmoDrawer::GenerateSphereGizmo()
vert1 = Vector3(x, 0, z);
vert2 = Vector3(x2, 0, z2);
}
circleVertices.push_back(LineVertex{ vert1, Color(1.0, 0, 0.7, 1.0) });
circleVertices.push_back(LineVertex{ vert2, Color(1.0, 0, 0.7, 1.0) });
circleVertices.push_back(LineVertex{ vert1, Color(1.0, 0, 0.0, 1.0) });
circleVertices.push_back(LineVertex{ vert2, Color(1.0, 0, 0.0, 1.0) });
}
mCircleBuffer = CreateRef<Nuake::VertexArray>();
@@ -81,101 +125,6 @@ void GizmoDrawer::GenerateSphereGizmo()
mCircleBuffer->AddBuffer(*mCircleVertexBuffer, *vblayout);
}
void GizmoDrawer::GenerateCapsuleGizmo()
{
float height = 1.5f;
float radius = 0.5f;
float halfHeight = height / 2.0f;
float bottomCircleHeight = -halfHeight + radius;
float topCircleHeight = halfHeight - radius;
// Generate circles
const float subDivision = 32.0f;
constexpr const float pi = glm::pi<float>() * 4.0;
float increment = pi / subDivision;
for (int i = 0; i < subDivision * 2.0; i++)
{
float current = increment * (i);
float x = glm::cos(current) * radius;
float z = glm::sin(current) * radius;
current = increment * (i + 1);
float x2 = glm::cos(current) * radius;
float z2 = glm::sin(current) * radius;
Vector3 vert1, vert2;
if (i < subDivision)
{
vert1 = Vector3(x, topCircleHeight, z);
vert2 = Vector3(x2, topCircleHeight, z2);
}
else
{
vert1 = Vector3(x, bottomCircleHeight, z);
vert2 = Vector3(x2, bottomCircleHeight, z2);
}
capsuleVertices.push_back(LineVertex{ vert1, Color(1.0, 0, 0.7, 1.0) });
capsuleVertices.push_back(LineVertex{ vert2, Color(1.0, 0, 0.7, 1.0) });
}
for (int i = 0; i < subDivision * 2.0; i++)
{
float current = increment * (i);
float x = glm::cos(current) * radius;
float z = glm::sin(current) * radius;
current = increment * (i + 1);
float x2 = glm::cos(current) * radius;
float z2 = glm::sin(current) * radius;
float heightOffset = topCircleHeight;
if (z < 0.0)
{
heightOffset = bottomCircleHeight;
}
Vector3 vert1, vert2;
if (i < subDivision)
{
vert1 = Vector3(x, z + heightOffset, 0);
vert2 = Vector3(x2, z2 + heightOffset, 0);
}
else
{
vert1 = Vector3(0, z + heightOffset, x);
vert2 = Vector3(0, z2 + heightOffset, x2 );
}
capsuleVertices.push_back(LineVertex{ vert1, Color(1.0, 0, 0.7, 1.0) });
capsuleVertices.push_back(LineVertex{ vert2, Color(1.0, 0, 0.7, 1.0) });
}
capsuleVertices.push_back(LineVertex{ Vector3(radius, bottomCircleHeight, 0), Color(1.0, 0, 0.7, 1.0)});
capsuleVertices.push_back(LineVertex{ Vector3(radius, topCircleHeight, 0), Color(1.0, 0, 0.7, 1.0) });
capsuleVertices.push_back(LineVertex{ Vector3(-radius, bottomCircleHeight, 0), Color(1.0, 0, 0.7, 1.0) });
capsuleVertices.push_back(LineVertex{ Vector3(-radius, topCircleHeight, 0), Color(1.0, 0, 0.7, 1.0) });
capsuleVertices.push_back(LineVertex{ Vector3(0, bottomCircleHeight, radius), Color(1.0, 0, 0.7, 1.0) });
capsuleVertices.push_back(LineVertex{ Vector3(0, topCircleHeight, radius), Color(1.0, 0, 0.7, 1.0) });
capsuleVertices.push_back(LineVertex{ Vector3(0, bottomCircleHeight, -radius), Color(1.0, 0, 0.7, 1.0) });
capsuleVertices.push_back(LineVertex{ Vector3(0, topCircleHeight, -radius), Color(1.0, 0, 0.7, 1.0) });
mCapsuleBuffer = CreateRef<Nuake::VertexArray>();
mCapsuleBuffer->Bind();
mCapsuleVertexBuffer = CreateRef<VertexBuffer>(capsuleVertices.data(), capsuleVertices.size() * sizeof(Nuake::LineVertex));
auto vblayout = CreateRef<VertexBufferLayout>();
vblayout->Push<float>(3);
vblayout->Push<float>(4);
mCapsuleBuffer->AddBuffer(*mCapsuleVertexBuffer, *vblayout);
}
void GizmoDrawer::DrawGizmos(Ref<Scene> scene)
{
using namespace Nuake;
@@ -191,6 +140,23 @@ void GizmoDrawer::DrawGizmos(Ref<Scene> scene)
Nuake::RenderCommand::DrawLines(0, 6);
}
glLineWidth(2.0f);
auto boxColliderView = scene->m_Registry.view<TransformComponent, BoxColliderComponent>();
for (auto e : boxColliderView)
{
auto [transform, box] = scene->m_Registry.get<TransformComponent, BoxColliderComponent>(e);
const Quat& globalRotation = glm::normalize(transform.GetGlobalRotation());
const Matrix4& rotationMatrix = glm::mat4_cast(globalRotation);
mLineShader->Bind();
mLineShader->SetUniformMat4f("u_View", glm::scale(glm::translate(scene->m_EditorCamera->GetTransform(), transform.Translation) * rotationMatrix, box.Size));
mLineShader->SetUniformMat4f("u_Projection", scene->m_EditorCamera->GetPerspective());
mBoxBuffer->Bind();
Nuake::RenderCommand::DrawLines(0, 26);
}
auto sphereColliderView = scene->m_Registry.view<TransformComponent, SphereColliderComponent>();
for (auto e : sphereColliderView)
{
@@ -206,15 +172,83 @@ void GizmoDrawer::DrawGizmos(Ref<Scene> scene)
auto capsuleColliderView = scene->m_Registry.view<TransformComponent, CapsuleColliderComponent>();
for (auto e : capsuleColliderView)
{
auto [transform, capsule] = scene->m_Registry.get<TransformComponent, CapsuleColliderComponent>(e);
auto& [transform, capsule] = scene->m_Registry.get<TransformComponent, CapsuleColliderComponent>(e);
const auto entityId = (uint32_t)e;
if (_CapsuleEntity.find(entityId) == _CapsuleEntity.end())
{
_CapsuleEntity[entityId] = CreateScope<CapsuleGizmo>();
}
_CapsuleEntity[entityId]->UpdateShape(capsule.Radius, capsule.Height);
const Quat& globalRotation = glm::normalize(transform.GetGlobalRotation());
const Matrix4& rotationMatrix = glm::mat4_cast(globalRotation);
mLineShader->Bind();
mLineShader->SetUniformMat4f("u_View", glm::translate(scene->m_EditorCamera->GetTransform(), transform.Translation));
mLineShader->SetUniformMat4f("u_View", glm::translate(scene->m_EditorCamera->GetTransform(), transform.Translation) * rotationMatrix);
mLineShader->SetUniformMat4f("u_Projection", scene->m_EditorCamera->GetPerspective());
mCapsuleBuffer->Bind();
_CapsuleEntity[entityId]->Bind();
Nuake::RenderCommand::DrawLines(0, 264);
}
auto cylinderColliderView = scene->m_Registry.view<TransformComponent, CylinderColliderComponent>();
for (auto e : cylinderColliderView)
{
auto& [transform, cylinder] = scene->m_Registry.get<TransformComponent, CylinderColliderComponent>(e);
const auto entityId = (uint32_t)e;
if (_CylinderEntity.find(entityId) == _CylinderEntity.end())
{
_CylinderEntity[entityId] = CreateScope<CylinderGizmo>();
}
_CylinderEntity[entityId]->UpdateShape(cylinder.Radius, cylinder.Height);
const Quat& globalRotation = glm::normalize(transform.GetGlobalRotation());
const Matrix4& rotationMatrix = glm::mat4_cast(globalRotation);
mLineShader->Bind();
mLineShader->SetUniformMat4f("u_View", glm::translate(scene->m_EditorCamera->GetTransform(), transform.Translation) * rotationMatrix);
mLineShader->SetUniformMat4f("u_Projection", scene->m_EditorCamera->GetPerspective());
_CylinderEntity[entityId]->Bind();
Nuake::RenderCommand::DrawLines(0, 264);
}
auto meshColliderView = scene->m_Registry.view<TransformComponent, MeshColliderComponent, ModelComponent>();
for (auto e : meshColliderView)
{
auto& [transform, mesh, model] = scene->m_Registry.get<TransformComponent, MeshColliderComponent, ModelComponent>(e);
// Component has no mesh set.
if (!model.ModelResource)
{
continue;
}
auto& resource = model.ModelResource;
const auto& meshes = resource->GetMeshes();
if (mesh.SubMesh >= meshes.size())
{
continue;
}
const Quat& globalRotation = glm::normalize(transform.GetGlobalRotation());
const Matrix4& rotationMatrix = glm::mat4_cast(globalRotation);
mLineShader->Bind();
mLineShader->SetUniformMat4f("u_View", glm::translate(scene->m_EditorCamera->GetTransform(), transform.Translation) * rotationMatrix);
mLineShader->SetUniformMat4f("u_Projection", scene->m_EditorCamera->GetPerspective());
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
meshes[mesh.SubMesh]->Bind();
meshes[mesh.SubMesh]->Draw(nullptr, false);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
auto flatShader = ShaderManager::GetShader("resources/Shaders/flat.shader");
flatShader->Bind();
flatShader->SetUniformMat4f("u_View", scene->m_EditorCamera->GetTransform());
@@ -225,6 +259,7 @@ void GizmoDrawer::DrawGizmos(Ref<Scene> scene)
RenderCommand::Enable(RendererEnum::FACE_CULL);
glCullFace(GL_BACK);
glLineWidth(1.0f);
RenderList renderList;
// Camera

View File

@@ -6,6 +6,10 @@
#include <src/Rendering/Vertex.h>
#include <src/Scene/Scene.h>
#include <src/Resource/Model.h>
#include <src/Core/Physics/PhysicsShapes.h>
#include "Gizmos/CapsuleGizmo.h"
#include "Gizmos/CylinderGizmo.h"
using namespace Nuake;
@@ -14,6 +18,9 @@ class GizmoDrawer
private:
std::map<std::string, Ref<Model>> _gizmos;
std::map<uint32_t, Scope<CapsuleGizmo>> _CapsuleEntity;
std::map<uint32_t, Scope<CylinderGizmo>> _CylinderEntity;
const std::vector<LineVertex> vertices
{
LineVertex {{10000.f, 0.0f, 0.0f}, {1.f, 0.f, 0.f, 1.f}},
@@ -27,9 +34,9 @@ private:
Ref<VertexArray> mCircleBuffer;
Ref<VertexBuffer> mCircleVertexBuffer;
std::vector<LineVertex> capsuleVertices;
Ref<VertexArray> mCapsuleBuffer;
Ref<VertexBuffer> mCapsuleVertexBuffer;
std::vector<LineVertex> mBoxVertices;
Ref<VertexArray> mBoxBuffer;
Ref<VertexBuffer> mBoxVertexBuffer;
Ref<VertexArray> mAxisLineBuffer;
Ref<VertexBuffer> mAxisLineVertexBuffer;
@@ -37,7 +44,6 @@ private:
Shader* mLineShader;
void GenerateSphereGizmo();
void GenerateCapsuleGizmo();
public:
GizmoDrawer();
~GizmoDrawer() = default;

View File

@@ -0,0 +1,122 @@
#include "CapsuleGizmo.h"
#include <src/Core/Maths.h>
CapsuleGizmo::CapsuleGizmo() :
_Radius(0.0f),
_Height(0.0f)
{
}
void CapsuleGizmo::Bind()
{
_CapsuleBuffer->Bind();
}
void CapsuleGizmo::UpdateShape(float radius, float height)
{
if (_Radius == radius && _Height == height)
{
return;
}
_Radius = radius;
_Height = height;
CreateMesh();
}
void CapsuleGizmo::CreateMesh()
{
using namespace Nuake;
_CapsuleVertices.clear();
const float halfHeight = _Height / 2.0f;
const float radius = _Radius;
const float bottomCircleHeight = -halfHeight + radius;
const float topCircleHeight = halfHeight - radius;
// Generate circles
const float subDivision = 32.0f;
constexpr const float pi = glm::pi<float>() * 4.0;
float increment = pi / subDivision;
for (int i = 0; i < subDivision * 2.0; i++)
{
float current = increment * (i);
float x = glm::cos(current) * radius;
float z = glm::sin(current) * radius;
current = increment * (i + 1);
float x2 = glm::cos(current) * radius;
float z2 = glm::sin(current) * radius;
Vector3 vert1, vert2;
if (i < subDivision)
{
vert1 = Vector3(x, topCircleHeight, z);
vert2 = Vector3(x2, topCircleHeight, z2);
}
else
{
vert1 = Vector3(x, bottomCircleHeight, z);
vert2 = Vector3(x2, bottomCircleHeight, z2);
}
_CapsuleVertices.push_back(LineVertex{ vert1, Color(1.0, 0, 0.0, 1.0) });
_CapsuleVertices.push_back(LineVertex{ vert2, Color(1.0, 0, 0.0, 1.0) });
}
for (int i = 0; i < subDivision * 2.0; i++)
{
float current = increment * (i);
float x = glm::cos(current) * radius;
float z = glm::sin(current) * radius;
current = increment * (i + 1);
float x2 = glm::cos(current) * radius;
float z2 = glm::sin(current) * radius;
float heightOffset = topCircleHeight;
if (z < 0.0)
{
heightOffset = bottomCircleHeight;
}
Vector3 vert1, vert2;
if (i < subDivision)
{
vert1 = Vector3(x, z + heightOffset, 0);
vert2 = Vector3(x2, z2 + heightOffset, 0);
}
else
{
vert1 = Vector3(0, z + heightOffset, x);
vert2 = Vector3(0, z2 + heightOffset, x2);
}
_CapsuleVertices.push_back(LineVertex{ vert1, Color(1.0, 0, 0.0, 1.0) });
_CapsuleVertices.push_back(LineVertex{ vert2, Color(1.0, 0, 0.0, 1.0) });
}
_CapsuleVertices.push_back(LineVertex{ Vector3(radius, bottomCircleHeight, 0), Color(1.0, 0, 0.0, 1.0) });
_CapsuleVertices.push_back(LineVertex{ Vector3(radius, topCircleHeight, 0), Color(1.0, 0, 0.0, 1.0) });
_CapsuleVertices.push_back(LineVertex{ Vector3(-radius, bottomCircleHeight, 0), Color(1.0, 0, 0.0, 1.0) });
_CapsuleVertices.push_back(LineVertex{ Vector3(-radius, topCircleHeight, 0), Color(1.0, 0, 0.0, 1.0) });
_CapsuleVertices.push_back(LineVertex{ Vector3(0, bottomCircleHeight, radius), Color(1.0, 0, 0.0, 1.0) });
_CapsuleVertices.push_back(LineVertex{ Vector3(0, topCircleHeight, radius), Color(1.0, 0, 0.0, 1.0) });
_CapsuleVertices.push_back(LineVertex{ Vector3(0, bottomCircleHeight, -radius), Color(1.0, 0, 0.0, 1.0) });
_CapsuleVertices.push_back(LineVertex{ Vector3(0, topCircleHeight, -radius), Color(1.0, 0, 0.0, 1.0) });
_CapsuleBuffer = CreateRef<Nuake::VertexArray>();
_CapsuleBuffer->Bind();
_CapsuleVertexBuffer = CreateRef<VertexBuffer>(_CapsuleVertices.data(), _CapsuleVertices.size() * sizeof(Nuake::LineVertex));
auto vblayout = CreateRef<VertexBufferLayout>();
vblayout->Push<float>(3);
vblayout->Push<float>(4);
_CapsuleBuffer->AddBuffer(*_CapsuleVertexBuffer, *vblayout);
}

View File

@@ -0,0 +1,26 @@
#pragma once
#include <src/Core/Core.h>
#include <src/Rendering/Vertex.h>
#include <src/Rendering/Buffers/VertexBuffer.h>
#include <src/Rendering/Buffers/VertexArray.h>
#include <vector>
class CapsuleGizmo
{
private:
std::vector<Nuake::LineVertex> _CapsuleVertices;
Ref<Nuake::VertexArray> _CapsuleBuffer;
Ref<Nuake::VertexBuffer> _CapsuleVertexBuffer;
float _Radius;
float _Height;
public:
CapsuleGizmo();
~CapsuleGizmo() = default;
void UpdateShape(float radius, float height);
void CreateMesh();
void Bind();
};

View File

@@ -0,0 +1,90 @@
#include "CylinderGizmo.h"
#include <src/Core/Maths.h>
CylinderGizmo::CylinderGizmo() :
_Radius(0.0f),
_Height(0.0f)
{
}
void CylinderGizmo::Bind()
{
_CylinderBuffer->Bind();
}
void CylinderGizmo::UpdateShape(float radius, float height)
{
if (_Radius == radius && _Height == height)
{
return;
}
_Radius = radius;
_Height = height;
CreateMesh();
}
void CylinderGizmo::CreateMesh()
{
using namespace Nuake;
_CylinderVertices.clear();
const float halfHeight = _Height / 2.0f;
const float radius = _Radius;
const float bottomCircleHeight = -halfHeight;
const float topCircleHeight = halfHeight;
// Generate circles
const float subDivision = 32.0f;
constexpr const float pi = glm::pi<float>() * 4.0;
float increment = pi / subDivision;
for (int i = 0; i < subDivision * 2.0; i++)
{
float current = increment * (i);
float x = glm::cos(current) * radius;
float z = glm::sin(current) * radius;
current = increment * (i + 1);
float x2 = glm::cos(current) * radius;
float z2 = glm::sin(current) * radius;
Vector3 vert1, vert2;
if (i < subDivision)
{
vert1 = Vector3(x, topCircleHeight, z);
vert2 = Vector3(x2, topCircleHeight, z2);
}
else
{
vert1 = Vector3(x, bottomCircleHeight, z);
vert2 = Vector3(x2, bottomCircleHeight, z2);
}
_CylinderVertices.push_back(LineVertex{ vert1, Color(1.0, 0, 0.0, 1.0) });
_CylinderVertices.push_back(LineVertex{ vert2, Color(1.0, 0, 0.0, 1.0) });
}
_CylinderVertices.push_back(LineVertex{ Vector3(radius, bottomCircleHeight, 0), Color(1.0, 0, 0.0, 1.0) });
_CylinderVertices.push_back(LineVertex{ Vector3(radius, topCircleHeight, 0), Color(1.0, 0, 0.0, 1.0) });
_CylinderVertices.push_back(LineVertex{ Vector3(-radius, bottomCircleHeight, 0), Color(1.0, 0, 0.0, 1.0) });
_CylinderVertices.push_back(LineVertex{ Vector3(-radius, topCircleHeight, 0), Color(1.0, 0, 0.0, 1.0) });
_CylinderVertices.push_back(LineVertex{ Vector3(0, bottomCircleHeight, radius), Color(1.0, 0, 0.0, 1.0) });
_CylinderVertices.push_back(LineVertex{ Vector3(0, topCircleHeight, radius), Color(1.0, 0, 0.0, 1.0) });
_CylinderVertices.push_back(LineVertex{ Vector3(0, bottomCircleHeight, -radius), Color(1.0, 0, 0.0, 1.0) });
_CylinderVertices.push_back(LineVertex{ Vector3(0, topCircleHeight, -radius), Color(1.0, 0, 0.0, 1.0) });
_CylinderBuffer = CreateRef<Nuake::VertexArray>();
_CylinderBuffer->Bind();
_CylinderVertexBuffer = CreateRef<VertexBuffer>(_CylinderVertices.data(), _CylinderVertices.size() * sizeof(Nuake::LineVertex));
auto vblayout = CreateRef<VertexBufferLayout>();
vblayout->Push<float>(3);
vblayout->Push<float>(4);
_CylinderBuffer->AddBuffer(*_CylinderVertexBuffer, *vblayout);
}

View File

@@ -0,0 +1,26 @@
#pragma once
#include <src/Core/Core.h>
#include <src/Rendering/Vertex.h>
#include <src/Rendering/Buffers/VertexBuffer.h>
#include <src/Rendering/Buffers/VertexArray.h>
#include <vector>
class CylinderGizmo
{
private:
std::vector<Nuake::LineVertex> _CylinderVertices;
Ref<Nuake::VertexArray> _CylinderBuffer;
Ref<Nuake::VertexBuffer> _CylinderVertexBuffer;
float _Radius;
float _Height;
public:
CylinderGizmo();
~CylinderGizmo() = default;
void UpdateShape(float radius, float height);
void CreateMesh();
void Bind();
};

View File

@@ -1219,7 +1219,6 @@ namespace Nuake {
}
ImGui::PopStyleVar();
ImGui::End();
int corner2 = 1;

View File

@@ -23,7 +23,7 @@ namespace Nuake
bool m_DrawGrid = false;
bool m_DrawAxis = true;
bool m_ShowImGuiDemo = false;
bool m_DebugCollisions = false;
bool m_DebugCollisions = true;
bool m_ShowOverlay = true;
bool m_IsHoveringViewport = false;
Vector2 m_ViewportPos = {0, 0};
@@ -59,5 +59,6 @@ namespace Nuake
void Overlay();
bool ShouldDrawAxis() const { return m_DrawAxis; }
bool ShouldDrawCollision() const { return m_DebugCollisions; }
};
}

View File

@@ -103,6 +103,7 @@ void EditorSelectionPanel::DrawEntity(Nuake::Entity entity)
mBoxColliderPanel.Draw(entity);
mSphereColliderPanel.Draw(entity);
mCapsuleColliderPanel.Draw(entity);
mCylinderColliderPanel.Draw(entity);
mMeshColliderPanel.Draw(entity);
mCharacterControllerPanel.Draw(entity);
}
@@ -127,8 +128,10 @@ void EditorSelectionPanel::DrawAddComponentMenu(Nuake::Entity entity)
ImGui::Separator();
MenuItemComponent("Character Controller", Nuake::CharacterControllerComponent)
MenuItemComponent("Rigid body", Nuake::RigidBodyComponent)
ImGui::Separator();
MenuItemComponent("Box collider", Nuake::BoxColliderComponent)
MenuItemComponent("Capsule collider", Nuake::CapsuleColliderComponent)
MenuItemComponent("Cylinder collider", Nuake::CylinderColliderComponent)
MenuItemComponent("Sphere collider", Nuake::SphereColliderComponent)
MenuItemComponent("Mesh collider", Nuake::MeshColliderComponent)
ImGui::Separator();
@@ -140,7 +143,6 @@ void EditorSelectionPanel::DrawAddComponentMenu(Nuake::Entity entity)
}
void EditorSelectionPanel::DrawFile(Ref<Nuake::File> file)
{
using namespace Nuake;

View File

@@ -14,6 +14,7 @@
#include "../ComponentsPanel/RigidbodyPanel.h"
#include "../ComponentsPanel/BoxColliderPanel.h"
#include "../ComponentsPanel/CapsuleColliderPanel.h"
#include "../ComponentsPanel/CylinderColliderPanel.h"
#include "../ComponentsPanel/SphereColliderPanel.h"
#include "../ComponentsPanel/MeshColliderPanel.h"
#include "../ComponentsPanel/CharacterControllerPanel.h"
@@ -31,6 +32,7 @@ private:
SphereColliderPanel mSphereColliderPanel;
MeshColliderPanel mMeshColliderPanel;
CapsuleColliderPanel mCapsuleColliderPanel;
CylinderColliderPanel mCylinderColliderPanel;
CharacterControllerPanel mCharacterControllerPanel;

View File

@@ -49,6 +49,7 @@ namespace Nuake
float Radius;
float Height;
public:
Capsule() = default;
Capsule(float radius, float height) :
Radius(radius),
Height(height)

View File

@@ -91,6 +91,11 @@ namespace Nuake
m_VertexArray->Unbind();
}
void Mesh::Bind() const
{
m_VertexArray->Bind();
}
void Mesh::Draw(Shader* shader, bool bindMaterial)
{
if (bindMaterial)

View File

@@ -25,6 +25,7 @@ namespace Nuake
Ref<Material> GetMaterial() inline const;
void SetMaterial(Ref<Material> material);
void Bind() const;
void Draw(Shader* shader, bool bindMaterial = true);
void DebugDraw();

View File

@@ -7,7 +7,7 @@ namespace Nuake
class CapsuleColliderComponent
{
public:
Ref<Physics::PhysicShape> Capsule;
Ref<Physics::Capsule> Capsule;
float Radius = 0.5f;
float Height = 1.0f;

View File

@@ -8,11 +8,15 @@
#include "CameraComponent.h"
#include "ModelComponent.h"
#include "QuakeMap.h"
#include "RigidbodyComponent.h"
#include "CharacterControllerComponent.h"
#include "SphereCollider.h"
#include "MeshCollider.h"
#include "CylinderColliderComponent.h"
#include "NativeScriptComponent.h"
#include "CharacterControllerComponent.h"
#include "ParentComponent.h"
#include "NameComponent.h"
#include "BoxCollider.h"

View File

@@ -0,0 +1,24 @@
#include "CylinderColliderComponent.h"
#include "src/Resource/Serializable.h"
namespace Nuake
{
json CylinderColliderComponent::Serialize()
{
BEGIN_SERIALIZE()
j["IsTrigger"] = IsTrigger;
SERIALIZE_VAL(Radius)
SERIALIZE_VAL(Height)
END_SERIALIZE()
}
bool CylinderColliderComponent::Deserialize(const std::string& str)
{
BEGIN_DESERIALIZE()
this->IsTrigger = j["IsTrigger"];
this->Radius = j["Radius"];
this->Height = j["Height"];
return true;
}
}

View File

@@ -0,0 +1,20 @@
#pragma once
#include "src/Core/Physics/PhysicsShapes.h"
#include "src/Core/Core.h"
namespace Nuake
{
class CylinderColliderComponent
{
public:
Ref<Physics::Cylinder> Cylinder;
float Radius = 0.5f;
float Height = 1.0f;
bool IsTrigger = false;
json Serialize();
bool Deserialize(const std::string& str);
};
}

View File

@@ -6,7 +6,7 @@ namespace Nuake {
class MeshColliderComponent
{
public:
int SubMesh = 0;
uint32_t SubMesh = 0;
bool IsTrigger;
Ref<Physics::MeshShape> Shape;

View File

@@ -49,6 +49,8 @@ namespace Nuake
SERIALIZE_OBJECT_REF_LBL("BoxColliderComponent", GetComponent<BoxColliderComponent>())
if (HasComponent<CapsuleColliderComponent>())
SERIALIZE_OBJECT_REF_LBL("CapsuleColliderComponent", GetComponent<CapsuleColliderComponent>())
if (HasComponent<CylinderColliderComponent>())
SERIALIZE_OBJECT_REF_LBL("CylinderColliderComponent", GetComponent<CylinderColliderComponent>())
if (HasComponent<SphereColliderComponent>())
SERIALIZE_OBJECT_REF_LBL("SphereColliderComponent", GetComponent<SphereColliderComponent>())
if (HasComponent<MeshColliderComponent>())
@@ -84,6 +86,7 @@ namespace Nuake
DESERIALIZE_COMPONENT(CharacterControllerComponent)
DESERIALIZE_COMPONENT(BoxColliderComponent)
DESERIALIZE_COMPONENT(CapsuleColliderComponent)
DESERIALIZE_COMPONENT(CylinderColliderComponent)
DESERIALIZE_COMPONENT(MeshColliderComponent)
DESERIALIZE_COMPONENT(SphereColliderComponent)
DESERIALIZE_COMPONENT(RigidBodyComponent)

View File

@@ -95,7 +95,6 @@ namespace Nuake {
Logger::Log("Init system");
if (!system->Init())
{
return false;
}
}

View File

@@ -12,6 +12,7 @@
#include <src/Scene/Components/QuakeMap.h>
#include <src/Scene/Components/BSPBrushComponent.h>
#include <src/Scene/Components/TriggerZone.h>
#include <src/Scene/Components/CylinderColliderComponent.h>
namespace Nuake
{
@@ -174,6 +175,15 @@ namespace Nuake
capsuleComponent.Capsule = CreateRef<Physics::Capsule>(radius, height);
}
const auto cylinderView = m_Scene->m_Registry.view<CylinderColliderComponent>();
for (auto entity : cylinderView)
{
auto& cylinderComponent = cylinderView.get<CylinderColliderComponent>(entity);
float radius = cylinderComponent.Radius;
float height = cylinderComponent.Height;
cylinderComponent.Cylinder = CreateRef<Physics::Cylinder>(radius, height);
}
const auto sphereView = m_Scene->m_Registry.view<SphereColliderComponent>();
for (auto entity : sphereView)
{
@@ -238,6 +248,17 @@ namespace Nuake
PhysicsManager::Get().RegisterBody(rigidBody);
}
if (ent.HasComponent<CylinderColliderComponent>())
{
auto& cylinderComponent = ent.GetComponent<CylinderColliderComponent>();
float radius = cylinderComponent.Radius;
float height = cylinderComponent.Height;
auto cylinderShape = CreateRef<Physics::Cylinder>(radius, height);
rigidBody = CreateRef<Physics::RigidBody>(rigidBodyComponent.Mass, transform.GetGlobalPosition(), transform.GetGlobalRotation(), transform.GetGlobalTransform(), cylinderShape, ent);
PhysicsManager::Get().RegisterBody(rigidBody);
}
if (ent.HasComponent<SphereColliderComponent>())
{
float mass = rigidBodyComponent.Mass;