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;