From 9c13bfd5175ed7b104239012efb9307d3567cc59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tur=C3=A1nszki=20J=C3=A1nos?= Date: Sun, 2 Jul 2023 19:52:41 +0200 Subject: [PATCH] editor: light direction visualizer arrows and some other updates --- Editor/Editor.cpp | 169 +++++++++++++++++++++++++++++++++++---- Editor/GeneralWindow.cpp | 1 + Editor/Translator.cpp | 10 ++- 3 files changed, 160 insertions(+), 20 deletions(-) diff --git a/Editor/Editor.cpp b/Editor/Editor.cpp index f1b291199..27afe8b10 100644 --- a/Editor/Editor.cpp +++ b/Editor/Editor.cpp @@ -767,18 +767,49 @@ void EditorComponent::Update(float dt) for (size_t i = 0; i < scene.lights.GetCount(); ++i) { Entity entity = scene.lights.GetEntity(i); - if (!scene.transforms.Contains(entity)) - continue; - const TransformComponent& transform = *scene.transforms.GetComponent(entity); + const LightComponent& light = scene.lights[i]; - XMVECTOR disV = XMVector3LinePointDistance(XMLoadFloat3(&pickRay.origin), XMLoadFloat3(&pickRay.origin) + XMLoadFloat3(&pickRay.direction), transform.GetPositionV()); + XMVECTOR disV = XMVector3LinePointDistance(XMLoadFloat3(&pickRay.origin), XMLoadFloat3(&pickRay.origin) + XMLoadFloat3(&pickRay.direction), XMLoadFloat3(&light.position)); float dis = XMVectorGetX(disV); - if (dis > 0.01f && dis < wi::math::Distance(transform.GetPosition(), pickRay.origin) * 0.05f && dis < hovered.distance) + if (dis > 0.01f && dis < wi::math::Distance(light.position, pickRay.origin) * 0.05f && dis < hovered.distance) { hovered = wi::scene::PickResult(); hovered.entity = entity; hovered.distance = dis; } + else + { + if (light.GetType() == LightComponent::DIRECTIONAL || light.GetType() == LightComponent::SPOT) + { + // Light direction visualizer picking: + const float dist = wi::math::Distance(light.position, camera.Eye); + float siz = 0.02f * dist; + const XMMATRIX M = + XMMatrixScaling(siz, siz, siz) * + XMMatrixRotationZ(-XM_PIDIV2) * + XMMatrixRotationQuaternion(XMLoadFloat4(&light.rotation)) * + XMMatrixTranslation(light.position.x, light.position.y, light.position.z) + ; + + const float origin_size = 0.4f * siz; + const float axis_length = 18; + + XMFLOAT3 base; + XMFLOAT3 tip; + XMStoreFloat3(&base, XMVector3Transform(XMVectorSet(0, 0, 0, 1), M)); + XMStoreFloat3(&tip, XMVector3Transform(XMVectorSet(axis_length, 0, 0, 1), M)); + Capsule capsule = Capsule(base, tip, origin_size); + if (pickRay.intersects(capsule, dis)) + { + if (dis < hovered.distance) + { + hovered = wi::scene::PickResult(); + hovered.entity = entity; + hovered.distance = dis; + } + } + } + } } } if (has_flag(optionsWnd.filter, OptionsWindow::Filter::Decal)) @@ -1419,6 +1450,7 @@ void EditorComponent::Update(float dt) componentsWnd.meshWnd.SetEntity(INVALID_ENTITY, -1); componentsWnd.materialWnd.SetEntity(INVALID_ENTITY); componentsWnd.soundWnd.SetEntity(INVALID_ENTITY); + componentsWnd.lightWnd.SetEntity(INVALID_ENTITY); componentsWnd.videoWnd.SetEntity(INVALID_ENTITY); componentsWnd.decalWnd.SetEntity(INVALID_ENTITY); componentsWnd.envProbeWnd.SetEntity(INVALID_ENTITY); @@ -1921,6 +1953,11 @@ void EditorComponent::Render() const cam.UpdateCamera(); const XMMATRIX VP = cam.GetViewProjection(); + MiscCB sb; + XMStoreFloat4x4(&sb.g_xTransform, VP); + sb.g_xColor = XMFLOAT4(1, 1, 1, 1); + device->BindDynamicConstantBuffer(sb, CB_GETBINDSLOT(MiscCB), cmd); + const XMMATRIX R = XMLoadFloat3x3(&cam.rotationMatrix); wi::font::Params fp; @@ -1930,7 +1967,7 @@ void EditorComponent::Render() const const float scaling = 0.0025f; fp.h_align = wi::font::WIFALIGN_CENTER; fp.v_align = wi::font::WIFALIGN_CENTER; - fp.shadowColor = wi::Color::Shadow(); + fp.shadowColor = backgroundEntityColor; fp.shadow_softness = 1; if (has_flag(optionsWnd.filter, OptionsWindow::Filter::Light)) @@ -1941,10 +1978,11 @@ void EditorComponent::Render() const Entity entity = scene.lights.GetEntity(i); if (!scene.transforms.Contains(entity)) continue; - const TransformComponent& transform = *scene.transforms.GetComponent(entity); - fp.position = transform.GetPosition(); - fp.scaling = scaling * wi::math::Distance(transform.GetPosition(), camera.Eye); + const float dist = wi::math::Distance(light.position, camera.Eye); + + fp.position = light.position; + fp.scaling = scaling * dist; fp.color = inactiveEntityColor; if (hovered.entity == entity) @@ -1974,6 +2012,110 @@ void EditorComponent::Render() const default: break; } + + if (light.GetType() == LightComponent::DIRECTIONAL || light.GetType() == LightComponent::SPOT) + { + // Light direction visualizer: + static PipelineState pso; + if (!pso.IsValid()) + { + static auto LoadShaders = [] { + PipelineStateDesc desc; + desc.vs = wi::renderer::GetShader(wi::enums::VSTYPE_VERTEXCOLOR); + desc.ps = wi::renderer::GetShader(wi::enums::PSTYPE_VERTEXCOLOR); + desc.il = wi::renderer::GetInputLayout(wi::enums::ILTYPE_VERTEXCOLOR); + desc.dss = wi::renderer::GetDepthStencilState(wi::enums::DSSTYPE_DEFAULT); + desc.rs = wi::renderer::GetRasterizerState(wi::enums::RSTYPE_DOUBLESIDED); + desc.bs = wi::renderer::GetBlendState(wi::enums::BSTYPE_TRANSPARENT); + desc.pt = PrimitiveTopology::TRIANGLELIST; + wi::graphics::GetDevice()->CreatePipelineState(&desc, &pso); + }; + static wi::eventhandler::Handle handle = wi::eventhandler::Subscribe(wi::eventhandler::EVENT_RELOAD_SHADERS, [](uint64_t userdata) { LoadShaders(); }); + LoadShaders(); + } + struct Vertex + { + XMFLOAT4 position; + XMFLOAT4 color; + }; + + device->BindPipelineState(&pso, cmd); + + const uint32_t segmentCount = 18; + const uint32_t cylinder_triangleCount = segmentCount * 2; + const uint32_t cone_triangleCount = cylinder_triangleCount; + const uint32_t vertexCount = (cylinder_triangleCount + cone_triangleCount) * 3; + auto mem = device->AllocateGPU(sizeof(Vertex) * vertexCount, cmd); + + float siz = 0.02f * dist; + const XMMATRIX M = + XMMatrixScaling(siz, siz, siz) * + XMMatrixRotationZ(-XM_PIDIV2) * + XMMatrixRotationQuaternion(XMLoadFloat4(&light.rotation)) * + XMMatrixTranslation(light.position.x, light.position.y, light.position.z) + ; + + const XMFLOAT4 col = fp.color; + const XMFLOAT4 col_fade = XMFLOAT4(col.x, col.y, col.z, 0); + const float origin_size = 0.2f; + const float cone_length = 0.75f; + const float axis_length = 18; + float cylinder_length = axis_length; + cylinder_length -= cone_length; + uint8_t* dst = (uint8_t*)mem.data; + for (uint32_t i = 0; i < segmentCount; ++i) + { + const float angle0 = (float)i / (float)segmentCount * XM_2PI; + const float angle1 = (float)(i + 1) / (float)segmentCount * XM_2PI; + // cylinder base: + { + const float cylinder_radius = 0.075f; + Vertex verts[] = { + {XMFLOAT4(0, std::sin(angle0) * cylinder_radius, std::cos(angle0) * cylinder_radius, 1), col_fade}, + {XMFLOAT4(0, std::sin(angle1) * cylinder_radius, std::cos(angle1) * cylinder_radius, 1), col_fade}, + {XMFLOAT4(cylinder_length, std::sin(angle0) * cylinder_radius, std::cos(angle0) * cylinder_radius, 1), col}, + {XMFLOAT4(cylinder_length, std::sin(angle0) * cylinder_radius, std::cos(angle0) * cylinder_radius, 1), col}, + {XMFLOAT4(cylinder_length, std::sin(angle1) * cylinder_radius, std::cos(angle1) * cylinder_radius, 1), col}, + {XMFLOAT4(0, std::sin(angle1) * cylinder_radius, std::cos(angle1) * cylinder_radius, 1), col_fade}, + }; + for (auto& vert : verts) + { + XMStoreFloat4(&vert.position, XMVector3Transform(XMLoadFloat4(&vert.position), M)); + } + std::memcpy(dst, verts, sizeof(verts)); + dst += sizeof(verts); + } + // cone cap: + { + const float cone_radius = origin_size; + Vertex verts[] = { + {XMFLOAT4(cylinder_length, 0, 0, 1), col}, + {XMFLOAT4(cylinder_length, std::sin(angle0) * cone_radius, std::cos(angle0) * cone_radius, 1), col}, + {XMFLOAT4(cylinder_length, std::sin(angle1) * cone_radius, std::cos(angle1) * cone_radius, 1), col}, + {XMFLOAT4(axis_length, 0, 0, 1), col}, + {XMFLOAT4(cylinder_length, std::sin(angle0) * cone_radius, std::cos(angle0) * cone_radius, 1), col}, + {XMFLOAT4(cylinder_length, std::sin(angle1) * cone_radius, std::cos(angle1) * cone_radius, 1), col}, + }; + for (auto& vert : verts) + { + XMStoreFloat4(&vert.position, XMVector3Transform(XMLoadFloat4(&vert.position), M)); + } + std::memcpy(dst, verts, sizeof(verts)); + dst += sizeof(verts); + } + } + const GPUBuffer* vbs[] = { + &mem.buffer, + }; + const uint32_t strides[] = { + sizeof(Vertex), + }; + const uint64_t offsets[] = { + mem.offset, + }; + device->BindVertexBuffers(vbs, 0, arraysize(vbs), strides, offsets, cmd); + device->Draw(vertexCount, 0, cmd); + } } } @@ -2428,11 +2570,6 @@ void EditorComponent::Render() const device->EventBegin("Bone capsules", cmd); device->BindPipelineState(&pso, cmd); - MiscCB sb; - XMStoreFloat4x4(&sb.g_xTransform, camera.GetViewProjection()); - sb.g_xColor = XMFLOAT4(1, 1, 1, 1); - device->BindDynamicConstantBuffer(sb, CB_GETBINDSLOT(MiscCB), cmd); - const GPUBuffer* vbs[] = { &mem.buffer, }; @@ -2562,7 +2699,6 @@ void EditorComponent::Compose(CommandList cmd) const params.v_align = wi::font::WIFALIGN_CENTER; params.size = 30; params.shadow_softness = 1; - params.shadowColor.setA(100); wi::font::Draw(save_text, params, cmd); } @@ -3330,8 +3466,9 @@ void EditorComponent::UpdateTopMenuAnimation() saveButton.SetPos(XMFLOAT2(openButton.GetPos().x - saveButton.GetSize().x - padding, 0)); + float static_pos = screenW - wid_idle * 11; stopButton.SetSize(XMFLOAT2(wid_idle * 0.75f, hei)); - stopButton.SetPos(XMFLOAT2(saveButton.GetPos().x - stopButton.GetSize().x - 20, 0)); + stopButton.SetPos(XMFLOAT2(static_pos - stopButton.GetSize().x - 20, 0)); playButton.SetSize(XMFLOAT2(wid_idle * 0.75f, hei)); playButton.SetPos(XMFLOAT2(stopButton.GetPos().x - playButton.GetSize().x - padding, 0)); diff --git a/Editor/GeneralWindow.cpp b/Editor/GeneralWindow.cpp index 258cd35aa..1400459d9 100644 --- a/Editor/GeneralWindow.cpp +++ b/Editor/GeneralWindow.cpp @@ -540,6 +540,7 @@ void GeneralWindow::Create(EditorComponent* _editor) editor->hoveredEntityColor = theme.font.color; } editor->inactiveEntityColor.setA(150); + editor->backgroundEntityColor = shadow_color; editor->save_text_color = theme.font.color; diff --git a/Editor/Translator.cpp b/Editor/Translator.cpp index 17c1e2b72..ce945e9fb 100644 --- a/Editor/Translator.cpp +++ b/Editor/Translator.cpp @@ -859,23 +859,23 @@ void Translator::Draw(const CameraComponent& camera, CommandList cmd) const params.scaling = 0.04f * dist; params.customProjection = &VP; params.customRotation = &R; - params.shadowColor = wi::Color(0, 0, 0, 127); + params.shadowColor = wi::Color(0, 0, 0, uint8_t(127 * opacity)); params.shadow_softness = 0.8f; XMVECTOR pos = transform.GetPositionV(); - params.color = wi::Color::fromFloat4(XMFLOAT4(1, channel_min, channel_min, 1)); + params.color = wi::Color::fromFloat4(XMFLOAT4(1, channel_min, channel_min, opacity)); XMStoreFloat3(¶ms.position, pos + XMVector3Transform(XMVectorSet(axis_length + 0.5f, 0, 0, 0) * dist, GetMirrorMatrix(TRANSLATOR_X, camera))); std::memset(TEXT, 0, sizeof(TEXT)); WriteAxisText(TRANSLATOR_X, camera, TEXT); wi::font::Draw(TEXT, strlen(TEXT), params, cmd); - params.color = wi::Color::fromFloat4(XMFLOAT4(channel_min, 1, channel_min, 1)); + params.color = wi::Color::fromFloat4(XMFLOAT4(channel_min, 1, channel_min, opacity)); XMStoreFloat3(¶ms.position, pos + XMVector3Transform(XMVectorSet(0, axis_length + 0.5f, 0, 0) * dist, GetMirrorMatrix(TRANSLATOR_Y, camera))); std::memset(TEXT, 0, sizeof(TEXT)); WriteAxisText(TRANSLATOR_Y, camera, TEXT); wi::font::Draw(TEXT, strlen(TEXT), params, cmd); - params.color = wi::Color::fromFloat4(XMFLOAT4(channel_min, channel_min, 1, 1)); + params.color = wi::Color::fromFloat4(XMFLOAT4(channel_min, channel_min, 1, opacity)); XMStoreFloat3(¶ms.position, pos + XMVector3Transform(XMVectorSet(0, 0, axis_length + 0.5f, 0) * dist, GetMirrorMatrix(TRANSLATOR_Z, camera))); std::memset(TEXT, 0, sizeof(TEXT)); WriteAxisText(TRANSLATOR_Z, camera, TEXT); @@ -1063,6 +1063,8 @@ void Translator::Draw(const CameraComponent& camera, CommandList cmd) const { str += "Scaling = " + std::to_string(transform.scale_local.x / transform_start.scale_local.x) + ", " + std::to_string(transform.scale_local.y / transform_start.scale_local.y) + ", " + std::to_string(transform.scale_local.z / transform_start.scale_local.z); } + params.shadowColor.setA(uint8_t(opacity * 255.0f)); + params.color.setA(uint8_t(opacity * 255.0f)); wi::font::Draw(str, params, cmd); }