1531 lines
41 KiB
C++
1531 lines
41 KiB
C++
#include "stdafx.h"
|
|
#include "ComponentsWindow.h"
|
|
|
|
using namespace wi::graphics;
|
|
using namespace wi::ecs;
|
|
using namespace wi::scene;
|
|
|
|
void ComponentsWindow::Create(EditorComponent* _editor)
|
|
{
|
|
editor = _editor;
|
|
|
|
wi::gui::Window::Create("Components ", wi::gui::Window::WindowControls::RESIZE_LEFT | wi::gui::Window::WindowControls::DISABLE_TITLE_BAR);
|
|
SetText("Entity - Component System");
|
|
font.params.h_align = wi::font::WIFALIGN_RIGHT;
|
|
SetShadowRadius(2);
|
|
|
|
filterCombo.Create("");
|
|
filterCombo.SetShadowRadius(0);
|
|
filterCombo.SetMaxVisibleItemCount(16);
|
|
filterCombo.SetDropArrowEnabled(false);
|
|
filterCombo.SetFixedDropWidth(40);
|
|
filterCombo.AddItem("*", (uint64_t)Filter::All);
|
|
filterCombo.AddItem(ICON_TRANSFORM, (uint64_t)Filter::Transform);
|
|
filterCombo.AddItem(ICON_MATERIAL, (uint64_t)Filter::Material);
|
|
filterCombo.AddItem(ICON_MESH, (uint64_t)Filter::Mesh);
|
|
filterCombo.AddItem(ICON_OBJECT, (uint64_t)Filter::Object);
|
|
filterCombo.AddItem(ICON_ENVIRONMENTPROBE, (uint64_t)Filter::EnvironmentProbe);
|
|
filterCombo.AddItem(ICON_DECAL, (uint64_t)Filter::Decal);
|
|
filterCombo.AddItem(ICON_SOUND, (uint64_t)Filter::Sound);
|
|
filterCombo.AddItem(ICON_VIDEO, (uint64_t)Filter::Video);
|
|
filterCombo.AddItem(ICON_WEATHER, (uint64_t)Filter::Weather);
|
|
filterCombo.AddItem(ICON_POINTLIGHT, (uint64_t)Filter::Light);
|
|
filterCombo.AddItem(ICON_ANIMATION, (uint64_t)Filter::Animation);
|
|
filterCombo.AddItem(ICON_FORCE, (uint64_t)Filter::Force);
|
|
filterCombo.AddItem(ICON_EMITTER, (uint64_t)Filter::Emitter);
|
|
filterCombo.AddItem(ICON_HAIR, (uint64_t)Filter::Hairparticle);
|
|
filterCombo.AddItem(ICON_IK, (uint64_t)Filter::IK);
|
|
filterCombo.AddItem(ICON_CAMERA, (uint64_t)Filter::Camera);
|
|
filterCombo.AddItem(ICON_ARMATURE, (uint64_t)Filter::Armature);
|
|
filterCombo.AddItem(ICON_SPRING, (uint64_t)Filter::Spring);
|
|
filterCombo.AddItem(ICON_COLLIDER, (uint64_t)Filter::Collider);
|
|
filterCombo.AddItem(ICON_SCRIPT, (uint64_t)Filter::Script);
|
|
filterCombo.AddItem(ICON_EXPRESSION, (uint64_t)Filter::Expression);
|
|
filterCombo.AddItem(ICON_HUMANOID, (uint64_t)Filter::Humanoid);
|
|
filterCombo.AddItem(ICON_TERRAIN, (uint64_t)Filter::Terrain);
|
|
filterCombo.AddItem(ICON_SPRITE, (uint64_t)Filter::Sprite);
|
|
filterCombo.AddItem(ICON_FONT, (uint64_t)Filter::Font);
|
|
filterCombo.AddItem(ICON_VOXELGRID, (uint64_t)Filter::VoxelGrid);
|
|
filterCombo.AddItem(ICON_RIGIDBODY, (uint64_t)Filter::RigidBody);
|
|
filterCombo.AddItem(ICON_SOFTBODY, (uint64_t)Filter::SoftBody);
|
|
filterCombo.AddItem(ICON_METADATA, (uint64_t)Filter::Metadata);
|
|
filterCombo.AddItem(ICON_VEHICLE, (uint64_t)Filter::Vehicle);
|
|
filterCombo.AddItem(ICON_CONSTRAINT, (uint64_t)Filter::Constraint);
|
|
filterCombo.AddItem(ICON_SPLINE, (uint64_t)Filter::Spline);
|
|
filterCombo.SetTooltip("Apply filtering to the Entities by components");
|
|
filterCombo.SetLocalizationEnabled(wi::gui::LocalizationEnabled::Tooltip);
|
|
filterCombo.OnSelect([this](wi::gui::EventArgs args) {
|
|
filter = (Filter)args.userdata;
|
|
RefreshEntityTree();
|
|
});
|
|
AddWidget(&filterCombo);
|
|
|
|
|
|
filterInput.Create("");
|
|
filterInput.SetShadowRadius(0);
|
|
filterInput.SetTooltip("Search entities by name");
|
|
filterInput.SetDescription(ICON_SEARCH " ");
|
|
filterInput.SetCancelInputEnabled(false);
|
|
filterInput.OnInput([=](wi::gui::EventArgs args) {
|
|
RefreshEntityTree();
|
|
});
|
|
filterInput.SetLocalizationEnabled(wi::gui::LocalizationEnabled::Tooltip);
|
|
AddWidget(&filterInput);
|
|
|
|
filterCaseCheckBox.Create("");
|
|
filterCaseCheckBox.SetShadowRadius(0);
|
|
filterCaseCheckBox.SetCheckText("Aa");
|
|
filterCaseCheckBox.SetUnCheckText("a");
|
|
filterCaseCheckBox.SetTooltip("Toggle case-sensitive name filtering");
|
|
filterCaseCheckBox.SetLocalizationEnabled(wi::gui::LocalizationEnabled::Tooltip);
|
|
filterCaseCheckBox.OnClick([=](wi::gui::EventArgs args) {
|
|
RefreshEntityTree();
|
|
});
|
|
AddWidget(&filterCaseCheckBox);
|
|
|
|
|
|
entityTree.Create("Entities");
|
|
entityTree.SetSize(XMFLOAT2(300, 300));
|
|
entityTree.OnSelect([this](wi::gui::EventArgs args) {
|
|
|
|
if (args.iValue < 0)
|
|
return;
|
|
|
|
wi::Archive& archive = editor->AdvanceHistory(true);
|
|
archive << EditorComponent::HISTORYOP_SELECTION;
|
|
// record PREVIOUS selection state...
|
|
editor->RecordSelection(archive);
|
|
|
|
editor->translator.selected.clear();
|
|
|
|
for (int i = 0; i < entityTree.GetItemCount(); ++i)
|
|
{
|
|
const wi::gui::TreeList::Item& item = entityTree.GetItem(i);
|
|
if (item.selected)
|
|
{
|
|
wi::scene::PickResult pick;
|
|
pick.entity = (Entity)item.userdata;
|
|
editor->AddSelected(pick, false);
|
|
}
|
|
}
|
|
|
|
// record NEW selection state...
|
|
editor->RecordSelection(archive);
|
|
|
|
});
|
|
entityTree.OnDelete([=](wi::gui::EventArgs args) {
|
|
// Deletions will be performed in a batch next frame:
|
|
// We don't delete here, because this callback will execute once for each item
|
|
editor->deleting = true;
|
|
});
|
|
entityTree.OnDoubleClick([this](wi::gui::EventArgs args) {
|
|
editor->FocusCameraOnSelected();
|
|
});
|
|
AddWidget(&entityTree);
|
|
|
|
if (editor->main->config.GetSection("layout").Has("entities.height"))
|
|
{
|
|
float height = editor->main->config.GetSection("layout").GetFloat("entities.height");
|
|
entityTree.SetSize(XMFLOAT2(entityTree.GetSize().x, height));
|
|
}
|
|
|
|
materialWnd.Create(editor);
|
|
weatherWnd.Create(editor);
|
|
objectWnd.Create(editor);
|
|
meshWnd.Create(editor);
|
|
envProbeWnd.Create(editor);
|
|
soundWnd.Create(editor);
|
|
videoWnd.Create(editor);
|
|
decalWnd.Create(editor);
|
|
lightWnd.Create(editor);
|
|
animWnd.Create(editor);
|
|
emitterWnd.Create(editor);
|
|
hairWnd.Create(editor);
|
|
forceFieldWnd.Create(editor);
|
|
springWnd.Create(editor);
|
|
ikWnd.Create(editor);
|
|
transformWnd.Create(editor);
|
|
layerWnd.Create(editor);
|
|
nameWnd.Create(editor);
|
|
scriptWnd.Create(editor);
|
|
rigidWnd.Create(editor);
|
|
softWnd.Create(editor);
|
|
colliderWnd.Create(editor);
|
|
hierarchyWnd.Create(editor);
|
|
cameraComponentWnd.Create(editor);
|
|
expressionWnd.Create(editor);
|
|
armatureWnd.Create(editor);
|
|
humanoidWnd.Create(editor);
|
|
terrainWnd.Create(editor);
|
|
spriteWnd.Create(editor);
|
|
fontWnd.Create(editor);
|
|
voxelGridWnd.Create(editor);
|
|
metadataWnd.Create(editor);
|
|
constraintWnd.Create(editor);
|
|
splineWnd.Create(editor);
|
|
|
|
enum ADD_THING
|
|
{
|
|
ADD_NAME,
|
|
ADD_LAYER,
|
|
ADD_HIERARCHY,
|
|
ADD_TRANSFORM,
|
|
ADD_LIGHT,
|
|
ADD_MATERIAL,
|
|
ADD_MESH,
|
|
ADD_OBJECT,
|
|
ADD_SPRING,
|
|
ADD_IK,
|
|
ADD_SOUND,
|
|
ADD_ENVPROBE,
|
|
ADD_EMITTER,
|
|
ADD_HAIR,
|
|
ADD_DECAL,
|
|
ADD_WEATHER,
|
|
ADD_FORCE,
|
|
ADD_ANIMATION,
|
|
ADD_SCRIPT,
|
|
ADD_RIGIDBODY,
|
|
ADD_SOFTBODY,
|
|
ADD_COLLIDER,
|
|
ADD_CAMERA,
|
|
ADD_VIDEO,
|
|
ADD_SPRITE,
|
|
ADD_FONT,
|
|
ADD_VOXELGRID,
|
|
ADD_METADATA,
|
|
ADD_CONSTRAINT,
|
|
ADD_SPLINE,
|
|
};
|
|
|
|
newComponentCombo.Create("Add component ");
|
|
newComponentCombo.SetDropArrowEnabled(false);
|
|
newComponentCombo.SetAngularHighlightWidth(3);
|
|
newComponentCombo.SetShadowRadius(0);
|
|
newComponentCombo.SetFixedDropWidth(250);
|
|
newComponentCombo.SetTooltip("Add a component to the selected entity.");
|
|
newComponentCombo.SetInvalidSelectionText("+");
|
|
newComponentCombo.AddItem("Name " ICON_NAME, ADD_NAME);
|
|
newComponentCombo.AddItem("Layer " ICON_LAYER, ADD_LAYER);
|
|
newComponentCombo.AddItem("Hierarchy " ICON_HIERARCHY, ADD_HIERARCHY);
|
|
newComponentCombo.AddItem("Transform " ICON_TRANSFORM, ADD_TRANSFORM);
|
|
newComponentCombo.AddItem("Light " ICON_POINTLIGHT, ADD_LIGHT);
|
|
newComponentCombo.AddItem("Material " ICON_MATERIAL, ADD_MATERIAL);
|
|
newComponentCombo.AddItem("Mesh " ICON_MESH, ADD_MESH);
|
|
newComponentCombo.AddItem("Object " ICON_OBJECT, ADD_OBJECT);
|
|
newComponentCombo.AddItem("Spring " ICON_SPRING, ADD_SPRING);
|
|
newComponentCombo.AddItem("Inverse Kinematics " ICON_IK, ADD_IK);
|
|
newComponentCombo.AddItem("Sound " ICON_SOUND, ADD_SOUND);
|
|
newComponentCombo.AddItem("Environment Probe " ICON_ENVIRONMENTPROBE, ADD_ENVPROBE);
|
|
newComponentCombo.AddItem("Emitted Particle System " ICON_EMITTER, ADD_EMITTER);
|
|
newComponentCombo.AddItem("Hair Particle System " ICON_HAIR, ADD_HAIR);
|
|
newComponentCombo.AddItem("Decal " ICON_DECAL, ADD_DECAL);
|
|
newComponentCombo.AddItem("Weather " ICON_WEATHER, ADD_WEATHER);
|
|
newComponentCombo.AddItem("Force Field " ICON_FORCE, ADD_FORCE);
|
|
newComponentCombo.AddItem("Animation " ICON_ANIMATION, ADD_ANIMATION);
|
|
newComponentCombo.AddItem("Script " ICON_SCRIPT, ADD_SCRIPT);
|
|
newComponentCombo.AddItem("Rigid Body Physics " ICON_RIGIDBODY, ADD_RIGIDBODY);
|
|
newComponentCombo.AddItem("Soft Body Physics " ICON_SOFTBODY, ADD_SOFTBODY);
|
|
newComponentCombo.AddItem("Collider " ICON_COLLIDER, ADD_COLLIDER);
|
|
newComponentCombo.AddItem("Camera " ICON_CAMERA, ADD_CAMERA);
|
|
newComponentCombo.AddItem("Video " ICON_VIDEO, ADD_VIDEO);
|
|
newComponentCombo.AddItem("Sprite " ICON_SPRITE, ADD_SPRITE);
|
|
newComponentCombo.AddItem("Font " ICON_FONT, ADD_FONT);
|
|
newComponentCombo.AddItem("Voxel Grid " ICON_VOXELGRID, ADD_VOXELGRID);
|
|
newComponentCombo.AddItem("Metadata " ICON_METADATA, ADD_METADATA);
|
|
newComponentCombo.AddItem("Constraint " ICON_CONSTRAINT, ADD_CONSTRAINT);
|
|
newComponentCombo.AddItem("Spline " ICON_SPLINE, ADD_SPLINE);
|
|
newComponentCombo.OnSelect([=](wi::gui::EventArgs args) {
|
|
newComponentCombo.SetSelectedWithoutCallback(-1);
|
|
wi::scene::Scene& scene = editor->GetCurrentScene();
|
|
wi::vector<Entity> entities;
|
|
for (auto& x : editor->translator.selected)
|
|
{
|
|
Entity entity = x.entity;
|
|
if (args.userdata == ADD_SOFTBODY)
|
|
{
|
|
// explanation: for softbody, we want to create it for the MeshComponent, if it's also selected together with the object:
|
|
ObjectComponent* object = scene.objects.GetComponent(entity);
|
|
if (object != nullptr)
|
|
{
|
|
entity = object->meshID;
|
|
}
|
|
}
|
|
if (entity == INVALID_ENTITY)
|
|
continue;
|
|
|
|
// Can early exit before creating history entry!
|
|
bool valid = true;
|
|
switch (args.userdata)
|
|
{
|
|
case ADD_NAME:
|
|
if (scene.names.Contains(entity))
|
|
valid = false;
|
|
break;
|
|
case ADD_LAYER:
|
|
if (scene.layers.Contains(entity))
|
|
valid = false;
|
|
break;
|
|
case ADD_TRANSFORM:
|
|
if (scene.transforms.Contains(entity))
|
|
valid = false;
|
|
break;
|
|
case ADD_LIGHT:
|
|
if (scene.lights.Contains(entity))
|
|
valid = false;
|
|
break;
|
|
case ADD_MATERIAL:
|
|
if (scene.materials.Contains(entity))
|
|
valid = false;
|
|
break;
|
|
case ADD_MESH:
|
|
if (scene.meshes.Contains(entity))
|
|
valid = false;
|
|
break;
|
|
case ADD_SPRING:
|
|
if (scene.springs.Contains(entity))
|
|
valid = false;
|
|
break;
|
|
case ADD_IK:
|
|
if (scene.inverse_kinematics.Contains(entity))
|
|
valid = false;
|
|
break;
|
|
case ADD_SOUND:
|
|
if (scene.sounds.Contains(entity))
|
|
valid = false;
|
|
break;
|
|
case ADD_ENVPROBE:
|
|
if (scene.probes.Contains(entity))
|
|
valid = false;
|
|
break;
|
|
case ADD_EMITTER:
|
|
if (scene.emitters.Contains(entity))
|
|
valid = false;
|
|
break;
|
|
case ADD_HAIR:
|
|
if (scene.hairs.Contains(entity))
|
|
valid = false;
|
|
break;
|
|
case ADD_DECAL:
|
|
if (scene.decals.Contains(entity))
|
|
valid = false;
|
|
break;
|
|
case ADD_WEATHER:
|
|
if (scene.weathers.Contains(entity))
|
|
valid = false;
|
|
break;
|
|
case ADD_FORCE:
|
|
if (scene.forces.Contains(entity))
|
|
valid = false;
|
|
break;
|
|
case ADD_ANIMATION:
|
|
if (scene.animations.Contains(entity))
|
|
valid = false;
|
|
break;
|
|
case ADD_SCRIPT:
|
|
if (scene.scripts.Contains(entity))
|
|
valid = false;
|
|
break;
|
|
case ADD_RIGIDBODY:
|
|
if (scene.rigidbodies.Contains(entity))
|
|
valid = false;
|
|
break;
|
|
case ADD_SOFTBODY:
|
|
if (scene.softbodies.Contains(entity))
|
|
valid = false;
|
|
break;
|
|
case ADD_COLLIDER:
|
|
if (scene.colliders.Contains(entity))
|
|
valid = false;
|
|
break;
|
|
case ADD_HIERARCHY:
|
|
if (scene.hierarchy.Contains(entity))
|
|
valid = false;
|
|
break;
|
|
case ADD_CAMERA:
|
|
if (scene.cameras.Contains(entity))
|
|
valid = false;
|
|
break;
|
|
case ADD_OBJECT:
|
|
if (scene.objects.Contains(entity))
|
|
valid = false;
|
|
break;
|
|
case ADD_VIDEO:
|
|
if (scene.videos.Contains(entity))
|
|
valid = false;
|
|
break;
|
|
case ADD_SPRITE:
|
|
if (scene.sprites.Contains(entity))
|
|
valid = false;
|
|
break;
|
|
case ADD_FONT:
|
|
if (scene.fonts.Contains(entity))
|
|
valid = false;
|
|
break;
|
|
case ADD_VOXELGRID:
|
|
if (scene.voxel_grids.Contains(entity))
|
|
valid = false;
|
|
break;
|
|
case ADD_METADATA:
|
|
if (scene.metadatas.Contains(entity))
|
|
valid = false;
|
|
break;
|
|
case ADD_CONSTRAINT:
|
|
if (scene.constraints.Contains(entity))
|
|
valid = false;
|
|
break;
|
|
case ADD_SPLINE:
|
|
if (scene.splines.Contains(entity))
|
|
valid = false;
|
|
break;
|
|
default:
|
|
valid = false;
|
|
break;
|
|
}
|
|
|
|
if (valid)
|
|
{
|
|
entities.push_back(entity);
|
|
}
|
|
}
|
|
|
|
wi::Archive& archive = editor->AdvanceHistory();
|
|
archive << EditorComponent::HISTORYOP_COMPONENT_DATA;
|
|
editor->RecordEntity(archive, entities);
|
|
|
|
for (Entity entity : entities)
|
|
{
|
|
switch (args.userdata)
|
|
{
|
|
case ADD_NAME:
|
|
scene.names.Create(entity);
|
|
break;
|
|
case ADD_LAYER:
|
|
scene.layers.Create(entity);
|
|
break;
|
|
case ADD_TRANSFORM:
|
|
scene.transforms.Create(entity);
|
|
break;
|
|
case ADD_LIGHT:
|
|
scene.lights.Create(entity);
|
|
break;
|
|
case ADD_MATERIAL:
|
|
scene.materials.Create(entity);
|
|
break;
|
|
case ADD_MESH:
|
|
scene.meshes.Create(entity);
|
|
break;
|
|
case ADD_SPRING:
|
|
scene.springs.Create(entity);
|
|
break;
|
|
case ADD_IK:
|
|
scene.inverse_kinematics.Create(entity);
|
|
break;
|
|
case ADD_SOUND:
|
|
scene.sounds.Create(entity);
|
|
break;
|
|
case ADD_ENVPROBE:
|
|
scene.probes.Create(entity);
|
|
break;
|
|
case ADD_EMITTER:
|
|
if (!scene.materials.Contains(entity))
|
|
scene.materials.Create(entity);
|
|
scene.emitters.Create(entity);
|
|
break;
|
|
case ADD_HAIR:
|
|
if (!scene.materials.Contains(entity))
|
|
scene.materials.Create(entity);
|
|
scene.hairs.Create(entity);
|
|
break;
|
|
case ADD_DECAL:
|
|
if (!scene.materials.Contains(entity))
|
|
scene.materials.Create(entity);
|
|
scene.decals.Create(entity);
|
|
break;
|
|
case ADD_WEATHER:
|
|
scene.weathers.Create(entity);
|
|
break;
|
|
case ADD_FORCE:
|
|
scene.forces.Create(entity);
|
|
break;
|
|
case ADD_ANIMATION:
|
|
scene.animations.Create(entity);
|
|
break;
|
|
case ADD_SCRIPT:
|
|
scene.scripts.Create(entity);
|
|
break;
|
|
case ADD_RIGIDBODY:
|
|
{
|
|
RigidBodyPhysicsComponent& rigidbody = scene.rigidbodies.Create(entity);
|
|
rigidbody.SetStartDeactivated(true);
|
|
}
|
|
break;
|
|
case ADD_SOFTBODY:
|
|
scene.softbodies.Create(entity);
|
|
break;
|
|
case ADD_COLLIDER:
|
|
scene.colliders.Create(entity);
|
|
break;
|
|
case ADD_HIERARCHY:
|
|
scene.hierarchy.Create(entity);
|
|
break;
|
|
case ADD_CAMERA:
|
|
scene.cameras.Create(entity);
|
|
break;
|
|
case ADD_OBJECT:
|
|
scene.objects.Create(entity);
|
|
break;
|
|
case ADD_VIDEO:
|
|
scene.videos.Create(entity);
|
|
break;
|
|
case ADD_SPRITE:
|
|
scene.sprites.Create(entity);
|
|
break;
|
|
case ADD_FONT:
|
|
scene.fonts.Create(entity);
|
|
break;
|
|
case ADD_VOXELGRID:
|
|
scene.voxel_grids.Create(entity);
|
|
break;
|
|
case ADD_METADATA:
|
|
scene.metadatas.Create(entity);
|
|
break;
|
|
case ADD_CONSTRAINT:
|
|
scene.constraints.Create(entity);
|
|
break;
|
|
case ADD_SPLINE:
|
|
scene.splines.Create(entity);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
editor->RecordEntity(archive, entities);
|
|
|
|
RefreshEntityTree();
|
|
|
|
});
|
|
AddWidget(&newComponentCombo);
|
|
|
|
|
|
AddWidget(&materialWnd);
|
|
AddWidget(&weatherWnd);
|
|
AddWidget(&objectWnd);
|
|
AddWidget(&meshWnd);
|
|
AddWidget(&envProbeWnd);
|
|
AddWidget(&soundWnd);
|
|
AddWidget(&videoWnd);
|
|
AddWidget(&decalWnd);
|
|
AddWidget(&lightWnd);
|
|
AddWidget(&animWnd);
|
|
AddWidget(&emitterWnd);
|
|
AddWidget(&hairWnd);
|
|
AddWidget(&forceFieldWnd);
|
|
AddWidget(&springWnd);
|
|
AddWidget(&ikWnd);
|
|
AddWidget(&transformWnd);
|
|
AddWidget(&layerWnd);
|
|
AddWidget(&nameWnd);
|
|
AddWidget(&scriptWnd);
|
|
AddWidget(&rigidWnd);
|
|
AddWidget(&softWnd);
|
|
AddWidget(&colliderWnd);
|
|
AddWidget(&hierarchyWnd);
|
|
AddWidget(&cameraComponentWnd);
|
|
AddWidget(&expressionWnd);
|
|
AddWidget(&armatureWnd);
|
|
AddWidget(&humanoidWnd);
|
|
AddWidget(&terrainWnd);
|
|
AddWidget(&spriteWnd);
|
|
AddWidget(&fontWnd);
|
|
AddWidget(&voxelGridWnd);
|
|
AddWidget(&metadataWnd);
|
|
AddWidget(&constraintWnd);
|
|
AddWidget(&splineWnd);
|
|
|
|
materialWnd.SetVisible(false);
|
|
weatherWnd.SetVisible(false);
|
|
objectWnd.SetVisible(false);
|
|
meshWnd.SetVisible(false);
|
|
envProbeWnd.SetVisible(false);
|
|
soundWnd.SetVisible(false);
|
|
videoWnd.SetVisible(false);
|
|
decalWnd.SetVisible(false);
|
|
lightWnd.SetVisible(false);
|
|
animWnd.SetVisible(false);
|
|
emitterWnd.SetVisible(false);
|
|
hairWnd.SetVisible(false);
|
|
forceFieldWnd.SetVisible(false);
|
|
springWnd.SetVisible(false);
|
|
ikWnd.SetVisible(false);
|
|
transformWnd.SetVisible(false);
|
|
layerWnd.SetVisible(false);
|
|
nameWnd.SetVisible(false);
|
|
scriptWnd.SetVisible(false);
|
|
rigidWnd.SetVisible(false);
|
|
softWnd.SetVisible(false);
|
|
colliderWnd.SetVisible(false);
|
|
hierarchyWnd.SetVisible(false);
|
|
cameraComponentWnd.SetVisible(false);
|
|
expressionWnd.SetVisible(false);
|
|
armatureWnd.SetVisible(false);
|
|
humanoidWnd.SetVisible(false);
|
|
terrainWnd.SetVisible(false);
|
|
spriteWnd.SetVisible(false);
|
|
fontWnd.SetVisible(false);
|
|
voxelGridWnd.SetVisible(false);
|
|
metadataWnd.SetVisible(false);
|
|
constraintWnd.SetVisible(false);
|
|
splineWnd.SetVisible(false);
|
|
|
|
XMFLOAT2 size = XMFLOAT2(338, 500);
|
|
if (editor->main->config.GetSection("layout").Has("components.width"))
|
|
{
|
|
size.x = editor->main->config.GetSection("layout").GetFloat("components.width");
|
|
}
|
|
if (editor->main->config.GetSection("layout").Has("components.height"))
|
|
{
|
|
size.y = editor->main->config.GetSection("layout").GetFloat("components.height");
|
|
}
|
|
SetSize(size);
|
|
}
|
|
void ComponentsWindow::UpdateData(float dt)
|
|
{
|
|
animWnd.UpdateData();
|
|
weatherWnd.UpdateData();
|
|
}
|
|
|
|
void ComponentsWindow::ResizeLayout()
|
|
{
|
|
wi::gui::Window::ResizeLayout();
|
|
const wi::scene::Scene& scene = editor->GetCurrentScene();
|
|
float padding = 2;
|
|
XMFLOAT2 pos = XMFLOAT2(padding, 0);
|
|
const float width = GetWidgetAreaSize().x;
|
|
const float height = GetWidgetAreaSize().y;
|
|
editor->main->config.GetSection("layout").Set("components.width", GetSize().x);
|
|
editor->main->config.GetSection("layout").Set("components.height", GetSize().y);
|
|
editor->main->config.GetSection("layout").Set("entities.height", entityTree.GetSize().y);
|
|
|
|
// Entities:
|
|
{
|
|
float x_off = 25;
|
|
float filterHeight = filterCombo.GetSize().y;
|
|
float filterComboWidth = 28;
|
|
|
|
filterInput.SetPos(XMFLOAT2(pos.x + x_off, pos.y));
|
|
filterInput.SetSize(XMFLOAT2(width - x_off - filterHeight - 3 - filterComboWidth, filterCombo.GetScale().y));
|
|
|
|
filterCaseCheckBox.SetPos(XMFLOAT2(filterInput.GetPos().x + filterInput.GetSize().x + 1, pos.y));
|
|
filterCaseCheckBox.SetSize(XMFLOAT2(filterHeight, filterHeight));
|
|
|
|
filterCombo.SetPos(XMFLOAT2(filterCaseCheckBox.GetPos().x + filterCaseCheckBox.GetSize().x + 1, pos.y));
|
|
filterCombo.SetSize(XMFLOAT2(filterComboWidth, filterHeight));
|
|
pos.y += filterCombo.GetSize().y;
|
|
pos.y += padding;
|
|
|
|
pos.x = 0;
|
|
entityTree.SetPos(pos);
|
|
entityTree.SetSize(XMFLOAT2(width, wi::math::Clamp(entityTree.GetSize().y, 0, height - pos.y - 50)));
|
|
pos.y += entityTree.GetSize().y;
|
|
pos.y += padding * 4;
|
|
}
|
|
|
|
if (!editor->translator.selected.empty())
|
|
{
|
|
newComponentCombo.SetVisible(true);
|
|
newComponentCombo.SetSize(XMFLOAT2(20, 20));
|
|
newComponentCombo.SetPos(XMFLOAT2(pos.x + width - 30, pos.y));
|
|
pos.y += newComponentCombo.GetSize().y;
|
|
pos.y += padding * 4;
|
|
}
|
|
else
|
|
{
|
|
newComponentCombo.SetVisible(false);
|
|
}
|
|
|
|
padding = 1;
|
|
|
|
if (scene.names.Contains(nameWnd.entity))
|
|
{
|
|
nameWnd.SetVisible(true);
|
|
nameWnd.SetPos(pos);
|
|
nameWnd.SetSize(XMFLOAT2(width, nameWnd.GetScale().y));
|
|
pos.y += nameWnd.GetSize().y;
|
|
pos.y += padding;
|
|
}
|
|
else
|
|
{
|
|
nameWnd.SetVisible(false);
|
|
}
|
|
|
|
if (scene.hierarchy.Contains(hierarchyWnd.entity))
|
|
{
|
|
hierarchyWnd.SetVisible(true);
|
|
hierarchyWnd.SetPos(pos);
|
|
hierarchyWnd.SetSize(XMFLOAT2(width, hierarchyWnd.GetScale().y));
|
|
pos.y += hierarchyWnd.GetSize().y;
|
|
pos.y += padding;
|
|
}
|
|
else
|
|
{
|
|
hierarchyWnd.SetVisible(false);
|
|
}
|
|
|
|
if (scene.layers.Contains(layerWnd.entity))
|
|
{
|
|
layerWnd.SetVisible(true);
|
|
layerWnd.SetPos(pos);
|
|
layerWnd.SetSize(XMFLOAT2(width, layerWnd.GetScale().y));
|
|
pos.y += layerWnd.GetSize().y;
|
|
pos.y += padding;
|
|
}
|
|
else
|
|
{
|
|
layerWnd.SetVisible(false);
|
|
}
|
|
|
|
if (scene.transforms.Contains(transformWnd.entity))
|
|
{
|
|
transformWnd.SetVisible(true);
|
|
transformWnd.SetPos(pos);
|
|
transformWnd.SetSize(XMFLOAT2(width, transformWnd.GetScale().y));
|
|
pos.y += transformWnd.GetSize().y;
|
|
pos.y += padding;
|
|
}
|
|
else
|
|
{
|
|
transformWnd.SetVisible(false);
|
|
}
|
|
|
|
if (scene.inverse_kinematics.Contains(ikWnd.entity))
|
|
{
|
|
ikWnd.SetVisible(true);
|
|
ikWnd.SetPos(pos);
|
|
ikWnd.SetSize(XMFLOAT2(width, ikWnd.GetScale().y));
|
|
pos.y += ikWnd.GetSize().y;
|
|
pos.y += padding;
|
|
}
|
|
else
|
|
{
|
|
ikWnd.SetVisible(false);
|
|
}
|
|
|
|
if (scene.springs.Contains(springWnd.entity))
|
|
{
|
|
springWnd.SetVisible(true);
|
|
springWnd.SetPos(pos);
|
|
springWnd.SetSize(XMFLOAT2(width, springWnd.GetScale().y));
|
|
pos.y += springWnd.GetSize().y;
|
|
pos.y += padding;
|
|
}
|
|
else
|
|
{
|
|
springWnd.SetVisible(false);
|
|
}
|
|
|
|
if (scene.forces.Contains(forceFieldWnd.entity))
|
|
{
|
|
forceFieldWnd.SetVisible(true);
|
|
forceFieldWnd.SetPos(pos);
|
|
forceFieldWnd.SetSize(XMFLOAT2(width, forceFieldWnd.GetScale().y));
|
|
pos.y += forceFieldWnd.GetSize().y;
|
|
pos.y += padding;
|
|
}
|
|
else
|
|
{
|
|
forceFieldWnd.SetVisible(false);
|
|
}
|
|
|
|
if (scene.hairs.Contains(hairWnd.entity))
|
|
{
|
|
hairWnd.SetVisible(true);
|
|
hairWnd.SetPos(pos);
|
|
hairWnd.SetSize(XMFLOAT2(width, hairWnd.GetScale().y));
|
|
pos.y += hairWnd.GetSize().y;
|
|
pos.y += padding;
|
|
}
|
|
else
|
|
{
|
|
hairWnd.SetVisible(false);
|
|
}
|
|
|
|
if (scene.emitters.Contains(emitterWnd.entity))
|
|
{
|
|
emitterWnd.SetVisible(true);
|
|
emitterWnd.SetPos(pos);
|
|
emitterWnd.SetSize(XMFLOAT2(width, emitterWnd.GetScale().y));
|
|
pos.y += emitterWnd.GetSize().y;
|
|
pos.y += padding;
|
|
}
|
|
else
|
|
{
|
|
emitterWnd.SetVisible(false);
|
|
}
|
|
|
|
if (scene.animations.Contains(animWnd.entity))
|
|
{
|
|
animWnd.SetVisible(true);
|
|
animWnd.SetPos(pos);
|
|
animWnd.SetSize(XMFLOAT2(width, animWnd.GetScale().y));
|
|
pos.y += animWnd.GetSize().y;
|
|
pos.y += padding;
|
|
}
|
|
else
|
|
{
|
|
animWnd.SetVisible(false);
|
|
}
|
|
|
|
if (scene.lights.Contains(lightWnd.entity))
|
|
{
|
|
lightWnd.SetVisible(true);
|
|
lightWnd.SetPos(pos);
|
|
lightWnd.SetSize(XMFLOAT2(width, lightWnd.GetScale().y));
|
|
pos.y += lightWnd.GetSize().y;
|
|
pos.y += padding;
|
|
}
|
|
else
|
|
{
|
|
lightWnd.SetVisible(false);
|
|
}
|
|
|
|
if (scene.sounds.Contains(soundWnd.entity))
|
|
{
|
|
soundWnd.SetVisible(true);
|
|
soundWnd.SetPos(pos);
|
|
soundWnd.SetSize(XMFLOAT2(width, soundWnd.GetScale().y));
|
|
pos.y += soundWnd.GetSize().y;
|
|
pos.y += padding;
|
|
}
|
|
else
|
|
{
|
|
soundWnd.SetVisible(false);
|
|
}
|
|
|
|
if (scene.videos.Contains(videoWnd.entity))
|
|
{
|
|
videoWnd.SetVisible(true);
|
|
videoWnd.SetPos(pos);
|
|
videoWnd.SetSize(XMFLOAT2(width, videoWnd.GetScale().y));
|
|
pos.y += videoWnd.GetSize().y;
|
|
pos.y += padding;
|
|
}
|
|
else
|
|
{
|
|
videoWnd.SetVisible(false);
|
|
}
|
|
|
|
if (scene.decals.Contains(decalWnd.entity))
|
|
{
|
|
decalWnd.SetVisible(true);
|
|
decalWnd.SetPos(pos);
|
|
decalWnd.SetSize(XMFLOAT2(width, decalWnd.GetScale().y));
|
|
pos.y += decalWnd.GetSize().y;
|
|
pos.y += padding;
|
|
}
|
|
else
|
|
{
|
|
decalWnd.SetVisible(false);
|
|
}
|
|
|
|
if (scene.probes.Contains(envProbeWnd.entity))
|
|
{
|
|
envProbeWnd.SetVisible(true);
|
|
envProbeWnd.SetPos(pos);
|
|
envProbeWnd.SetSize(XMFLOAT2(width, envProbeWnd.GetScale().y));
|
|
pos.y += envProbeWnd.GetSize().y;
|
|
pos.y += padding;
|
|
}
|
|
else
|
|
{
|
|
envProbeWnd.SetVisible(false);
|
|
}
|
|
|
|
//if (scene.cameras.Contains(cameraWnd.entity))
|
|
//{
|
|
// cameraWnd.SetVisible(true);
|
|
// cameraWnd.SetPos(pos);
|
|
// cameraWnd.SetSize(XMFLOAT2(width, cameraWnd.GetScale().y));
|
|
// pos.y += cameraWnd.GetSize().y;
|
|
// pos.y += padding;
|
|
//}
|
|
//else
|
|
//{
|
|
// cameraWnd.SetVisible(false);
|
|
//}
|
|
|
|
if (scene.materials.Contains(materialWnd.entity))
|
|
{
|
|
materialWnd.SetVisible(true);
|
|
materialWnd.SetPos(pos);
|
|
materialWnd.SetSize(XMFLOAT2(width, materialWnd.GetScale().y));
|
|
pos.y += materialWnd.GetSize().y;
|
|
pos.y += padding;
|
|
}
|
|
else
|
|
{
|
|
materialWnd.SetVisible(false);
|
|
}
|
|
|
|
if (scene.meshes.Contains(meshWnd.entity))
|
|
{
|
|
meshWnd.SetVisible(true);
|
|
meshWnd.SetPos(pos);
|
|
meshWnd.SetSize(XMFLOAT2(width, meshWnd.GetScale().y));
|
|
pos.y += meshWnd.GetSize().y;
|
|
pos.y += padding;
|
|
}
|
|
else
|
|
{
|
|
meshWnd.SetVisible(false);
|
|
}
|
|
|
|
if (scene.softbodies.Contains(softWnd.entity))
|
|
{
|
|
softWnd.SetVisible(true);
|
|
softWnd.SetPos(pos);
|
|
softWnd.SetSize(XMFLOAT2(width, softWnd.GetScale().y));
|
|
pos.y += softWnd.GetSize().y;
|
|
pos.y += padding;
|
|
}
|
|
else
|
|
{
|
|
softWnd.SetVisible(false);
|
|
}
|
|
|
|
if (scene.objects.Contains(objectWnd.entity))
|
|
{
|
|
objectWnd.SetVisible(true);
|
|
objectWnd.SetPos(pos);
|
|
objectWnd.SetSize(XMFLOAT2(width, objectWnd.GetScale().y));
|
|
pos.y += objectWnd.GetSize().y;
|
|
pos.y += padding;
|
|
}
|
|
else
|
|
{
|
|
objectWnd.SetVisible(false);
|
|
}
|
|
|
|
if (scene.rigidbodies.Contains(rigidWnd.entity))
|
|
{
|
|
rigidWnd.SetVisible(true);
|
|
rigidWnd.SetPos(pos);
|
|
rigidWnd.SetSize(XMFLOAT2(width, rigidWnd.GetScale().y));
|
|
pos.y += rigidWnd.GetSize().y;
|
|
pos.y += padding;
|
|
}
|
|
else
|
|
{
|
|
rigidWnd.SetVisible(false);
|
|
}
|
|
|
|
if (scene.constraints.Contains(constraintWnd.entity))
|
|
{
|
|
constraintWnd.SetVisible(true);
|
|
constraintWnd.SetPos(pos);
|
|
constraintWnd.SetSize(XMFLOAT2(width, constraintWnd.GetScale().y));
|
|
pos.y += constraintWnd.GetSize().y;
|
|
pos.y += padding;
|
|
}
|
|
else
|
|
{
|
|
constraintWnd.SetVisible(false);
|
|
}
|
|
|
|
if (scene.splines.Contains(splineWnd.entity))
|
|
{
|
|
splineWnd.SetVisible(true);
|
|
splineWnd.SetPos(pos);
|
|
splineWnd.SetSize(XMFLOAT2(width, splineWnd.GetScale().y));
|
|
pos.y += splineWnd.GetSize().y;
|
|
pos.y += padding;
|
|
}
|
|
else
|
|
{
|
|
splineWnd.SetVisible(false);
|
|
}
|
|
|
|
if (scene.weathers.Contains(weatherWnd.entity))
|
|
{
|
|
weatherWnd.SetVisible(true);
|
|
weatherWnd.SetPos(pos);
|
|
weatherWnd.SetSize(XMFLOAT2(width, weatherWnd.GetScale().y));
|
|
pos.y += weatherWnd.GetSize().y;
|
|
pos.y += padding;
|
|
}
|
|
else
|
|
{
|
|
weatherWnd.SetVisible(false);
|
|
}
|
|
|
|
if (scene.colliders.Contains(colliderWnd.entity))
|
|
{
|
|
colliderWnd.SetVisible(true);
|
|
colliderWnd.SetPos(pos);
|
|
colliderWnd.SetSize(XMFLOAT2(width, colliderWnd.GetScale().y));
|
|
pos.y += colliderWnd.GetSize().y;
|
|
pos.y += padding;
|
|
}
|
|
else
|
|
{
|
|
colliderWnd.SetVisible(false);
|
|
}
|
|
|
|
if (scene.cameras.Contains(cameraComponentWnd.entity))
|
|
{
|
|
cameraComponentWnd.SetVisible(true);
|
|
cameraComponentWnd.SetPos(pos);
|
|
cameraComponentWnd.SetSize(XMFLOAT2(width, cameraComponentWnd.GetScale().y));
|
|
pos.y += cameraComponentWnd.GetSize().y;
|
|
pos.y += padding;
|
|
}
|
|
else
|
|
{
|
|
cameraComponentWnd.SetVisible(false);
|
|
}
|
|
|
|
if (scene.scripts.Contains(scriptWnd.entity))
|
|
{
|
|
scriptWnd.SetVisible(true);
|
|
scriptWnd.SetPos(pos);
|
|
scriptWnd.SetSize(XMFLOAT2(width, scriptWnd.GetScale().y));
|
|
pos.y += scriptWnd.GetSize().y;
|
|
pos.y += padding;
|
|
}
|
|
else
|
|
{
|
|
scriptWnd.SetVisible(false);
|
|
}
|
|
|
|
if (scene.armatures.Contains(armatureWnd.entity))
|
|
{
|
|
armatureWnd.SetVisible(true);
|
|
armatureWnd.SetPos(pos);
|
|
armatureWnd.SetSize(XMFLOAT2(width, armatureWnd.GetScale().y));
|
|
pos.y += armatureWnd.GetSize().y;
|
|
pos.y += padding;
|
|
}
|
|
else
|
|
{
|
|
armatureWnd.SetVisible(false);
|
|
}
|
|
|
|
if (scene.humanoids.Contains(humanoidWnd.entity))
|
|
{
|
|
humanoidWnd.SetVisible(true);
|
|
humanoidWnd.SetPos(pos);
|
|
humanoidWnd.SetSize(XMFLOAT2(width, humanoidWnd.GetScale().y));
|
|
pos.y += humanoidWnd.GetSize().y;
|
|
pos.y += padding;
|
|
}
|
|
else
|
|
{
|
|
humanoidWnd.SetVisible(false);
|
|
}
|
|
|
|
if (scene.expressions.Contains(expressionWnd.entity))
|
|
{
|
|
expressionWnd.SetVisible(true);
|
|
expressionWnd.SetPos(pos);
|
|
expressionWnd.SetSize(XMFLOAT2(width, expressionWnd.GetScale().y));
|
|
pos.y += expressionWnd.GetSize().y;
|
|
pos.y += padding;
|
|
}
|
|
else
|
|
{
|
|
expressionWnd.SetVisible(false);
|
|
}
|
|
|
|
if (scene.terrains.Contains(terrainWnd.entity))
|
|
{
|
|
terrainWnd.SetVisible(true);
|
|
terrainWnd.SetPos(pos);
|
|
terrainWnd.SetSize(XMFLOAT2(width, terrainWnd.GetScale().y));
|
|
pos.y += terrainWnd.GetSize().y;
|
|
pos.y += padding;
|
|
}
|
|
else
|
|
{
|
|
terrainWnd.SetVisible(false);
|
|
}
|
|
|
|
if (scene.sprites.Contains(spriteWnd.entity))
|
|
{
|
|
spriteWnd.SetVisible(true);
|
|
spriteWnd.SetPos(pos);
|
|
spriteWnd.SetSize(XMFLOAT2(width, spriteWnd.GetScale().y));
|
|
pos.y += spriteWnd.GetSize().y;
|
|
pos.y += padding;
|
|
}
|
|
else
|
|
{
|
|
spriteWnd.SetVisible(false);
|
|
}
|
|
|
|
if (scene.fonts.Contains(fontWnd.entity))
|
|
{
|
|
fontWnd.SetVisible(true);
|
|
fontWnd.SetPos(pos);
|
|
fontWnd.SetSize(XMFLOAT2(width, fontWnd.GetScale().y));
|
|
pos.y += fontWnd.GetSize().y;
|
|
pos.y += padding;
|
|
}
|
|
else
|
|
{
|
|
fontWnd.SetVisible(false);
|
|
}
|
|
|
|
if (scene.voxel_grids.Contains(voxelGridWnd.entity))
|
|
{
|
|
voxelGridWnd.SetVisible(true);
|
|
voxelGridWnd.SetPos(pos);
|
|
voxelGridWnd.SetSize(XMFLOAT2(width, voxelGridWnd.GetScale().y));
|
|
pos.y += voxelGridWnd.GetSize().y;
|
|
pos.y += padding;
|
|
}
|
|
else
|
|
{
|
|
voxelGridWnd.SetVisible(false);
|
|
}
|
|
|
|
if (scene.metadatas.Contains(metadataWnd.entity))
|
|
{
|
|
metadataWnd.SetVisible(true);
|
|
metadataWnd.SetPos(pos);
|
|
metadataWnd.SetSize(XMFLOAT2(width, metadataWnd.GetScale().y));
|
|
pos.y += metadataWnd.GetSize().y;
|
|
pos.y += padding;
|
|
}
|
|
else
|
|
{
|
|
metadataWnd.SetVisible(false);
|
|
}
|
|
}
|
|
|
|
|
|
void ComponentsWindow::PushToEntityTree(wi::ecs::Entity entity, int level)
|
|
{
|
|
if (entitytree_added_items.count(entity) != 0)
|
|
{
|
|
return;
|
|
}
|
|
const Scene& scene = editor->GetCurrentScene();
|
|
|
|
if (CheckEntityFilter(entity))
|
|
{
|
|
wi::gui::TreeList::Item item;
|
|
if (filter == Filter::All)
|
|
{
|
|
item.level = level;
|
|
}
|
|
else
|
|
{
|
|
item.level = 0;
|
|
}
|
|
item.userdata = entity;
|
|
item.selected = editor->IsSelected(entity);
|
|
item.open = entitytree_opened_items.count(entity) != 0;
|
|
|
|
const NameComponent* name = scene.names.GetComponent(entity);
|
|
|
|
std::string name_string;
|
|
if (name == nullptr)
|
|
{
|
|
name_string = "[no_name] " + std::to_string(entity);
|
|
}
|
|
else if (name->name.empty())
|
|
{
|
|
name_string = "[name_empty] " + std::to_string(entity);
|
|
}
|
|
else
|
|
{
|
|
name_string = name->name;
|
|
}
|
|
|
|
bool filter_valid = true;
|
|
std::string name_filter = filterInput.GetCurrentInputValue();
|
|
if (!name_filter.empty())
|
|
{
|
|
if (filterCaseCheckBox.GetCheck() && name_string.find(name_filter) == std::string::npos)
|
|
{
|
|
filter_valid = false;
|
|
}
|
|
else if (wi::helper::toUpper(name_string).find(wi::helper::toUpper(name_filter)) == std::string::npos)
|
|
{
|
|
filter_valid = false;
|
|
}
|
|
item.level = 0;
|
|
}
|
|
|
|
if (filter_valid)
|
|
{
|
|
// Icons:
|
|
if (scene.layers.Contains(entity))
|
|
{
|
|
item.name += ICON_LAYER " ";
|
|
}
|
|
if (scene.transforms.Contains(entity))
|
|
{
|
|
item.name += ICON_TRANSFORM " ";
|
|
}
|
|
if (scene.terrains.Contains(entity))
|
|
{
|
|
item.name += ICON_TERRAIN " ";
|
|
}
|
|
if (scene.meshes.Contains(entity))
|
|
{
|
|
item.name += ICON_MESH " ";
|
|
}
|
|
if (scene.objects.Contains(entity))
|
|
{
|
|
item.name += ICON_OBJECT " ";
|
|
}
|
|
if (scene.rigidbodies.Contains(entity))
|
|
{
|
|
item.name += ICON_RIGIDBODY " ";
|
|
if (scene.rigidbodies.GetComponent(entity)->IsVehicle())
|
|
{
|
|
item.name += ICON_VEHICLE " ";
|
|
}
|
|
}
|
|
if (scene.softbodies.Contains(entity))
|
|
{
|
|
item.name += ICON_SOFTBODY " ";
|
|
}
|
|
if (scene.emitters.Contains(entity))
|
|
{
|
|
item.name += ICON_EMITTER " ";
|
|
}
|
|
if (scene.hairs.Contains(entity))
|
|
{
|
|
item.name += ICON_HAIR " ";
|
|
}
|
|
if (scene.forces.Contains(entity))
|
|
{
|
|
item.name += ICON_FORCE " ";
|
|
}
|
|
if (scene.sounds.Contains(entity))
|
|
{
|
|
item.name += ICON_SOUND " ";
|
|
}
|
|
if (scene.videos.Contains(entity))
|
|
{
|
|
item.name += ICON_VIDEO " ";
|
|
}
|
|
if (scene.decals.Contains(entity))
|
|
{
|
|
item.name += ICON_DECAL " ";
|
|
}
|
|
if (scene.cameras.Contains(entity))
|
|
{
|
|
item.name += ICON_CAMERA " ";
|
|
}
|
|
if (scene.probes.Contains(entity))
|
|
{
|
|
item.name += ICON_ENVIRONMENTPROBE " ";
|
|
}
|
|
if (scene.animations.Contains(entity))
|
|
{
|
|
item.name += ICON_ANIMATION " ";
|
|
}
|
|
if (scene.animation_datas.Contains(entity))
|
|
{
|
|
item.name += "[animation_data] ";
|
|
}
|
|
if (scene.armatures.Contains(entity))
|
|
{
|
|
item.name += ICON_ARMATURE " ";
|
|
}
|
|
if (scene.humanoids.Contains(entity))
|
|
{
|
|
item.name += ICON_HUMANOID " ";
|
|
}
|
|
if (scene.sprites.Contains(entity))
|
|
{
|
|
item.name += ICON_SPRITE " ";
|
|
}
|
|
if (scene.fonts.Contains(entity))
|
|
{
|
|
item.name += ICON_FONT " ";
|
|
}
|
|
if (scene.voxel_grids.Contains(entity))
|
|
{
|
|
item.name += ICON_VOXELGRID " ";
|
|
}
|
|
if (scene.metadatas.Contains(entity))
|
|
{
|
|
item.name += ICON_METADATA " ";
|
|
}
|
|
if (scene.constraints.Contains(entity))
|
|
{
|
|
item.name += ICON_CONSTRAINT " ";
|
|
}
|
|
if (scene.splines.Contains(entity))
|
|
{
|
|
item.name += ICON_SPLINE " ";
|
|
}
|
|
if (scene.lights.Contains(entity))
|
|
{
|
|
const LightComponent* light = scene.lights.GetComponent(entity);
|
|
switch (light->type)
|
|
{
|
|
default:
|
|
case LightComponent::POINT:
|
|
item.name += ICON_POINTLIGHT " ";
|
|
break;
|
|
case LightComponent::SPOT:
|
|
item.name += ICON_SPOTLIGHT " ";
|
|
break;
|
|
case LightComponent::DIRECTIONAL:
|
|
item.name += ICON_DIRECTIONALLIGHT " ";
|
|
break;
|
|
}
|
|
}
|
|
if (scene.materials.Contains(entity))
|
|
{
|
|
item.name += ICON_MATERIAL " ";
|
|
}
|
|
if (scene.weathers.Contains(entity))
|
|
{
|
|
item.name += ICON_WEATHER " ";
|
|
}
|
|
if (scene.inverse_kinematics.Contains(entity))
|
|
{
|
|
item.name += ICON_IK " ";
|
|
}
|
|
if (scene.springs.Contains(entity))
|
|
{
|
|
item.name += ICON_SPRING " ";
|
|
}
|
|
if (scene.colliders.Contains(entity))
|
|
{
|
|
item.name += ICON_COLLIDER " ";
|
|
}
|
|
if (scene.scripts.Contains(entity))
|
|
{
|
|
item.name += ICON_SCRIPT " ";
|
|
}
|
|
if (scene.expressions.Contains(entity))
|
|
{
|
|
item.name += ICON_EXPRESSION " ";
|
|
}
|
|
bool bone_found = false;
|
|
for (size_t i = 0; i < scene.armatures.GetCount() && !bone_found; ++i)
|
|
{
|
|
const ArmatureComponent& armature = scene.armatures[i];
|
|
for (Entity bone : armature.boneCollection)
|
|
{
|
|
if (entity == bone)
|
|
{
|
|
item.name += ICON_BONE " ";
|
|
bone_found = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
item.name += name_string;
|
|
entityTree.AddItem(item);
|
|
|
|
entitytree_added_items.insert(entity);
|
|
}
|
|
}
|
|
|
|
// Collect children
|
|
wi::vector<Entity> children;
|
|
for (size_t i = 0; i < scene.hierarchy.GetCount(); ++i)
|
|
{
|
|
if (scene.hierarchy[i].parentID == entity)
|
|
{
|
|
children.push_back(scene.hierarchy.GetEntity(i));
|
|
}
|
|
}
|
|
|
|
// Get sorting mode from config and sort children
|
|
const int sortingMode = editor->main->config.GetSection("options").GetInt("entity_tree_sorting");
|
|
SortEntitiesByMode(children, scene, sortingMode);
|
|
|
|
// Add sorted children
|
|
for (Entity child : children)
|
|
{
|
|
PushToEntityTree(child, level + 1);
|
|
}
|
|
}
|
|
void ComponentsWindow::RefreshEntityTree()
|
|
{
|
|
if (editor == nullptr)
|
|
return;
|
|
const Scene& scene = editor->GetCurrentScene();
|
|
editor->materialPickerWnd.RecreateButtons();
|
|
|
|
for (int i = 0; i < entityTree.GetItemCount(); ++i)
|
|
{
|
|
const wi::gui::TreeList::Item& item = entityTree.GetItem(i);
|
|
if (item.open)
|
|
{
|
|
entitytree_opened_items.insert((Entity)item.userdata);
|
|
}
|
|
}
|
|
|
|
entityTree.ClearItems();
|
|
|
|
entitytree_temp_items.clear();
|
|
scene.FindAllEntities(entitytree_temp_items);
|
|
|
|
// Add items to level 0 that are not in hierarchy (not in hierarchy can also mean top level parent):
|
|
// Note that PushToEntityTree will add children recursively, so this is all we need
|
|
wi::vector<Entity> topLevelEntities;
|
|
for (auto& x : entitytree_temp_items)
|
|
{
|
|
const HierarchyComponent* hier = scene.hierarchy.GetComponent(x);
|
|
if (hier == nullptr || hier->parentID == INVALID_ENTITY || entitytree_temp_items.count(hier->parentID) == 0)
|
|
{
|
|
topLevelEntities.push_back(x);
|
|
}
|
|
}
|
|
|
|
// Get sorting mode from config and sort top-level entities
|
|
const int sortingMode = editor->main->config.GetSection("options").GetInt("entity_tree_sorting");
|
|
SortEntitiesByMode(topLevelEntities, scene, sortingMode);
|
|
|
|
// Add sorted top-level entities
|
|
for (const auto& x : topLevelEntities)
|
|
{
|
|
PushToEntityTree(x, 0);
|
|
}
|
|
|
|
entitytree_added_items.clear();
|
|
entitytree_opened_items.clear();
|
|
}
|
|
|
|
// Returns a priority value for an entity based on its component type.
|
|
// Lower values = higher priority (sorted first).
|
|
// Used when sorting entities "By type" - groups similar entity types together.
|
|
// Priority order reflects the typical hierarchical structure:
|
|
// 1. Organizational
|
|
// 2. Geometry & physics
|
|
// 3. Effects & media
|
|
// 4. Animation & data
|
|
// 5. Scene & logic
|
|
int ComponentsWindow::GetEntityTypePriority(const wi::ecs::Entity entity, const wi::scene::Scene& scene)
|
|
{
|
|
if (scene.layers.Contains(entity)) return 0;
|
|
if (scene.transforms.Contains(entity)) return 1;
|
|
if (scene.terrains.Contains(entity)) return 2;
|
|
if (scene.meshes.Contains(entity)) return 3;
|
|
if (scene.objects.Contains(entity)) return 4;
|
|
if (scene.rigidbodies.Contains(entity)) return 5;
|
|
if (scene.softbodies.Contains(entity)) return 6;
|
|
if (scene.colliders.Contains(entity)) return 7;
|
|
if (scene.lights.Contains(entity)) return 8;
|
|
if (scene.weathers.Contains(entity)) return 9;
|
|
if (scene.emitters.Contains(entity)) return 10;
|
|
if (scene.hairs.Contains(entity)) return 11;
|
|
if (scene.forces.Contains(entity)) return 12;
|
|
if (scene.sounds.Contains(entity)) return 13;
|
|
if (scene.videos.Contains(entity)) return 14;
|
|
if (scene.decals.Contains(entity)) return 15;
|
|
if (scene.cameras.Contains(entity)) return 16;
|
|
if (scene.probes.Contains(entity)) return 17;
|
|
if (scene.animations.Contains(entity)) return 18;
|
|
if (scene.armatures.Contains(entity)) return 19;
|
|
if (scene.humanoids.Contains(entity)) return 20;
|
|
if (scene.sprites.Contains(entity)) return 21;
|
|
if (scene.fonts.Contains(entity)) return 22;
|
|
if (scene.voxel_grids.Contains(entity)) return 23;
|
|
if (scene.materials.Contains(entity)) return 24;
|
|
if (scene.inverse_kinematics.Contains(entity)) return 25;
|
|
if (scene.constraints.Contains(entity)) return 26;
|
|
if (scene.springs.Contains(entity)) return 27;
|
|
if (scene.splines.Contains(entity)) return 28;
|
|
if (scene.scripts.Contains(entity)) return 29;
|
|
if (scene.expressions.Contains(entity)) return 30;
|
|
if (scene.metadatas.Contains(entity)) return 31;
|
|
return INT_MAX; // Entities with no specific component (sorted last)
|
|
}
|
|
|
|
std::string ComponentsWindow::GetEntityNameForSorting(const wi::ecs::Entity entity, const wi::scene::Scene& scene)
|
|
{
|
|
const NameComponent* name = scene.names.GetComponent(entity);
|
|
if (name && !name->name.empty())
|
|
{
|
|
return wi::helper::toUpper(name->name);
|
|
}
|
|
return "[unnamed] " + std::to_string(entity);
|
|
}
|
|
|
|
void ComponentsWindow::SortEntitiesByMode(wi::vector<wi::ecs::Entity>& entities, const wi::scene::Scene& scene, const int sortingMode)
|
|
{
|
|
if (sortingMode == 1) // By name
|
|
{
|
|
std::sort(entities.begin(), entities.end(), [&scene](const Entity a, const Entity b) {
|
|
return GetEntityNameForSorting(a, scene) < GetEntityNameForSorting(b, scene);
|
|
});
|
|
}
|
|
else if (sortingMode == 2) // By type
|
|
{
|
|
std::sort(entities.begin(), entities.end(), [&scene](const Entity a, const Entity b) {
|
|
const int priority_a = GetEntityTypePriority(a, scene);
|
|
const int priority_b = GetEntityTypePriority(b, scene);
|
|
|
|
if (priority_a != priority_b)
|
|
{
|
|
return priority_a < priority_b;
|
|
}
|
|
|
|
// Same type, sort by name
|
|
return GetEntityNameForSorting(a, scene) < GetEntityNameForSorting(b, scene);
|
|
});
|
|
}
|
|
// else sortingMode == 0 (Unsorted) - don't sort, keep original order
|
|
}
|
|
|
|
bool ComponentsWindow::CheckEntityFilter(const wi::ecs::Entity entity) const
|
|
{
|
|
if (filter == Filter::All)
|
|
return true;
|
|
|
|
const Scene& scene = editor->GetCurrentScene();
|
|
bool valid = false;
|
|
|
|
if (
|
|
(has_flag(filter, Filter::Transform) && scene.transforms.Contains(entity)) ||
|
|
(has_flag(filter, Filter::Material) && scene.materials.Contains(entity)) ||
|
|
(has_flag(filter, Filter::Mesh) && scene.meshes.Contains(entity)) ||
|
|
(has_flag(filter, Filter::Object) && scene.objects.Contains(entity)) ||
|
|
(has_flag(filter, Filter::EnvironmentProbe) && scene.probes.Contains(entity)) ||
|
|
(has_flag(filter, Filter::Decal) && scene.decals.Contains(entity)) ||
|
|
(has_flag(filter, Filter::Sound) && scene.sounds.Contains(entity)) ||
|
|
(has_flag(filter, Filter::Weather) && scene.weathers.Contains(entity)) ||
|
|
(has_flag(filter, Filter::Light) && scene.lights.Contains(entity)) ||
|
|
(has_flag(filter, Filter::Animation) && scene.animations.Contains(entity)) ||
|
|
(has_flag(filter, Filter::Force) && scene.forces.Contains(entity)) ||
|
|
(has_flag(filter, Filter::Emitter) && scene.emitters.Contains(entity)) ||
|
|
(has_flag(filter, Filter::IK) && scene.inverse_kinematics.Contains(entity)) ||
|
|
(has_flag(filter, Filter::Camera) && scene.cameras.Contains(entity)) ||
|
|
(has_flag(filter, Filter::Armature) && scene.armatures.Contains(entity)) ||
|
|
(has_flag(filter, Filter::Collider) && scene.colliders.Contains(entity)) ||
|
|
(has_flag(filter, Filter::Script) && scene.scripts.Contains(entity)) ||
|
|
(has_flag(filter, Filter::Expression) && scene.expressions.Contains(entity)) ||
|
|
(has_flag(filter, Filter::Terrain) && scene.terrains.Contains(entity)) ||
|
|
(has_flag(filter, Filter::Spring) && scene.springs.Contains(entity)) ||
|
|
(has_flag(filter, Filter::Humanoid) && scene.humanoids.Contains(entity)) ||
|
|
(has_flag(filter, Filter::Video) && scene.videos.Contains(entity)) ||
|
|
(has_flag(filter, Filter::Sprite) && scene.sprites.Contains(entity)) ||
|
|
(has_flag(filter, Filter::Font) && scene.fonts.Contains(entity)) ||
|
|
(has_flag(filter, Filter::VoxelGrid) && scene.voxel_grids.Contains(entity)) ||
|
|
(has_flag(filter, Filter::RigidBody) && scene.rigidbodies.Contains(entity)) ||
|
|
(has_flag(filter, Filter::SoftBody) && scene.softbodies.Contains(entity)) ||
|
|
(has_flag(filter, Filter::Metadata) && scene.metadatas.Contains(entity)) ||
|
|
(has_flag(filter, Filter::Constraint) && scene.constraints.Contains(entity)) ||
|
|
(has_flag(filter, Filter::Spline) && scene.splines.Contains(entity)) ||
|
|
(has_flag(filter, Filter::Vehicle) && (scene.rigidbodies.Contains(entity) && scene.rigidbodies.GetComponent(entity)->IsVehicle()))
|
|
)
|
|
{
|
|
valid = true;
|
|
}
|
|
|
|
return valid;
|
|
}
|