simplified transform component;

resurrected hair particle + added editor window
This commit is contained in:
turanszkij
2018-09-12 18:34:54 +01:00
parent 905c190561
commit ecea9f086d
20 changed files with 729 additions and 480 deletions
+96 -27
View File
@@ -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)
{
+3 -1
View File
@@ -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;
+2
View File
@@ -172,6 +172,7 @@
<ClInclude Include="EmitterWindow.h" />
<ClInclude Include="EnvProbeWindow.h" />
<ClInclude Include="ForceFieldWindow.h" />
<ClInclude Include="HairParticleWindow.h" />
<ClInclude Include="json.hpp" />
<ClInclude Include="LightWindow.h" />
<ClInclude Include="main.h" />
@@ -198,6 +199,7 @@
<ClCompile Include="EmitterWindow.cpp" />
<ClCompile Include="EnvProbeWindow.cpp" />
<ClCompile Include="ForceFieldWindow.cpp" />
<ClCompile Include="HairParticleWindow.cpp" />
<ClCompile Include="LightWindow.cpp" />
<ClCompile Include="main.cpp" />
<ClCompile Include="MaterialWindow.cpp" />
+6
View File
@@ -85,6 +85,9 @@
<ClInclude Include="Translator.h">
<Filter>Code</Filter>
</ClInclude>
<ClInclude Include="HairParticleWindow.h">
<Filter>Code</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="CameraWindow.cpp">
@@ -150,6 +153,9 @@
<ClCompile Include="Translator.cpp">
<Filter>Code</Filter>
</ClCompile>
<ClCompile Include="HairParticleWindow.cpp">
<Filter>Code</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Image Include="small.ico">
-1
View File
@@ -1,6 +1,5 @@
#include "stdafx.h"
#include "EmitterWindow.h"
#include "MaterialWindow.h"
#include <sstream>
+1
View File
@@ -7,6 +7,7 @@ class wiCheckBox;
class wiSlider;
class wiComboBox;
class wiColorPicker;
class wiButton;
class MaterialWindow;
+162
View File
@@ -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);
}
}
}
+37
View File
@@ -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;
};
+10
View File
@@ -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;
+4 -2
View File
@@ -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;
+5 -4
View File
@@ -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);
+1 -1
View File
@@ -5,7 +5,7 @@
CBUFFER(HairParticleCB, CBSLOT_OTHER_HAIRPARTICLE)
{
float4x4 xWorld;
float3 xColor; float __pad0;
float4 xColor;
float LOD0;
float LOD1;
float LOD2;
+1 -1
View File
@@ -3,5 +3,5 @@
float4 main() : SV_TARGET
{
return float4(xColor, 1.0f);
return float4(xColor.rgb, 1.0f);
}
+82 -246
View File
@@ -222,278 +222,114 @@ void wiHairParticle::Settings(int l0,int l1,int l2)
}
void wiHairParticle::Generate()
void wiHairParticle::Generate(const MeshComponent& mesh)
{
//std::vector<Patch> points;
std::vector<Patch> 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; i<mesh->indices.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<PATCHSIZE;++p)
// {
// float f = wiRandom::getRandom(0, 1000) * 0.001f, g = wiRandom::getRandom(0, 1000) * 0.001f;
// if (f + g > 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);
}
}
+6 -8
View File
@@ -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<wiGraphicsTypes::GPUBuffer> cb;
std::unique_ptr<wiGraphicsTypes::GPUBuffer> particleBuffer;
std::unique_ptr<wiGraphicsTypes::GPUBuffer> ib;
std::unique_ptr<wiGraphicsTypes::GPUBuffer> ib_transposed;
std::unique_ptr<wiGraphicsTypes::GPUBuffer> 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;
};
}
+72 -82
View File
@@ -118,8 +118,6 @@ struct FrameCulling
CulledCollection culledRenderer_opaque;
CulledCollection culledRenderer_transparent;
vector<Entity> culledObjects;
vector<Entity> culledHairParticleSystems;
vector<Entity> culledEmitters;
vector<Entity> culledLights;
vector<Entity> culledDecals;
vector<Entity> 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())
{
+157 -63
View File
@@ -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<TransformComponent>& transforms,
ComponentManager<ForceFieldComponent>& 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<TransformComponent>& 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<wiEmittedParticle>& emitters, float dt)
void RunParticleUpdateSystem(
const ComponentManager<TransformComponent>& transforms,
ComponentManager<wiEmittedParticle>& emitters,
ComponentManager<wiHairParticle>& 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;
}
}
}
+30 -4
View File
@@ -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<wiGraphicsTypes::Texture2D*> lensFlareRimTextures;
std::vector<std::string> 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>& aabb_probes,
wiECS::ComponentManager<EnvironmentProbeComponent>& probes
);
void RunForceUpdateSystem(
const wiECS::ComponentManager<TransformComponent>& transforms,
wiECS::ComponentManager<ForceFieldComponent>& forces
);
void RunLightUpdateSystem(
const CameraComponent& cascadeCamera,
const wiECS::ComponentManager<TransformComponent>& transforms,
@@ -826,7 +847,12 @@ namespace wiSceneSystem
wiECS::ComponentManager<LightComponent>& lights,
XMFLOAT3& sunDirection, XMFLOAT3& sunColor
);
void RunEmitterUpdateSystem(wiECS::ComponentManager<wiEmittedParticle>& emitters, float dt);
void RunParticleUpdateSystem(
const wiECS::ComponentManager<TransformComponent>& transforms,
wiECS::ComponentManager<wiEmittedParticle>& emitters,
wiECS::ComponentManager<wiHairParticle>& hairs,
float dt
);
}
+51 -40
View File
@@ -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);
+3
View File
@@ -88,6 +88,9 @@ public:
virtual void Render(wiGUI* gui) = 0;
void RenderTooltip(wiGUI* gui);
XMFLOAT3 translation;
XMFLOAT3 scale;
Hitbox2D hitBox;
wiWidget* container;