Added spotlight gizmo + yellow gizmo when selected
This commit is contained in:
@@ -91,6 +91,7 @@ struct PSOutput {
|
||||
|
||||
struct DebugConstant
|
||||
{
|
||||
float4 Color;
|
||||
float4x4 Transform;
|
||||
int TextureID;
|
||||
};
|
||||
@@ -117,7 +118,7 @@ PSOutput main(PSInput input)
|
||||
discard;
|
||||
}
|
||||
|
||||
output.oColor0 = textureSample;
|
||||
output.oColor0 = textureSample * pushConstants.Color;
|
||||
}
|
||||
|
||||
return output;
|
||||
|
||||
@@ -82,6 +82,7 @@ StructuredBuffer<CameraView> cameras;
|
||||
|
||||
struct DebugConstant
|
||||
{
|
||||
float4 Color;
|
||||
float4x4 Transform;
|
||||
int TextureID;
|
||||
};
|
||||
|
||||
@@ -322,7 +322,7 @@ PSOutput main(PSInput input)
|
||||
float theta = dot(L, normalize(-light.direction));
|
||||
float epsilon = light.innerConeAngle - light.outerConeAngle;
|
||||
float intensity = clamp((theta - light.outerConeAngle) / epsilon, 0.0, 1.0);
|
||||
radiance = light.color * intensity;
|
||||
radiance = light.color * intensity * attenuation;
|
||||
}
|
||||
|
||||
float3 H = normalize(V + L);
|
||||
|
||||
@@ -234,7 +234,7 @@ float GetGizmoScale(const Vector3& camPosition, const Nuake::Vector3& position)
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void DrawIconGizmo(DebugCmd& debugCmd, const std::string& icon)
|
||||
void DrawIconGizmo(DebugCmd& debugCmd, const std::string& icon, const EditorContext& context)
|
||||
{
|
||||
auto scene = debugCmd.GetScene();
|
||||
auto cam = scene->GetCurrentCamera();
|
||||
@@ -247,12 +247,15 @@ void DrawIconGizmo(DebugCmd& debugCmd, const std::string& icon)
|
||||
{
|
||||
auto [transform, cam] = scene->m_Registry.get<TransformComponent, T>(e);
|
||||
|
||||
auto selection = context.GetSelection();
|
||||
bool isSelected = selection.Type == EditorSelectionType::Entity && selection.Entity.GetHandle() == (int)e;
|
||||
|
||||
Matrix4 initialTransform = transform.GetGlobalTransform();
|
||||
Matrix4 gizmoTransform = initialTransform;
|
||||
gizmoTransform = glm::inverse(scene->GetCurrentCamera()->GetTransform());
|
||||
gizmoTransform[3] = initialTransform[3];
|
||||
gizmoTransform = glm::scale(gizmoTransform, gizmoSize * GetGizmoScale(cameraPosition, initialTransform[3]));
|
||||
debugCmd.DrawTexturedQuad(proj * view * gizmoTransform, TextureManager::Get()->GetTexture2(icon));
|
||||
debugCmd.DrawTexturedQuad(proj * view * gizmoTransform, TextureManager::Get()->GetTexture2(icon), isSelected ? Color(1, 1, 0, 1) : Color(1, 1, 1, 1));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -284,6 +287,57 @@ void ViewportWidget::OnLineDraw(DebugLineCmd& lineCmd)
|
||||
lineCmd.DrawBox(proj * boxTransform, Color(1, 0, 0, 1.0f), 1.5f, false);
|
||||
}
|
||||
|
||||
auto lightView = scene->m_Registry.view<TransformComponent, LightComponent>();
|
||||
for (auto e : lightView)
|
||||
{
|
||||
auto [transformComp, lightComp] = scene->m_Registry.get<TransformComponent, LightComponent>(e);
|
||||
|
||||
const int32_t type = lightComp.Type;
|
||||
const Quat& rotationOffset = QuatFromEuler(-90.0f, 0, 0);
|
||||
const Quat& globalRotation = glm::normalize(transformComp.GetGlobalRotation()) * rotationOffset;
|
||||
const Matrix4& rotationMatrix = glm::mat4_cast(globalRotation);
|
||||
|
||||
Matrix4 transform = Matrix4(1.0f);
|
||||
transform = glm::translate(view, Vector3(transformComp.GetGlobalTransform()[3]));
|
||||
transform = transform * rotationMatrix;
|
||||
transform = glm::translate(transform, { 0, -1.0, 0.0 });
|
||||
|
||||
if (type == LightType::Spot)
|
||||
{
|
||||
const Quat& rotationOffset = QuatFromEuler(90.0f, 0, 0);
|
||||
const Quat& globalRotation = glm::normalize(transformComp.GetGlobalRotation()) * rotationOffset;
|
||||
const Matrix4& rotationMatrix = glm::mat4_cast(globalRotation);
|
||||
|
||||
Matrix4 transform = Matrix4(1.0f);
|
||||
transform = glm::translate(view, Vector3(transformComp.GetGlobalTransform()[3]));
|
||||
transform = transform * rotationMatrix;
|
||||
|
||||
float length = 1.0f;
|
||||
float scaleDistance = glm::sqrt(lightComp.Strength);
|
||||
length *= scaleDistance;
|
||||
|
||||
transform = glm::translate(transform, { 0, -length, 0.0 });
|
||||
|
||||
float radiusScale = (length) * glm::tan(Rad(lightComp.OuterCutoff)) / 0.25f;
|
||||
Vector3 coneScale = Vector3(radiusScale, length, radiusScale);
|
||||
transform = glm::scale(transform, coneScale);
|
||||
|
||||
lineCmd.DrawCone(proj * transform, Color{ lightComp.Color, 1.0f }, 1.5f, false);
|
||||
}
|
||||
else if (type == LightType::Directional)
|
||||
{
|
||||
const Quat& rotationOffset = QuatFromEuler(-90.0f, 0, 0);
|
||||
const Quat& globalRotation = glm::normalize(transformComp.GetGlobalRotation()) * rotationOffset;
|
||||
const Matrix4& rotationMatrix = glm::mat4_cast(globalRotation);
|
||||
|
||||
Matrix4 transform = Matrix4(1.0f);
|
||||
transform = glm::translate(view, Vector3(transformComp.GetGlobalTransform()[3]));
|
||||
transform = transform * rotationMatrix;
|
||||
transform = glm::translate(transform, { 0, -1.0, 0.0 });
|
||||
lineCmd.DrawCylinder(proj * transform, Color { lightComp.Color, 1.0f }, 1.5f, false);
|
||||
}
|
||||
}
|
||||
|
||||
auto boxColliderView = scene->m_Registry.view<TransformComponent, BoxColliderComponent>();
|
||||
for (auto e : boxColliderView)
|
||||
{
|
||||
@@ -344,14 +398,14 @@ void ViewportWidget::OnDebugDraw(DebugCmd& debugCmd)
|
||||
auto view = cam->GetTransform();
|
||||
auto proj = cam->GetPerspective();
|
||||
|
||||
static auto drawGizmoIcon = [&](TransformComponent& transform, const std::string& icon)
|
||||
static auto drawGizmoIcon = [&](TransformComponent& transform, const std::string& icon, const Color& color)
|
||||
{
|
||||
Matrix4 initialTransform = transform.GetGlobalTransform();
|
||||
Matrix4 gizmoTransform = initialTransform;
|
||||
gizmoTransform = glm::inverse(scene->GetCurrentCamera()->GetTransform());
|
||||
gizmoTransform[3] = initialTransform[3];
|
||||
gizmoTransform = glm::scale(gizmoTransform, gizmoSize * GetGizmoScale(cameraPosition, initialTransform[3]));
|
||||
debugCmd.DrawTexturedQuad(proj * view * gizmoTransform, TextureManager::Get()->GetTexture2(icon));
|
||||
debugCmd.DrawTexturedQuad(proj * view * gizmoTransform, TextureManager::Get()->GetTexture2(icon), color);
|
||||
};
|
||||
|
||||
debugCmd.DrawQuad(proj * view * glm::translate(Matrix4(1.0f), { 0, 4, 0 }));
|
||||
@@ -361,6 +415,9 @@ void ViewportWidget::OnDebugDraw(DebugCmd& debugCmd)
|
||||
{
|
||||
auto [transform, light] = scene->m_Registry.get<TransformComponent, LightComponent>(e);
|
||||
|
||||
auto selection = editorContext.GetSelection();
|
||||
bool isSelected = selection.Type == EditorSelectionType::Entity && selection.Entity.GetHandle() == (int)e;
|
||||
|
||||
std::string texturePath = "Resources/Gizmos/";
|
||||
switch (light.Type)
|
||||
{
|
||||
@@ -378,15 +435,15 @@ void ViewportWidget::OnDebugDraw(DebugCmd& debugCmd)
|
||||
}
|
||||
|
||||
// Billboard + scaling logic
|
||||
drawGizmoIcon(transform, texturePath);
|
||||
drawGizmoIcon(transform, texturePath, isSelected ? Color(1, 1, 0, 1) : Color(1, 1, 1, 1));
|
||||
}
|
||||
|
||||
DrawIconGizmo<CameraComponent>(debugCmd, "Resources/Gizmos/Camera.png");
|
||||
DrawIconGizmo<CharacterControllerComponent>(debugCmd, "Resources/Gizmos/player.png");
|
||||
DrawIconGizmo<BoneComponent>(debugCmd, "Resources/Gizmos/bone.png");
|
||||
DrawIconGizmo<AudioEmitterComponent>(debugCmd, "Resources/Gizmos/sound_emitter.png");
|
||||
DrawIconGizmo<RigidBodyComponent>(debugCmd, "Resources/Gizmos/rigidbody.png");
|
||||
DrawIconGizmo<ParticleEmitterComponent>(debugCmd, "Resources/Gizmos/particles.png");
|
||||
DrawIconGizmo<CameraComponent>(debugCmd, "Resources/Gizmos/Camera.png", editorContext);
|
||||
DrawIconGizmo<CharacterControllerComponent>(debugCmd, "Resources/Gizmos/player.png", editorContext);
|
||||
DrawIconGizmo<BoneComponent>(debugCmd, "Resources/Gizmos/bone.png", editorContext);
|
||||
DrawIconGizmo<AudioEmitterComponent>(debugCmd, "Resources/Gizmos/sound_emitter.png", editorContext);
|
||||
DrawIconGizmo<RigidBodyComponent>(debugCmd, "Resources/Gizmos/rigidbody.png", editorContext);
|
||||
DrawIconGizmo<ParticleEmitterComponent>(debugCmd, "Resources/Gizmos/particles.png", editorContext);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace Nuake
|
||||
{
|
||||
struct DebugConstant
|
||||
{
|
||||
Vector4 Color = Vector4(1, 1, 1, 1);
|
||||
Matrix4 Transform;
|
||||
int TextureID;
|
||||
};
|
||||
|
||||
@@ -28,10 +28,11 @@ void DebugCmd::DrawQuad(const Matrix4& transform)
|
||||
cmd.DrawIndexed(6);
|
||||
}
|
||||
|
||||
void DebugCmd::DrawTexturedQuad(const Matrix4& transform, Ref<VulkanImage> texture)
|
||||
void DebugCmd::DrawTexturedQuad(const Matrix4& transform, Ref<VulkanImage> texture, const Color& color)
|
||||
{
|
||||
debugConstant.Transform = transform;
|
||||
debugConstant.TextureID = GPUResources::Get().GetBindlessTextureID(texture->GetID());
|
||||
debugConstant.Color = color;
|
||||
|
||||
cmd.PushConstants(ctx.renderPass->PipelineLayout, sizeof(DebugConstant), &debugConstant);
|
||||
|
||||
@@ -41,8 +42,6 @@ void DebugCmd::DrawTexturedQuad(const Matrix4& transform, Ref<VulkanImage> textu
|
||||
cmd.DrawIndexed(6);
|
||||
}
|
||||
|
||||
|
||||
|
||||
DebugLineCmd::DebugLineCmd(Cmd& inCmd, PassRenderContext& inCtx) :
|
||||
cmd(inCmd), ctx(inCtx), lineConstant({})
|
||||
{
|
||||
@@ -182,29 +181,6 @@ void DebugLineCmd::DrawArrow(const Vector3& from, const Vector3& to, const Matri
|
||||
|
||||
cmd.SetLineWidth(lineWidth);
|
||||
|
||||
// Shaft direction (normalized)
|
||||
glm::vec3 dir = glm::normalize(to - from);
|
||||
|
||||
// Get camera position from inverse of view
|
||||
glm::vec3 cameraPos = glm::vec3(glm::inverse(view)[3]);
|
||||
glm::vec3 toCamera = glm::normalize(cameraPos - to);
|
||||
|
||||
// Billboard basis
|
||||
glm::vec3 right = glm::normalize(glm::cross(dir, toCamera));
|
||||
glm::vec3 up = glm::normalize(glm::cross(right, dir));
|
||||
|
||||
//// Build arrowhead transform
|
||||
//glm::mat4 arrowTransform(1.0f);
|
||||
//arrowTransform[0] = glm::vec4(right, 0.0f); // X axis
|
||||
//arrowTransform[1] = glm::vec4(up, 0.0f); // Y axis
|
||||
//arrowTransform[2] = glm::vec4(dir, 0.0f); // Z axis (forward)
|
||||
//arrowTransform[3] = glm::vec4(to, 1.0f); // Position
|
||||
|
||||
// Optional: scale arrowhead size
|
||||
//float arrowScale = 0.2f; // You can tweak this
|
||||
//arrowTransform = arrowTransform * glm::scale(glm::mat4(1.0f), glm::vec3(arrowScale));
|
||||
|
||||
// Final matrix
|
||||
lineConstant.Transform = proj * view;
|
||||
|
||||
lineConstant.LineColor = inColor;
|
||||
@@ -215,3 +191,27 @@ void DebugLineCmd::DrawArrow(const Vector3& from, const Vector3& to, const Matri
|
||||
cmd.BindIndexBuffer(sphereMesh->GetIndexBuffer()->GetBuffer());
|
||||
cmd.DrawIndexed(sphereMesh->GetIndexBuffer()->GetSize() / sizeof(uint32_t));
|
||||
}
|
||||
|
||||
void DebugLineCmd::DrawCone(const Matrix4& transform, const Color& inColor, float lineWidth, bool stippled)
|
||||
{
|
||||
cmd.SetPolygonMode(VK_POLYGON_MODE_LINE);
|
||||
cmd.SetLineRasterizationMode(VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH);
|
||||
cmd.SetPrimitiveTopology(VK_PRIMITIVE_TOPOLOGY_LINE_LIST);
|
||||
|
||||
cmd.SetLineStippleEnabled(stippled);
|
||||
if (stippled)
|
||||
{
|
||||
cmd.SetLineStipple(2, 0b1111111100000000);
|
||||
}
|
||||
|
||||
cmd.SetLineWidth(lineWidth);
|
||||
|
||||
lineConstant.LineColor = inColor;
|
||||
lineConstant.Transform = transform;
|
||||
cmd.PushConstants(ctx.renderPass->PipelineLayout, sizeof(LineConstant), &lineConstant);
|
||||
|
||||
auto& coneMesh = VkSceneRenderer::ConeMesh;
|
||||
cmd.BindDescriptorSet(ctx.renderPass->PipelineLayout, coneMesh->GetDescriptorSet(), 1);
|
||||
cmd.BindIndexBuffer(coneMesh->GetIndexBuffer()->GetBuffer());
|
||||
cmd.DrawIndexed(coneMesh->GetIndexBuffer()->GetSize() / sizeof(uint32_t));
|
||||
}
|
||||
@@ -26,7 +26,7 @@ namespace Nuake
|
||||
Ref<Scene> GetScene() const;
|
||||
|
||||
void DrawQuad(const Matrix4& transform);
|
||||
void DrawTexturedQuad(const Matrix4& transform, Ref<VulkanImage> texture);
|
||||
void DrawTexturedQuad(const Matrix4& transform, Ref<VulkanImage> texture, const Color& color = Color(1, 1, 1 ,1));
|
||||
|
||||
void DrawSphere(const Vector2& position, float radius, const Color& color) const;
|
||||
void DrawCube(const Vector3& position, const Vector3& size, const Color& color) const;
|
||||
@@ -59,5 +59,6 @@ namespace Nuake
|
||||
void DrawSphere(const Matrix4& transform, const Color& color, float lineWidth = 1.0f, bool stippled = false);
|
||||
void DrawCylinder(const Matrix4& transform, const Color& color, float lineWidth = 1.0f, bool stippled = false);
|
||||
void DrawArrow(const Vector3& from, const Vector3& to, const Matrix4& view, const Matrix4& proj, const Color& color, float lineWidth = 1.0f, bool stippled = false);
|
||||
void DrawCone(const Matrix4& transform, const Color& color, float lineWidth = 1.0f, bool stippled = false);
|
||||
};
|
||||
}
|
||||
@@ -606,7 +606,7 @@ void SceneRenderPipeline::RecreatePipeline()
|
||||
|
||||
auto& gizmoPass = GBufferPipeline.AddPass("Gizmo");
|
||||
gizmoPass.SetShaders(shaderMgr.GetShader("gizmo_vert"), shaderMgr.GetShader("gizmo_frag"));
|
||||
gizmoPass.SetPushConstant(debugConstant);
|
||||
gizmoPass.SetPushConstant<DebugConstant>(debugConstant);
|
||||
gizmoPass.AddInput("Depth");
|
||||
gizmoPass.AddAttachment("GizmoOutput", GizmoOutput->GetFormat());
|
||||
gizmoPass.AddAttachment("GizmoDepth", GBufferDepth->GetFormat(), ImageUsage::Depth, false);
|
||||
|
||||
@@ -28,6 +28,7 @@ Ref<VkMesh> VkSceneRenderer::CapsuleMesh;
|
||||
Ref<VkMesh> VkSceneRenderer::SphereMesh;
|
||||
Ref<VkMesh> VkSceneRenderer::CylinderMesh;
|
||||
Ref<VkMesh> VkSceneRenderer::ArrowMesh;
|
||||
Ref<VkMesh> VkSceneRenderer::ConeMesh;
|
||||
|
||||
void VkSceneRenderer::Init()
|
||||
{
|
||||
@@ -293,7 +294,7 @@ void VkSceneRenderer::Init()
|
||||
std::vector<uint32_t> cylinderIndices;
|
||||
|
||||
const int segments = 16;
|
||||
const float radius = 0.5f;
|
||||
const float radius = 0.25f;
|
||||
const float halfHeight = 1.0f;
|
||||
|
||||
// Vertex pairs: top and bottom
|
||||
@@ -341,6 +342,52 @@ void VkSceneRenderer::Init()
|
||||
CylinderMesh = CreateRef<VkMesh>(cylinderVertices, cylinderIndices);
|
||||
}
|
||||
|
||||
{
|
||||
std::vector<Vertex> coneVertices;
|
||||
std::vector<uint32_t> coneIndices;
|
||||
|
||||
const int segments = 16;
|
||||
const float radius = 0.5f;
|
||||
const float height = 2.0f;
|
||||
const float halfHeight = height * 0.5f;
|
||||
|
||||
// Tip vertex at the top center
|
||||
Vector3 tipPosition = Vector3(0.0f, +halfHeight, 0.0f);
|
||||
coneVertices.push_back({ tipPosition, 0.0f, Vector3(), 0.0f });
|
||||
uint32_t tipIndex = 0;
|
||||
|
||||
// Base ring vertices
|
||||
for (int i = 0; i < segments; ++i)
|
||||
{
|
||||
float angle = (2.0f * glm::pi<float>() * i) / segments;
|
||||
float x = cos(angle) * radius;
|
||||
float z = sin(angle) * radius;
|
||||
|
||||
Vector3 pos = Vector3(x, -halfHeight, z);
|
||||
coneVertices.push_back({ pos, 0.0f, Vector3(), 0.0f });
|
||||
}
|
||||
|
||||
// Circle outline on base
|
||||
for (int i = 0; i < segments; ++i)
|
||||
{
|
||||
uint32_t currIdx = tipIndex + 1 + i;
|
||||
uint32_t nextIdx = tipIndex + 1 + ((i + 1) % segments);
|
||||
|
||||
coneIndices.push_back(currIdx);
|
||||
coneIndices.push_back(nextIdx);
|
||||
}
|
||||
|
||||
// Lines from base to tip
|
||||
for (int i = 0; i < segments; ++i)
|
||||
{
|
||||
uint32_t baseIdx = tipIndex + 1 + i;
|
||||
coneIndices.push_back(tipIndex); // tip
|
||||
coneIndices.push_back(baseIdx); // base
|
||||
}
|
||||
|
||||
// Final creation of the cone outline mesh
|
||||
ConeMesh = CreateRef<VkMesh>(coneVertices, coneIndices);
|
||||
}
|
||||
}
|
||||
|
||||
void VkSceneRenderer::LoadShaders()
|
||||
|
||||
@@ -30,6 +30,7 @@ namespace Nuake
|
||||
static Ref<VkMesh> SphereMesh;
|
||||
static Ref<VkMesh> CylinderMesh;
|
||||
static Ref<VkMesh> ArrowMesh;
|
||||
static Ref<VkMesh> ConeMesh;
|
||||
|
||||
public:
|
||||
//RenderContext Context;
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
namespace Nuake
|
||||
{
|
||||
enum LightType
|
||||
enum LightType : int32_t
|
||||
{
|
||||
Directional, Point, Spot
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user