mirror of
https://github.com/antopilo/Nuake.git
synced 2026-09-27 16:17:12 +03:00
Dynamic gizmos
- Added cylinder collider component - Dynamic cylinder, capsule, box, sphere gizmos - Added wireframe for mesh shape
This commit is contained in:
@@ -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,8 @@ 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,100 +124,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)
|
||||
{
|
||||
@@ -191,6 +140,20 @@ 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);
|
||||
mLineShader->Bind();
|
||||
mLineShader->SetUniformMat4f("u_View", glm::scale(glm::translate(scene->m_EditorCamera->GetTransform(), transform.Translation), 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 +169,80 @@ 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);
|
||||
|
||||
mLineShader->Bind();
|
||||
mLineShader->SetUniformMat4f("u_View", glm::translate(scene->m_EditorCamera->GetTransform(), transform.Translation));
|
||||
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);
|
||||
|
||||
mLineShader->Bind();
|
||||
mLineShader->SetUniformMat4f("u_View", glm::translate(scene->m_EditorCamera->GetTransform(), transform.Translation));
|
||||
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;
|
||||
|
||||
auto meshes = resource->GetMeshes();
|
||||
|
||||
if (mesh.SubMesh >= meshes.size())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
mLineShader->Bind();
|
||||
|
||||
const Vector3& localTranslate = transform.GetGlobalPosition();
|
||||
const Quat& localRot = glm::normalize(transform.GetGlobalRotation());
|
||||
const Matrix4& translationMatrix = glm::translate(Matrix4(1.0f), localTranslate);
|
||||
const Matrix4& rotationMatrix = glm::mat4_cast(localRot);
|
||||
const Matrix4& newLocalTransform = translationMatrix * rotationMatrix;
|
||||
|
||||
mLineShader->SetUniformMat4f("u_View", glm::translate(scene->m_EditorCamera->GetTransform(), transform.Translation) * rotationMatrix);
|
||||
mLineShader->SetUniformMat4f("u_Projection", scene->m_EditorCamera->GetPerspective());
|
||||
|
||||
meshes[mesh.SubMesh]->Bind();
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
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 +253,7 @@ void GizmoDrawer::DrawGizmos(Ref<Scene> scene)
|
||||
RenderCommand::Enable(RendererEnum::FACE_CULL);
|
||||
glCullFace(GL_BACK);
|
||||
|
||||
glLineWidth(1.0f);
|
||||
RenderList renderList;
|
||||
|
||||
// Camera
|
||||
|
||||
Reference in New Issue
Block a user