editor: light direction visualizer arrows and some other updates

This commit is contained in:
Turánszki János
2023-07-02 19:52:41 +02:00
parent 92ac1be038
commit 9c13bfd517
3 changed files with 160 additions and 20 deletions
+153 -16
View File
@@ -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));
+1
View File
@@ -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;
+6 -4
View File
@@ -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(&params.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(&params.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(&params.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);
}