From fe81c80b04bd2e919dfcc6ffb5bc2d903bf63e35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tur=C3=A1nszki=20J=C3=A1nos?= Date: Mon, 22 Aug 2022 23:42:49 +0200 Subject: [PATCH] Softbody and rigidbody windows separated (#526) --- Editor/CMakeLists.txt | 2 + Editor/ComponentsWindow.cpp | 48 ++++ Editor/ComponentsWindow.h | 4 + Editor/Editor.cpp | 7 + Editor/Editor_SOURCE.vcxitems | 4 + Editor/Editor_SOURCE.vcxitems.filters | 4 + Editor/MeshWindow.cpp | 103 ++----- Editor/MeshWindow.h | 4 - Editor/ObjectWindow.cpp | 381 ++----------------------- Editor/ObjectWindow.h | 15 - Editor/RigidBodyWindow.cpp | 393 ++++++++++++++++++++++++++ Editor/RigidBodyWindow.h | 29 ++ Editor/SoftBodyWindow.cpp | 98 +++++++ Editor/SoftBodyWindow.h | 19 ++ WickedEngine/wiPhysics_Bullet.cpp | 2 + WickedEngine/wiScene.cpp | 36 +-- WickedEngine/wiVersion.cpp | 2 +- 17 files changed, 652 insertions(+), 499 deletions(-) create mode 100644 Editor/RigidBodyWindow.cpp create mode 100644 Editor/RigidBodyWindow.h create mode 100644 Editor/SoftBodyWindow.cpp create mode 100644 Editor/SoftBodyWindow.h diff --git a/Editor/CMakeLists.txt b/Editor/CMakeLists.txt index c61040352..b0cb8b14e 100644 --- a/Editor/CMakeLists.txt +++ b/Editor/CMakeLists.txt @@ -29,6 +29,8 @@ set (SOURCE_FILES TransformWindow.cpp Translator.cpp WeatherWindow.cpp + RigidBodyWindow.cpp + SoftBodyWindow.cpp OptionsWindow.cpp ComponentsWindow.cpp TerrainGenerator.cpp diff --git a/Editor/ComponentsWindow.cpp b/Editor/ComponentsWindow.cpp index 31b713014..d332c968b 100644 --- a/Editor/ComponentsWindow.cpp +++ b/Editor/ComponentsWindow.cpp @@ -33,6 +33,8 @@ void ComponentsWindow::Create(EditorComponent* _editor) layerWnd.Create(editor); nameWnd.Create(editor); scriptWnd.Create(editor); + rigidWnd.Create(editor); + softWnd.Create(editor); newComponentCombo.Create("Add: "); @@ -57,6 +59,8 @@ void ComponentsWindow::Create(EditorComponent* _editor) newComponentCombo.AddItem("Force Field " ICON_FORCE, 13); newComponentCombo.AddItem("Animation " ICON_ANIMATION, 14); newComponentCombo.AddItem("Script " ICON_SCRIPT, 15); + newComponentCombo.AddItem("Rigid Body " ICON_RIGIDBODY, 16); + newComponentCombo.AddItem("Soft Body " ICON_SOFTBODY, 17); newComponentCombo.OnSelect([=](wi::gui::EventArgs args) { newComponentCombo.SetSelectedWithoutCallback(-1); if (editor->translator.selected.empty()) @@ -136,6 +140,14 @@ void ComponentsWindow::Create(EditorComponent* _editor) if (scene.scripts.Contains(entity)) return; break; + case 16: + if (scene.rigidbodies.Contains(entity)) + return; + break; + case 17: + if (scene.softbodies.Contains(entity)) + return; + break; default: return; } @@ -217,6 +229,12 @@ void ComponentsWindow::Create(EditorComponent* _editor) case 15: scene.scripts.Create(entity); break; + case 16: + scene.rigidbodies.Create(entity); + break; + case 17: + scene.softbodies.Create(entity); + break; default: break; } @@ -247,6 +265,8 @@ void ComponentsWindow::Create(EditorComponent* _editor) AddWidget(&layerWnd); AddWidget(&nameWnd); AddWidget(&scriptWnd); + AddWidget(&rigidWnd); + AddWidget(&softWnd); materialWnd.SetVisible(false); weatherWnd.SetVisible(false); @@ -266,6 +286,8 @@ void ComponentsWindow::Create(EditorComponent* _editor) layerWnd.SetVisible(false); nameWnd.SetVisible(false); scriptWnd.SetVisible(false); + rigidWnd.SetVisible(false); + softWnd.SetVisible(false); SetSize(editor->optionsWnd.GetSize()); @@ -506,6 +528,19 @@ void ComponentsWindow::ResizeLayout() 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); @@ -519,6 +554,19 @@ void ComponentsWindow::ResizeLayout() 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.weathers.Contains(weatherWnd.entity)) { weatherWnd.SetVisible(true); diff --git a/Editor/ComponentsWindow.h b/Editor/ComponentsWindow.h index 97d121b33..8d3278704 100644 --- a/Editor/ComponentsWindow.h +++ b/Editor/ComponentsWindow.h @@ -18,6 +18,8 @@ #include "LayerWindow.h" #include "NameWindow.h" #include "ScriptWindow.h" +#include "RigidBodyWindow.h" +#include "SoftBodyWindow.h" class EditorComponent; @@ -49,4 +51,6 @@ public: LayerWindow layerWnd; NameWindow nameWnd; ScriptWindow scriptWnd; + RigidBodyWindow rigidWnd; + SoftBodyWindow softWnd; }; diff --git a/Editor/Editor.cpp b/Editor/Editor.cpp index dae5e9e89..66c8c570c 100644 --- a/Editor/Editor.cpp +++ b/Editor/Editor.cpp @@ -363,6 +363,8 @@ void EditorComponent::Load() componentsWnd.nameWnd.SetEntity(INVALID_ENTITY); componentsWnd.animWnd.SetEntity(INVALID_ENTITY); componentsWnd.scriptWnd.SetEntity(INVALID_ENTITY); + componentsWnd.rigidWnd.SetEntity(INVALID_ENTITY); + componentsWnd.softWnd.SetEntity(INVALID_ENTITY); optionsWnd.RefreshEntityTree(); ResetHistory(); @@ -1311,6 +1313,8 @@ void EditorComponent::Update(float dt) componentsWnd.weatherWnd.SetEntity(INVALID_ENTITY); componentsWnd.animWnd.SetEntity(INVALID_ENTITY); componentsWnd.scriptWnd.SetEntity(INVALID_ENTITY); + componentsWnd.rigidWnd.SetEntity(INVALID_ENTITY); + componentsWnd.softWnd.SetEntity(INVALID_ENTITY); } else { @@ -1344,6 +1348,7 @@ void EditorComponent::Update(float dt) componentsWnd.weatherWnd.SetEntity(picked.entity); componentsWnd.animWnd.SetEntity(picked.entity); componentsWnd.scriptWnd.SetEntity(picked.entity); + componentsWnd.rigidWnd.SetEntity(picked.entity); if (picked.subsetIndex >= 0) { @@ -1351,6 +1356,7 @@ void EditorComponent::Update(float dt) if (object != nullptr) // maybe it was deleted... { componentsWnd.meshWnd.SetEntity(object->meshID, picked.subsetIndex); + componentsWnd.softWnd.SetEntity(object->meshID); const MeshComponent* mesh = scene.meshes.GetComponent(object->meshID); if (mesh != nullptr && (int)mesh->subsets.size() > picked.subsetIndex) @@ -1362,6 +1368,7 @@ void EditorComponent::Update(float dt) else { componentsWnd.meshWnd.SetEntity(picked.entity, picked.subsetIndex); + componentsWnd.softWnd.SetEntity(picked.entity); componentsWnd.materialWnd.SetEntity(picked.entity); } diff --git a/Editor/Editor_SOURCE.vcxitems b/Editor/Editor_SOURCE.vcxitems index 854f4a245..fd4db280b 100644 --- a/Editor/Editor_SOURCE.vcxitems +++ b/Editor/Editor_SOURCE.vcxitems @@ -96,7 +96,9 @@ + + @@ -151,7 +153,9 @@ + + diff --git a/Editor/Editor_SOURCE.vcxitems.filters b/Editor/Editor_SOURCE.vcxitems.filters index bdcd9efb7..2f0b7dc9b 100644 --- a/Editor/Editor_SOURCE.vcxitems.filters +++ b/Editor/Editor_SOURCE.vcxitems.filters @@ -77,6 +77,8 @@ + + @@ -118,6 +120,8 @@ + + diff --git a/Editor/MeshWindow.cpp b/Editor/MeshWindow.cpp index 752a2e08b..577927d83 100644 --- a/Editor/MeshWindow.cpp +++ b/Editor/MeshWindow.cpp @@ -14,8 +14,22 @@ using namespace wi::scene; void MeshWindow::Create(EditorComponent* _editor) { editor = _editor; - wi::gui::Window::Create(ICON_MESH " Mesh", wi::gui::Window::WindowControls::COLLAPSE); - SetSize(XMFLOAT2(580, 720)); + wi::gui::Window::Create(ICON_MESH " Mesh", wi::gui::Window::WindowControls::COLLAPSE | wi::gui::Window::WindowControls::CLOSE); + SetSize(XMFLOAT2(580, 650)); + + closeButton.SetTooltip("Delete MeshComponent"); + OnClose([=](wi::gui::EventArgs args) { + + wi::Archive& archive = editor->AdvanceHistory(); + archive << EditorComponent::HISTORYOP_COMPONENT_DATA; + editor->RecordEntity(archive, entity); + + editor->GetCurrentScene().meshes.Remove(entity); + + editor->RecordEntity(archive, entity); + + editor->optionsWnd.RefreshEntityTree(); + }); float x = 95; float y = 0; @@ -65,80 +79,6 @@ void MeshWindow::Create(EditorComponent* _editor) }); AddWidget(&doubleSidedCheckBox); - softbodyCheckBox.Create("Soft body: "); - softbodyCheckBox.SetTooltip("Enable soft body simulation. Tip: Use the Paint Tool to control vertex pinning."); - softbodyCheckBox.SetSize(XMFLOAT2(hei, hei)); - softbodyCheckBox.SetPos(XMFLOAT2(x, y += step)); - softbodyCheckBox.OnClick([&](wi::gui::EventArgs args) { - - Scene& scene = editor->GetCurrentScene(); - SoftBodyPhysicsComponent* physicscomponent = scene.softbodies.GetComponent(entity); - - if (args.bValue) - { - if (physicscomponent == nullptr) - { - SoftBodyPhysicsComponent& softbody = scene.softbodies.Create(entity); - softbody.friction = frictionSlider.GetValue(); - softbody.restitution = restitutionSlider.GetValue(); - softbody.mass = massSlider.GetValue(); - } - } - else - { - if (physicscomponent != nullptr) - { - scene.softbodies.Remove(entity); - MeshComponent* mesh = editor->GetCurrentScene().meshes.GetComponent(entity); - if (mesh != nullptr) - { - mesh->CreateRenderData(); - } - } - } - - }); - AddWidget(&softbodyCheckBox); - - massSlider.Create(0, 10, 1, 100000, "Mass: "); - massSlider.SetTooltip("Set the mass amount for the physics engine."); - massSlider.SetSize(XMFLOAT2(wid, hei)); - massSlider.SetPos(XMFLOAT2(x, y += step)); - massSlider.OnSlide([&](wi::gui::EventArgs args) { - SoftBodyPhysicsComponent* physicscomponent = editor->GetCurrentScene().softbodies.GetComponent(entity); - if (physicscomponent != nullptr) - { - physicscomponent->mass = args.fValue; - } - }); - AddWidget(&massSlider); - - frictionSlider.Create(0, 1, 0.5f, 100000, "Friction: "); - frictionSlider.SetTooltip("Set the friction amount for the physics engine."); - frictionSlider.SetSize(XMFLOAT2(wid, hei)); - frictionSlider.SetPos(XMFLOAT2(x, y += step)); - frictionSlider.OnSlide([&](wi::gui::EventArgs args) { - SoftBodyPhysicsComponent* physicscomponent = editor->GetCurrentScene().softbodies.GetComponent(entity); - if (physicscomponent != nullptr) - { - physicscomponent->friction = args.fValue; - } - }); - AddWidget(&frictionSlider); - - restitutionSlider.Create(0, 1, 0, 100000, "Restitution: "); - restitutionSlider.SetTooltip("Set the restitution amount for the physics engine."); - restitutionSlider.SetSize(XMFLOAT2(wid, hei)); - restitutionSlider.SetPos(XMFLOAT2(x, y += step)); - restitutionSlider.OnSlide([&](wi::gui::EventArgs args) { - SoftBodyPhysicsComponent* physicscomponent = editor->GetCurrentScene().softbodies.GetComponent(entity); - if (physicscomponent != nullptr) - { - physicscomponent->restitution = args.fValue; - } - }); - AddWidget(&restitutionSlider); - impostorCreateButton.Create("Create Impostor"); impostorCreateButton.SetTooltip("Create an impostor image of the mesh. The mesh will be replaced by this image when far away, to render faster."); impostorCreateButton.SetSize(XMFLOAT2(wid, hei)); @@ -748,17 +688,6 @@ void MeshWindow::SetEntity(Entity entity, int subset) } tessellationFactorSlider.SetValue(mesh->GetTessellationFactor()); - softbodyCheckBox.SetCheck(false); - - SoftBodyPhysicsComponent* physicscomponent = editor->GetCurrentScene().softbodies.GetComponent(entity); - if (physicscomponent != nullptr) - { - softbodyCheckBox.SetCheck(true); - massSlider.SetValue(physicscomponent->mass); - frictionSlider.SetValue(physicscomponent->friction); - restitutionSlider.SetValue(physicscomponent->restitution); - } - uint8_t selected = morphTargetCombo.GetSelected(); morphTargetCombo.ClearItems(); for (size_t i = 0; i < mesh->morph_targets.size(); i++) diff --git a/Editor/MeshWindow.h b/Editor/MeshWindow.h index 1d31c4092..2a4e44241 100644 --- a/Editor/MeshWindow.h +++ b/Editor/MeshWindow.h @@ -17,10 +17,6 @@ public: wi::gui::ComboBox subsetComboBox; wi::gui::ComboBox subsetMaterialComboBox; wi::gui::CheckBox doubleSidedCheckBox; - wi::gui::CheckBox softbodyCheckBox; - wi::gui::Slider massSlider; - wi::gui::Slider frictionSlider; - wi::gui::Slider restitutionSlider; wi::gui::Button impostorCreateButton; wi::gui::Slider impostorDistanceSlider; wi::gui::Slider tessellationFactorSlider; diff --git a/Editor/ObjectWindow.cpp b/Editor/ObjectWindow.cpp index cc42335ce..b05fabe9b 100644 --- a/Editor/ObjectWindow.cpp +++ b/Editor/ObjectWindow.cpp @@ -260,25 +260,34 @@ void ObjectWindow::Create(EditorComponent* _editor) { editor = _editor; - wi::gui::Window::Create(ICON_OBJECT " Object", wi::gui::Window::WindowControls::COLLAPSE); + wi::gui::Window::Create(ICON_OBJECT " Object", wi::gui::Window::WindowControls::COLLAPSE | wi::gui::Window::WindowControls::CLOSE); SetSize(XMFLOAT2(670, 860)); + closeButton.SetTooltip("Delete ObjectComponent"); + OnClose([=](wi::gui::EventArgs args) { + + wi::Archive& archive = editor->AdvanceHistory(); + archive << EditorComponent::HISTORYOP_COMPONENT_DATA; + editor->RecordEntity(archive, entity); + + editor->GetCurrentScene().objects.Remove(entity); + editor->GetCurrentScene().aabb_objects.Remove(entity); + + editor->RecordEntity(archive, entity); + + editor->optionsWnd.RefreshEntityTree(); + }); + float x = 140; float y = 0; float hei = 18; float step = hei + 2; float wid = 130; - nameLabel.Create("NAMELABEL"); - nameLabel.SetText(""); - nameLabel.SetPos(XMFLOAT2(x, y)); - nameLabel.SetSize(XMFLOAT2(wid, hei)); - AddWidget(&nameLabel); - renderableCheckBox.Create("Renderable: "); renderableCheckBox.SetTooltip("Set object to be participating in rendering."); renderableCheckBox.SetSize(XMFLOAT2(hei, hei)); - renderableCheckBox.SetPos(XMFLOAT2(x, y += step)); + renderableCheckBox.SetPos(XMFLOAT2(x, y)); renderableCheckBox.SetCheck(true); renderableCheckBox.OnClick([&](wi::gui::EventArgs args) { ObjectComponent* object = editor->GetCurrentScene().objects.GetComponent(entity); @@ -342,304 +351,6 @@ void ObjectWindow::Create(EditorComponent* _editor) }); AddWidget(&lodSlider); - y += step; - - physicsLabel.Create("PHYSICSLABEL"); - physicsLabel.SetText("PHYSICS SETTINGS"); - physicsLabel.SetPos(XMFLOAT2(x, y += step)); - physicsLabel.SetSize(XMFLOAT2(wid, hei)); - AddWidget(&physicsLabel); - - - collisionShapeComboBox.Create("Collision Shape: "); - collisionShapeComboBox.SetSize(XMFLOAT2(wid, hei)); - collisionShapeComboBox.SetPos(XMFLOAT2(x, y += step)); - collisionShapeComboBox.AddItem("DISABLED"); - collisionShapeComboBox.AddItem("Box"); - collisionShapeComboBox.AddItem("Sphere"); - collisionShapeComboBox.AddItem("Capsule"); - collisionShapeComboBox.AddItem("Convex Hull"); - collisionShapeComboBox.AddItem("Triangle Mesh"); - collisionShapeComboBox.OnSelect([&](wi::gui::EventArgs args) - { - if (entity == INVALID_ENTITY) - return; - - Scene& scene = editor->GetCurrentScene(); - RigidBodyPhysicsComponent* physicscomponent = scene.rigidbodies.GetComponent(entity); - - if (args.iValue == 0) - { - if (physicscomponent != nullptr) - { - scene.rigidbodies.Remove(entity); - } - return; - } - - if (physicscomponent == nullptr) - { - physicscomponent = &scene.rigidbodies.Create(entity); - physicscomponent->SetKinematic(kinematicCheckBox.GetCheck()); - physicscomponent->SetDisableDeactivation(disabledeactivationCheckBox.GetCheck()); - physicscomponent->shape = (RigidBodyPhysicsComponent::CollisionShape)collisionShapeComboBox.GetSelected(); - } - - if (physicscomponent != nullptr) - { - XSlider.SetEnabled(false); - YSlider.SetEnabled(false); - ZSlider.SetEnabled(false); - XSlider.SetText("-"); - YSlider.SetText("-"); - ZSlider.SetText("-"); - - switch (args.iValue) - { - case 1: - if (physicscomponent->shape != RigidBodyPhysicsComponent::CollisionShape::BOX) - { - physicscomponent->physicsobject = nullptr; - physicscomponent->shape = RigidBodyPhysicsComponent::CollisionShape::BOX; - } - XSlider.SetEnabled(true); - YSlider.SetEnabled(true); - ZSlider.SetEnabled(true); - XSlider.SetText("Width"); - YSlider.SetText("Height"); - ZSlider.SetText("Depth"); - XSlider.SetValue(physicscomponent->box.halfextents.x); - YSlider.SetValue(physicscomponent->box.halfextents.y); - ZSlider.SetValue(physicscomponent->box.halfextents.z); - break; - case 2: - if (physicscomponent->shape != RigidBodyPhysicsComponent::CollisionShape::SPHERE) - { - physicscomponent->physicsobject = nullptr; - physicscomponent->shape = RigidBodyPhysicsComponent::CollisionShape::SPHERE; - } - XSlider.SetEnabled(true); - XSlider.SetText("Radius"); - YSlider.SetText("-"); - ZSlider.SetText("-"); - XSlider.SetValue(physicscomponent->sphere.radius); - break; - case 3: - if (physicscomponent->shape != RigidBodyPhysicsComponent::CollisionShape::CAPSULE) - { - physicscomponent->physicsobject = nullptr; - physicscomponent->shape = RigidBodyPhysicsComponent::CollisionShape::CAPSULE; - } - XSlider.SetEnabled(true); - YSlider.SetEnabled(true); - XSlider.SetText("Height"); - YSlider.SetText("Radius"); - ZSlider.SetText("-"); - XSlider.SetValue(physicscomponent->capsule.height); - YSlider.SetValue(physicscomponent->capsule.radius); - break; - case 4: - if (physicscomponent->shape != RigidBodyPhysicsComponent::CollisionShape::CONVEX_HULL) - { - physicscomponent->physicsobject = nullptr; - physicscomponent->shape = RigidBodyPhysicsComponent::CollisionShape::CONVEX_HULL; - } - break; - case 5: - if (physicscomponent->shape != RigidBodyPhysicsComponent::CollisionShape::TRIANGLE_MESH) - { - physicscomponent->physicsobject = nullptr; - physicscomponent->shape = RigidBodyPhysicsComponent::CollisionShape::TRIANGLE_MESH; - } - break; - default: - break; - } - } - }); - collisionShapeComboBox.SetSelected(0); - collisionShapeComboBox.SetEnabled(true); - collisionShapeComboBox.SetTooltip("Set rigid body collision shape."); - AddWidget(&collisionShapeComboBox); - - XSlider.Create(0, 10, 1, 100000, "X: "); - XSlider.SetSize(XMFLOAT2(wid, hei)); - XSlider.SetPos(XMFLOAT2(x, y += step)); - XSlider.OnSlide([&](wi::gui::EventArgs args) { - RigidBodyPhysicsComponent* physicscomponent = editor->GetCurrentScene().rigidbodies.GetComponent(entity); - if (physicscomponent != nullptr) - { - switch (physicscomponent->shape) - { - default: - case RigidBodyPhysicsComponent::CollisionShape::BOX: - physicscomponent->box.halfextents.x = args.fValue; - break; - case RigidBodyPhysicsComponent::CollisionShape::SPHERE: - physicscomponent->sphere.radius = args.fValue; - break; - case RigidBodyPhysicsComponent::CollisionShape::CAPSULE: - physicscomponent->capsule.height = args.fValue; - break; - } - physicscomponent->physicsobject = nullptr; - } - }); - AddWidget(&XSlider); - - YSlider.Create(0, 10, 1, 100000, "Y: "); - YSlider.SetSize(XMFLOAT2(wid, hei)); - YSlider.SetPos(XMFLOAT2(x, y += step)); - YSlider.OnSlide([&](wi::gui::EventArgs args) { - RigidBodyPhysicsComponent* physicscomponent = editor->GetCurrentScene().rigidbodies.GetComponent(entity); - if (physicscomponent != nullptr) - { - switch (physicscomponent->shape) - { - default: - case RigidBodyPhysicsComponent::CollisionShape::BOX: - physicscomponent->box.halfextents.y = args.fValue; - break; - case RigidBodyPhysicsComponent::CollisionShape::CAPSULE: - physicscomponent->capsule.radius = args.fValue; - break; - } - physicscomponent->physicsobject = nullptr; - } - }); - AddWidget(&YSlider); - - ZSlider.Create(0, 10, 1, 100000, "Z: "); - ZSlider.SetSize(XMFLOAT2(wid, hei)); - ZSlider.SetPos(XMFLOAT2(x, y += step)); - ZSlider.OnSlide([&](wi::gui::EventArgs args) { - RigidBodyPhysicsComponent* physicscomponent = editor->GetCurrentScene().rigidbodies.GetComponent(entity); - if (physicscomponent != nullptr) - { - switch (physicscomponent->shape) - { - default: - case RigidBodyPhysicsComponent::CollisionShape::BOX: - physicscomponent->box.halfextents.z = args.fValue; - break; - } - physicscomponent->physicsobject = nullptr; - } - }); - AddWidget(&ZSlider); - - massSlider.Create(0, 10, 1, 100000, "Mass: "); - massSlider.SetTooltip("Set the mass amount for the physics engine."); - massSlider.SetSize(XMFLOAT2(wid, hei)); - massSlider.SetPos(XMFLOAT2(x, y += step)); - massSlider.OnSlide([&](wi::gui::EventArgs args) { - RigidBodyPhysicsComponent* physicscomponent = editor->GetCurrentScene().rigidbodies.GetComponent(entity); - if (physicscomponent != nullptr) - { - physicscomponent->mass = args.fValue; - } - }); - AddWidget(&massSlider); - - frictionSlider.Create(0, 1, 0.5f, 100000, "Friction: "); - frictionSlider.SetTooltip("Set the friction amount for the physics engine."); - frictionSlider.SetSize(XMFLOAT2(wid, hei)); - frictionSlider.SetPos(XMFLOAT2(x, y += step)); - frictionSlider.OnSlide([&](wi::gui::EventArgs args) { - RigidBodyPhysicsComponent* physicscomponent = editor->GetCurrentScene().rigidbodies.GetComponent(entity); - if (physicscomponent != nullptr) - { - physicscomponent->friction = args.fValue; - } - }); - AddWidget(&frictionSlider); - - restitutionSlider.Create(0, 1, 0, 100000, "Restitution: "); - restitutionSlider.SetTooltip("Set the restitution amount for the physics engine."); - restitutionSlider.SetSize(XMFLOAT2(wid, hei)); - restitutionSlider.SetPos(XMFLOAT2(x, y += step)); - restitutionSlider.OnSlide([&](wi::gui::EventArgs args) { - RigidBodyPhysicsComponent* physicscomponent = editor->GetCurrentScene().rigidbodies.GetComponent(entity); - if (physicscomponent != nullptr) - { - physicscomponent->restitution = args.fValue; - } - }); - AddWidget(&restitutionSlider); - - lineardampingSlider.Create(0, 1, 0, 100000, "Linear Damping: "); - lineardampingSlider.SetTooltip("Set the linear damping amount for the physics engine."); - lineardampingSlider.SetSize(XMFLOAT2(wid, hei)); - lineardampingSlider.SetPos(XMFLOAT2(x, y += step)); - lineardampingSlider.OnSlide([&](wi::gui::EventArgs args) { - RigidBodyPhysicsComponent* physicscomponent = editor->GetCurrentScene().rigidbodies.GetComponent(entity); - if (physicscomponent != nullptr) - { - physicscomponent->damping_linear = args.fValue; - } - }); - AddWidget(&lineardampingSlider); - - angulardampingSlider.Create(0, 1, 0, 100000, "Angular Damping: "); - angulardampingSlider.SetTooltip("Set the angular damping amount for the physics engine."); - angulardampingSlider.SetSize(XMFLOAT2(wid, hei)); - angulardampingSlider.SetPos(XMFLOAT2(x, y += step)); - angulardampingSlider.OnSlide([&](wi::gui::EventArgs args) { - RigidBodyPhysicsComponent* physicscomponent = editor->GetCurrentScene().rigidbodies.GetComponent(entity); - if (physicscomponent != nullptr) - { - physicscomponent->damping_angular = args.fValue; - } - }); - AddWidget(&angulardampingSlider); - - physicsMeshLODSlider.Create(0, 6, 0, 6, "Physics Mesh LOD: "); - physicsMeshLODSlider.SetTooltip("Specify which LOD to use for triangle mesh physics."); - physicsMeshLODSlider.SetSize(XMFLOAT2(wid, hei)); - physicsMeshLODSlider.SetPos(XMFLOAT2(x, y += step)); - physicsMeshLODSlider.OnSlide([&](wi::gui::EventArgs args) { - RigidBodyPhysicsComponent* physicscomponent = editor->GetCurrentScene().rigidbodies.GetComponent(entity); - if (physicscomponent != nullptr) - { - if (physicscomponent->mesh_lod != uint32_t(args.iValue)) - { - physicscomponent->physicsobject = nullptr; // will be recreated automatically - physicscomponent->mesh_lod = uint32_t(args.iValue); - } - physicscomponent->mesh_lod = uint32_t(args.iValue); - } - }); - AddWidget(&physicsMeshLODSlider); - - kinematicCheckBox.Create("Kinematic: "); - kinematicCheckBox.SetTooltip("Toggle kinematic behaviour."); - kinematicCheckBox.SetSize(XMFLOAT2(hei, hei)); - kinematicCheckBox.SetPos(XMFLOAT2(x, y += step)); - kinematicCheckBox.SetCheck(false); - kinematicCheckBox.OnClick([&](wi::gui::EventArgs args) { - RigidBodyPhysicsComponent* physicscomponent = editor->GetCurrentScene().rigidbodies.GetComponent(entity); - if (physicscomponent != nullptr) - { - physicscomponent->SetKinematic(args.bValue); - } - }); - AddWidget(&kinematicCheckBox); - - disabledeactivationCheckBox.Create("Disable Deactivation: "); - disabledeactivationCheckBox.SetTooltip("Toggle kinematic behaviour."); - disabledeactivationCheckBox.SetSize(XMFLOAT2(hei, hei)); - disabledeactivationCheckBox.SetPos(XMFLOAT2(x, y += step)); - disabledeactivationCheckBox.SetCheck(false); - disabledeactivationCheckBox.OnClick([&](wi::gui::EventArgs args) { - RigidBodyPhysicsComponent* physicscomponent = editor->GetCurrentScene().rigidbodies.GetComponent(entity); - if (physicscomponent != nullptr) - { - physicscomponent->SetDisableDeactivation(args.bValue); - } - }); - AddWidget(&disabledeactivationCheckBox); - - y += step; @@ -845,9 +556,6 @@ void ObjectWindow::SetEntity(Entity entity) { SetEnabled(true); - const NameComponent* name = scene.names.GetComponent(entity); - nameLabel.SetText(name == nullptr ? std::to_string(entity) : name->name); - renderableCheckBox.SetCheck(object->IsRenderable()); shadowCheckBox.SetCheck(object->IsCastingShadow()); cascadeMaskSlider.SetValue((float)object->cascadeMask); @@ -871,60 +579,5 @@ void ObjectWindow::SetEntity(Entity entity) SetEnabled(false); } - const TransformComponent* transform = scene.transforms.GetComponent(entity); - const RigidBodyPhysicsComponent* physicsComponent = scene.rigidbodies.GetComponent(entity); - - if (transform != nullptr) - { - kinematicCheckBox.SetEnabled(true); - disabledeactivationCheckBox.SetEnabled(true); - collisionShapeComboBox.SetEnabled(true); - massSlider.SetEnabled(true); - frictionSlider.SetEnabled(true); - restitutionSlider.SetEnabled(true); - lineardampingSlider.SetEnabled(true); - angulardampingSlider.SetEnabled(true); - physicsMeshLODSlider.SetEnabled(true); - - if (physicsComponent != nullptr) - { - massSlider.SetValue(physicsComponent->mass); - frictionSlider.SetValue(physicsComponent->friction); - restitutionSlider.SetValue(physicsComponent->restitution); - lineardampingSlider.SetValue(physicsComponent->damping_linear); - angulardampingSlider.SetValue(physicsComponent->damping_angular); - physicsMeshLODSlider.SetValue(float(physicsComponent->mesh_lod)); - - kinematicCheckBox.SetCheck(physicsComponent->IsKinematic()); - disabledeactivationCheckBox.SetCheck(physicsComponent->IsDisableDeactivation()); - - if (physicsComponent->shape == RigidBodyPhysicsComponent::CollisionShape::BOX) - { - collisionShapeComboBox.SetSelected(1); - } - else if (physicsComponent->shape == RigidBodyPhysicsComponent::CollisionShape::SPHERE) - { - collisionShapeComboBox.SetSelected(2); - } - else if (physicsComponent->shape == RigidBodyPhysicsComponent::CollisionShape::CAPSULE) - { - collisionShapeComboBox.SetSelected(3); - } - else if (physicsComponent->shape == RigidBodyPhysicsComponent::CollisionShape::CONVEX_HULL) - { - collisionShapeComboBox.SetSelected(4); - } - else if (physicsComponent->shape == RigidBodyPhysicsComponent::CollisionShape::TRIANGLE_MESH) - { - collisionShapeComboBox.SetSelected(5); - } - } - else - { - collisionShapeComboBox.SetSelected(0); - kinematicCheckBox.SetCheck(false); - disabledeactivationCheckBox.SetCheck(false); - } - } } diff --git a/Editor/ObjectWindow.h b/Editor/ObjectWindow.h index 422800b1d..1a32b8ed3 100644 --- a/Editor/ObjectWindow.h +++ b/Editor/ObjectWindow.h @@ -12,7 +12,6 @@ public: wi::ecs::Entity entity; void SetEntity(wi::ecs::Entity entity); - wi::gui::Label nameLabel; wi::gui::CheckBox renderableCheckBox; wi::gui::CheckBox shadowCheckBox; wi::gui::Slider ditherSlider; @@ -22,20 +21,6 @@ public: wi::gui::ComboBox colorComboBox; wi::gui::ColorPicker colorPicker; - wi::gui::Label physicsLabel; - wi::gui::ComboBox collisionShapeComboBox; - wi::gui::Slider XSlider; - wi::gui::Slider YSlider; - wi::gui::Slider ZSlider; - wi::gui::Slider massSlider; - wi::gui::Slider frictionSlider; - wi::gui::Slider restitutionSlider; - wi::gui::Slider lineardampingSlider; - wi::gui::Slider angulardampingSlider; - wi::gui::Slider physicsMeshLODSlider; - wi::gui::CheckBox disabledeactivationCheckBox; - wi::gui::CheckBox kinematicCheckBox; - wi::gui::Slider lightmapResolutionSlider; wi::gui::ComboBox lightmapSourceUVSetComboBox; wi::gui::Button generateLightmapButton; diff --git a/Editor/RigidBodyWindow.cpp b/Editor/RigidBodyWindow.cpp new file mode 100644 index 000000000..bbcb43d5b --- /dev/null +++ b/Editor/RigidBodyWindow.cpp @@ -0,0 +1,393 @@ +#include "stdafx.h" +#include "RigidBodyWindow.h" +#include "Editor.h" + +using namespace wi::ecs; +using namespace wi::scene; + +void RigidBodyWindow::Create(EditorComponent* _editor) +{ + editor = _editor; + + wi::gui::Window::Create(ICON_RIGIDBODY " Rigid Body Physics", wi::gui::Window::WindowControls::COLLAPSE | wi::gui::Window::WindowControls::CLOSE); + SetSize(XMFLOAT2(670, 280)); + + closeButton.SetTooltip("Delete RigidBodyPhysicsComponent"); + OnClose([=](wi::gui::EventArgs args) { + + wi::Archive& archive = editor->AdvanceHistory(); + archive << EditorComponent::HISTORYOP_COMPONENT_DATA; + editor->RecordEntity(archive, entity); + + editor->GetCurrentScene().rigidbodies.Remove(entity); + + editor->RecordEntity(archive, entity); + + editor->optionsWnd.RefreshEntityTree(); + }); + + float x = 140; + float y = 0; + float hei = 18; + float step = hei + 2; + float wid = 130; + + + collisionShapeComboBox.Create("Collision Shape: "); + collisionShapeComboBox.SetSize(XMFLOAT2(wid, hei)); + collisionShapeComboBox.SetPos(XMFLOAT2(x, y)); + collisionShapeComboBox.AddItem("DISABLED"); + collisionShapeComboBox.AddItem("Box"); + collisionShapeComboBox.AddItem("Sphere"); + collisionShapeComboBox.AddItem("Capsule"); + collisionShapeComboBox.AddItem("Convex Hull"); + collisionShapeComboBox.AddItem("Triangle Mesh"); + collisionShapeComboBox.OnSelect([&](wi::gui::EventArgs args) + { + if (entity == INVALID_ENTITY) + return; + + Scene& scene = editor->GetCurrentScene(); + RigidBodyPhysicsComponent* physicscomponent = scene.rigidbodies.GetComponent(entity); + + if (args.iValue == 0) + { + if (physicscomponent != nullptr) + { + scene.rigidbodies.Remove(entity); + } + return; + } + + if (physicscomponent == nullptr) + { + physicscomponent = &scene.rigidbodies.Create(entity); + physicscomponent->SetKinematic(kinematicCheckBox.GetCheck()); + physicscomponent->SetDisableDeactivation(disabledeactivationCheckBox.GetCheck()); + physicscomponent->shape = (RigidBodyPhysicsComponent::CollisionShape)collisionShapeComboBox.GetSelected(); + } + + if (physicscomponent != nullptr) + { + XSlider.SetEnabled(false); + YSlider.SetEnabled(false); + ZSlider.SetEnabled(false); + XSlider.SetText("-"); + YSlider.SetText("-"); + ZSlider.SetText("-"); + + switch (args.iValue) + { + case 1: + if (physicscomponent->shape != RigidBodyPhysicsComponent::CollisionShape::BOX) + { + physicscomponent->physicsobject = nullptr; + physicscomponent->shape = RigidBodyPhysicsComponent::CollisionShape::BOX; + } + XSlider.SetEnabled(true); + YSlider.SetEnabled(true); + ZSlider.SetEnabled(true); + XSlider.SetText("Width"); + YSlider.SetText("Height"); + ZSlider.SetText("Depth"); + XSlider.SetValue(physicscomponent->box.halfextents.x); + YSlider.SetValue(physicscomponent->box.halfextents.y); + ZSlider.SetValue(physicscomponent->box.halfextents.z); + break; + case 2: + if (physicscomponent->shape != RigidBodyPhysicsComponent::CollisionShape::SPHERE) + { + physicscomponent->physicsobject = nullptr; + physicscomponent->shape = RigidBodyPhysicsComponent::CollisionShape::SPHERE; + } + XSlider.SetEnabled(true); + XSlider.SetText("Radius"); + YSlider.SetText("-"); + ZSlider.SetText("-"); + XSlider.SetValue(physicscomponent->sphere.radius); + break; + case 3: + if (physicscomponent->shape != RigidBodyPhysicsComponent::CollisionShape::CAPSULE) + { + physicscomponent->physicsobject = nullptr; + physicscomponent->shape = RigidBodyPhysicsComponent::CollisionShape::CAPSULE; + } + XSlider.SetEnabled(true); + YSlider.SetEnabled(true); + XSlider.SetText("Height"); + YSlider.SetText("Radius"); + ZSlider.SetText("-"); + XSlider.SetValue(physicscomponent->capsule.height); + YSlider.SetValue(physicscomponent->capsule.radius); + break; + case 4: + if (physicscomponent->shape != RigidBodyPhysicsComponent::CollisionShape::CONVEX_HULL) + { + physicscomponent->physicsobject = nullptr; + physicscomponent->shape = RigidBodyPhysicsComponent::CollisionShape::CONVEX_HULL; + } + break; + case 5: + if (physicscomponent->shape != RigidBodyPhysicsComponent::CollisionShape::TRIANGLE_MESH) + { + physicscomponent->physicsobject = nullptr; + physicscomponent->shape = RigidBodyPhysicsComponent::CollisionShape::TRIANGLE_MESH; + } + break; + default: + break; + } + } + }); + collisionShapeComboBox.SetSelected(0); + collisionShapeComboBox.SetEnabled(true); + collisionShapeComboBox.SetTooltip("Set rigid body collision shape."); + AddWidget(&collisionShapeComboBox); + + XSlider.Create(0, 10, 1, 100000, "X: "); + XSlider.SetSize(XMFLOAT2(wid, hei)); + XSlider.SetPos(XMFLOAT2(x, y += step)); + XSlider.OnSlide([&](wi::gui::EventArgs args) { + RigidBodyPhysicsComponent* physicscomponent = editor->GetCurrentScene().rigidbodies.GetComponent(entity); + if (physicscomponent != nullptr) + { + switch (physicscomponent->shape) + { + default: + case RigidBodyPhysicsComponent::CollisionShape::BOX: + physicscomponent->box.halfextents.x = args.fValue; + break; + case RigidBodyPhysicsComponent::CollisionShape::SPHERE: + physicscomponent->sphere.radius = args.fValue; + break; + case RigidBodyPhysicsComponent::CollisionShape::CAPSULE: + physicscomponent->capsule.height = args.fValue; + break; + } + physicscomponent->physicsobject = nullptr; + } + }); + AddWidget(&XSlider); + + YSlider.Create(0, 10, 1, 100000, "Y: "); + YSlider.SetSize(XMFLOAT2(wid, hei)); + YSlider.SetPos(XMFLOAT2(x, y += step)); + YSlider.OnSlide([&](wi::gui::EventArgs args) { + RigidBodyPhysicsComponent* physicscomponent = editor->GetCurrentScene().rigidbodies.GetComponent(entity); + if (physicscomponent != nullptr) + { + switch (physicscomponent->shape) + { + default: + case RigidBodyPhysicsComponent::CollisionShape::BOX: + physicscomponent->box.halfextents.y = args.fValue; + break; + case RigidBodyPhysicsComponent::CollisionShape::CAPSULE: + physicscomponent->capsule.radius = args.fValue; + break; + } + physicscomponent->physicsobject = nullptr; + } + }); + AddWidget(&YSlider); + + ZSlider.Create(0, 10, 1, 100000, "Z: "); + ZSlider.SetSize(XMFLOAT2(wid, hei)); + ZSlider.SetPos(XMFLOAT2(x, y += step)); + ZSlider.OnSlide([&](wi::gui::EventArgs args) { + RigidBodyPhysicsComponent* physicscomponent = editor->GetCurrentScene().rigidbodies.GetComponent(entity); + if (physicscomponent != nullptr) + { + switch (physicscomponent->shape) + { + default: + case RigidBodyPhysicsComponent::CollisionShape::BOX: + physicscomponent->box.halfextents.z = args.fValue; + break; + } + physicscomponent->physicsobject = nullptr; + } + }); + AddWidget(&ZSlider); + + massSlider.Create(0, 10, 1, 100000, "Mass: "); + massSlider.SetTooltip("Set the mass amount for the physics engine."); + massSlider.SetSize(XMFLOAT2(wid, hei)); + massSlider.SetPos(XMFLOAT2(x, y += step)); + massSlider.OnSlide([&](wi::gui::EventArgs args) { + RigidBodyPhysicsComponent* physicscomponent = editor->GetCurrentScene().rigidbodies.GetComponent(entity); + if (physicscomponent != nullptr) + { + physicscomponent->mass = args.fValue; + physicscomponent->physicsobject = {}; + } + }); + AddWidget(&massSlider); + + frictionSlider.Create(0, 1, 0.5f, 100000, "Friction: "); + frictionSlider.SetTooltip("Set the friction amount for the physics engine."); + frictionSlider.SetSize(XMFLOAT2(wid, hei)); + frictionSlider.SetPos(XMFLOAT2(x, y += step)); + frictionSlider.OnSlide([&](wi::gui::EventArgs args) { + RigidBodyPhysicsComponent* physicscomponent = editor->GetCurrentScene().rigidbodies.GetComponent(entity); + if (physicscomponent != nullptr) + { + physicscomponent->friction = args.fValue; + physicscomponent->physicsobject = {}; + } + }); + AddWidget(&frictionSlider); + + restitutionSlider.Create(0, 1, 0, 100000, "Restitution: "); + restitutionSlider.SetTooltip("Set the restitution amount for the physics engine."); + restitutionSlider.SetSize(XMFLOAT2(wid, hei)); + restitutionSlider.SetPos(XMFLOAT2(x, y += step)); + restitutionSlider.OnSlide([&](wi::gui::EventArgs args) { + RigidBodyPhysicsComponent* physicscomponent = editor->GetCurrentScene().rigidbodies.GetComponent(entity); + if (physicscomponent != nullptr) + { + physicscomponent->restitution = args.fValue; + physicscomponent->physicsobject = {}; + } + }); + AddWidget(&restitutionSlider); + + lineardampingSlider.Create(0, 1, 0, 100000, "Linear Damping: "); + lineardampingSlider.SetTooltip("Set the linear damping amount for the physics engine."); + lineardampingSlider.SetSize(XMFLOAT2(wid, hei)); + lineardampingSlider.SetPos(XMFLOAT2(x, y += step)); + lineardampingSlider.OnSlide([&](wi::gui::EventArgs args) { + RigidBodyPhysicsComponent* physicscomponent = editor->GetCurrentScene().rigidbodies.GetComponent(entity); + if (physicscomponent != nullptr) + { + physicscomponent->damping_linear = args.fValue; + physicscomponent->physicsobject = {}; + } + }); + AddWidget(&lineardampingSlider); + + angulardampingSlider.Create(0, 1, 0, 100000, "Angular Damping: "); + angulardampingSlider.SetTooltip("Set the angular damping amount for the physics engine."); + angulardampingSlider.SetSize(XMFLOAT2(wid, hei)); + angulardampingSlider.SetPos(XMFLOAT2(x, y += step)); + angulardampingSlider.OnSlide([&](wi::gui::EventArgs args) { + RigidBodyPhysicsComponent* physicscomponent = editor->GetCurrentScene().rigidbodies.GetComponent(entity); + if (physicscomponent != nullptr) + { + physicscomponent->damping_angular = args.fValue; + physicscomponent->physicsobject = {}; + } + }); + AddWidget(&angulardampingSlider); + + physicsMeshLODSlider.Create(0, 6, 0, 6, "Physics Mesh LOD: "); + physicsMeshLODSlider.SetTooltip("Specify which LOD to use for triangle mesh physics."); + physicsMeshLODSlider.SetSize(XMFLOAT2(wid, hei)); + physicsMeshLODSlider.SetPos(XMFLOAT2(x, y += step)); + physicsMeshLODSlider.OnSlide([&](wi::gui::EventArgs args) { + RigidBodyPhysicsComponent* physicscomponent = editor->GetCurrentScene().rigidbodies.GetComponent(entity); + if (physicscomponent != nullptr) + { + if (physicscomponent->mesh_lod != uint32_t(args.iValue)) + { + physicscomponent->physicsobject = nullptr; // will be recreated automatically + physicscomponent->mesh_lod = uint32_t(args.iValue); + } + physicscomponent->mesh_lod = uint32_t(args.iValue); + physicscomponent->physicsobject = {}; + } + }); + AddWidget(&physicsMeshLODSlider); + + kinematicCheckBox.Create("Kinematic: "); + kinematicCheckBox.SetTooltip("Toggle kinematic behaviour."); + kinematicCheckBox.SetSize(XMFLOAT2(hei, hei)); + kinematicCheckBox.SetPos(XMFLOAT2(x, y += step)); + kinematicCheckBox.SetCheck(false); + kinematicCheckBox.OnClick([&](wi::gui::EventArgs args) { + RigidBodyPhysicsComponent* physicscomponent = editor->GetCurrentScene().rigidbodies.GetComponent(entity); + if (physicscomponent != nullptr) + { + physicscomponent->SetKinematic(args.bValue); + physicscomponent->physicsobject = {}; + } + }); + AddWidget(&kinematicCheckBox); + + disabledeactivationCheckBox.Create("Disable Deactivation: "); + disabledeactivationCheckBox.SetTooltip("Toggle kinematic behaviour."); + disabledeactivationCheckBox.SetSize(XMFLOAT2(hei, hei)); + disabledeactivationCheckBox.SetPos(XMFLOAT2(x, y += step)); + disabledeactivationCheckBox.SetCheck(false); + disabledeactivationCheckBox.OnClick([&](wi::gui::EventArgs args) { + RigidBodyPhysicsComponent* physicscomponent = editor->GetCurrentScene().rigidbodies.GetComponent(entity); + if (physicscomponent != nullptr) + { + physicscomponent->SetDisableDeactivation(args.bValue); + physicscomponent->physicsobject = {}; + } + }); + AddWidget(&disabledeactivationCheckBox); + + + + SetMinimized(true); + SetVisible(false); + + SetEntity(INVALID_ENTITY); +} + + +void RigidBodyWindow::SetEntity(Entity entity) +{ + if (this->entity == entity) + return; + + this->entity = entity; + + Scene& scene = editor->GetCurrentScene(); + + + const RigidBodyPhysicsComponent* physicsComponent = scene.rigidbodies.GetComponent(entity); + + if (physicsComponent != nullptr) + { + massSlider.SetValue(physicsComponent->mass); + frictionSlider.SetValue(physicsComponent->friction); + restitutionSlider.SetValue(physicsComponent->restitution); + lineardampingSlider.SetValue(physicsComponent->damping_linear); + angulardampingSlider.SetValue(physicsComponent->damping_angular); + physicsMeshLODSlider.SetValue(float(physicsComponent->mesh_lod)); + + kinematicCheckBox.SetCheck(physicsComponent->IsKinematic()); + disabledeactivationCheckBox.SetCheck(physicsComponent->IsDisableDeactivation()); + + if (physicsComponent->shape == RigidBodyPhysicsComponent::CollisionShape::BOX) + { + collisionShapeComboBox.SetSelected(1); + } + else if (physicsComponent->shape == RigidBodyPhysicsComponent::CollisionShape::SPHERE) + { + collisionShapeComboBox.SetSelected(2); + } + else if (physicsComponent->shape == RigidBodyPhysicsComponent::CollisionShape::CAPSULE) + { + collisionShapeComboBox.SetSelected(3); + } + else if (physicsComponent->shape == RigidBodyPhysicsComponent::CollisionShape::CONVEX_HULL) + { + collisionShapeComboBox.SetSelected(4); + } + else if (physicsComponent->shape == RigidBodyPhysicsComponent::CollisionShape::TRIANGLE_MESH) + { + collisionShapeComboBox.SetSelected(5); + } + } + else + { + collisionShapeComboBox.SetSelected(0); + kinematicCheckBox.SetCheck(false); + disabledeactivationCheckBox.SetCheck(false); + } + +} diff --git a/Editor/RigidBodyWindow.h b/Editor/RigidBodyWindow.h new file mode 100644 index 000000000..a2d01be5c --- /dev/null +++ b/Editor/RigidBodyWindow.h @@ -0,0 +1,29 @@ +#pragma once +#include "WickedEngine.h" + +class EditorComponent; + +class RigidBodyWindow : public wi::gui::Window +{ +public: + void Create(EditorComponent* editor); + + EditorComponent* editor = nullptr; + wi::ecs::Entity entity = wi::ecs::INVALID_ENTITY; + void SetEntity(wi::ecs::Entity entity); + + wi::gui::Label physicsLabel; + wi::gui::ComboBox collisionShapeComboBox; + wi::gui::Slider XSlider; + wi::gui::Slider YSlider; + wi::gui::Slider ZSlider; + wi::gui::Slider massSlider; + wi::gui::Slider frictionSlider; + wi::gui::Slider restitutionSlider; + wi::gui::Slider lineardampingSlider; + wi::gui::Slider angulardampingSlider; + wi::gui::Slider physicsMeshLODSlider; + wi::gui::CheckBox disabledeactivationCheckBox; + wi::gui::CheckBox kinematicCheckBox; +}; + diff --git a/Editor/SoftBodyWindow.cpp b/Editor/SoftBodyWindow.cpp new file mode 100644 index 000000000..69f620563 --- /dev/null +++ b/Editor/SoftBodyWindow.cpp @@ -0,0 +1,98 @@ +#include "stdafx.h" +#include "SoftBodyWindow.h" +#include "Editor.h" + +using namespace wi::ecs; +using namespace wi::scene; + +void SoftBodyWindow::Create(EditorComponent* _editor) +{ + editor = _editor; + wi::gui::Window::Create(ICON_SOFTBODY " Soft Body Physics", wi::gui::Window::WindowControls::COLLAPSE | wi::gui::Window::WindowControls::CLOSE); + SetSize(XMFLOAT2(580, 120)); + + closeButton.SetTooltip("Delete MeshComponent"); + OnClose([=](wi::gui::EventArgs args) { + + wi::Archive& archive = editor->AdvanceHistory(); + archive << EditorComponent::HISTORYOP_COMPONENT_DATA; + editor->RecordEntity(archive, entity); + + editor->GetCurrentScene().softbodies.Remove(entity); + + editor->RecordEntity(archive, entity); + + editor->optionsWnd.RefreshEntityTree(); + }); + + float x = 95; + float y = 0; + float hei = 18; + float step = hei + 2; + float wid = 170; + + massSlider.Create(0, 10, 1, 100000, "Mass: "); + massSlider.SetTooltip("Set the mass amount for the physics engine."); + massSlider.SetSize(XMFLOAT2(wid, hei)); + massSlider.SetPos(XMFLOAT2(x, y)); + massSlider.OnSlide([&](wi::gui::EventArgs args) { + SoftBodyPhysicsComponent* physicscomponent = editor->GetCurrentScene().softbodies.GetComponent(entity); + if (physicscomponent != nullptr) + { + physicscomponent->physicsobject = {}; + physicscomponent->mass = args.fValue; + } + }); + AddWidget(&massSlider); + + frictionSlider.Create(0, 1, 0.5f, 100000, "Friction: "); + frictionSlider.SetTooltip("Set the friction amount for the physics engine."); + frictionSlider.SetSize(XMFLOAT2(wid, hei)); + frictionSlider.SetPos(XMFLOAT2(x, y += step)); + frictionSlider.OnSlide([&](wi::gui::EventArgs args) { + SoftBodyPhysicsComponent* physicscomponent = editor->GetCurrentScene().softbodies.GetComponent(entity); + if (physicscomponent != nullptr) + { + physicscomponent->physicsobject = {}; + physicscomponent->friction = args.fValue; + } + }); + AddWidget(&frictionSlider); + + restitutionSlider.Create(0, 1, 0, 100000, "Restitution: "); + restitutionSlider.SetTooltip("Set the restitution amount for the physics engine."); + restitutionSlider.SetSize(XMFLOAT2(wid, hei)); + restitutionSlider.SetPos(XMFLOAT2(x, y += step)); + restitutionSlider.OnSlide([&](wi::gui::EventArgs args) { + SoftBodyPhysicsComponent* physicscomponent = editor->GetCurrentScene().softbodies.GetComponent(entity); + if (physicscomponent != nullptr) + { + physicscomponent->physicsobject = {}; + physicscomponent->restitution = args.fValue; + } + }); + AddWidget(&restitutionSlider); + + + + SetMinimized(true); + SetVisible(false); + + SetEntity(INVALID_ENTITY); +} + + +void SoftBodyWindow::SetEntity(Entity entity) +{ + this->entity = entity; + + Scene& scene = editor->GetCurrentScene(); + + const SoftBodyPhysicsComponent* physicscomponent = scene.softbodies.GetComponent(entity); + if (physicscomponent != nullptr) + { + massSlider.SetValue(physicscomponent->mass); + frictionSlider.SetValue(physicscomponent->friction); + restitutionSlider.SetValue(physicscomponent->restitution); + } +} diff --git a/Editor/SoftBodyWindow.h b/Editor/SoftBodyWindow.h new file mode 100644 index 000000000..6beffc2b6 --- /dev/null +++ b/Editor/SoftBodyWindow.h @@ -0,0 +1,19 @@ +#pragma once +#include "WickedEngine.h" + +class EditorComponent; + +class SoftBodyWindow : public wi::gui::Window +{ +public: + void Create(EditorComponent* editor); + + EditorComponent* editor = nullptr; + wi::ecs::Entity entity = wi::ecs::INVALID_ENTITY; + void SetEntity(wi::ecs::Entity entity); + + wi::gui::Slider massSlider; + wi::gui::Slider frictionSlider; + wi::gui::Slider restitutionSlider; +}; + diff --git a/WickedEngine/wiPhysics_Bullet.cpp b/WickedEngine/wiPhysics_Bullet.cpp index 026da634d..19c2c9fcf 100644 --- a/WickedEngine/wiPhysics_Bullet.cpp +++ b/WickedEngine/wiPhysics_Bullet.cpp @@ -565,6 +565,8 @@ namespace wi::physics SoftBodyPhysicsComponent& physicscomponent = scene.softbodies[args.jobIndex]; Entity entity = scene.softbodies.GetEntity(args.jobIndex); + if (!scene.meshes.Contains(entity)) + return; MeshComponent& mesh = *scene.meshes.GetComponent(entity); const ArmatureComponent* armature = mesh.IsSkinned() ? scene.armatures.GetComponent(mesh.armatureID) : nullptr; mesh.SetDynamic(true); diff --git a/WickedEngine/wiScene.cpp b/WickedEngine/wiScene.cpp index 2bd67a447..9f37fc779 100644 --- a/WickedEngine/wiScene.cpp +++ b/WickedEngine/wiScene.cpp @@ -2377,7 +2377,6 @@ namespace wi::scene const std::string& name ) { - // 1) Create an ObjectComponent, this can be used to instance a mesh: Entity entity = CreateEntity(); if (!name.empty()) @@ -2393,19 +2392,10 @@ namespace wi::scene ObjectComponent& object = objects.Create(entity); - // 2) Create a mesh, this will contain vertex buffers: - // Here a separate mesh entity is created, to allow efficient instancing (not duplicating mesh data when duplicating objects) - Entity entity_mesh_material = CreateEntity(); - - if (!name.empty()) - { - names.Create(entity_mesh_material) = name + "_mesh_material"; - } - - MeshComponent& mesh = meshes.Create(entity_mesh_material); + MeshComponent& mesh = meshes.Create(entity); // object references the mesh entity (there can be multiple objects referencing one mesh): - object.meshID = entity_mesh_material; + object.meshID = entity; mesh.vertex_positions = { // -Z @@ -2521,8 +2511,8 @@ namespace wi::scene // Subset maps a part of the mesh to a material: MeshComponent::MeshSubset& subset = mesh.subsets.emplace_back(); subset.indexCount = uint32_t(mesh.indices.size()); - materials.Create(entity_mesh_material); - subset.materialID = entity_mesh_material; // the material component is created on the same entity as the mesh component, though it is not required as it could also use a different material entity + materials.Create(entity); + subset.materialID = entity; // the material component is created on the same entity as the mesh component, though it is not required as it could also use a different material entity // vertex buffer GPU data will be packed and uploaded here: mesh.CreateRenderData(); @@ -2533,7 +2523,6 @@ namespace wi::scene const std::string& name ) { - // 1) Create an ObjectComponent, this can be used to instance a mesh: Entity entity = CreateEntity(); if (!name.empty()) @@ -2549,19 +2538,10 @@ namespace wi::scene ObjectComponent& object = objects.Create(entity); - // 2) Create a mesh, this will contain vertex buffers: - // Here a separate mesh entity is created, to allow efficient instancing (not duplicating mesh data when duplicating objects) - Entity entity_mesh_material = CreateEntity(); - - if (!name.empty()) - { - names.Create(entity_mesh_material) = name + "_mesh_material"; - } - - MeshComponent& mesh = meshes.Create(entity_mesh_material); + MeshComponent& mesh = meshes.Create(entity); // object references the mesh entity (there can be multiple objects referencing one mesh): - object.meshID = entity_mesh_material; + object.meshID = entity; mesh.vertex_positions = { // +Y @@ -2592,8 +2572,8 @@ namespace wi::scene // Subset maps a part of the mesh to a material: MeshComponent::MeshSubset& subset = mesh.subsets.emplace_back(); subset.indexCount = uint32_t(mesh.indices.size()); - materials.Create(entity_mesh_material); - subset.materialID = entity_mesh_material; // the material component is created on the same entity as the mesh component, though it is not required as it could also use a different material entity + materials.Create(entity); + subset.materialID = entity; // the material component is created on the same entity as the mesh component, though it is not required as it could also use a different material entity // vertex buffer GPU data will be packed and uploaded here: mesh.CreateRenderData(); diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index 8e1affc36..f281b41d4 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -9,7 +9,7 @@ namespace wi::version // minor features, major updates, breaking compatibility changes const int minor = 71; // minor bug fixes, alterations, refactors, updates - const int revision = 22; + const int revision = 23; const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);