Files
WickedEngine/Editor/HairParticleWindow.cpp
T

294 lines
8.7 KiB
C++

#include "stdafx.h"
#include "HairParticleWindow.h"
using namespace std;
using namespace wiECS;
using namespace wiScene;
HairParticleWindow::HairParticleWindow(wiGUI* gui) : GUI(gui)
{
assert(GUI && "Invalid GUI!");
hairWindow = new wiWindow(GUI, "Hair Particle System Window");
hairWindow->SetSize(XMFLOAT2(600, 400));
GUI->AddWidget(hairWindow);
float x = 160;
float y = 0;
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 = wiScene::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 = wiScene::GetScene();
hair->meshID = scene.meshes.GetEntity(args.iValue - 1);
}
}
});
meshComboBox->SetTooltip("Choose a mesh where hair will grow from...");
hairWindow->AddWidget(meshComboBox);
countSlider = new wiSlider(0, 100000, 1000, 100000, "Strand Count: ");
countSlider->SetSize(XMFLOAT2(360, 30));
countSlider->SetPos(XMFLOAT2(x, y += step));
countSlider->OnSlide([&](wiEventArgs args) {
auto hair = GetHair();
if (hair != nullptr)
{
hair->strandCount = (uint32_t)args.iValue;
}
});
countSlider->SetEnabled(false);
countSlider->SetTooltip("Set hair strand count");
hairWindow->AddWidget(countSlider);
lengthSlider = new wiSlider(0, 4, 1, 100000, "Particle Length: ");
lengthSlider->SetSize(XMFLOAT2(360, 30));
lengthSlider->SetPos(XMFLOAT2(x, y += step));
lengthSlider->OnSlide([&](wiEventArgs args) {
auto hair = GetHair();
if (hair != nullptr)
{
hair->length = args.fValue;
}
});
lengthSlider->SetEnabled(false);
lengthSlider->SetTooltip("Set hair strand length");
hairWindow->AddWidget(lengthSlider);
stiffnessSlider = new wiSlider(0, 20, 5, 100000, "Particle Stiffness: ");
stiffnessSlider->SetSize(XMFLOAT2(360, 30));
stiffnessSlider->SetPos(XMFLOAT2(x, y += step));
stiffnessSlider->OnSlide([&](wiEventArgs args) {
auto hair = GetHair();
if (hair != nullptr)
{
hair->stiffness = args.fValue;
}
});
stiffnessSlider->SetEnabled(false);
stiffnessSlider->SetTooltip("Set hair strand stiffness, how much it tries to get back to rest position.");
hairWindow->AddWidget(stiffnessSlider);
randomnessSlider = new wiSlider(0, 1, 0.2f, 100000, "Particle Randomness: ");
randomnessSlider->SetSize(XMFLOAT2(360, 30));
randomnessSlider->SetPos(XMFLOAT2(x, y += step));
randomnessSlider->OnSlide([&](wiEventArgs args) {
auto hair = GetHair();
if (hair != nullptr)
{
hair->randomness = args.fValue;
}
});
randomnessSlider->SetEnabled(false);
randomnessSlider->SetTooltip("Set hair length randomization factor. This will affect randomness of hair lengths.");
hairWindow->AddWidget(randomnessSlider);
segmentcountSlider = new wiSlider(1, 10, 1, 9, "Segment Count: ");
segmentcountSlider->SetSize(XMFLOAT2(360, 30));
segmentcountSlider->SetPos(XMFLOAT2(x, y += step));
segmentcountSlider->OnSlide([&](wiEventArgs args) {
auto hair = GetHair();
if (hair != nullptr)
{
hair->segmentCount = (uint32_t)args.iValue;
}
});
segmentcountSlider->SetEnabled(false);
segmentcountSlider->SetTooltip("Set hair strand segment count. This will affect simulation quality and performance.");
hairWindow->AddWidget(segmentcountSlider);
randomSeedSlider = new wiSlider(1, 12345, 1, 12344, "Random seed: ");
randomSeedSlider->SetSize(XMFLOAT2(360, 30));
randomSeedSlider->SetPos(XMFLOAT2(x, y += step));
randomSeedSlider->OnSlide([&](wiEventArgs args) {
auto hair = GetHair();
if (hair != nullptr)
{
hair->randomSeed = (uint32_t)args.iValue;
}
});
randomSeedSlider->SetEnabled(false);
randomSeedSlider->SetTooltip("Set hair system-wide random seed value. This will affect hair patch placement randomization.");
hairWindow->AddWidget(randomSeedSlider);
viewDistanceSlider = new wiSlider(0, 1000, 100, 10000, "View distance: ");
viewDistanceSlider->SetSize(XMFLOAT2(360, 30));
viewDistanceSlider->SetPos(XMFLOAT2(x, y += step));
viewDistanceSlider->OnSlide([&](wiEventArgs args) {
auto hair = GetHair();
if (hair != nullptr)
{
hair->viewDistance = args.fValue;
}
});
viewDistanceSlider->SetEnabled(false);
viewDistanceSlider->SetTooltip("Set view distance. After this, particles will be faded out.");
hairWindow->AddWidget(viewDistanceSlider);
frameWidthInput = new wiTextInputField("");
frameWidthInput->SetPos(XMFLOAT2(x, y += step));
frameWidthInput->SetSize(XMFLOAT2(40, 18));
frameWidthInput->SetText("");
frameWidthInput->SetTooltip("Enter a value to enable sprite sheet frame width in pixels.");
frameWidthInput->SetDescription("Frame Width: ");
frameWidthInput->OnInputAccepted([this](wiEventArgs args) {
auto hair = GetHair();
if (hair != nullptr)
{
hair->frameWidth = (uint32_t)args.iValue;
}
});
hairWindow->AddWidget(frameWidthInput);
frameHeightInput = new wiTextInputField("");
frameHeightInput->SetPos(XMFLOAT2(x + 250, y));
frameHeightInput->SetSize(XMFLOAT2(40, 18));
frameHeightInput->SetText("");
frameHeightInput->SetTooltip("Enter a value to enable sprite sheet frame height in pixels.");
frameHeightInput->SetDescription("Frame Height: ");
frameHeightInput->OnInputAccepted([this](wiEventArgs args) {
auto hair = GetHair();
if (hair != nullptr)
{
hair->frameHeight = (uint32_t)args.iValue;
}
});
hairWindow->AddWidget(frameHeightInput);
step = 20;
frameCountInput = new wiTextInputField("");
frameCountInput->SetPos(XMFLOAT2(x, y += step));
frameCountInput->SetSize(XMFLOAT2(40, 18));
frameCountInput->SetText("");
frameCountInput->SetTooltip("Enter a value to enable the random sprite sheet frame selection's max frame number.");
frameCountInput->SetDescription("Frame Count: ");
frameCountInput->OnInputAccepted([this](wiEventArgs args) {
auto hair = GetHair();
if (hair != nullptr)
{
hair->frameCount = (uint32_t)args.iValue;
}
});
hairWindow->AddWidget(frameCountInput);
horizontalFrameCountInput = new wiTextInputField("");
horizontalFrameCountInput->SetPos(XMFLOAT2(x + 250, y));
horizontalFrameCountInput->SetSize(XMFLOAT2(40, 18));
horizontalFrameCountInput->SetText("");
horizontalFrameCountInput->SetTooltip("Specifies how many sprite sheet frames are in the horizontal direction. 0 = all frames are placed horizontally.");
horizontalFrameCountInput->SetDescription("Horizontal Frame Count: ");
horizontalFrameCountInput->OnInputAccepted([this](wiEventArgs args) {
auto hair = GetHair();
if (hair != nullptr)
{
hair->horizontalFrameCount = (uint32_t)args.iValue;
}
});
hairWindow->AddWidget(horizontalFrameCountInput);
hairWindow->Translate(XMFLOAT3(200, 50, 0));
hairWindow->SetVisible(false);
SetEntity(entity);
}
HairParticleWindow::~HairParticleWindow()
{
hairWindow->RemoveWidgets(true);
GUI->RemoveWidget(hairWindow);
delete hairWindow;
}
void HairParticleWindow::SetEntity(Entity entity)
{
this->entity = entity;
auto hair = GetHair();
if (hair != nullptr)
{
lengthSlider->SetValue(hair->length);
stiffnessSlider->SetValue(hair->stiffness);
randomnessSlider->SetValue(hair->randomness);
countSlider->SetValue((float)hair->strandCount);
segmentcountSlider->SetValue((float)hair->segmentCount);
randomSeedSlider->SetValue((float)hair->randomSeed);
viewDistanceSlider->SetValue(hair->viewDistance);
frameWidthInput->SetValue((int)hair->frameWidth);
frameHeightInput->SetValue((int)hair->frameHeight);
frameCountInput->SetValue((int)hair->frameCount);
horizontalFrameCountInput->SetValue((int)hair->horizontalFrameCount);
hairWindow->SetEnabled(true);
}
else
{
hairWindow->SetEnabled(false);
}
addButton->SetEnabled(true);
}
wiHairParticle* HairParticleWindow::GetHair()
{
if (entity == INVALID_ENTITY)
{
return nullptr;
}
Scene& scene = wiScene::GetScene();
wiHairParticle* hair = scene.hairs.GetComponent(entity);
return hair;
}
void HairParticleWindow::UpdateData()
{
auto emitter = GetHair();
if (emitter == nullptr)
{
return;
}
Scene& scene = wiScene::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);
}
}
}