From ecea9f086d904d50cd670017d001afbcd56d4e6f Mon Sep 17 00:00:00 2001 From: turanszkij Date: Wed, 12 Sep 2018 18:34:54 +0100 Subject: [PATCH] simplified transform component; resurrected hair particle + added editor window --- Editor/Editor.cpp | 123 ++++++-- Editor/Editor.h | 4 +- Editor/Editor.vcxproj | 2 + Editor/Editor.vcxproj.filters | 6 + Editor/EmitterWindow.cpp | 1 - Editor/EmitterWindow.h | 1 + Editor/HairParticleWindow.cpp | 162 +++++++++++ Editor/HairParticleWindow.h | 37 +++ Editor/RendererWindow.cpp | 10 + Editor/RendererWindow.h | 6 +- Editor/Translator.cpp | 9 +- WickedEngine/hairparticleHF.hlsli | 2 +- WickedEngine/hairparticlePS_simplest.hlsl | 2 +- WickedEngine/wiHairParticle.cpp | 328 ++++++---------------- WickedEngine/wiHairParticle.h | 14 +- WickedEngine/wiRenderer.cpp | 154 +++++----- WickedEngine/wiSceneSystem.cpp | 220 ++++++++++----- WickedEngine/wiSceneSystem.h | 34 ++- WickedEngine/wiWidget.cpp | 91 +++--- WickedEngine/wiWidget.h | 3 + 20 files changed, 729 insertions(+), 480 deletions(-) create mode 100644 Editor/HairParticleWindow.cpp create mode 100644 Editor/HairParticleWindow.h diff --git a/Editor/Editor.cpp b/Editor/Editor.cpp index fd24f65ba..b0f50d29e 100644 --- a/Editor/Editor.cpp +++ b/Editor/Editor.cpp @@ -13,6 +13,7 @@ #include "LightWindow.h" #include "AnimationWindow.h" #include "EmitterWindow.h" +#include "HairParticleWindow.h" #include "ForceFieldWindow.h" #include "OceanWindow.h" @@ -188,7 +189,7 @@ void BeginTranslate() TransformComponent* transform = wiRenderer::GetScene().transforms.GetComponent(x); if (transform != nullptr) { - centerV = XMVectorAdd(centerV, XMLoadFloat3(&transform->translation)); + centerV = XMVectorAdd(centerV, transform->GetPositionV()); count += 1.0f; } } @@ -335,6 +336,7 @@ void EditorComponent::ChangeRenderPath(RENDERPATH path) lightWnd = new LightWindow(&GetGUI()); animWnd = new AnimationWindow(&GetGUI()); emitterWnd = new EmitterWindow(&GetGUI()); + hairWnd = new HairParticleWindow(&GetGUI()); forceFieldWnd = new ForceFieldWindow(&GetGUI()); oceanWnd = new OceanWindow(&GetGUI()); } @@ -352,6 +354,7 @@ void EditorComponent::DeleteWindows() SAFE_DELETE(lightWnd); SAFE_DELETE(animWnd); SAFE_DELETE(emitterWnd); + SAFE_DELETE(hairWnd); SAFE_DELETE(forceFieldWnd); SAFE_DELETE(oceanWnd); } @@ -370,6 +373,7 @@ void EditorComponent::Initialize() SAFE_INIT(lightWnd); SAFE_INIT(animWnd); SAFE_INIT(emitterWnd); + SAFE_INIT(hairWnd); SAFE_INIT(forceFieldWnd); SAFE_INIT(oceanWnd); @@ -557,6 +561,15 @@ void EditorComponent::Load() }); GetGUI().AddWidget(emitterWnd_Toggle); + wiButton* hairWnd_Toggle = new wiButton("HairParticle"); + hairWnd_Toggle->SetTooltip("Emitter Particle System properties"); + hairWnd_Toggle->SetPos(XMFLOAT2(x += step, screenH - 40)); + hairWnd_Toggle->SetSize(XMFLOAT2(100, 40)); + hairWnd_Toggle->OnClick([=](wiEventArgs args) { + hairWnd->hairWindow->SetVisible(!hairWnd->hairWindow->IsVisible()); + }); + GetGUI().AddWidget(hairWnd_Toggle); + wiButton* forceFieldWnd_Toggle = new wiButton("ForceField"); forceFieldWnd_Toggle->SetTooltip("Force Field properties"); forceFieldWnd_Toggle->SetPos(XMFLOAT2(x += step, screenH - 40)); @@ -857,6 +870,7 @@ void EditorComponent::Load() envProbeWnd->SetEntity(INVALID_ENTITY); materialWnd->SetEntity(INVALID_ENTITY); emitterWnd->SetEntity(INVALID_ENTITY); + hairWnd->SetEntity(INVALID_ENTITY); forceFieldWnd->SetEntity(INVALID_ENTITY); cameraWnd->SetEntity(INVALID_ENTITY); }); @@ -936,6 +950,7 @@ void EditorComponent::Load() decalTex = *(Texture2D*)Content.add("images/decal.dds"); forceFieldTex = *(Texture2D*)Content.add("images/forcefield.dds"); emitterTex = *(Texture2D*)Content.add("images/emitter.dds"); + hairTex = *(Texture2D*)Content.add("images/emitter.dds"); cameraTex = *(Texture2D*)Content.add("images/camera.dds"); armatureTex = *(Texture2D*)Content.add("images/armature.dds"); } @@ -1117,9 +1132,9 @@ void EditorComponent::Update(float dt) Entity entity = scene.lights.GetEntity(i); const TransformComponent& transform = *scene.transforms.GetComponent(entity); - XMVECTOR disV = XMVector3LinePointDistance(XMLoadFloat3(&pickRay.origin), XMLoadFloat3(&pickRay.origin) + XMLoadFloat3(&pickRay.direction), XMLoadFloat3(&transform.translation)); + XMVECTOR disV = XMVector3LinePointDistance(XMLoadFloat3(&pickRay.origin), XMLoadFloat3(&pickRay.origin) + XMLoadFloat3(&pickRay.direction), transform.GetPositionV()); float dis = XMVectorGetX(disV); - if (dis < wiMath::Distance(transform.translation, pickRay.origin) * 0.05f && dis < hovered.distance) + if (dis < wiMath::Distance(transform.GetPosition(), pickRay.origin) * 0.05f && dis < hovered.distance) { hovered.Clear(); hovered.entity = entity; @@ -1134,9 +1149,9 @@ void EditorComponent::Update(float dt) Entity entity = scene.decals.GetEntity(i); const TransformComponent& transform = *scene.transforms.GetComponent(entity); - XMVECTOR disV = XMVector3LinePointDistance(XMLoadFloat3(&pickRay.origin), XMLoadFloat3(&pickRay.origin) + XMLoadFloat3(&pickRay.direction), XMLoadFloat3(&transform.translation)); + XMVECTOR disV = XMVector3LinePointDistance(XMLoadFloat3(&pickRay.origin), XMLoadFloat3(&pickRay.origin) + XMLoadFloat3(&pickRay.direction), transform.GetPositionV()); float dis = XMVectorGetX(disV); - if (dis < wiMath::Distance(transform.translation, pickRay.origin) * 0.05f && dis < hovered.distance) + if (dis < wiMath::Distance(transform.GetPosition(), pickRay.origin) * 0.05f && dis < hovered.distance) { hovered.Clear(); hovered.entity = entity; @@ -1151,9 +1166,9 @@ void EditorComponent::Update(float dt) Entity entity = scene.forces.GetEntity(i); const TransformComponent& transform = *scene.transforms.GetComponent(entity); - XMVECTOR disV = XMVector3LinePointDistance(XMLoadFloat3(&pickRay.origin), XMLoadFloat3(&pickRay.origin) + XMLoadFloat3(&pickRay.direction), XMLoadFloat3(&transform.translation)); + XMVECTOR disV = XMVector3LinePointDistance(XMLoadFloat3(&pickRay.origin), XMLoadFloat3(&pickRay.origin) + XMLoadFloat3(&pickRay.direction), transform.GetPositionV()); float dis = XMVectorGetX(disV); - if (dis < wiMath::Distance(transform.translation, pickRay.origin) * 0.05f && dis < hovered.distance) + if (dis < wiMath::Distance(transform.GetPosition(), pickRay.origin) * 0.05f && dis < hovered.distance) { hovered.Clear(); hovered.entity = entity; @@ -1168,9 +1183,26 @@ void EditorComponent::Update(float dt) Entity entity = scene.emitters.GetEntity(i); const TransformComponent& transform = *scene.transforms.GetComponent(entity); - XMVECTOR disV = XMVector3LinePointDistance(XMLoadFloat3(&pickRay.origin), XMLoadFloat3(&pickRay.origin) + XMLoadFloat3(&pickRay.direction), XMLoadFloat3(&transform.translation)); + XMVECTOR disV = XMVector3LinePointDistance(XMLoadFloat3(&pickRay.origin), XMLoadFloat3(&pickRay.origin) + XMLoadFloat3(&pickRay.direction), transform.GetPositionV()); float dis = XMVectorGetX(disV); - if (dis < wiMath::Distance(transform.translation, pickRay.origin) * 0.05f && dis < hovered.distance) + if (dis < wiMath::Distance(transform.GetPosition(), pickRay.origin) * 0.05f && dis < hovered.distance) + { + hovered.Clear(); + hovered.entity = entity; + hovered.distance = dis; + } + } + } + if (pickMask & PICK_HAIR) + { + for (size_t i = 0; i < scene.hairs.GetCount(); ++i) + { + Entity entity = scene.hairs.GetEntity(i); + const TransformComponent& transform = *scene.transforms.GetComponent(entity); + + XMVECTOR disV = XMVector3LinePointDistance(XMLoadFloat3(&pickRay.origin), XMLoadFloat3(&pickRay.origin) + XMLoadFloat3(&pickRay.direction), transform.GetPositionV()); + float dis = XMVectorGetX(disV); + if (dis < wiMath::Distance(transform.GetPosition(), pickRay.origin) * 0.05f && dis < hovered.distance) { hovered.Clear(); hovered.entity = entity; @@ -1185,9 +1217,9 @@ void EditorComponent::Update(float dt) Entity entity = scene.probes.GetEntity(i); const TransformComponent& transform = *scene.transforms.GetComponent(entity); - if (SPHERE(transform.translation, 1).intersects(pickRay)) + if (SPHERE(transform.GetPosition(), 1).intersects(pickRay)) { - float dis = wiMath::Distance(transform.translation, pickRay.origin); + float dis = wiMath::Distance(transform.GetPosition(), pickRay.origin); if (dis < hovered.distance) { hovered.Clear(); @@ -1209,9 +1241,9 @@ void EditorComponent::Update(float dt) const TransformComponent& transform = *scene.transforms.GetComponent(entity); - XMVECTOR disV = XMVector3LinePointDistance(XMLoadFloat3(&pickRay.origin), XMLoadFloat3(&pickRay.origin) + XMLoadFloat3(&pickRay.direction), XMLoadFloat3(&transform.translation)); + XMVECTOR disV = XMVector3LinePointDistance(XMLoadFloat3(&pickRay.origin), XMLoadFloat3(&pickRay.origin) + XMLoadFloat3(&pickRay.direction), transform.GetPositionV()); float dis = XMVectorGetX(disV); - if (dis < wiMath::Distance(transform.translation, pickRay.origin) * 0.05f && dis < hovered.distance) + if (dis < wiMath::Distance(transform.GetPosition(), pickRay.origin) * 0.05f && dis < hovered.distance) { hovered.Clear(); hovered.entity = entity; @@ -1226,9 +1258,9 @@ void EditorComponent::Update(float dt) Entity entity = scene.armatures.GetEntity(i); const TransformComponent& transform = *scene.transforms.GetComponent(entity); - XMVECTOR disV = XMVector3LinePointDistance(XMLoadFloat3(&pickRay.origin), XMLoadFloat3(&pickRay.origin) + XMLoadFloat3(&pickRay.direction), XMLoadFloat3(&transform.translation)); + XMVECTOR disV = XMVector3LinePointDistance(XMLoadFloat3(&pickRay.origin), XMLoadFloat3(&pickRay.origin) + XMLoadFloat3(&pickRay.direction), transform.GetPositionV()); float dis = XMVectorGetX(disV); - if (dis < wiMath::Distance(transform.translation, pickRay.origin) * 0.05f && dis < hovered.distance) + if (dis < wiMath::Distance(transform.GetPosition(), pickRay.origin) * 0.05f && dis < hovered.distance) { hovered.Clear(); hovered.entity = entity; @@ -1369,6 +1401,7 @@ void EditorComponent::Update(float dt) { objectWnd->SetEntity(INVALID_ENTITY); emitterWnd->SetEntity(INVALID_ENTITY); + hairWnd->SetEntity(INVALID_ENTITY); meshWnd->SetEntity(INVALID_ENTITY); materialWnd->SetEntity(INVALID_ENTITY); lightWnd->SetEntity(INVALID_ENTITY); @@ -1395,6 +1428,7 @@ void EditorComponent::Update(float dt) objectWnd->SetEntity(picked->entity); emitterWnd->SetEntity(picked->entity); + hairWnd->SetEntity(picked->entity); lightWnd->SetEntity(picked->entity); decalWnd->SetEntity(picked->entity); envProbeWnd->SetEntity(picked->entity); @@ -1620,6 +1654,7 @@ void EditorComponent::Update(float dt) } emitterWnd->UpdateData(); + hairWnd->UpdateData(); __super::Update(dt); @@ -1738,10 +1773,10 @@ void EditorComponent::Compose() Entity entity = scene.lights.GetEntity(i); const TransformComponent& transform = *scene.transforms.GetComponent(entity); - float dist = wiMath::Distance(transform.translation, camera->Eye) * 0.08f; + float dist = wiMath::Distance(transform.GetPosition(), camera->Eye) * 0.08f; wiImageEffects fx; - fx.pos = transform.translation; + fx.pos = transform.GetPosition(); fx.siz = XMFLOAT2(dist, dist); fx.typeFlag = ImageType::WORLD; fx.pivot = XMFLOAT2(0.5f, 0.5f); @@ -1786,10 +1821,10 @@ void EditorComponent::Compose() Entity entity = scene.decals.GetEntity(i); const TransformComponent& transform = *scene.transforms.GetComponent(entity); - float dist = wiMath::Distance(transform.translation, camera->Eye) * 0.08f; + float dist = wiMath::Distance(transform.GetPosition(), camera->Eye) * 0.08f; wiImageEffects fx; - fx.pos = transform.translation; + fx.pos = transform.GetPosition(); fx.siz = XMFLOAT2(dist, dist); fx.typeFlag = ImageType::WORLD; fx.pivot = XMFLOAT2(0.5f, 0.5f); @@ -1821,10 +1856,10 @@ void EditorComponent::Compose() Entity entity = scene.forces.GetEntity(i); const TransformComponent& transform = *scene.transforms.GetComponent(entity); - float dist = wiMath::Distance(transform.translation, camera->Eye) * 0.08f; + float dist = wiMath::Distance(transform.GetPosition(), camera->Eye) * 0.08f; wiImageEffects fx; - fx.pos = transform.translation; + fx.pos = transform.GetPosition(); fx.siz = XMFLOAT2(dist, dist); fx.typeFlag = ImageType::WORLD; fx.pivot = XMFLOAT2(0.5f, 0.5f); @@ -1860,10 +1895,10 @@ void EditorComponent::Compose() const TransformComponent& transform = *scene.transforms.GetComponent(entity); - float dist = wiMath::Distance(transform.translation, camera->Eye) * 0.08f; + float dist = wiMath::Distance(transform.GetPosition(), camera->Eye) * 0.08f; wiImageEffects fx; - fx.pos = transform.translation; + fx.pos = transform.GetPosition(); fx.siz = XMFLOAT2(dist, dist); fx.typeFlag = ImageType::WORLD; fx.pivot = XMFLOAT2(0.5f, 0.5f); @@ -1894,10 +1929,10 @@ void EditorComponent::Compose() Entity entity = scene.armatures.GetEntity(i); const TransformComponent& transform = *scene.transforms.GetComponent(entity); - float dist = wiMath::Distance(transform.translation, camera->Eye) * 0.08f; + float dist = wiMath::Distance(transform.GetPosition(), camera->Eye) * 0.08f; wiImageEffects fx; - fx.pos = transform.translation; + fx.pos = transform.GetPosition(); fx.siz = XMFLOAT2(dist, dist); fx.typeFlag = ImageType::WORLD; fx.pivot = XMFLOAT2(0.5f, 0.5f); @@ -1928,10 +1963,10 @@ void EditorComponent::Compose() Entity entity = scene.emitters.GetEntity(i); const TransformComponent& transform = *scene.transforms.GetComponent(entity); - float dist = wiMath::Distance(transform.translation, camera->Eye) * 0.08f; + float dist = wiMath::Distance(transform.GetPosition(), camera->Eye) * 0.08f; wiImageEffects fx; - fx.pos = transform.translation; + fx.pos = transform.GetPosition(); fx.siz = XMFLOAT2(dist, dist); fx.typeFlag = ImageType::WORLD; fx.pivot = XMFLOAT2(0.5f, 0.5f); @@ -1955,6 +1990,40 @@ void EditorComponent::Compose() } } + if (rendererWnd->GetPickType() & PICK_HAIR) + { + for (size_t i = 0; i < scene.hairs.GetCount(); ++i) + { + Entity entity = scene.hairs.GetEntity(i); + const TransformComponent& transform = *scene.transforms.GetComponent(entity); + + float dist = wiMath::Distance(transform.GetPosition(), camera->Eye) * 0.08f; + + wiImageEffects fx; + fx.pos = transform.GetPosition(); + fx.siz = XMFLOAT2(dist, dist); + fx.typeFlag = ImageType::WORLD; + fx.pivot = XMFLOAT2(0.5f, 0.5f); + fx.col = XMFLOAT4(1, 1, 1, 0.5f); + + if (hovered.entity == entity) + { + fx.col = XMFLOAT4(1, 1, 1, 1); + } + for (auto& picked : selected) + { + if (picked->entity == entity) + { + fx.col = XMFLOAT4(1, 1, 0, 1); + break; + } + } + + + wiImage::Draw(&hairTex, fx, GRAPHICSTHREAD_IMMEDIATE); + } + } + if (translator_active && translator->enabled) { diff --git a/Editor/Editor.h b/Editor/Editor.h index 0c5e14932..27db4d776 100644 --- a/Editor/Editor.h +++ b/Editor/Editor.h @@ -13,6 +13,7 @@ class DecalWindow; class LightWindow; class AnimationWindow; class EmitterWindow; +class HairParticleWindow; class ForceFieldWindow; class OceanWindow; @@ -31,7 +32,7 @@ class Editor; class EditorComponent : public Renderable2DComponent { private: - wiGraphicsTypes::Texture2D pointLightTex, spotLightTex, dirLightTex, areaLightTex, decalTex, forceFieldTex, emitterTex, cameraTex, armatureTex; + wiGraphicsTypes::Texture2D pointLightTex, spotLightTex, dirLightTex, areaLightTex, decalTex, forceFieldTex, emitterTex, hairTex, cameraTex, armatureTex; public: MaterialWindow* materialWnd; PostprocessWindow* postprocessWnd; @@ -45,6 +46,7 @@ public: LightWindow* lightWnd; AnimationWindow* animWnd; EmitterWindow* emitterWnd; + HairParticleWindow* hairWnd; ForceFieldWindow* forceFieldWnd; OceanWindow* oceanWnd; diff --git a/Editor/Editor.vcxproj b/Editor/Editor.vcxproj index 330282b07..8e66229ee 100644 --- a/Editor/Editor.vcxproj +++ b/Editor/Editor.vcxproj @@ -172,6 +172,7 @@ + @@ -198,6 +199,7 @@ + diff --git a/Editor/Editor.vcxproj.filters b/Editor/Editor.vcxproj.filters index dfa3e1a39..b4021aa6d 100644 --- a/Editor/Editor.vcxproj.filters +++ b/Editor/Editor.vcxproj.filters @@ -85,6 +85,9 @@ Code + + Code + @@ -150,6 +153,9 @@ Code + + Code + diff --git a/Editor/EmitterWindow.cpp b/Editor/EmitterWindow.cpp index 3d44f0078..1a89d4305 100644 --- a/Editor/EmitterWindow.cpp +++ b/Editor/EmitterWindow.cpp @@ -1,6 +1,5 @@ #include "stdafx.h" #include "EmitterWindow.h" -#include "MaterialWindow.h" #include diff --git a/Editor/EmitterWindow.h b/Editor/EmitterWindow.h index 659e28c0c..fcef2d70b 100644 --- a/Editor/EmitterWindow.h +++ b/Editor/EmitterWindow.h @@ -7,6 +7,7 @@ class wiCheckBox; class wiSlider; class wiComboBox; class wiColorPicker; +class wiButton; class MaterialWindow; diff --git a/Editor/HairParticleWindow.cpp b/Editor/HairParticleWindow.cpp new file mode 100644 index 000000000..50ffd7e50 --- /dev/null +++ b/Editor/HairParticleWindow.cpp @@ -0,0 +1,162 @@ +#include "stdafx.h" +#include "HairParticleWindow.h" + +using namespace std; +using namespace wiECS; +using namespace wiSceneSystem; + +HairParticleWindow::HairParticleWindow(wiGUI* gui) : GUI(gui) +{ + assert(GUI && "Invalid GUI!"); + + + float screenW = (float)wiRenderer::GetDevice()->GetScreenWidth(); + float screenH = (float)wiRenderer::GetDevice()->GetScreenHeight(); + + hairWindow = new wiWindow(GUI, "Hair Particle System Window"); + hairWindow->SetSize(XMFLOAT2(800, 600)); + hairWindow->SetEnabled(false); + GUI->AddWidget(hairWindow); + + float x = 150; + float y = 20; + float step = 35; + + + addButton = new wiButton("Add Hair Particle System"); + addButton->SetPos(XMFLOAT2(x, y += step)); + addButton->SetSize(XMFLOAT2(200, 30)); + addButton->OnClick([&](wiEventArgs args) { + Scene& scene = wiRenderer::GetScene(); + scene.Entity_CreateHair("editorHair"); + }); + addButton->SetTooltip("Add new hair particle system."); + hairWindow->AddWidget(addButton); + + meshComboBox = new wiComboBox("Mesh: "); + meshComboBox->SetSize(XMFLOAT2(300, 25)); + meshComboBox->SetPos(XMFLOAT2(x, y += step)); + meshComboBox->SetEnabled(false); + meshComboBox->OnSelect([&](wiEventArgs args) { + auto hair = GetHair(); + if (hair != nullptr) + { + if (args.iValue == 0) + { + hair->meshID = INVALID_ENTITY; + } + else + { + Scene& scene = wiRenderer::GetScene(); + hair->meshID = scene.meshes.GetEntity(args.iValue - 1); + } + } + }); + meshComboBox->SetTooltip("Choose an animation clip..."); + hairWindow->AddWidget(meshComboBox); + + countSlider = new wiSlider(0.1f, 100.0f, 1.0f, 100000, "Particle Count: "); + countSlider->SetSize(XMFLOAT2(360, 30)); + countSlider->SetPos(XMFLOAT2(x, y += step * 2)); + countSlider->OnSlide([&](wiEventArgs args) { + auto hair = GetHair(); + if (hair != nullptr) + { + hair->particleCount = (size_t)args.iValue; + } + }); + countSlider->SetEnabled(false); + countSlider->SetTooltip("Set hair strand count"); + hairWindow->AddWidget(countSlider); + + generateButton = new wiButton("Generate Hair"); + generateButton->SetPos(XMFLOAT2(x, y += step)); + generateButton->SetSize(XMFLOAT2(150, 30)); + generateButton->OnClick([&](wiEventArgs args) { + auto hair = GetHair(); + if (hair != nullptr) + { + const MeshComponent* mesh = wiRenderer::GetScene().meshes.GetComponent(hair->meshID); + if (mesh != nullptr) + { + hair->Generate(*mesh); + } + else + { + wiHelper::messageBox("Please choose a mesh first!"); + } + } + }); + generateButton->SetTooltip("Generate hair particles on a mesh surface"); + hairWindow->AddWidget(generateButton); + + + hairWindow->Translate(XMFLOAT3(200, 50, 0)); + hairWindow->SetVisible(false); + + SetEntity(entity); +} + +HairParticleWindow::~HairParticleWindow() +{ + hairWindow->RemoveWidgets(true); + GUI->RemoveWidget(hairWindow); + SAFE_DELETE(hairWindow); +} + +void HairParticleWindow::SetEntity(Entity entity) +{ + if (this->entity == entity) + return; + + this->entity = entity; + + auto hair = GetHair(); + + if (hair != nullptr) + { + countSlider->SetValue((float)hair->particleCount); + } + else + { + } + +} + +wiHairParticle* HairParticleWindow::GetHair() +{ + if (entity == INVALID_ENTITY) + { + return nullptr; + } + + Scene& scene = wiRenderer::GetScene(); + wiHairParticle* hair = scene.hairs.GetComponent(entity); + + return hair; +} + +void HairParticleWindow::UpdateData() +{ + auto emitter = GetHair(); + if (emitter == nullptr) + { + return; + } + + Scene& scene = wiRenderer::GetScene(); + + meshComboBox->ClearItems(); + meshComboBox->AddItem("NO MESH"); + for (size_t i = 0; i < scene.meshes.GetCount(); ++i) + { + Entity entity = scene.meshes.GetEntity(i); + const NameComponent& name = *scene.names.GetComponent(entity); + meshComboBox->AddItem(name.name); + + if (emitter->meshID == entity) + { + meshComboBox->SetSelected((int)i + 1); + } + } +} diff --git a/Editor/HairParticleWindow.h b/Editor/HairParticleWindow.h new file mode 100644 index 000000000..3ac900d02 --- /dev/null +++ b/Editor/HairParticleWindow.h @@ -0,0 +1,37 @@ +#pragma once + +class wiGUI; +class wiWindow; +class wiLabel; +class wiCheckBox; +class wiSlider; +class wiComboBox; +class wiColorPicker; +class wiButton; + +class MaterialWindow; + +class HairParticleWindow +{ +public: + HairParticleWindow(wiGUI* gui); + ~HairParticleWindow(); + + wiECS::Entity entity; + void SetEntity(wiECS::Entity entity); + + void UpdateData(); + + wiSceneSystem::wiHairParticle* GetHair(); + + wiGUI* GUI; + + wiWindow* hairWindow; + + wiButton* addButton; + wiComboBox* meshComboBox; + wiSlider* countSlider; + wiButton* generateButton; + +}; + diff --git a/Editor/RendererWindow.cpp b/Editor/RendererWindow.cpp index 8f96f4a9a..d18137c2c 100644 --- a/Editor/RendererWindow.cpp +++ b/Editor/RendererWindow.cpp @@ -510,6 +510,12 @@ RendererWindow::RendererWindow(wiGUI* gui, Renderable3DComponent* component) : G pickTypeEmitterCheckBox->SetCheck(true); rendererWindow->AddWidget(pickTypeEmitterCheckBox); + pickTypeHairCheckBox = new wiCheckBox("Pick Hairs: "); + pickTypeHairCheckBox->SetTooltip("Enable if you want to pick hairs with the pointer"); + pickTypeHairCheckBox->SetPos(XMFLOAT2(x, y += step)); + pickTypeHairCheckBox->SetCheck(true); + rendererWindow->AddWidget(pickTypeHairCheckBox); + pickTypeCameraCheckBox = new wiCheckBox("Pick Cameras: "); pickTypeCameraCheckBox->SetTooltip("Enable if you want to pick cameras with the pointer"); pickTypeCameraCheckBox->SetPos(XMFLOAT2(x, y += step)); @@ -574,6 +580,10 @@ UINT RendererWindow::GetPickType() { pickType |= PICK_EMITTER; } + if (pickTypeHairCheckBox->GetCheck()) + { + pickType |= PICK_HAIR; + } if (pickTypeCameraCheckBox->GetCheck()) { pickType |= PICK_CAMERA; diff --git a/Editor/RendererWindow.h b/Editor/RendererWindow.h index f1f852285..37ba4585d 100644 --- a/Editor/RendererWindow.h +++ b/Editor/RendererWindow.h @@ -16,8 +16,9 @@ enum PICKTYPE PICK_ENVPROBE = 32, PICK_FORCEFIELD = 64, PICK_EMITTER = 128, - PICK_CAMERA = 256, - PICK_ARMATURE = 512, + PICK_HAIR = 256, + PICK_CAMERA = 512, + PICK_ARMATURE = 1024, }; class RendererWindow @@ -60,6 +61,7 @@ public: wiCheckBox* pickTypeDecalCheckBox; wiCheckBox* pickTypeForceFieldCheckBox; wiCheckBox* pickTypeEmitterCheckBox; + wiCheckBox* pickTypeHairCheckBox; wiCheckBox* pickTypeCameraCheckBox; wiCheckBox* pickTypeArmatureCheckBox; wiSlider* speedMultiplierSlider; diff --git a/Editor/Translator.cpp b/Editor/Translator.cpp index b401a95ef..1afd79136 100644 --- a/Editor/Translator.cpp +++ b/Editor/Translator.cpp @@ -204,7 +204,7 @@ void Translator::Update() XMFLOAT4 pointer = wiInputManager::GetInstance()->getpointer(); CameraComponent* cam = wiRenderer::getCamera(); - XMVECTOR pos = XMLoadFloat3(&transform.translation); + XMVECTOR pos = transform.GetPositionV(); if (enabled) { @@ -215,7 +215,7 @@ void Translator::Update() XMMATRIX V = cam->GetView(); XMMATRIX W = XMMatrixIdentity(); - dist = wiMath::Distance(transform.translation, cam->Eye) * 0.05f; + dist = wiMath::Distance(transform.GetPosition(), cam->Eye) * 0.05f; XMVECTOR o, x, y, z, p, xy, xz, yz; @@ -387,7 +387,8 @@ void Translator::Update() } if (isScalator) { - transf *= XMMatrixScaling((1.0f / transform.scale.x) * (transform.scale.x + delta.x), (1.0f / transform.scale.y) * (transform.scale.y + delta.y), (1.0f / transform.scale.z) * (transform.scale.z + delta.z)); + XMFLOAT3 scale = transform.GetScale(); + transf *= XMMatrixScaling((1.0f / scale.x) * (scale.x + delta.x), (1.0f / scale.y) * (scale.y + delta.y), (1.0f / scale.z) * (scale.z + delta.z)); } transform.MatrixTransform(transf); @@ -437,7 +438,7 @@ void Translator::Draw(CameraComponent* camera, GRAPHICSTHREAD threadID) wiRenderer::MiscCB sb; - XMMATRIX mat = XMMatrixScaling(dist, dist, dist)*XMMatrixTranslation(transform.translation.x, transform.translation.y, transform.translation.z) * VP; + XMMATRIX mat = XMMatrixScaling(dist, dist, dist)*XMMatrixTranslationFromVector(transform.GetPositionV()) * VP; XMMATRIX matX = XMMatrixTranspose(mat); XMMATRIX matY = XMMatrixTranspose(XMMatrixRotationZ(XM_PIDIV2)*XMMatrixRotationY(XM_PIDIV2)*mat); XMMATRIX matZ = XMMatrixTranspose(XMMatrixRotationY(-XM_PIDIV2)*XMMatrixRotationZ(-XM_PIDIV2)*mat); diff --git a/WickedEngine/hairparticleHF.hlsli b/WickedEngine/hairparticleHF.hlsli index b573a8851..af984a3b6 100644 --- a/WickedEngine/hairparticleHF.hlsli +++ b/WickedEngine/hairparticleHF.hlsli @@ -5,7 +5,7 @@ CBUFFER(HairParticleCB, CBSLOT_OTHER_HAIRPARTICLE) { float4x4 xWorld; - float3 xColor; float __pad0; + float4 xColor; float LOD0; float LOD1; float LOD2; diff --git a/WickedEngine/hairparticlePS_simplest.hlsl b/WickedEngine/hairparticlePS_simplest.hlsl index be14097d7..3bca133a3 100644 --- a/WickedEngine/hairparticlePS_simplest.hlsl +++ b/WickedEngine/hairparticlePS_simplest.hlsl @@ -3,5 +3,5 @@ float4 main() : SV_TARGET { - return float4(xColor, 1.0f); + return float4(xColor.rgb, 1.0f); } \ No newline at end of file diff --git a/WickedEngine/wiHairParticle.cpp b/WickedEngine/wiHairParticle.cpp index 31906d720..b70dd5eab 100644 --- a/WickedEngine/wiHairParticle.cpp +++ b/WickedEngine/wiHairParticle.cpp @@ -222,278 +222,114 @@ void wiHairParticle::Settings(int l0,int l1,int l2) } -void wiHairParticle::Generate() +void wiHairParticle::Generate(const MeshComponent& mesh) { - //std::vector points; + std::vector points(particleCount); - //Mesh* mesh = object->mesh; + // Now the distribution is completely uniform. TODO: bring back distribution, but make it more intuitive to set up! - //XMMATRIX matr = object->getMatrix(); - //XMStoreFloat4x4(&OriginalMatrix_Inverse, XMMatrixInverse(nullptr, matr)); + for (UINT i = 0; i < particleCount; ++i) + { + int tri = wiRandom::getRandom(0, (int)((mesh.indices.size() - 1) / 3)); - //int dVG = -1, lVG = -1; - //if (densityG.compare("")) { - // for (unsigned int i = 0; i < mesh->vertexGroups.size(); ++i) - // if (!mesh->vertexGroups[i].name.compare(densityG)) - // dVG = i; - //} - //if (lenG.compare("")) { - // for (unsigned int i = 0; i < mesh->vertexGroups.size(); ++i) - // if (!mesh->vertexGroups[i].name.compare(lenG)) - // lVG = i; - //} - // - //float avgPatchSize; - //if(dVG>=0) - // avgPatchSize = (float)count/((float)mesh->vertexGroups[dVG].vertices.size()/3.0f); - //else - // avgPatchSize = (float)count/((float)mesh->indices.size()/3.0f); + uint32_t i0 = mesh.indices[tri * 3 + 0]; + uint32_t i1 = mesh.indices[tri * 3 + 1]; + uint32_t i2 = mesh.indices[tri * 3 + 2]; - //if (mesh->indices.size() < 4) - // return; + XMVECTOR p0 = XMLoadFloat3(&mesh.vertex_positions[i0]); + XMVECTOR p1 = XMLoadFloat3(&mesh.vertex_positions[i1]); + XMVECTOR p2 = XMLoadFloat3(&mesh.vertex_positions[i2]); - //for (unsigned int i = 0; iindices.size() - 3; i += 3) - //{ + XMVECTOR n0 = XMLoadFloat3(&mesh.vertex_normals[i0]); + XMVECTOR n1 = XMLoadFloat3(&mesh.vertex_normals[i1]); + XMVECTOR n2 = XMLoadFloat3(&mesh.vertex_normals[i2]); - // unsigned int vi[]={mesh->indices[i],mesh->indices[i+1],mesh->indices[i+2]}; - // float denMod[]={1,1,1},lenMod[]={1,1,1}; - // if (dVG >= 0) { - // auto found = mesh->vertexGroups[dVG].vertices.find(vi[0]); - // if (found != mesh->vertexGroups[dVG].vertices.end()) - // denMod[0] = found->second; - // else - // continue; + float f = wiRandom::getRandom(0, 1000) * 0.001f; + float g = wiRandom::getRandom(0, 1000) * 0.001f; - // found = mesh->vertexGroups[dVG].vertices.find(vi[1]); - // if (found != mesh->vertexGroups[dVG].vertices.end()) - // denMod[1] = found->second; - // else - // continue; + XMVECTOR P = XMVectorBaryCentric(p0, p1, p2, f, g); + XMVECTOR N = XMVectorBaryCentric(n0, n1, n2, f, g); + XMVECTOR T = XMVector3Normalize(XMVectorSubtract(i % 2 == 0 ? p0 : p2, p1)); - // found = mesh->vertexGroups[dVG].vertices.find(vi[2]); - // if (found != mesh->vertexGroups[dVG].vertices.end()) - // denMod[2] = found->second; - // else - // continue; - // } - // if (lVG >= 0) { - // auto found = mesh->vertexGroups[lVG].vertices.find(vi[0]); - // if (found != mesh->vertexGroups[lVG].vertices.end()) - // lenMod[0] = found->second; - // else - // continue; + XMStoreFloat4(&points[i].posLen, P); + points[i].posLen.w = 1.0f; - // found = mesh->vertexGroups[lVG].vertices.find(vi[1]); - // if (found != mesh->vertexGroups[lVG].vertices.end()) - // lenMod[1] = found->second; - // else - // continue; + XMFLOAT3 normal, tangent; + XMStoreFloat3(&normal, N); + XMStoreFloat3(&tangent, T); - // found = mesh->vertexGroups[lVG].vertices.find(vi[2]); - // if (found != mesh->vertexGroups[lVG].vertices.end()) - // lenMod[2] = found->second; - // else - // continue; - // } - // for (int m = 0; m < 3; ++m) { - // if (denMod[m] < 0) denMod[m] = 0; - // if (lenMod[m] < 0) lenMod[m] = 0; - // } + points[i].normalRand = wiMath::CompressNormal(normal); + points[i].tangent = wiMath::CompressNormal(tangent); + } - // Mesh::Vertex_FULL verts[] = { - // mesh->vertices_FULL[vi[0]], - // mesh->vertices_FULL[vi[1]], - // mesh->vertices_FULL[vi[2]], - // }; + cb.reset(new GPUBuffer); + particleBuffer.reset(new GPUBuffer); - // if( - // (denMod[0]>FLT_EPSILON || denMod[1]>FLT_EPSILON || denMod[2]>FLT_EPSILON) && - // (lenMod[0]>FLT_EPSILON || lenMod[1]>FLT_EPSILON || lenMod[2]>FLT_EPSILON) - // ) - // { + GPUBufferDesc bd; + ZeroMemory(&bd, sizeof(bd)); + bd.Usage = USAGE_IMMUTABLE; + bd.ByteWidth = (UINT)(sizeof(Patch) * particleCount); + bd.BindFlags = BIND_VERTEX_BUFFER | BIND_SHADER_RESOURCE; + bd.CPUAccessFlags = 0; + bd.MiscFlags = RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS; + SubresourceData data = {}; + data.pSysMem = points.data(); + wiRenderer::GetDevice()->CreateBuffer(&bd, &data, particleBuffer.get()); - // float density = (float)(denMod[0]+denMod[1]+denMod[2])/3.0f*avgPatchSize; - // int rdense = (int)(( density - (int)density ) * 100); - // density += ((wiRandom::getRandom(0, 99)) <= rdense ? 1.0f : 0.0f); - // int PATCHSIZE = material->texture?(int)density:(int)density*10; - // - // if(PATCHSIZE) - // { - - // for(int p=0;p 1) - // { - // f = 1 - f; - // g = 1 - g; - // } - // XMVECTOR pos[] = { - // XMVector3Transform(XMLoadFloat4(&verts[0].pos),matr) - // , XMVector3Transform(XMLoadFloat4(&verts[1].pos),matr) - // , XMVector3Transform(XMLoadFloat4(&verts[2].pos),matr) - // }; - // XMVECTOR vbar=XMVectorBaryCentric( - // pos[0],pos[1],pos[2] - // , f - // , g - // ); - // XMVECTOR nbar=XMVectorBaryCentric( - // XMLoadFloat4(&verts[0].nor) - // , XMLoadFloat4(&verts[1].nor) - // , XMLoadFloat4(&verts[2].nor) - // , f - // , g - // ); - // int ti = wiRandom::getRandom(0, 2); - // XMVECTOR tangent = XMVector3Normalize(XMVectorSubtract(pos[ti], pos[(ti + 1) % 3])); - // - // Patch addP; - // ::XMStoreFloat4(&addP.posLen,vbar); - - // XMFLOAT3 nor, tan; - // ::XMStoreFloat3(&nor,XMVector3Normalize(nbar)); - // ::XMStoreFloat3(&tan,tangent); - - // addP.normalRand = wiMath::CompressNormal(nor); - // addP.tangent = wiMath::CompressNormal(tan); - - // float lbar = lenMod[0] + f*(lenMod[1]-lenMod[0]) + g*(lenMod[2]-lenMod[0]); - // addP.posLen.w = length*lbar + (float)(wiRandom::getRandom(0, 1000) - 500)*0.001f*length*lbar; - // addP.normalRand |= (uint8_t)wiRandom::getRandom(0, 256) << 24; - // points.push_back(addP); - // } - - // } - // } - //} - - //particleCount = points.size(); - - //SAFE_DELETE(cb); - //SAFE_DELETE(particleBuffer); - //SAFE_DELETE(ib); - //SAFE_DELETE(ib_transposed); - - //GPUBufferDesc bd; - //ZeroMemory(&bd, sizeof(bd)); - //bd.Usage = USAGE_IMMUTABLE; - //bd.ByteWidth = (UINT)(sizeof(Patch) * particleCount); - //bd.BindFlags = BIND_VERTEX_BUFFER | BIND_SHADER_RESOURCE; - //bd.CPUAccessFlags = 0; - //bd.MiscFlags = RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS; - //SubresourceData data = {}; - //data.pSysMem = points.data(); - //particleBuffer = new GPUBuffer; - //wiRenderer::GetDevice()->CreateBuffer(&bd, &data, particleBuffer); - - - //uint32_t* indices = new uint32_t[particleCount]; - //for (size_t i = 0; i < points.size(); ++i) - //{ - // indices[i] = (uint32_t)i; - //} - //data.pSysMem = indices; - - //bd.Usage = USAGE_DEFAULT; - //bd.ByteWidth = (UINT)(sizeof(uint32_t) * particleCount); - //bd.BindFlags = BIND_INDEX_BUFFER | BIND_UNORDERED_ACCESS; - //bd.MiscFlags = RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS; - //ib = new GPUBuffer; - //wiRenderer::GetDevice()->CreateBuffer(&bd, &data, ib); - //ib_transposed = new GPUBuffer; - //wiRenderer::GetDevice()->CreateBuffer(&bd, &data, ib_transposed); - - //SAFE_DELETE_ARRAY(indices); - - - //IndirectDrawArgsIndexedInstanced args; - //args.BaseVertexLocation = 0; - //args.IndexCountPerInstance = (UINT)points.size(); - //args.InstanceCount = 1; - //args.StartIndexLocation = 0; - //args.StartInstanceLocation = 0; - //data.pSysMem = &args; - - //bd.ByteWidth = (UINT)(sizeof(IndirectDrawArgsIndexedInstanced)); - //bd.MiscFlags = RESOURCE_MISC_DRAWINDIRECT_ARGS | RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS; - //bd.BindFlags = BIND_UNORDERED_ACCESS; - //drawargs = new GPUBuffer; - //wiRenderer::GetDevice()->CreateBuffer(&bd, &data, drawargs); - - - - - //ZeroMemory(&bd, sizeof(bd)); - //bd.Usage = USAGE_DYNAMIC; - //bd.ByteWidth = sizeof(ConstantBuffer); - //bd.BindFlags = BIND_CONSTANT_BUFFER; - //bd.CPUAccessFlags = CPU_ACCESS_WRITE; - //cb = new GPUBuffer; - //wiRenderer::GetDevice()->CreateBuffer(&bd, nullptr, cb); + ZeroMemory(&bd, sizeof(bd)); + bd.Usage = USAGE_DYNAMIC; + bd.ByteWidth = sizeof(ConstantBuffer); + bd.BindFlags = BIND_CONSTANT_BUFFER; + bd.CPUAccessFlags = CPU_ACCESS_WRITE; + wiRenderer::GetDevice()->CreateBuffer(&bd, nullptr, cb.get()); } -void wiHairParticle::ComputeCulling(CameraComponent* camera, GRAPHICSTHREAD threadID) +void wiHairParticle::Draw(CameraComponent* camera, const MaterialComponent& material, SHADERTYPE shaderType, bool transparent, GRAPHICSTHREAD threadID) const { - //GraphicsDevice* device = wiRenderer::GetDevice(); - //device->EventBegin("HairParticle - Culling", threadID); + if (cb == nullptr) + { + return; + } - //XMMATRIX inverseMat = XMLoadFloat4x4(&OriginalMatrix_Inverse); - //XMMATRIX renderMatrix = inverseMat * object->getMatrix(); + GraphicsDevice* device = wiRenderer::GetDevice(); + device->EventBegin("HairParticle - Draw", threadID); - //ConstantBuffer gcb; - //gcb.mWorld = XMMatrixTranspose(renderMatrix); - //gcb.color = material->baseColor; - //gcb.LOD0 = (float)LOD[0]; - //gcb.LOD1 = (float)LOD[1]; - //gcb.LOD2 = (float)LOD[2]; + if (wiRenderer::IsWireRender()) + { + if (transparent || shaderType == SHADERTYPE_DEPTHONLY) + { + return; + } + device->BindGraphicsPSO(&PSO_wire, threadID); + device->BindResource(VS, wiTextureHelper::getInstance()->getWhite(), TEXSLOT_ONDEMAND0, threadID); + } + else + { + device->BindGraphicsPSO(&PSO[shaderType][transparent], threadID); - //device->UpdateBuffer(cb, &gcb, threadID); + GPUResource* res[] = { + material.GetBaseColorMap() + }; + device->BindResources(PS, res, TEXSLOT_ONDEMAND0, ARRAYSIZE(res), threadID); + device->BindResources(VS, res, TEXSLOT_ONDEMAND0, ARRAYSIZE(res), threadID); + } - //// old solution removed, todo new solution + ConstantBuffer gcb; + gcb.mWorld = XMMatrixTranspose(XMLoadFloat4x4(&world)); + gcb.color = material.baseColor; + gcb.LOD0 = (float)LOD[0]; + gcb.LOD1 = (float)LOD[1]; + gcb.LOD2 = (float)LOD[2]; + device->UpdateBuffer(cb.get(), &gcb, threadID); - //device->EventEnd(threadID); -} + device->BindConstantBuffer(VS, cb.get(), CB_GETBINDSLOT(ConstantBuffer), threadID); -void wiHairParticle::Draw(CameraComponent* camera, SHADERTYPE shaderType, bool transparent, GRAPHICSTHREAD threadID) -{ - //Texture2D* texture = material->texture; - //texture = texture == nullptr ? wiTextureHelper::getInstance()->getWhite() : texture; + device->BindResource(VS, particleBuffer.get(), 0, threadID); - //{ - // GraphicsDevice* device = wiRenderer::GetDevice(); - // device->EventBegin("HairParticle - Draw", threadID); + device->Draw((int)particleCount * 12, 0, threadID); - // if (wiRenderer::IsWireRender()) - // { - // if (transparent || shaderType == SHADERTYPE_DEPTHONLY) - // { - // return; - // } - // device->BindGraphicsPSO(&PSO_wire, threadID); - // device->BindResource(VS, wiTextureHelper::getInstance()->getWhite(), TEXSLOT_ONDEMAND0, threadID); - // device->BindConstantBuffer(PS, cb, CB_GETBINDSLOT(ConstantBuffer), threadID); - // } - // else - // { - // device->BindGraphicsPSO(&PSO[shaderType][transparent], threadID); - - // if (texture) - // { - // device->BindResource(PS, texture, TEXSLOT_ONDEMAND0, threadID); - // device->BindResource(VS, texture, TEXSLOT_ONDEMAND0, threadID); - // } - // } - - // device->BindConstantBuffer(VS, cb, CB_GETBINDSLOT(ConstantBuffer),threadID); - - // device->BindResource(VS, particleBuffer, 0, threadID); - - // device->Draw((int)particleCount * 12, 0, threadID); - - // device->EventEnd(threadID); - //} + device->EventEnd(threadID); } } diff --git a/WickedEngine/wiHairParticle.h b/WickedEngine/wiHairParticle.h index 628bb7b87..4318b3f43 100644 --- a/WickedEngine/wiHairParticle.h +++ b/WickedEngine/wiHairParticle.h @@ -2,6 +2,7 @@ #include "CommonInclude.h" #include "wiGraphicsAPI.h" #include "ShaderInterop.h" +#include "wiECS.h" #include "wiSceneSystem_Decl.h" class wiArchive; @@ -22,7 +23,7 @@ private: CBUFFER(ConstantBuffer, CBSLOT_OTHER_HAIRPARTICLE) { XMMATRIX mWorld; - XMFLOAT3 color; float __pad0; + XMFLOAT4 color; float LOD0; float LOD1; float LOD2; @@ -31,9 +32,6 @@ private: std::unique_ptr cb; std::unique_ptr particleBuffer; - std::unique_ptr ib; - std::unique_ptr ib_transposed; - std::unique_ptr drawargs; static wiGraphicsTypes::VertexShader *vs; static wiGraphicsTypes::PixelShader *ps[SHADERTYPE_COUNT]; @@ -49,17 +47,17 @@ public: public: - void Generate(); - void ComputeCulling(wiSceneSystem::CameraComponent* camera, GRAPHICSTHREAD threadID); - void Draw(wiSceneSystem::CameraComponent* camera, SHADERTYPE shaderType, bool transparent, GRAPHICSTHREAD threadID); + void Generate(const MeshComponent& mesh); + void Draw(wiSceneSystem::CameraComponent* camera, const MaterialComponent& material, SHADERTYPE shaderType, bool transparent, GRAPHICSTHREAD threadID) const; static void CleanUpStatic(); static void SetUpStatic(); static void Settings(int lod0,int lod1,int lod2); float length = 1.0f; - XMFLOAT4X4 OriginalMatrix_Inverse; size_t particleCount = 0; + wiECS::Entity meshID = wiECS::INVALID_ENTITY; + XMFLOAT4X4 world; }; } diff --git a/WickedEngine/wiRenderer.cpp b/WickedEngine/wiRenderer.cpp index b3ff87147..2b99df0c7 100644 --- a/WickedEngine/wiRenderer.cpp +++ b/WickedEngine/wiRenderer.cpp @@ -118,8 +118,6 @@ struct FrameCulling CulledCollection culledRenderer_opaque; CulledCollection culledRenderer_transparent; vector culledObjects; - vector culledHairParticleSystems; - vector culledEmitters; vector culledLights; vector culledDecals; vector culledEnvProbes; @@ -129,8 +127,6 @@ struct FrameCulling culledRenderer_opaque.clear(); culledRenderer_transparent.clear(); culledObjects.clear(); - culledHairParticleSystems.clear(); - culledEmitters.clear(); culledLights.clear(); culledDecals.clear(); culledEnvProbes.clear(); @@ -3195,12 +3191,11 @@ void wiRenderer::UpdateRenderData(GRAPHICSTHREAD threadID) } const LightComponent& light = *scene.lights.GetComponent(entity); - const TransformComponent& transform = *scene.transforms.GetComponent(entity); const int shadowIndex = light.shadowMap_index; entityArray[entityCounter].type = light.GetType(); - entityArray[entityCounter].positionWS = transform.translation; + entityArray[entityCounter].positionWS = light.position; XMStoreFloat3(&entityArray[entityCounter].positionVS, XMVector3TransformCoord(XMLoadFloat3(&entityArray[entityCounter].positionWS), viewMatrix)); entityArray[entityCounter].range = light.range; entityArray[entityCounter].color = wiMath::CompressColor(light.color); @@ -3247,11 +3242,10 @@ void wiRenderer::UpdateRenderData(GRAPHICSTHREAD threadID) case LightComponent::RECTANGLE: case LightComponent::TUBE: { - XMMATRIX lightMat = XMLoadFloat4x4(&transform.world); // Note: area lights are facing back by default - XMStoreFloat3(&entityArray[entityCounter].directionWS, XMVector3TransformNormal(XMVectorSet(-1, 0, 0, 0), lightMat)); // right dir - XMStoreFloat3(&entityArray[entityCounter].directionVS, XMVector3TransformNormal(XMVectorSet(0, 1, 0, 0), lightMat)); // up dir - XMStoreFloat3(&entityArray[entityCounter].positionVS, XMVector3TransformNormal(XMVectorSet(0, 0, -1, 0), lightMat)); // front dir + entityArray[entityCounter].directionWS = light.right; + entityArray[entityCounter].directionVS = light.direction; + entityArray[entityCounter].positionVS = light.front; entityArray[entityCounter].texMulAdd = XMFLOAT4(light.radius, light.width, light.height, 0); } break; @@ -3283,16 +3277,14 @@ void wiRenderer::UpdateRenderData(GRAPHICSTHREAD threadID) continue; } - const TransformComponent& transform = *scene.transforms.GetComponent(entity); - entityArray[entityCounter].type = ENTITY_TYPE_ENVMAP; - entityArray[entityCounter].positionWS = transform.translation; - XMStoreFloat3(&entityArray[entityCounter].positionVS, XMVector3TransformCoord(XMLoadFloat3(&transform.translation), viewMatrix)); - entityArray[entityCounter].range = max(transform.scale.x, max(transform.scale.y, transform.scale.z)) * 2; + entityArray[entityCounter].positionWS = probe.position; + XMStoreFloat3(&entityArray[entityCounter].positionVS, XMVector3TransformCoord(XMLoadFloat3(&probe.position), viewMatrix)); + entityArray[entityCounter].range = probe.range; entityArray[entityCounter].shadowBias = (float)probe.textureIndex; entityArray[entityCounter].additionalData_index = matrixCounter; - matrixArray[matrixCounter] = XMMatrixTranspose(XMMatrixInverse(nullptr, XMLoadFloat4x4(&transform.world))); + matrixArray[matrixCounter] = XMMatrixTranspose(XMLoadFloat4x4(&probe.inverseMatrix)); matrixCounter++; entityCounter++; @@ -3315,12 +3307,11 @@ void wiRenderer::UpdateRenderData(GRAPHICSTHREAD threadID) break; } const DecalComponent& decal = *scene.decals.GetComponent(entity); - const TransformComponent& transform = *scene.transforms.GetComponent(entity); entityArray[entityCounter].type = ENTITY_TYPE_DECAL; - entityArray[entityCounter].positionWS = transform.translation; - XMStoreFloat3(&entityArray[entityCounter].positionVS, XMVector3TransformCoord(XMLoadFloat3(&transform.translation), viewMatrix)); - entityArray[entityCounter].range = max(transform.scale.x, max(transform.scale.y, transform.scale.z)) * 2; + entityArray[entityCounter].positionWS = decal.position; + XMStoreFloat3(&entityArray[entityCounter].positionVS, XMVector3TransformCoord(XMLoadFloat3(&decal.position), viewMatrix)); + entityArray[entityCounter].range = decal.range; entityArray[entityCounter].texMulAdd = decal.atlasMulAdd; entityArray[entityCounter].color = wiMath::CompressColor(XMFLOAT4(decal.color.x, decal.color.y, decal.color.z, decal.GetOpacity())); entityArray[entityCounter].energy = decal.emissive; @@ -3345,15 +3336,14 @@ void wiRenderer::UpdateRenderData(GRAPHICSTHREAD threadID) const ForceFieldComponent& force = scene.forces[i]; Entity entity = scene.forces.GetEntity(i); - const TransformComponent& transform = *scene.transforms.GetComponent(entity); entityArray[entityCounter].type = force.type; - entityArray[entityCounter].positionWS = transform.translation; + entityArray[entityCounter].positionWS = force.position; entityArray[entityCounter].energy = force.gravity; entityArray[entityCounter].range = 1.0f / max(0.0001f, force.range); // avoid division in shader entityArray[entityCounter].coneAngleCos = force.range; // this will be the real range in the less common shaders... // The default planar force field is facing upwards, and thus the pull direction is downwards: - XMStoreFloat3(&entityArray[entityCounter].directionWS, XMVector3Normalize(XMVector3TransformNormal(XMVectorSet(0, -1, 0, 0), XMLoadFloat4x4(&transform.world)))); + entityArray[entityCounter].directionWS = force.direction; entityCounter++; } @@ -3851,10 +3841,7 @@ void wiRenderer::DrawDebugWorld(CameraComponent* camera, GRAPHICSTHREAD threadID { EnvironmentProbeComponent& probe = scene.probes[i]; - Entity entity = scene.probes.GetEntity(i); - const TransformComponent& transform = *scene.transforms.GetComponent(entity); - - sb.mTransform = XMMatrixTranspose(XMMatrixTranslation(transform.translation.x, transform.translation.y, transform.translation.z)); + sb.mTransform = XMMatrixTranspose(XMMatrixTranslationFromVector(XMLoadFloat3(&probe.position))); device->UpdateBuffer(constantBuffers[CBTYPE_MISC], &sb, threadID); if (probe.textureIndex < 0) @@ -4256,8 +4243,6 @@ void wiRenderer::DrawLights(CameraComponent* camera, GRAPHICSTHREAD threadID) if (light.GetType() != type) continue; - const TransformComponent& transform = *scene.transforms.GetComponent(entity); - switch (type) { case LightComponent::DIRECTIONAL: @@ -4278,7 +4263,7 @@ void wiRenderer::DrawLights(CameraComponent* camera, GRAPHICSTHREAD threadID) MiscCB miscCb; miscCb.mColor.x = (float)light.entityArray_index; float sca = light.range + 1; - miscCb.mTransform = XMMatrixTranspose(XMMatrixScaling(sca, sca, sca)*XMMatrixTranslation(transform.translation.x, transform.translation.y, transform.translation.z) * camera->GetViewProjection()); + miscCb.mTransform = XMMatrixTranspose(XMMatrixScaling(sca, sca, sca)*XMMatrixTranslationFromVector(XMLoadFloat3(&light.position)) * camera->GetViewProjection()); GetDevice()->UpdateBuffer(constantBuffers[CBTYPE_MISC], &miscCb, threadID); GetDevice()->Draw(240, 0, threadID); // icosphere @@ -4291,8 +4276,8 @@ void wiRenderer::DrawLights(CameraComponent* camera, GRAPHICSTHREAD threadID) const float coneS = (const float)(light.fov / XM_PIDIV4); miscCb.mTransform = XMMatrixTranspose( XMMatrixScaling(coneS*light.range, light.range, coneS*light.range)* - XMMatrixRotationQuaternion(XMLoadFloat4(&transform.rotation))* - XMMatrixTranslationFromVector(XMLoadFloat3(&transform.translation)) * + XMMatrixRotationQuaternion(XMLoadFloat4(&light.rotation))* + XMMatrixTranslationFromVector(XMLoadFloat3(&light.position)) * camera->GetViewProjection() ); GetDevice()->UpdateBuffer(constantBuffers[CBTYPE_MISC], &miscCb, threadID); @@ -4328,8 +4313,6 @@ void wiRenderer::DrawLightVisualizers(CameraComponent* camera, GRAPHICSTHREAD th for (size_t i = 0; i < scene.lights.GetCount(); ++i) { LightComponent& light = scene.lights[i]; - Entity entity = scene.lights.GetEntity(i); - const TransformComponent& transform = *scene.transforms.GetComponent(entity); if (light.GetType() == type && light.visualizer) { @@ -4344,7 +4327,7 @@ void wiRenderer::DrawLightVisualizers(CameraComponent* camera, GRAPHICSTHREAD th lcb.world = XMMatrixTranspose( XMMatrixScaling(lcb.enerdis.w, lcb.enerdis.w, lcb.enerdis.w)* camrot* - XMMatrixTranslationFromVector(XMLoadFloat3(&transform.translation)) + XMMatrixTranslationFromVector(XMLoadFloat3(&light.position)) ); GetDevice()->UpdateBuffer(constantBuffers[CBTYPE_VOLUMELIGHT], &lcb, threadID); @@ -4357,8 +4340,8 @@ void wiRenderer::DrawLightVisualizers(CameraComponent* camera, GRAPHICSTHREAD th lcb.enerdis.w = light.range*light.energy*0.03f; // scale lcb.world = XMMatrixTranspose( XMMatrixScaling(coneS*lcb.enerdis.w, lcb.enerdis.w, coneS*lcb.enerdis.w)* - XMMatrixRotationQuaternion(XMLoadFloat4(&transform.rotation))* - XMMatrixTranslationFromVector(XMLoadFloat3(&transform.translation)) + XMMatrixRotationQuaternion(XMLoadFloat4(&light.rotation))* + XMMatrixTranslationFromVector(XMLoadFloat3(&light.position)) ); GetDevice()->UpdateBuffer(constantBuffers[CBTYPE_VOLUMELIGHT], &lcb, threadID); @@ -4369,8 +4352,8 @@ void wiRenderer::DrawLightVisualizers(CameraComponent* camera, GRAPHICSTHREAD th { lcb.world = XMMatrixTranspose( XMMatrixScaling(light.radius, light.radius, light.radius)* - XMMatrixRotationQuaternion(XMLoadFloat4(&transform.rotation))* - XMMatrixTranslationFromVector(XMLoadFloat3(&transform.translation))* + XMMatrixRotationQuaternion(XMLoadFloat4(&light.rotation))* + XMMatrixTranslationFromVector(XMLoadFloat3(&light.position))* camera->GetViewProjection() ); @@ -4382,8 +4365,8 @@ void wiRenderer::DrawLightVisualizers(CameraComponent* camera, GRAPHICSTHREAD th { lcb.world = XMMatrixTranspose( XMMatrixScaling(light.radius, light.radius, light.radius)* - XMMatrixRotationQuaternion(XMLoadFloat4(&transform.rotation))* - XMMatrixTranslationFromVector(XMLoadFloat3(&transform.translation))* + XMMatrixRotationQuaternion(XMLoadFloat4(&light.rotation))* + XMMatrixTranslationFromVector(XMLoadFloat3(&light.position))* camera->GetViewProjection() ); @@ -4395,8 +4378,8 @@ void wiRenderer::DrawLightVisualizers(CameraComponent* camera, GRAPHICSTHREAD th { lcb.world = XMMatrixTranspose( XMMatrixScaling(light.width * 0.5f, light.height * 0.5f, 0.5f)* - XMMatrixRotationQuaternion(XMLoadFloat4(&transform.rotation))* - XMMatrixTranslationFromVector(XMLoadFloat3(&transform.translation))* + XMMatrixRotationQuaternion(XMLoadFloat4(&light.rotation))* + XMMatrixTranslationFromVector(XMLoadFloat3(&light.position))* camera->GetViewProjection() ); @@ -4408,8 +4391,8 @@ void wiRenderer::DrawLightVisualizers(CameraComponent* camera, GRAPHICSTHREAD th { lcb.world = XMMatrixTranspose( XMMatrixScaling(max(light.width * 0.5f, light.radius), light.radius, light.radius)* - XMMatrixRotationQuaternion(XMLoadFloat4(&transform.rotation))* - XMMatrixTranslationFromVector(XMLoadFloat3(&transform.translation))* + XMMatrixRotationQuaternion(XMLoadFloat4(&light.rotation))* + XMMatrixTranslationFromVector(XMLoadFloat3(&light.position))* camera->GetViewProjection() ); @@ -4454,8 +4437,6 @@ void wiRenderer::DrawVolumeLights(CameraComponent* camera, GRAPHICSTHREAD thread if (light.GetType() == type && light.volumetrics) { - const TransformComponent& transform = *scene.transforms.GetComponent(entity); - switch (type) { case LightComponent::DIRECTIONAL: @@ -4476,7 +4457,7 @@ void wiRenderer::DrawVolumeLights(CameraComponent* camera, GRAPHICSTHREAD thread MiscCB miscCb; miscCb.mColor.x = (float)light.entityArray_index; float sca = light.range + 1; - miscCb.mTransform = XMMatrixTranspose(XMMatrixScaling(sca, sca, sca)*XMMatrixTranslation(transform.translation.x, transform.translation.y, transform.translation.z) * camera->GetViewProjection()); + miscCb.mTransform = XMMatrixTranspose(XMMatrixScaling(sca, sca, sca)*XMMatrixTranslationFromVector(XMLoadFloat3(&light.position)) * camera->GetViewProjection()); GetDevice()->UpdateBuffer(constantBuffers[CBTYPE_MISC], &miscCb, threadID); GetDevice()->Draw(240, 0, threadID); // icosphere @@ -4489,8 +4470,8 @@ void wiRenderer::DrawVolumeLights(CameraComponent* camera, GRAPHICSTHREAD thread const float coneS = (const float)(light.fov / XM_PIDIV4); miscCb.mTransform = XMMatrixTranspose( XMMatrixScaling(coneS*light.range, light.range, coneS*light.range)* - XMMatrixRotationQuaternion(XMLoadFloat4(&transform.rotation))* - XMMatrixTranslationFromVector(XMLoadFloat3(&transform.translation)) * + XMMatrixRotationQuaternion(XMLoadFloat4(&light.rotation))* + XMMatrixTranslationFromVector(XMLoadFloat3(&light.position)) * camera->GetViewProjection() ); GetDevice()->UpdateBuffer(constantBuffers[CBTYPE_MISC], &miscCb, threadID); @@ -4523,18 +4504,16 @@ void wiRenderer::DrawLensFlares(GRAPHICSTHREAD threadID) if(!light.lensFlareRimTextures.empty()) { - - const TransformComponent& transform = *scene.transforms.GetComponent(entity); - XMVECTOR POS; - if(light.GetType() ==LightComponent::POINT || light.GetType() ==LightComponent::SPOT){ - POS = XMLoadFloat3(&transform.translation); + if(light.GetType() ==LightComponent::POINT || light.GetType() ==LightComponent::SPOT) + { + POS = XMLoadFloat3(&light.position); } else{ POS = XMVector3Normalize( - -XMVector3Transform(XMVectorSet(0, -1, 0, 1), XMMatrixRotationQuaternion(XMLoadFloat4(&transform.rotation))) + -XMVector3Transform(XMVectorSet(0, -1, 0, 1), XMMatrixRotationQuaternion(XMLoadFloat4(&light.rotation))) ) * 100000; } @@ -4825,13 +4804,11 @@ void wiRenderer::DrawForShadowMap(GRAPHICSTHREAD threadID, uint32_t layerMask) break; shadowCounter_Cube++; // shadow indices are already complete so a shadow slot is consumed here even if no rendering actually happens! - const TransformComponent& transform = *scene.transforms.GetComponent(entity); - CulledCollection culledRenderer; for (size_t i = 0; i < scene.aabb_objects.GetCount(); ++i) { const AABB& aabb = scene.aabb_objects[i]; - if (SPHERE(transform.translation, light.range).intersects(aabb)) + if (SPHERE(light.position, light.range).intersects(aabb)) { const ObjectComponent& object = scene.objects[i]; if (object.IsCastingShadow() && object.GetRenderTypes() == RENDERTYPE_OPAQUE) @@ -4851,7 +4828,7 @@ void wiRenderer::DrawForShadowMap(GRAPHICSTHREAD threadID, uint32_t layerMask) GetDevice()->ClearDepthStencil(shadowMapArray_Cube, CLEAR_DEPTH, 0.0f, 0, threadID, light.shadowMap_index); MiscCB miscCb; - miscCb.mColor = XMFLOAT4(transform.translation.x, transform.translation.y, transform.translation.z, 1.0f / light.GetRange()); // reciprocal range, to avoid division in shader + miscCb.mColor = XMFLOAT4(light.position.x, light.position.y, light.position.z, 1.0f / light.GetRange()); // reciprocal range, to avoid division in shader GetDevice()->UpdateBuffer(constantBuffers[CBTYPE_MISC], &miscCb, threadID); CubeMapRenderCB cb; @@ -4860,7 +4837,7 @@ void wiRenderer::DrawForShadowMap(GRAPHICSTHREAD threadID, uint32_t layerMask) GetDevice()->UpdateBuffer(constantBuffers[CBTYPE_CUBEMAPRENDER], &cb, threadID); - RenderMeshes(transform.translation, culledRenderer, SHADERTYPE_SHADOWCUBE, RENDERTYPE_OPAQUE, threadID); + RenderMeshes(light.position, culledRenderer, SHADERTYPE_SHADOWCUBE, RENDERTYPE_OPAQUE, threadID); } } @@ -5336,20 +5313,27 @@ void wiRenderer::DrawWorld(CameraComponent* camera, bool tessellation, GRAPHICST GetDevice()->BindResource(PS, resourceBuffers[RBTYPE_ENTITYINDEXLIST_OPAQUE], SBSLOT_ENTITYINDEXLIST, threadID); } - //if (grass) - //{ - // if (GetAlphaCompositionEnabled()) - // { - // // cut off most transparent areas - // SetAlphaRef(0.25f, threadID); - // } - // for (wiHairParticle* hair : culling.culledHairParticleSystems) - // { - // hair->Draw(camera, shaderType, false, threadID); - // } - //} + if (grass) + { + if (GetAlphaCompositionEnabled()) + { + // cut off most transparent areas + SetAlphaRef(0.25f, threadID); + } - if (!culling.culledRenderer_opaque.empty() || (grass && culling.culledHairParticleSystems.empty())) + Scene& scene = GetScene(); + + for (size_t i = 0; i < scene.hairs.GetCount(); ++i) + { + const wiHairParticle& hair = scene.hairs[i]; + Entity entity = scene.hairs.GetEntity(i); + const MaterialComponent& material = *scene.materials.GetComponent(entity); + + hair.Draw(camera, material, shaderType, false, threadID); + } + } + + if (!culling.culledRenderer_opaque.empty()/* || (grass && culling.culledHairParticleSystems.empty())*/) { RenderMeshes(camera->Eye, culling.culledRenderer_opaque, shaderType, RENDERTYPE_OPAQUE, threadID, tessellation, GetOcclusionCullingEnabled() && occlusionCulling, layerMask); } @@ -5374,14 +5358,20 @@ void wiRenderer::DrawWorldTransparent(CameraComponent* camera, SHADERTYPE shader ocean->Render(camera, renderTime, threadID); } - //if (grass && GetAlphaCompositionEnabled()) - //{ - // // transparent passes can only render hair when alpha composition is enabled - // for (wiHairParticle* hair : culling.culledHairParticleSystems) - // { - // hair->Draw(camera, shaderType, true, threadID); - // } - //} + if (grass && GetAlphaCompositionEnabled()) + { + // transparent passes can only render hair when alpha composition is enabled + Scene& scene = GetScene(); + + for (size_t i = 0; i < scene.hairs.GetCount(); ++i) + { + const wiHairParticle& hair = scene.hairs[i]; + Entity entity = scene.hairs.GetEntity(i); + const MaterialComponent& material = *scene.materials.GetComponent(entity); + + hair.Draw(camera, material, shaderType, true, threadID); + } + } if (!culling.culledRenderer_transparent.empty()) { diff --git a/WickedEngine/wiSceneSystem.cpp b/WickedEngine/wiSceneSystem.cpp index 670795f82..7e85d8ff7 100644 --- a/WickedEngine/wiSceneSystem.cpp +++ b/WickedEngine/wiSceneSystem.cpp @@ -10,6 +10,38 @@ using namespace wiGraphicsTypes; namespace wiSceneSystem { + XMFLOAT3 TransformComponent::GetPosition() const + { + return *((XMFLOAT3*)&world._41); + } + XMFLOAT4 TransformComponent::GetRotation() const + { + XMFLOAT4 rotation; + XMStoreFloat4(&rotation, GetRotationV()); + return rotation; + } + XMFLOAT3 TransformComponent::GetScale() const + { + XMFLOAT3 scale; + XMStoreFloat3(&scale, GetScaleV()); + return scale; + } + XMVECTOR TransformComponent::GetPositionV() const + { + return XMLoadFloat3((XMFLOAT3*)&world._41); + } + XMVECTOR TransformComponent::GetRotationV() const + { + XMVECTOR S, R, T; + XMMatrixDecompose(&S, &R, &T, XMLoadFloat4x4(&world)); + return R; + } + XMVECTOR TransformComponent::GetScaleV() const + { + XMVECTOR S, R, T; + XMMatrixDecompose(&S, &R, &T, XMLoadFloat4x4(&world)); + return S; + } void TransformComponent::UpdateTransform() { if (dirty) @@ -24,10 +56,6 @@ namespace wiSceneSystem XMMatrixRotationQuaternion(R_local) * XMMatrixTranslationFromVector(T_local); - scale = scale_local; - rotation = rotation_local; - translation = translation_local; - XMStoreFloat4x4(&world, W); } } @@ -62,20 +90,17 @@ namespace wiSceneSystem XMMATRIX B = XMLoadFloat4x4(&inverseParentBindMatrix); W = W * B * W_parent; - XMVECTOR S, R, T; - XMMatrixDecompose(&S, &R, &T, W); - XMStoreFloat3(&scale, S); - XMStoreFloat4(&rotation, R); - XMStoreFloat3(&translation, T); - XMStoreFloat4x4(&world, W); } void TransformComponent::ApplyTransform() { dirty = true; - scale_local = scale; - rotation_local = rotation; - translation_local = translation; + + XMVECTOR S, R, T; + XMMatrixDecompose(&S, &R, &T, XMLoadFloat4x4(&world)); + XMStoreFloat3(&scale_local, S); + XMStoreFloat4(&rotation_local, R); + XMStoreFloat3(&translation_local, T); } void TransformComponent::ClearTransform() { @@ -147,13 +172,11 @@ namespace wiSceneSystem { dirty = true; - XMVECTOR aS = XMLoadFloat3(&a.scale); - XMVECTOR aR = XMLoadFloat4(&a.rotation); - XMVECTOR aT = XMLoadFloat3(&a.translation); + XMVECTOR aS, aR, aT; + XMMatrixDecompose(&aS, &aR, &aT, XMLoadFloat4x4(&a.world)); - XMVECTOR bS = XMLoadFloat3(&b.scale); - XMVECTOR bR = XMLoadFloat4(&b.rotation); - XMVECTOR bT = XMLoadFloat3(&b.translation); + XMVECTOR bS, bR, bT; + XMMatrixDecompose(&bS, &bR, &bT, XMLoadFloat4x4(&b.world)); XMVECTOR S = XMVectorLerp(aS, bS, t); XMVECTOR R = XMQuaternionSlerp(aR, bR, t); @@ -167,21 +190,17 @@ namespace wiSceneSystem { dirty = true; - XMVECTOR aS = XMLoadFloat3(&a.scale); - XMVECTOR aR = XMLoadFloat4(&a.rotation); - XMVECTOR aT = XMLoadFloat3(&a.translation); + XMVECTOR aS, aR, aT; + XMMatrixDecompose(&aS, &aR, &aT, XMLoadFloat4x4(&a.world)); - XMVECTOR bS = XMLoadFloat3(&b.scale); - XMVECTOR bR = XMLoadFloat4(&b.rotation); - XMVECTOR bT = XMLoadFloat3(&b.translation); + XMVECTOR bS, bR, bT; + XMMatrixDecompose(&bS, &bR, &bT, XMLoadFloat4x4(&b.world)); - XMVECTOR cS = XMLoadFloat3(&c.scale); - XMVECTOR cR = XMLoadFloat4(&c.rotation); - XMVECTOR cT = XMLoadFloat3(&c.translation); + XMVECTOR cS, cR, cT; + XMMatrixDecompose(&cS, &cR, &cT, XMLoadFloat4x4(&c.world)); - XMVECTOR dS = XMLoadFloat3(&d.scale); - XMVECTOR dR = XMLoadFloat4(&d.rotation); - XMVECTOR dT = XMLoadFloat3(&d.translation); + XMVECTOR dS, dR, dT; + XMMatrixDecompose(&dS, &dR, &dT, XMLoadFloat4x4(&d.world)); XMVECTOR T = XMVectorCatmullRom(aT, bT, cT, dT, t); @@ -652,9 +671,7 @@ namespace wiSceneSystem CreateRenderData(); } - - - + void CameraComponent::CreatePerspective(float newWidth, float newHeight, float newNear, float newFar, float newFOV) { zNearP = newNear; @@ -682,11 +699,14 @@ namespace wiSceneSystem if (transform != nullptr) { - _Eye = XMLoadFloat3(&transform->translation); + XMVECTOR S, R, T; + XMMatrixDecompose(&S, &R, &T, XMLoadFloat4x4(&transform->world)); + + _Eye = T; _At = XMVectorSet(0, 0, 1, 0); _Up = XMVectorSet(0, 1, 0, 0); - XMMATRIX _Rot = XMMatrixRotationQuaternion(XMLoadFloat4(&transform->rotation)); + XMMATRIX _Rot = XMMatrixRotationQuaternion(R); _At = XMVector3TransformNormal(_At, _Rot); _Up = XMVector3TransformNormal(_Up, _Rot); XMStoreFloat3x3(&rotationMatrix, _Rot); @@ -761,9 +781,11 @@ namespace wiSceneSystem RunProbeUpdateSystem(transforms, aabb_probes, probes); + RunForceUpdateSystem(transforms, forces); + RunLightUpdateSystem(*cameras.GetComponent(wiRenderer::getCameraID()), transforms, aabb_lights, lights, sunDirection, sunColor); - RunEmitterUpdateSystem(emitters, dt); + RunParticleUpdateSystem(transforms, emitters, hairs, dt); } void Scene::Clear() @@ -1065,6 +1087,27 @@ namespace wiSceneSystem return entity; } + Entity Scene::Entity_CreateHair( + const std::string& name, + const XMFLOAT3& position + ) + { + Entity entity = CreateEntity(); + + owned_entities.insert(entity); + + names.Create(entity) = name; + + hairs.Create(entity); + + TransformComponent& transform = transforms.Create(entity); + transform.Translate(position); + transform.UpdateTransform(); + + materials.Create(entity); + + return entity; + } void Scene::Component_Attach(Entity entity, Entity parent) { @@ -1192,7 +1235,7 @@ namespace wiSceneSystem if (rigidbody.kinematic) { - physicsEngine->transformBody(transform.rotation, transform.translation, rigidbody.physicsObjectID); + //physicsEngine->transformBody(transform.rotation, transform.translation, rigidbody.physicsObjectID); } else { @@ -1272,6 +1315,8 @@ namespace wiSceneSystem TransformComponent& transform = *transforms.GetComponent(channel.target); + XMMATRIX ANIM; + if (channel.mode == AnimationComponent::AnimationChannel::Mode::STEP || keyLeft == keyRight) { // Nearest neighbor method (snap to left): @@ -1280,19 +1325,19 @@ namespace wiSceneSystem case AnimationComponent::AnimationChannel::Type::TRANSLATION: { assert(channel.keyframe_data.size() == channel.keyframe_times.size() * 3); - transform.translation = ((const XMFLOAT3*)channel.keyframe_data.data())[keyLeft]; + ANIM = XMMatrixTranslationFromVector(XMLoadFloat3(&((const XMFLOAT3*)channel.keyframe_data.data())[keyLeft])); } break; case AnimationComponent::AnimationChannel::Type::ROTATION: { assert(channel.keyframe_data.size() == channel.keyframe_times.size() * 4); - transform.rotation = ((const XMFLOAT4*)channel.keyframe_data.data())[keyLeft]; + ANIM = XMMatrixRotationQuaternion(XMLoadFloat4(&((const XMFLOAT4*)channel.keyframe_data.data())[keyLeft])); } break; case AnimationComponent::AnimationChannel::Type::SCALE: { assert(channel.keyframe_data.size() == channel.keyframe_times.size() * 3); - transform.scale = ((const XMFLOAT3*)channel.keyframe_data.data())[keyLeft]; + ANIM = XMMatrixScalingFromVector(XMLoadFloat3(&((const XMFLOAT3*)channel.keyframe_data.data())[keyLeft])); } break; } @@ -1312,7 +1357,7 @@ namespace wiSceneSystem XMVECTOR vLeft = XMLoadFloat3(&data[keyLeft]); XMVECTOR vRight = XMLoadFloat3(&data[keyRight]); XMVECTOR vAnim = XMVectorLerp(vLeft, vRight, t); - XMStoreFloat3(&transform.translation, vAnim); + ANIM = XMMatrixTranslationFromVector(vAnim); } break; case AnimationComponent::AnimationChannel::Type::ROTATION: @@ -1323,7 +1368,7 @@ namespace wiSceneSystem XMVECTOR vRight = XMLoadFloat4(&data[keyRight]); XMVECTOR vAnim = XMQuaternionSlerp(vLeft, vRight, t); vAnim = XMQuaternionNormalize(vAnim); - XMStoreFloat4(&transform.rotation, vAnim); + ANIM = XMMatrixRotationQuaternion(vAnim); } break; case AnimationComponent::AnimationChannel::Type::SCALE: @@ -1333,17 +1378,16 @@ namespace wiSceneSystem XMVECTOR vLeft = XMLoadFloat3(&data[keyLeft]); XMVECTOR vRight = XMLoadFloat3(&data[keyRight]); XMVECTOR vAnim = XMVectorLerp(vLeft, vRight, t); - XMStoreFloat3(&transform.scale, vAnim); + ANIM = XMMatrixScalingFromVector(vAnim); } break; } } - XMVECTOR S = XMLoadFloat3(&transform.scale); - XMVECTOR R = XMLoadFloat4(&transform.rotation); - XMVECTOR T = XMLoadFloat3(&transform.translation); - XMMATRIX W = XMMatrixScalingFromVector(S) * XMMatrixRotationQuaternion(R) * XMMatrixTranslationFromVector(T); - XMStoreFloat4x4(&transform.world, W); + XMMATRIX W = XMLoadFloat4x4(&transform.world); + XMMATRIX M = W * ANIM; + + XMStoreFloat4x4(&transform.world, M); transform.dirty = true; } @@ -1503,7 +1547,7 @@ namespace wiSceneSystem { object.rendertypeMask |= RENDERTYPE_TRANSPARENT | RENDERTYPE_WATER; - XMVECTOR _refPlane = XMPlaneFromPointNormal(XMLoadFloat3(&transform->translation), XMVectorSet(0, 1, 0, 0)); + XMVECTOR _refPlane = XMPlaneFromPointNormal(transform->GetPositionV(), XMVectorSet(0, 1, 0, 0)); XMStoreFloat4(&waterPlane, _refPlane); } @@ -1541,10 +1585,19 @@ namespace wiSceneSystem Entity entity = decals.GetEntity(i); const TransformComponent& transform = *transforms.GetComponent(entity); decal.world = transform.world; + + XMMATRIX W = XMLoadFloat4x4(&decal.world); XMVECTOR front = XMVectorSet(0, 0, 1, 0); - front = XMVector3TransformNormal(front, XMLoadFloat4x4(&decal.world)); + front = XMVector3TransformNormal(front, W); XMStoreFloat3(&decal.front, front); + XMVECTOR S, R, T; + XMMatrixDecompose(&S, &R, &T, W); + XMStoreFloat3(&decal.position, T); + XMFLOAT3 scale; + XMStoreFloat3(&scale, S); + decal.range = max(scale.x, max(scale.y, scale.z)) * 2; + AABB& aabb = aabb_decals[i]; aabb.createFromHalfWidth(XMFLOAT3(0, 0, 0), XMFLOAT3(1, 1, 1)); aabb = aabb.get(transform.world); @@ -1564,13 +1617,36 @@ namespace wiSceneSystem Entity entity = probes.GetEntity(i); const TransformComponent& transform = *transforms.GetComponent(entity); - probe.position = transform.translation; + probe.position = transform.GetPosition(); + + XMMATRIX W = XMLoadFloat4x4(&transform.world); + XMStoreFloat4x4(&probe.inverseMatrix, XMMatrixInverse(nullptr, W)); + + XMVECTOR S, R, T; + XMMatrixDecompose(&S, &R, &T, W); + XMFLOAT3 scale; + XMStoreFloat3(&scale, S); + probe.range = max(scale.x, max(scale.y, scale.z)) * 2; AABB& aabb = aabb_probes[i]; aabb.createFromHalfWidth(XMFLOAT3(0, 0, 0), XMFLOAT3(1, 1, 1)); aabb = aabb.get(transform.world); } } + void RunForceUpdateSystem( + const ComponentManager& transforms, + ComponentManager& forces + ) + { + for (size_t i = 0; i < forces.GetCount(); ++i) + { + ForceFieldComponent& force = forces[i]; + Entity entity = forces.GetEntity(i); + const TransformComponent& transform = *transforms.GetComponent(entity); + force.position = transform.GetPosition(); + XMStoreFloat3(&force.direction, XMVector3Normalize(XMVector3TransformNormal(XMVectorSet(0, -1, 0, 0), XMLoadFloat4x4(&transform.world)))); + } + } void RunLightUpdateSystem( const CameraComponent& cascadeCamera, const ComponentManager& transforms, @@ -1588,11 +1664,13 @@ namespace wiSceneSystem const TransformComponent& transform = *transforms.GetComponent(entity); AABB& aabb = aabb_lights[i]; - XMMATRIX world = XMLoadFloat4x4(&transform.world); - XMVECTOR translation = XMLoadFloat3(&transform.translation); - XMVECTOR rotation = XMLoadFloat4(&transform.rotation); + XMMATRIX W = XMLoadFloat4x4(&transform.world); + XMVECTOR S, R, T; + XMMatrixDecompose(&S, &R, &T, W); - XMStoreFloat3(&light.direction, XMVector3TransformNormal(XMVectorSet(0, 1, 0, 1), world)); + XMStoreFloat3(&light.position, T); + XMStoreFloat4(&light.rotation, R); + XMStoreFloat3(&light.direction, XMVector3TransformNormal(XMVectorSet(0, 1, 0, 0), W)); switch (light.type) { @@ -1660,7 +1738,7 @@ namespace wiSceneSystem XMVECTOR e1 = XMVectorFloor(XMVectorLerp(c, d, lerp1) / f1) * f1; XMVECTOR e2 = XMVectorFloor(XMVectorLerp(c, d, lerp2) / f2) * f2; - XMMATRIX rrr = XMMatrixRotationQuaternion(XMLoadFloat4(&transform.rotation)); + XMMATRIX rrr = XMMatrixRotationQuaternion(R); light.shadowCam_dirLight[0].Update(rrr, e0); light.shadowCam_dirLight[1].Update(rrr, e1); @@ -1679,12 +1757,12 @@ namespace wiSceneSystem { light.shadowCam_spotLight.push_back(LightComponent::SHCAM(XMFLOAT4(0, 0, 0, 1), 0.1f, 1000.0f, light.fov)); } - light.shadowCam_spotLight[0].Update(world); + light.shadowCam_spotLight[0].Update(W); light.shadowCam_spotLight[0].farplane = light.range; light.shadowCam_spotLight[0].Create_Perspective(light.fov); } - aabb.createFromHalfWidth(transform.translation, XMFLOAT3(light.range, light.range, light.range)); + aabb.createFromHalfWidth(light.position, XMFLOAT3(light.range, light.range, light.range)); } break; case LightComponent::POINT: @@ -1706,8 +1784,9 @@ namespace wiSceneSystem light.shadowCam_pointLight.push_back(LightComponent::SHCAM(XMFLOAT4(0.707f, 0, 0, -0.707f), 0.1f, 1000.0f, XM_PIDIV2)); //+z light.shadowCam_pointLight.push_back(LightComponent::SHCAM(XMFLOAT4(0, 0.707f, 0.707f, 0), 0.1f, 1000.0f, XM_PIDIV2)); //-z } - for (auto& x : light.shadowCam_pointLight) { - x.Update(translation); + for (auto& x : light.shadowCam_pointLight) + { + x.Update(T); x.farplane = max(1.0f, light.range); x.Create_Perspective(XM_PIDIV2); } @@ -1715,10 +1794,12 @@ namespace wiSceneSystem if (light.type == LightComponent::POINT) { - aabb.createFromHalfWidth(transform.translation, XMFLOAT3(light.range, light.range, light.range)); + aabb.createFromHalfWidth(light.position, XMFLOAT3(light.range, light.range, light.range)); } else { + XMStoreFloat3(&light.right, XMVector3TransformNormal(XMVectorSet(-1, 0, 0, 0), W)); + XMStoreFloat3(&light.front, XMVector3TransformNormal(XMVectorSet(0, 0, -1, 0), W)); // area lights have no bounds, just like directional lights (maybe todo) aabb.createFromHalfWidth(wiRenderer::getCamera()->Eye, XMFLOAT3(10000, 10000, 10000)); } @@ -1728,13 +1809,26 @@ namespace wiSceneSystem } } - void RunEmitterUpdateSystem(ComponentManager& emitters, float dt) + void RunParticleUpdateSystem( + const ComponentManager& transforms, + ComponentManager& emitters, + ComponentManager& hairs, + float dt + ) { for (size_t i = 0; i < emitters.GetCount(); ++i) { wiEmittedParticle& emitter = emitters[i]; emitter.Update(dt); } + + for (size_t i = 0; i < hairs.GetCount(); ++i) + { + wiHairParticle& hair = hairs[i]; + Entity entity = hairs.GetEntity(i); + const TransformComponent& transform = *transforms.GetComponent(entity); + hair.world = transform.world; + } } } diff --git a/WickedEngine/wiSceneSystem.h b/WickedEngine/wiSceneSystem.h index 04ecfa083..98cf6c490 100644 --- a/WickedEngine/wiSceneSystem.h +++ b/WickedEngine/wiSceneSystem.h @@ -44,11 +44,14 @@ namespace wiSceneSystem XMFLOAT4 rotation_local = XMFLOAT4(0, 0, 0, 1); XMFLOAT3 translation_local = XMFLOAT3(0, 0, 0); - XMFLOAT3 scale = XMFLOAT3(1, 1, 1); - XMFLOAT4 rotation = XMFLOAT4(0, 0, 0, 1); - XMFLOAT3 translation = XMFLOAT3(0, 0, 0); XMFLOAT4X4 world = IDENTITYMATRIX; + XMFLOAT3 GetPosition() const; + XMFLOAT4 GetRotation() const; + XMFLOAT3 GetScale() const; + XMVECTOR GetPositionV() const; + XMVECTOR GetRotationV() const; + XMVECTOR GetScaleV() const; void UpdateTransform(); void UpdateParentedTransform(const TransformComponent& parent, const XMFLOAT4X4& inverseParentBindMatrix); void ApplyTransform(); @@ -446,7 +449,9 @@ namespace wiSceneSystem std::vector lensFlareRimTextures; std::vector lensFlareNames; + XMFLOAT3 position; XMFLOAT3 direction; + XMFLOAT4 rotation; int shadowMap_index = -1; int entityArray_index = -1; @@ -457,6 +462,8 @@ namespace wiSceneSystem float radius = 1.0f; float width = 1.0f; float height = 1.0f; + XMFLOAT3 front; + XMFLOAT3 right; inline float GetRange() const { return range; } @@ -588,6 +595,8 @@ namespace wiSceneSystem bool realTime = false; bool isUpToDate = false; XMFLOAT3 position; + float range; + XMFLOAT4X4 inverseMatrix; }; struct ForceFieldComponent @@ -595,6 +604,8 @@ namespace wiSceneSystem int type = ENTITY_TYPE_FORCEFIELD_POINT; float gravity = 0.0f; // negative = deflector, positive = attractor float range = 0.0f; // affection range + XMFLOAT3 position; + XMFLOAT3 direction; }; struct DecalComponent @@ -603,6 +614,8 @@ namespace wiSceneSystem XMFLOAT4 atlasMulAdd = XMFLOAT4(0, 0, 0, 0); XMFLOAT4X4 world; XMFLOAT3 front; + XMFLOAT3 position; + float range; float emissive = 0; @@ -759,6 +772,10 @@ namespace wiSceneSystem const std::string& name, const XMFLOAT3& position = XMFLOAT3(0, 0, 0) ); + wiECS::Entity Entity_CreateHair( + const std::string& name, + const XMFLOAT3& position = XMFLOAT3(0, 0, 0) + ); // Attaches an entity to a parent: void Component_Attach(wiECS::Entity entity, wiECS::Entity parent); @@ -819,6 +836,10 @@ namespace wiSceneSystem wiECS::ComponentManager& aabb_probes, wiECS::ComponentManager& probes ); + void RunForceUpdateSystem( + const wiECS::ComponentManager& transforms, + wiECS::ComponentManager& forces + ); void RunLightUpdateSystem( const CameraComponent& cascadeCamera, const wiECS::ComponentManager& transforms, @@ -826,7 +847,12 @@ namespace wiSceneSystem wiECS::ComponentManager& lights, XMFLOAT3& sunDirection, XMFLOAT3& sunColor ); - void RunEmitterUpdateSystem(wiECS::ComponentManager& emitters, float dt); + void RunParticleUpdateSystem( + const wiECS::ComponentManager& transforms, + wiECS::ComponentManager& emitters, + wiECS::ComponentManager& hairs, + float dt + ); } diff --git a/WickedEngine/wiWidget.cpp b/WickedEngine/wiWidget.cpp index d87ed0c6d..ba7178764 100644 --- a/WickedEngine/wiWidget.cpp +++ b/WickedEngine/wiWidget.cpp @@ -36,6 +36,8 @@ wiWidget::wiWidget() : TransformComponent() tooltipTimer = 0; textColor = wiColor(255, 255, 255, 255); textShadowColor = wiColor(0, 0, 0, 255); + translation = XMFLOAT3(0, 0, 0); + scale = XMFLOAT3(1, 1, 1); } wiWidget::~wiWidget() { @@ -59,6 +61,11 @@ void wiWidget::Update(wiGUI* gui, float dt) { this->UpdateParentedTransform(*container, world_parent_bind); } + + XMVECTOR S, R, T; + XMMatrixDecompose(&S, &R, &T, XMLoadFloat4x4(&world)); + XMStoreFloat3(&translation, T); + XMStoreFloat3(&scale, S); } void wiWidget::AttachTo(wiWidget* parent) { @@ -147,6 +154,8 @@ void wiWidget::SetPos(const XMFLOAT2& value) TransformComponent::translation_local.x = value.x; TransformComponent::translation_local.y = value.y; TransformComponent::UpdateTransform(); + + translation = translation_local; } void wiWidget::SetSize(const XMFLOAT2& value) { @@ -154,6 +163,8 @@ void wiWidget::SetSize(const XMFLOAT2& value) TransformComponent::scale_local.x = value.x; TransformComponent::scale_local.y = value.y; TransformComponent::UpdateTransform(); + + scale = scale_local; } wiWidget::WIDGETSTATE wiWidget::GetState() { @@ -219,22 +230,19 @@ void wiWidget::SetScissorRect(const wiGraphicsTypes::Rect& rect) } void wiWidget::LoadShaders() { - - { - GraphicsPSODesc desc; - desc.vs = wiRenderer::vertexShaders[VSTYPE_LINE]; - desc.ps = wiRenderer::pixelShaders[PSTYPE_LINE]; - desc.il = wiRenderer::vertexLayouts[VLTYPE_LINE]; - desc.dss = wiRenderer::depthStencils[DSSTYPE_XRAY]; - desc.bs = wiRenderer::blendStates[BSTYPE_OPAQUE]; - desc.rs = wiRenderer::rasterizers[RSTYPE_DOUBLESIDED]; - desc.numRTs = 1; - desc.RTFormats[0] = wiRenderer::GetDevice()->GetBackBufferFormat(); - desc.pt = TRIANGLESTRIP; - RECREATE(PSO_colorpicker); - HRESULT hr = wiRenderer::GetDevice()->CreateGraphicsPSO(&desc, PSO_colorpicker); - assert(SUCCEEDED(hr)); - } + GraphicsPSODesc desc; + desc.vs = wiRenderer::vertexShaders[VSTYPE_LINE]; + desc.ps = wiRenderer::pixelShaders[PSTYPE_LINE]; + desc.il = wiRenderer::vertexLayouts[VLTYPE_LINE]; + desc.dss = wiRenderer::depthStencils[DSSTYPE_XRAY]; + desc.bs = wiRenderer::blendStates[BSTYPE_OPAQUE]; + desc.rs = wiRenderer::rasterizers[RSTYPE_DOUBLESIDED]; + desc.numRTs = 1; + desc.RTFormats[0] = wiRenderer::GetDevice()->GetBackBufferFormat(); + desc.pt = TRIANGLESTRIP; + RECREATE(PSO_colorpicker); + HRESULT hr = wiRenderer::GetDevice()->CreateGraphicsPSO(&desc, PSO_colorpicker); + assert(SUCCEEDED(hr)); } @@ -266,10 +274,10 @@ void wiButton::Update(wiGUI* gui, float dt) return; } - hitBox.pos.x = TransformComponent::translation.x; - hitBox.pos.y = TransformComponent::translation.y; - hitBox.siz.x = TransformComponent::scale.x; - hitBox.siz.y = TransformComponent::scale.y; + hitBox.pos.x = translation.x; + hitBox.pos.y = translation.y; + hitBox.siz.x = scale.x; + hitBox.siz.y = scale.y; Hitbox2D pointerHitbox = Hitbox2D(gui->GetPointerPos(), XMFLOAT2(1, 1)); @@ -494,10 +502,10 @@ void wiTextInputField::Update(wiGUI* gui, float dt) return; } - hitBox.pos.x = TransformComponent::translation.x; - hitBox.pos.y = TransformComponent::translation.y; - hitBox.siz.x = TransformComponent::scale.x; - hitBox.siz.y = TransformComponent::scale.y; + hitBox.pos.x = translation.x; + hitBox.pos.y = translation.y; + hitBox.siz.x = scale.x; + hitBox.siz.y = scale.y; Hitbox2D pointerHitbox = Hitbox2D(gui->GetPointerPos(), XMFLOAT2(1, 1)); bool intersectsPointer = pointerHitbox.intersects(hitBox); @@ -721,10 +729,10 @@ void wiSlider::Update(wiGUI* gui, float dt) float headWidth = scale.x*0.05f; - hitBox.pos.x = TransformComponent::translation.x - headWidth * 0.5f; - hitBox.pos.y = TransformComponent::translation.y; - hitBox.siz.x = TransformComponent::scale.x + headWidth; - hitBox.siz.y = TransformComponent::scale.y; + hitBox.pos.x = translation.x - headWidth * 0.5f; + hitBox.pos.y = translation.y; + hitBox.siz.x = scale.x + headWidth; + hitBox.siz.y = scale.y; Hitbox2D pointerHitbox = Hitbox2D(gui->GetPointerPos(), XMFLOAT2(1, 1)); @@ -855,10 +863,10 @@ void wiCheckBox::Update(wiGUI* gui, float dt) gui->DeactivateWidget(this); } - hitBox.pos.x = TransformComponent::translation.x; - hitBox.pos.y = TransformComponent::translation.y; - hitBox.siz.x = TransformComponent::scale.x; - hitBox.siz.y = TransformComponent::scale.y; + hitBox.pos.x = translation.x; + hitBox.pos.y = translation.y; + hitBox.siz.x = scale.x; + hitBox.siz.y = scale.y; Hitbox2D pointerHitbox = Hitbox2D(gui->GetPointerPos(), XMFLOAT2(1, 1)); @@ -997,10 +1005,10 @@ void wiComboBox::Update(wiGUI* gui, float dt) gui->DeactivateWidget(this); } - hitBox.pos.x = TransformComponent::translation.x; - hitBox.pos.y = TransformComponent::translation.y; - hitBox.siz.x = TransformComponent::scale.x + scale.y + 1; // + drop-down indicator arrow + little offset - hitBox.siz.y = TransformComponent::scale.y; + hitBox.pos.x = translation.x; + hitBox.pos.y = translation.y; + hitBox.siz.x = scale.x + scale.y + 1; // + drop-down indicator arrow + little offset + hitBox.siz.y = scale.y; Hitbox2D pointerHitbox = Hitbox2D(gui->GetPointerPos(), XMFLOAT2(1, 1)); @@ -1062,10 +1070,10 @@ void wiComboBox::Update(wiGUI* gui, float dt) } Hitbox2D itembox; - itembox.pos.x = TransformComponent::translation.x; - itembox.pos.y = TransformComponent::translation.y + _GetItemOffset((int)i); - itembox.siz.x = TransformComponent::scale.x; - itembox.siz.y = TransformComponent::scale.y; + itembox.pos.x = translation.x; + itembox.pos.y = translation.y + _GetItemOffset((int)i); + itembox.siz.x = scale.x; + itembox.siz.y = scale.y; if (pointerHitbox.intersects(itembox)) { hovered = (int)i; @@ -1260,6 +1268,7 @@ wiWindow::wiWindow(wiGUI* gui, const std::string& name) :wiWidget() moveDragger->SetPos(XMFLOAT2(windowcontrolSize, 0)); moveDragger->OnDrag([this](wiEventArgs args) { this->Translate(XMFLOAT3(args.deltaPos.x, args.deltaPos.y, 0)); + this->UpdateTransform(); }); AddWidget(moveDragger); @@ -1296,6 +1305,7 @@ wiWindow::wiWindow(wiGUI* gui, const std::string& name) :wiWidget() scaleDiff.y = (scale.y - args.deltaPos.y) / scale.y; this->Translate(XMFLOAT3(args.deltaPos.x, args.deltaPos.y, 0)); this->Scale(XMFLOAT3(scaleDiff.x, scaleDiff.y, 1)); + this->UpdateTransform(); }); AddWidget(resizeDragger_UpperLeft); @@ -1309,6 +1319,7 @@ wiWindow::wiWindow(wiGUI* gui, const std::string& name) :wiWidget() scaleDiff.x = (scale.x + args.deltaPos.x) / scale.x; scaleDiff.y = (scale.y + args.deltaPos.y) / scale.y; this->Scale(XMFLOAT3(scaleDiff.x, scaleDiff.y, 1)); + this->UpdateTransform(); }); AddWidget(resizeDragger_BottomRight); diff --git a/WickedEngine/wiWidget.h b/WickedEngine/wiWidget.h index 825660ea5..edd4c1871 100644 --- a/WickedEngine/wiWidget.h +++ b/WickedEngine/wiWidget.h @@ -88,6 +88,9 @@ public: virtual void Render(wiGUI* gui) = 0; void RenderTooltip(wiGUI* gui); + XMFLOAT3 translation; + XMFLOAT3 scale; + Hitbox2D hitBox; wiWidget* container;