diff --git a/Editor/LightWindow.cpp b/Editor/LightWindow.cpp index edbc1354e..256efce8b 100644 --- a/Editor/LightWindow.cpp +++ b/Editor/LightWindow.cpp @@ -23,7 +23,7 @@ void LightWindow::Create(EditorComponent* _editor) editor->RecordEntity(archive, entity); editor->componentsWnd.RefreshEntityTree(); - }); + }); float x = 130; float y = 0; @@ -39,12 +39,16 @@ void LightWindow::Create(EditorComponent* _editor) colorPicker.SetVisible(true); colorPicker.SetEnabled(false); colorPicker.OnColorChanged([&](wi::gui::EventArgs args) { - LightComponent* light = editor->GetCurrentScene().lights.GetComponent(entity); - if (light != nullptr) + wi::scene::Scene& scene = editor->GetCurrentScene(); + for (auto& x : editor->translator.selected) { - light->color = args.color.toFloat3(); + LightComponent* light = scene.lights.GetComponent(x.entity); + if (light != nullptr) + { + light->color = args.color.toFloat3(); + } } - }); + }); AddWidget(&colorPicker); float mod_wid = colorPicker.GetScale().x; @@ -54,10 +58,14 @@ void LightWindow::Create(EditorComponent* _editor) intensitySlider.SetSize(XMFLOAT2(wid, hei)); intensitySlider.SetPos(XMFLOAT2(x, y)); intensitySlider.OnSlide([&](wi::gui::EventArgs args) { - LightComponent* light = editor->GetCurrentScene().lights.GetComponent(entity); - if (light != nullptr) + wi::scene::Scene& scene = editor->GetCurrentScene(); + for (auto& x : editor->translator.selected) { - light->intensity = args.fValue; + LightComponent* light = scene.lights.GetComponent(x.entity); + if (light != nullptr) + { + light->intensity = args.fValue; + } } }); intensitySlider.SetEnabled(false); @@ -68,10 +76,14 @@ void LightWindow::Create(EditorComponent* _editor) rangeSlider.SetSize(XMFLOAT2(wid, hei)); rangeSlider.SetPos(XMFLOAT2(x, y += step)); rangeSlider.OnSlide([&](wi::gui::EventArgs args) { - LightComponent* light = editor->GetCurrentScene().lights.GetComponent(entity); - if (light != nullptr) + wi::scene::Scene& scene = editor->GetCurrentScene(); + for (auto& x : editor->translator.selected) { - light->range = args.fValue; + LightComponent* light = scene.lights.GetComponent(x.entity); + if (light != nullptr) + { + light->range = args.fValue; + } } }); rangeSlider.SetEnabled(false); @@ -82,12 +94,16 @@ void LightWindow::Create(EditorComponent* _editor) radiusSlider.SetSize(XMFLOAT2(wid, hei)); radiusSlider.SetPos(XMFLOAT2(x, y += step)); radiusSlider.OnSlide([&](wi::gui::EventArgs args) { - LightComponent* light = editor->GetCurrentScene().lights.GetComponent(entity); - if (light != nullptr) + wi::scene::Scene& scene = editor->GetCurrentScene(); + for (auto& x : editor->translator.selected) { - light->radius = args.fValue; + LightComponent* light = scene.lights.GetComponent(x.entity); + if (light != nullptr) + { + light->radius = args.fValue; + } } - }); + }); radiusSlider.SetEnabled(false); radiusSlider.SetTooltip("[Experimental] Adjust the radius of the light source.\nFor directional light, this will only affect ray traced shadow softness."); AddWidget(&radiusSlider); @@ -96,12 +112,16 @@ void LightWindow::Create(EditorComponent* _editor) lengthSlider.SetSize(XMFLOAT2(wid, hei)); lengthSlider.SetPos(XMFLOAT2(x, y += step)); lengthSlider.OnSlide([&](wi::gui::EventArgs args) { - LightComponent* light = editor->GetCurrentScene().lights.GetComponent(entity); - if (light != nullptr) + wi::scene::Scene& scene = editor->GetCurrentScene(); + for (auto& x : editor->translator.selected) { - light->length = args.fValue; + LightComponent* light = scene.lights.GetComponent(x.entity); + if (light != nullptr) + { + light->length = args.fValue; + } } - }); + }); lengthSlider.SetEnabled(false); lengthSlider.SetTooltip("[Experimental] Adjust the length of the light source.\nWith this you can make capsule light out of a point light."); AddWidget(&lengthSlider); @@ -110,10 +130,14 @@ void LightWindow::Create(EditorComponent* _editor) outerConeAngleSlider.SetSize(XMFLOAT2(wid, hei)); outerConeAngleSlider.SetPos(XMFLOAT2(x, y += step)); outerConeAngleSlider.OnSlide([&](wi::gui::EventArgs args) { - LightComponent* light = editor->GetCurrentScene().lights.GetComponent(entity); - if (light != nullptr) + wi::scene::Scene& scene = editor->GetCurrentScene(); + for (auto& x : editor->translator.selected) { - light->outerConeAngle = args.fValue; + LightComponent* light = scene.lights.GetComponent(x.entity); + if (light != nullptr) + { + light->outerConeAngle = args.fValue; + } } }); outerConeAngleSlider.SetEnabled(false); @@ -124,12 +148,16 @@ void LightWindow::Create(EditorComponent* _editor) innerConeAngleSlider.SetSize(XMFLOAT2(wid, hei)); innerConeAngleSlider.SetPos(XMFLOAT2(x, y += step)); innerConeAngleSlider.OnSlide([&](wi::gui::EventArgs args) { - LightComponent* light = editor->GetCurrentScene().lights.GetComponent(entity); - if (light != nullptr) + wi::scene::Scene& scene = editor->GetCurrentScene(); + for (auto& x : editor->translator.selected) { - light->innerConeAngle = args.fValue; + LightComponent* light = scene.lights.GetComponent(x.entity); + if (light != nullptr) + { + light->innerConeAngle = args.fValue; + } } - }); + }); innerConeAngleSlider.SetEnabled(false); innerConeAngleSlider.SetTooltip("Adjust the inner cone aperture for spotlight.\n(The inner cone will always be inside the outer cone)"); AddWidget(&innerConeAngleSlider); @@ -138,10 +166,14 @@ void LightWindow::Create(EditorComponent* _editor) shadowCheckBox.SetSize(XMFLOAT2(hei, hei)); shadowCheckBox.SetPos(XMFLOAT2(x, y += step)); shadowCheckBox.OnClick([&](wi::gui::EventArgs args) { - LightComponent* light = editor->GetCurrentScene().lights.GetComponent(entity); - if (light != nullptr) + wi::scene::Scene& scene = editor->GetCurrentScene(); + for (auto& x : editor->translator.selected) { - light->SetCastShadow(args.bValue); + LightComponent* light = scene.lights.GetComponent(x.entity); + if (light != nullptr) + { + light->SetCastShadow(args.bValue); + } } }); shadowCheckBox.SetEnabled(false); @@ -152,10 +184,14 @@ void LightWindow::Create(EditorComponent* _editor) volumetricsCheckBox.SetSize(XMFLOAT2(hei, hei)); volumetricsCheckBox.SetPos(XMFLOAT2(x, y += step)); volumetricsCheckBox.OnClick([&](wi::gui::EventArgs args) { - LightComponent* light = editor->GetCurrentScene().lights.GetComponent(entity); - if (light != nullptr) + wi::scene::Scene& scene = editor->GetCurrentScene(); + for (auto& x : editor->translator.selected) { - light->SetVolumetricsEnabled(args.bValue); + LightComponent* light = scene.lights.GetComponent(x.entity); + if (light != nullptr) + { + light->SetVolumetricsEnabled(args.bValue); + } } }); volumetricsCheckBox.SetEnabled(false); @@ -166,10 +202,14 @@ void LightWindow::Create(EditorComponent* _editor) haloCheckBox.SetSize(XMFLOAT2(hei, hei)); haloCheckBox.SetPos(XMFLOAT2(x, y += step)); haloCheckBox.OnClick([&](wi::gui::EventArgs args) { - LightComponent* light = editor->GetCurrentScene().lights.GetComponent(entity); - if (light != nullptr) + wi::scene::Scene& scene = editor->GetCurrentScene(); + for (auto& x : editor->translator.selected) { - light->SetVisualizerEnabled(args.bValue); + LightComponent* light = scene.lights.GetComponent(x.entity); + if (light != nullptr) + { + light->SetVisualizerEnabled(args.bValue); + } } }); haloCheckBox.SetEnabled(false); @@ -180,10 +220,14 @@ void LightWindow::Create(EditorComponent* _editor) staticCheckBox.SetSize(XMFLOAT2(hei, hei)); staticCheckBox.SetPos(XMFLOAT2(x, y += step)); staticCheckBox.OnClick([&](wi::gui::EventArgs args) { - LightComponent* light = editor->GetCurrentScene().lights.GetComponent(entity); - if (light != nullptr) + wi::scene::Scene& scene = editor->GetCurrentScene(); + for (auto& x : editor->translator.selected) { - light->SetStatic(args.bValue); + LightComponent* light = scene.lights.GetComponent(x.entity); + if (light != nullptr) + { + light->SetStatic(args.bValue); + } } }); staticCheckBox.SetEnabled(false); @@ -194,10 +238,14 @@ void LightWindow::Create(EditorComponent* _editor) volumetricCloudsCheckBox.SetSize(XMFLOAT2(hei, hei)); volumetricCloudsCheckBox.SetPos(XMFLOAT2(x, y += step)); volumetricCloudsCheckBox.OnClick([&](wi::gui::EventArgs args) { - LightComponent* light = editor->GetCurrentScene().lights.GetComponent(entity); - if (light != nullptr) + wi::scene::Scene& scene = editor->GetCurrentScene(); + for (auto& x : editor->translator.selected) { - light->SetVolumetricCloudsEnabled(args.bValue); + LightComponent* light = scene.lights.GetComponent(x.entity); + if (light != nullptr) + { + light->SetVolumetricCloudsEnabled(args.bValue); + } } }); volumetricCloudsCheckBox.SetEnabled(false); @@ -208,11 +256,17 @@ void LightWindow::Create(EditorComponent* _editor) typeSelectorComboBox.SetSize(XMFLOAT2(wid, hei)); typeSelectorComboBox.SetPos(XMFLOAT2(x, y += step)); typeSelectorComboBox.OnSelect([&](wi::gui::EventArgs args) { - LightComponent* light = editor->GetCurrentScene().lights.GetComponent(entity); - if (light != nullptr && args.iValue >= 0) + if (args.iValue < 0) + return; + wi::scene::Scene& scene = editor->GetCurrentScene(); + for (auto& x : editor->translator.selected) { - light->SetType((LightComponent::LightType)args.iValue); - SetLightType(light->GetType()); + LightComponent* light = scene.lights.GetComponent(x.entity); + if (light != nullptr) + { + light->SetType((LightComponent::LightType)args.iValue); + SetLightType(light->GetType()); + } } }); typeSelectorComboBox.AddItem("Directional"); @@ -235,11 +289,16 @@ void LightWindow::Create(EditorComponent* _editor) shadowResolutionComboBox.AddItem("1024", 1024); shadowResolutionComboBox.AddItem("2048", 2048); shadowResolutionComboBox.OnSelect([&](wi::gui::EventArgs args) { - LightComponent* light = editor->GetCurrentScene().lights.GetComponent(entity); - if (light == nullptr) - return; - light->forced_shadow_resolution = int(args.userdata); - }); + wi::scene::Scene& scene = editor->GetCurrentScene(); + for (auto& x : editor->translator.selected) + { + LightComponent* light = scene.lights.GetComponent(x.entity); + if (light != nullptr) + { + light->forced_shadow_resolution = int(args.userdata); + } + } + }); shadowResolutionComboBox.SetSelected(0); AddWidget(&shadowResolutionComboBox); diff --git a/Editor/RigidBodyWindow.cpp b/Editor/RigidBodyWindow.cpp index 520c407ff..cb2cd108e 100644 --- a/Editor/RigidBodyWindow.cpp +++ b/Editor/RigidBodyWindow.cpp @@ -9,7 +9,7 @@ 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, 400)); + SetSize(XMFLOAT2(670, 420)); closeButton.SetTooltip("Delete RigidBodyPhysicsComponent"); OnClose([=](wi::gui::EventArgs args) { @@ -23,7 +23,7 @@ void RigidBodyWindow::Create(EditorComponent* _editor) editor->RecordEntity(archive, entity); editor->componentsWnd.RefreshEntityTree(); - }); + }); float x = 140; float y = 0; @@ -41,66 +41,23 @@ void RigidBodyWindow::Create(EditorComponent* _editor) collisionShapeComboBox.AddItem("Cylinder", RigidBodyPhysicsComponent::CollisionShape::CYLINDER); collisionShapeComboBox.AddItem("Convex Hull", RigidBodyPhysicsComponent::CollisionShape::CONVEX_HULL); collisionShapeComboBox.AddItem("Triangle Mesh", RigidBodyPhysicsComponent::CollisionShape::TRIANGLE_MESH); - collisionShapeComboBox.OnSelect([&](wi::gui::EventArgs args) + collisionShapeComboBox.OnSelect([&](wi::gui::EventArgs args) { + wi::scene::Scene& scene = editor->GetCurrentScene(); + for (auto& x : editor->translator.selected) { - if (entity == INVALID_ENTITY) - return; - - Scene& scene = editor->GetCurrentScene(); - RigidBodyPhysicsComponent* physicscomponent = scene.rigidbodies.GetComponent(entity); - if (physicscomponent == nullptr) - return; - - XSlider.SetEnabled(false); - YSlider.SetEnabled(false); - ZSlider.SetEnabled(false); - XSlider.SetText("-"); - YSlider.SetText("-"); - ZSlider.SetText("-"); - - RigidBodyPhysicsComponent::CollisionShape shape = (RigidBodyPhysicsComponent::CollisionShape)args.userdata; - if (physicscomponent->shape != shape) + RigidBodyPhysicsComponent* physicscomponent = scene.rigidbodies.GetComponent(x.entity); + if (physicscomponent != nullptr) { - physicscomponent->physicsobject = nullptr; - physicscomponent->shape = shape; + RigidBodyPhysicsComponent::CollisionShape shape = (RigidBodyPhysicsComponent::CollisionShape)args.userdata; + if (physicscomponent->shape != shape) + { + physicscomponent->physicsobject = nullptr; + physicscomponent->shape = shape; + } } - - switch (shape) - { - case 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 RigidBodyPhysicsComponent::CollisionShape::SPHERE: - XSlider.SetEnabled(true); - XSlider.SetText("Radius"); - YSlider.SetText("-"); - ZSlider.SetText("-"); - XSlider.SetValue(physicscomponent->sphere.radius); - break; - case RigidBodyPhysicsComponent::CollisionShape::CAPSULE: - case RigidBodyPhysicsComponent::CollisionShape::CYLINDER: - 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 RigidBodyPhysicsComponent::CollisionShape::CONVEX_HULL: - case RigidBodyPhysicsComponent::CollisionShape::TRIANGLE_MESH: - default: - break; - } - }); + } + RefreshShapeType(); + }); collisionShapeComboBox.SetSelected(0); collisionShapeComboBox.SetEnabled(true); collisionShapeComboBox.SetTooltip("Set rigid body collision shape."); @@ -110,69 +67,81 @@ void RigidBodyWindow::Create(EditorComponent* _editor) 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) + wi::scene::Scene& scene = editor->GetCurrentScene(); + for (auto& x : editor->translator.selected) { - switch (physicscomponent->shape) + RigidBodyPhysicsComponent* physicscomponent = scene.rigidbodies.GetComponent(x.entity); + if (physicscomponent != nullptr) { - 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: - case RigidBodyPhysicsComponent::CollisionShape::CYLINDER: - physicscomponent->capsule.height = args.fValue; - break; + 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: + case RigidBodyPhysicsComponent::CollisionShape::CYLINDER: + physicscomponent->capsule.height = args.fValue; + break; + } + physicscomponent->physicsobject = nullptr; } - 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) + wi::scene::Scene& scene = editor->GetCurrentScene(); + for (auto& x : editor->translator.selected) { - switch (physicscomponent->shape) + RigidBodyPhysicsComponent* physicscomponent = scene.rigidbodies.GetComponent(x.entity); + if (physicscomponent != nullptr) { - default: - case RigidBodyPhysicsComponent::CollisionShape::BOX: - physicscomponent->box.halfextents.y = args.fValue; - break; - case RigidBodyPhysicsComponent::CollisionShape::CAPSULE: - case RigidBodyPhysicsComponent::CollisionShape::CYLINDER: - physicscomponent->capsule.radius = args.fValue; - break; + switch (physicscomponent->shape) + { + default: + case RigidBodyPhysicsComponent::CollisionShape::BOX: + physicscomponent->box.halfextents.y = args.fValue; + break; + case RigidBodyPhysicsComponent::CollisionShape::CAPSULE: + case RigidBodyPhysicsComponent::CollisionShape::CYLINDER: + physicscomponent->capsule.radius = args.fValue; + break; + } + physicscomponent->physicsobject = nullptr; } - 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) + wi::scene::Scene& scene = editor->GetCurrentScene(); + for (auto& x : editor->translator.selected) { - switch (physicscomponent->shape) + RigidBodyPhysicsComponent* physicscomponent = scene.rigidbodies.GetComponent(x.entity); + if (physicscomponent != nullptr) { - default: - case RigidBodyPhysicsComponent::CollisionShape::BOX: - case RigidBodyPhysicsComponent::CollisionShape::CYLINDER: - physicscomponent->box.halfextents.z = args.fValue; - break; + switch (physicscomponent->shape) + { + default: + case RigidBodyPhysicsComponent::CollisionShape::BOX: + case RigidBodyPhysicsComponent::CollisionShape::CYLINDER: + physicscomponent->box.halfextents.z = args.fValue; + break; + } + physicscomponent->physicsobject = nullptr; } - physicscomponent->physicsobject = nullptr; } - }); + }); AddWidget(&ZSlider); XSlider.SetText("Width"); @@ -184,13 +153,17 @@ void RigidBodyWindow::Create(EditorComponent* _editor) 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) + wi::scene::Scene& scene = editor->GetCurrentScene(); + for (auto& x : editor->translator.selected) { - physicscomponent->mass = args.fValue; - physicscomponent->physicsobject = {}; + RigidBodyPhysicsComponent* physicscomponent = scene.rigidbodies.GetComponent(x.entity); + if (physicscomponent != nullptr) + { + physicscomponent->mass = args.fValue; + physicscomponent->physicsobject = {}; + } } - }); + }); AddWidget(&massSlider); frictionSlider.Create(0, 1, 0.5f, 100000, "Friction: "); @@ -198,12 +171,16 @@ void RigidBodyWindow::Create(EditorComponent* _editor) 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) + wi::scene::Scene& scene = editor->GetCurrentScene(); + for (auto& x : editor->translator.selected) { - physicscomponent->friction = args.fValue; + RigidBodyPhysicsComponent* physicscomponent = scene.rigidbodies.GetComponent(x.entity); + if (physicscomponent != nullptr) + { + physicscomponent->friction = args.fValue; + } } - }); + }); AddWidget(&frictionSlider); restitutionSlider.Create(0, 1, 0, 100000, "Restitution: "); @@ -211,12 +188,16 @@ void RigidBodyWindow::Create(EditorComponent* _editor) 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) + wi::scene::Scene& scene = editor->GetCurrentScene(); + for (auto& x : editor->translator.selected) { - physicscomponent->restitution = args.fValue; + RigidBodyPhysicsComponent* physicscomponent = scene.rigidbodies.GetComponent(x.entity); + if (physicscomponent != nullptr) + { + physicscomponent->restitution = args.fValue; + } } - }); + }); AddWidget(&restitutionSlider); lineardampingSlider.Create(0, 1, 0, 100000, "Linear Damping: "); @@ -224,13 +205,17 @@ void RigidBodyWindow::Create(EditorComponent* _editor) 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) + wi::scene::Scene& scene = editor->GetCurrentScene(); + for (auto& x : editor->translator.selected) { - physicscomponent->damping_linear = args.fValue; - physicscomponent->physicsobject = {}; + RigidBodyPhysicsComponent* physicscomponent = scene.rigidbodies.GetComponent(x.entity); + if (physicscomponent != nullptr) + { + physicscomponent->damping_linear = args.fValue; + physicscomponent->physicsobject = {}; + } } - }); + }); AddWidget(&lineardampingSlider); angulardampingSlider.Create(0, 1, 0, 100000, "Angular Damping: "); @@ -238,13 +223,17 @@ void RigidBodyWindow::Create(EditorComponent* _editor) 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) + wi::scene::Scene& scene = editor->GetCurrentScene(); + for (auto& x : editor->translator.selected) { - physicscomponent->damping_angular = args.fValue; - physicscomponent->physicsobject = {}; + RigidBodyPhysicsComponent* physicscomponent = scene.rigidbodies.GetComponent(x.entity); + if (physicscomponent != nullptr) + { + physicscomponent->damping_angular = args.fValue; + physicscomponent->physicsobject = {}; + } } - }); + }); AddWidget(&angulardampingSlider); physicsMeshLODSlider.Create(0, 6, 0, 6, "Use Mesh LOD: "); @@ -252,18 +241,22 @@ void RigidBodyWindow::Create(EditorComponent* _editor) 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) + wi::scene::Scene& scene = editor->GetCurrentScene(); + for (auto& x : editor->translator.selected) { - if (physicscomponent->mesh_lod != uint32_t(args.iValue)) + RigidBodyPhysicsComponent* physicscomponent = scene.rigidbodies.GetComponent(x.entity); + if (physicscomponent != nullptr) { - physicscomponent->physicsobject = nullptr; // will be recreated automatically + 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 = {}; } - physicscomponent->mesh_lod = uint32_t(args.iValue); - physicscomponent->physicsobject = {}; } - }); + }); AddWidget(&physicsMeshLODSlider); kinematicCheckBox.Create("Kinematic: "); @@ -272,13 +265,17 @@ void RigidBodyWindow::Create(EditorComponent* _editor) 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) + wi::scene::Scene& scene = editor->GetCurrentScene(); + for (auto& x : editor->translator.selected) { - physicscomponent->SetKinematic(args.bValue); - physicscomponent->physicsobject = {}; + RigidBodyPhysicsComponent* physicscomponent = scene.rigidbodies.GetComponent(x.entity); + if (physicscomponent != nullptr) + { + physicscomponent->SetKinematic(args.bValue); + physicscomponent->physicsobject = {}; + } } - }); + }); AddWidget(&kinematicCheckBox); disabledeactivationCheckBox.Create("Disable Deactivation: "); @@ -287,15 +284,38 @@ void RigidBodyWindow::Create(EditorComponent* _editor) 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) + wi::scene::Scene& scene = editor->GetCurrentScene(); + for (auto& x : editor->translator.selected) { - physicscomponent->SetDisableDeactivation(args.bValue); - physicscomponent->physicsobject = {}; + RigidBodyPhysicsComponent* physicscomponent = scene.rigidbodies.GetComponent(x.entity); + if (physicscomponent != nullptr) + { + physicscomponent->SetDisableDeactivation(args.bValue); + physicscomponent->physicsobject = {}; + } } - }); + }); AddWidget(&disabledeactivationCheckBox); + startDeactivatedCheckBox.Create("Start deactivated: "); + startDeactivatedCheckBox.SetTooltip("If enabled, the rigid body will start in a deactivated state.\nEven if the body is dynamic (non-kinematic, mass > 0), it will not fall unless interacted with."); + startDeactivatedCheckBox.SetSize(XMFLOAT2(hei, hei)); + startDeactivatedCheckBox.SetPos(XMFLOAT2(x, y += step)); + startDeactivatedCheckBox.SetCheck(false); + startDeactivatedCheckBox.OnClick([&](wi::gui::EventArgs args) { + wi::scene::Scene& scene = editor->GetCurrentScene(); + for (auto& x : editor->translator.selected) + { + RigidBodyPhysicsComponent* physicscomponent = scene.rigidbodies.GetComponent(x.entity); + if (physicscomponent != nullptr) + { + physicscomponent->SetStartDeactivated(args.bValue); + physicscomponent->physicsobject = {}; + } + } + }); + AddWidget(&startDeactivatedCheckBox); + offsetXSlider.Create(-10, 10, 0, 100000, "Local Offset X: "); @@ -303,11 +323,15 @@ void RigidBodyWindow::Create(EditorComponent* _editor) offsetXSlider.SetSize(XMFLOAT2(wid, hei)); offsetXSlider.SetPos(XMFLOAT2(x, y += step)); offsetXSlider.OnSlide([&](wi::gui::EventArgs args) { - RigidBodyPhysicsComponent* physicscomponent = editor->GetCurrentScene().rigidbodies.GetComponent(entity); - if (physicscomponent != nullptr) + wi::scene::Scene& scene = editor->GetCurrentScene(); + for (auto& x : editor->translator.selected) { - physicscomponent->local_offset.x = args.fValue; - physicscomponent->physicsobject = {}; + RigidBodyPhysicsComponent* physicscomponent = scene.rigidbodies.GetComponent(x.entity); + if (physicscomponent != nullptr) + { + physicscomponent->local_offset.x = args.fValue; + physicscomponent->physicsobject = {}; + } } }); AddWidget(&offsetXSlider); @@ -317,11 +341,15 @@ void RigidBodyWindow::Create(EditorComponent* _editor) offsetYSlider.SetSize(XMFLOAT2(wid, hei)); offsetYSlider.SetPos(XMFLOAT2(x, y += step)); offsetYSlider.OnSlide([&](wi::gui::EventArgs args) { - RigidBodyPhysicsComponent* physicscomponent = editor->GetCurrentScene().rigidbodies.GetComponent(entity); - if (physicscomponent != nullptr) + wi::scene::Scene& scene = editor->GetCurrentScene(); + for (auto& x : editor->translator.selected) { - physicscomponent->local_offset.y = args.fValue; - physicscomponent->physicsobject = {}; + RigidBodyPhysicsComponent* physicscomponent = scene.rigidbodies.GetComponent(x.entity); + if (physicscomponent != nullptr) + { + physicscomponent->local_offset.y = args.fValue; + physicscomponent->physicsobject = {}; + } } }); AddWidget(&offsetYSlider); @@ -331,11 +359,15 @@ void RigidBodyWindow::Create(EditorComponent* _editor) offsetZSlider.SetSize(XMFLOAT2(wid, hei)); offsetZSlider.SetPos(XMFLOAT2(x, y += step)); offsetZSlider.OnSlide([&](wi::gui::EventArgs args) { - RigidBodyPhysicsComponent* physicscomponent = editor->GetCurrentScene().rigidbodies.GetComponent(entity); - if (physicscomponent != nullptr) + wi::scene::Scene& scene = editor->GetCurrentScene(); + for (auto& x : editor->translator.selected) { - physicscomponent->local_offset.z = args.fValue; - physicscomponent->physicsobject = {}; + RigidBodyPhysicsComponent* physicscomponent = scene.rigidbodies.GetComponent(x.entity); + if (physicscomponent != nullptr) + { + physicscomponent->local_offset.z = args.fValue; + physicscomponent->physicsobject = {}; + } } }); AddWidget(&offsetZSlider); @@ -348,6 +380,57 @@ void RigidBodyWindow::Create(EditorComponent* _editor) SetEntity(INVALID_ENTITY); } +void RigidBodyWindow::RefreshShapeType() +{ + XSlider.SetEnabled(false); + YSlider.SetEnabled(false); + ZSlider.SetEnabled(false); + XSlider.SetText("-"); + YSlider.SetText("-"); + ZSlider.SetText("-"); + + Scene& scene = editor->GetCurrentScene(); + + const RigidBodyPhysicsComponent* physicscomponent = scene.rigidbodies.GetComponent(entity); + if (physicscomponent == nullptr) + return; + + switch (physicscomponent->shape) + { + case 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 RigidBodyPhysicsComponent::CollisionShape::SPHERE: + XSlider.SetEnabled(true); + XSlider.SetText("Radius"); + YSlider.SetText("-"); + ZSlider.SetText("-"); + XSlider.SetValue(physicscomponent->sphere.radius); + break; + case RigidBodyPhysicsComponent::CollisionShape::CAPSULE: + case RigidBodyPhysicsComponent::CollisionShape::CYLINDER: + 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 RigidBodyPhysicsComponent::CollisionShape::CONVEX_HULL: + case RigidBodyPhysicsComponent::CollisionShape::TRIANGLE_MESH: + default: + break; + } +} void RigidBodyWindow::SetEntity(Entity entity) { @@ -373,8 +456,11 @@ void RigidBodyWindow::SetEntity(Entity entity) kinematicCheckBox.SetCheck(physicsComponent->IsKinematic()); disabledeactivationCheckBox.SetCheck(physicsComponent->IsDisableDeactivation()); + startDeactivatedCheckBox.SetCheck(physicsComponent->IsStartDeactivated()); - collisionShapeComboBox.SetSelectedByUserdata((uint64_t)physicsComponent->shape); + collisionShapeComboBox.SetSelectedByUserdataWithoutCallback((uint64_t)physicsComponent->shape); + + RefreshShapeType(); } else { @@ -434,6 +520,7 @@ void RigidBodyWindow::ResizeLayout() add(offsetXSlider); add(offsetYSlider); add(offsetZSlider); + add_right(startDeactivatedCheckBox); add_right(disabledeactivationCheckBox); add_right(kinematicCheckBox); diff --git a/Editor/RigidBodyWindow.h b/Editor/RigidBodyWindow.h index f1e6364c0..31f575590 100644 --- a/Editor/RigidBodyWindow.h +++ b/Editor/RigidBodyWindow.h @@ -10,6 +10,8 @@ public: wi::ecs::Entity entity = wi::ecs::INVALID_ENTITY; void SetEntity(wi::ecs::Entity entity); + void RefreshShapeType(); + wi::gui::ComboBox collisionShapeComboBox; wi::gui::Slider XSlider; wi::gui::Slider YSlider; @@ -20,6 +22,7 @@ public: wi::gui::Slider lineardampingSlider; wi::gui::Slider angulardampingSlider; wi::gui::Slider physicsMeshLODSlider; + wi::gui::CheckBox startDeactivatedCheckBox; wi::gui::CheckBox disabledeactivationCheckBox; wi::gui::CheckBox kinematicCheckBox; wi::gui::Slider offsetXSlider; diff --git a/WickedEngine/wiGraphics.h b/WickedEngine/wiGraphics.h index 1ef6e0746..e895d7d58 100644 --- a/WickedEngine/wiGraphics.h +++ b/WickedEngine/wiGraphics.h @@ -14,7 +14,7 @@ namespace wi::graphics struct GPUBuffer; struct Texture; - enum class ValidationMode + enum class ValidationMode : uint8_t { Disabled, // No validation is enabled Enabled, // CPU command validation @@ -22,7 +22,7 @@ namespace wi::graphics Verbose // Print all warnings, errors and info messages }; - enum class AdapterType + enum class AdapterType : uint8_t { Other, IntegratedGpu, @@ -31,13 +31,13 @@ namespace wi::graphics Cpu, }; - enum class GPUPreference + enum class GPUPreference : uint8_t { Discrete, Integrated, }; - enum class ShaderStage + enum class ShaderStage : uint8_t { MS, // Mesh Shader AS, // Amplification Shader @@ -50,7 +50,7 @@ namespace wi::graphics LIB, // Shader Library Count, }; - enum class ShaderFormat + enum class ShaderFormat : uint8_t { NONE, // Not used HLSL5, // DXBC @@ -59,7 +59,7 @@ namespace wi::graphics HLSL6_XS, // XBOX Series Native PS5, // Playstation 5 }; - enum class ShaderModel + enum class ShaderModel : uint8_t { SM_5_0, SM_6_0, @@ -71,7 +71,7 @@ namespace wi::graphics SM_6_6, SM_6_7, }; - enum class PrimitiveTopology + enum class PrimitiveTopology : uint8_t { UNDEFINED, TRIANGLELIST, @@ -81,7 +81,7 @@ namespace wi::graphics LINESTRIP, PATCHLIST, }; - enum class ComparisonFunc + enum class ComparisonFunc : uint8_t { NEVER, LESS, @@ -92,12 +92,12 @@ namespace wi::graphics GREATER_EQUAL, ALWAYS, }; - enum class DepthWriteMask + enum class DepthWriteMask : uint8_t { ZERO, // Disables depth write ALL, // Enables depth write }; - enum class StencilOp + enum class StencilOp : uint8_t { KEEP, ZERO, @@ -108,7 +108,7 @@ namespace wi::graphics INCR, DECR, }; - enum class Blend + enum class Blend : uint8_t { ZERO, ONE, @@ -128,7 +128,7 @@ namespace wi::graphics SRC1_ALPHA, INV_SRC1_ALPHA, }; - enum class BlendOp + enum class BlendOp : uint8_t { ADD, SUBTRACT, @@ -136,29 +136,29 @@ namespace wi::graphics MIN, MAX, }; - enum class FillMode + enum class FillMode : uint8_t { WIREFRAME, SOLID, }; - enum class CullMode + enum class CullMode : uint8_t { NONE, FRONT, BACK, }; - enum class InputClassification + enum class InputClassification : uint8_t { PER_VERTEX_DATA, PER_INSTANCE_DATA, }; - enum class Usage + enum class Usage : uint8_t { DEFAULT, // CPU no access, GPU read/write UPLOAD, // CPU write, GPU read READBACK, // CPU read, GPU write }; - enum class TextureAddressMode + enum class TextureAddressMode : uint8_t { WRAP, MIRROR, @@ -166,7 +166,7 @@ namespace wi::graphics BORDER, MIRROR_ONCE, }; - enum class Filter + enum class Filter : uint8_t { MIN_MAG_MIP_POINT, MIN_MAG_POINT_MIP_LINEAR, @@ -205,13 +205,13 @@ namespace wi::graphics MAXIMUM_MIN_MAG_MIP_LINEAR, MAXIMUM_ANISOTROPIC, }; - enum class SamplerBorderColor + enum class SamplerBorderColor : uint8_t { TRANSPARENT_BLACK, OPAQUE_BLACK, OPAQUE_WHITE, }; - enum class Format + enum class Format : uint8_t { UNKNOWN, @@ -291,18 +291,18 @@ namespace wi::graphics NV12, // video YUV420; SRV Luminance aspect: R8_UNORM, SRV Chrominance aspect: R8G8_UNORM }; - enum class GpuQueryType + enum class GpuQueryType : uint8_t { TIMESTAMP, // retrieve time point of gpu execution OCCLUSION, // how many samples passed depth test? OCCLUSION_BINARY, // depth test passed or not? }; - enum class IndexBufferFormat + enum class IndexBufferFormat : uint8_t { UINT16, UINT32, }; - enum class SubresourceType + enum class SubresourceType : uint8_t { SRV, // shader resource view UAV, // unordered access view @@ -310,7 +310,7 @@ namespace wi::graphics DSV, // depth stencil view }; - enum class ShadingRate + enum class ShadingRate : uint8_t { RATE_1X1, // Default/full shading rate RATE_1X2, @@ -323,13 +323,13 @@ namespace wi::graphics RATE_INVALID }; - enum class PredicationOp + enum class PredicationOp : uint8_t { EQUAL_ZERO, NOT_EQUAL_ZERO, }; - enum class ImageAspect + enum class ImageAspect : uint8_t { COLOR, DEPTH, @@ -338,18 +338,18 @@ namespace wi::graphics CHROMINANCE, }; - enum class VideoFrameType + enum class VideoFrameType : uint8_t { Intra, Predictive, }; - enum class VideoProfile + enum class VideoProfile : uint8_t { H264, // AVC }; - enum class ComponentSwizzle + enum class ComponentSwizzle : uint8_t { R, G, @@ -359,6 +359,13 @@ namespace wi::graphics ONE, }; + enum class ColorSpace : uint8_t + { + SRGB, // SDR color space (8 or 10 bits per channel) + HDR10_ST2084, // HDR10 color space (10 bits per channel) + HDR_LINEAR, // HDR color space (16 bits per channel) + }; + // Flags //////////////////////////////////////////// enum class ColorWrite @@ -474,13 +481,6 @@ namespace wi::graphics VIDEO_DECODE_DST = 1 << 16, // video decode operation destination DPB texture }; - enum class ColorSpace - { - SRGB, // SDR color space (8 or 10 bits per channel) - HDR10_ST2084, // HDR10 color space (10 bits per channel) - HDR_LINEAR, // HDR color space (16 bits per channel) - }; - enum class RenderPassFlags { NONE = 0, @@ -538,25 +538,25 @@ namespace wi::graphics struct TextureDesc { - enum class Type + enum class Type : uint8_t { TEXTURE_1D, TEXTURE_2D, TEXTURE_3D, } type = Type::TEXTURE_2D; + Format format = Format::UNKNOWN; uint32_t width = 1; uint32_t height = 1; uint32_t depth = 1; uint32_t array_size = 1; uint32_t mip_levels = 1; - Format format = Format::UNKNOWN; uint32_t sample_count = 1; + ClearValue clear = {}; + Swizzle swizzle; Usage usage = Usage::DEFAULT; BindFlag bind_flags = BindFlag::NONE; ResourceMiscFlag misc_flags = ResourceMiscFlag::NONE; - ClearValue clear = {}; ResourceState layout = ResourceState::SHADER_RESOURCE; - Swizzle swizzle; }; struct SamplerDesc @@ -632,11 +632,11 @@ namespace wi::graphics { uint64_t size = 0; Usage usage = Usage::DEFAULT; + Format format = Format::UNKNOWN; // only needed for typed buffer! + uint32_t stride = 0; // only needed for structured buffer types! + uint64_t alignment = 0; // needed for tile pools BindFlag bind_flags = BindFlag::NONE; ResourceMiscFlag misc_flags = ResourceMiscFlag::NONE; - uint32_t stride = 0; // only needed for structured buffer types! - Format format = Format::UNKNOWN; // only needed for typed buffer! - uint64_t alignment = 0; // needed for tile pools }; struct GPUQueryHeapDesc @@ -840,7 +840,7 @@ namespace wi::graphics struct GPUResource : public GraphicsDeviceChild { - enum class Type + enum class Type : uint8_t { BUFFER, TEXTURE, diff --git a/WickedEngine/wiPhysics_Jolt.cpp b/WickedEngine/wiPhysics_Jolt.cpp index 3f4f31767..00be3c5a0 100644 --- a/WickedEngine/wiPhysics_Jolt.cpp +++ b/WickedEngine/wiPhysics_Jolt.cpp @@ -64,6 +64,12 @@ namespace wi::physics float TIMESTEP = 1.0f / 60.0f; bool INTERPOLATION = true; + const uint cMaxBodies = 65536; + const uint cNumBodyMutexes = 0; + const uint cMaxBodyPairs = 65536; + const uint cMaxContactConstraints = 65536; + const EMotionQuality cMotionQuality = EMotionQuality::LinearCast; + inline Vec3 cast(const XMFLOAT3& v) { return Vec3(v.x, v.y, v.z); } inline Quat cast(const XMFLOAT4& v) { return Quat(v.x, v.y, v.z, v.w); } inline Mat44 cast(const XMFLOAT4X4& v) @@ -197,10 +203,6 @@ namespace wi::physics { auto physics_scene = std::make_shared(); - const uint cMaxBodies = 65536; - const uint cNumBodyMutexes = 0; - const uint cMaxBodyPairs = 65536; - const uint cMaxContactConstraints = 10240; physics_scene->physics_system.Init( cMaxBodies, cNumBodyMutexes, @@ -343,8 +345,8 @@ namespace wi::physics } else { - wi::backlog::post("Convex Hull physics requested, but no MeshComponent provided!", wi::backlog::LogLevel::Error); - assert(0); + wi::backlog::post("AddRigidBody failed: convex hull physics requested, but no MeshComponent provided!", wi::backlog::LogLevel::Error); + return; } break; @@ -377,8 +379,8 @@ namespace wi::physics } else { - wi::backlog::post("Triangle Mesh physics requested, but no MeshComponent provided!", wi::backlog::LogLevel::Error); - assert(0); + wi::backlog::post("AddRigidBody failed: triangle mesh physics requested, but no MeshComponent provided!", wi::backlog::LogLevel::Error); + return; } break; } @@ -430,12 +432,14 @@ namespace wi::physics settings.mMassPropertiesOverride.mMass = 1; } settings.mAllowSleeping = !physicscomponent.IsDisableDeactivation(); - settings.mMotionQuality = EMotionQuality::LinearCast; + settings.mMotionQuality = cMotionQuality; settings.mUserData = (uint64_t)&physicsobject; BodyInterface& body_interface = physics_scene.physics_system.GetBodyInterface(); // locking version because this is called from job system! - physicsobject.bodyID = body_interface.CreateAndAddBody(settings, EActivation::Activate); + const EActivation activation = physicscomponent.IsStartDeactivated() ? EActivation::DontActivate : EActivation::Activate; + + physicsobject.bodyID = body_interface.CreateAndAddBody(settings, activation); if (physicsobject.bodyID.IsInvalid()) { physicscomponent.physicsobject = nullptr; @@ -884,7 +888,7 @@ namespace wi::physics part.mPosition = positions[p]; part.mRotation = Quat::sIdentity(); part.mMotionType = EMotionType::Kinematic; - part.mMotionQuality = EMotionQuality::LinearCast; + part.mMotionQuality = cMotionQuality; part.mObjectLayer = Layers::MOVING; part.mOverrideMassProperties = EOverrideMassProperties::CalculateInertia; part.mMassPropertiesOverride.mMass = masses[p]; @@ -1178,29 +1182,40 @@ namespace wi::physics } } - if (currentMotionType == EMotionType::Kinematic) - { - TransformComponent* transform = scene.transforms.GetComponent(entity); - if (transform == nullptr) - return; + TransformComponent* transform = scene.transforms.GetComponent(entity); + if (transform == nullptr) + return; - body_interface.MoveKinematic( - physicsobject.bodyID, - cast(transform->GetPosition()), - cast(transform->GetRotation()), - physics_scene.GetKinematicDT(scene.dt) - ); + if (IsSimulationEnabled()) + { + if (currentMotionType == EMotionType::Kinematic) + { + body_interface.MoveKinematic( + physicsobject.bodyID, + cast(transform->GetPosition()), + cast(transform->GetRotation()), + physics_scene.GetKinematicDT(scene.dt) + ); + } + else if (currentMotionType == EMotionType::Static) + { + body_interface.SetPositionAndRotation( + physicsobject.bodyID, + cast(transform->GetPosition()), + cast(transform->GetRotation()), + EActivation::DontActivate + ); + } } - else if (currentMotionType == EMotionType::Static) + else if (currentMotionType != EMotionType::Dynamic) { - TransformComponent* transform = scene.transforms.GetComponent(entity); - if (transform == nullptr) - return; - + // Simulation is disabled, update physics state immediately: + physicsobject.prev_position = cast(transform->GetPosition()); + physicsobject.prev_rotation = cast(transform->GetRotation()); body_interface.SetPositionAndRotation( physicsobject.bodyID, - cast(transform->GetPosition()), - cast(transform->GetRotation()), + physicsobject.prev_position, + physicsobject.prev_rotation, EActivation::Activate ); } @@ -1240,11 +1255,14 @@ namespace wi::physics body_interface.SetFriction(physicsobject.bodyID, physicscomponent.friction); body_interface.SetRestitution(physicsobject.bodyID, physicscomponent.restitution); - // Add wind: - const Vec3 wind = cast(scene.weather.windDirection); - if (!wind.IsNearZero()) + if (IsSimulationEnabled()) { - body_interface.AddForce(physicsobject.bodyID, wind, EActivation::Activate); + // Add wind: + const Vec3 wind = cast(scene.weather.windDirection); + if (!wind.IsNearZero()) + { + body_interface.AddForce(physicsobject.bodyID, wind, EActivation::Activate); + } } // This is different from rigid bodies, because soft body is a per mesh component (no TransformComponent). World matrix is propagated down from single mesh instance (ObjectUpdateSystem). @@ -1300,14 +1318,43 @@ namespace wi::physics humanoid.ragdoll = std::make_shared(scene, humanoid, humanoidEntity, scale); } Ragdoll& ragdoll = *(Ragdoll*)humanoid.ragdoll.get(); - if (humanoid.IsRagdollPhysicsEnabled()) - { - ragdoll.Activate(scene, humanoidEntity); - } - else - { - ragdoll.Deactivate(scene); + if (IsSimulationEnabled()) + { + if (humanoid.IsRagdollPhysicsEnabled()) + { + ragdoll.Activate(scene, humanoidEntity); + } + else + { + ragdoll.Deactivate(scene); + + BodyInterface& body_interface = physics_scene.physics_system.GetBodyInterface(); // locking, these jobs can be adding bodies + for (auto& rb : ragdoll.rigidbodies) + { + TransformComponent* transform = scene.transforms.GetComponent(rb.entity); + if (transform == nullptr) + return; + + const Vec3 position = cast(transform->GetPosition()); + const Quat rotation = cast(transform->GetRotation()); + + Mat44 m = Mat44::sTranslation(position) * Mat44::sRotation(rotation); + m = m * rb.restBasisInverse; + m = m * rb.additionalTransform; + + body_interface.MoveKinematic( + rb.bodyID, + m.GetTranslation(), + m.GetQuaternion().Normalized(), + physics_scene.GetKinematicDT(scene.dt) + ); + } + } + } + else if(!humanoid.IsRagdollPhysicsEnabled()) + { + // Simulation is disabled, update physics state immediately: BodyInterface& body_interface = physics_scene.physics_system.GetBodyInterface(); // locking, these jobs can be adding bodies for (auto& rb : ragdoll.rigidbodies) { @@ -1315,24 +1362,21 @@ namespace wi::physics if (transform == nullptr) return; - XMVECTOR SCA = {}; - XMVECTOR ROT = {}; - XMVECTOR TRA = {}; - XMMatrixDecompose(&SCA, &ROT, &TRA, XMLoadFloat4x4(&transform->world)); - XMFLOAT4 rot = {}; - XMFLOAT3 tra = {}; - XMStoreFloat4(&rot, ROT); - XMStoreFloat3(&tra, TRA); + const Vec3 position = cast(transform->GetPosition()); + const Quat rotation = cast(transform->GetRotation()); - Mat44 m = Mat44::sTranslation(cast(tra)) * Mat44::sRotation(cast(rot)); + Mat44 m = Mat44::sTranslation(position) * Mat44::sRotation(rotation); m = m * rb.restBasisInverse; m = m * rb.additionalTransform; - body_interface.MoveKinematic( + rb.prev_position = m.GetTranslation(); + rb.prev_rotation = m.GetQuaternion().Normalized(); + + body_interface.SetPositionAndRotation( rb.bodyID, - m.GetTranslation(), - m.GetQuaternion().Normalized(), - physics_scene.GetKinematicDT(scene.dt) + rb.prev_position, + rb.prev_rotation, + EActivation::DontActivate ); } } @@ -1345,7 +1389,8 @@ namespace wi::physics // Perform internal simulation step: if (IsSimulationEnabled()) { - static TempAllocatorImpl temp_allocator(10 * 1024 * 1024); + //static TempAllocatorImpl temp_allocator(10 * 1024 * 1024); + static TempAllocatorMalloc temp_allocator; // 10-100 MB was not enough for large simulation, I don't want to reserve more memory up front static JobSystemThreadPool job_system(cMaxPhysicsJobs, cMaxPhysicsBarriers, thread::hardware_concurrency() - 1); physics_scene.accumulator += dt; diff --git a/WickedEngine/wiScene_Components.h b/WickedEngine/wiScene_Components.h index a83026a38..f8102d32a 100644 --- a/WickedEngine/wiScene_Components.h +++ b/WickedEngine/wiScene_Components.h @@ -902,6 +902,7 @@ namespace wi::scene EMPTY = 0, DISABLE_DEACTIVATION = 1 << 0, KINEMATIC = 1 << 1, + START_DEACTIVATED = 1 << 2, }; uint32_t _flags = EMPTY; @@ -916,7 +917,7 @@ namespace wi::scene ENUM_FORCE_UINT32 = 0xFFFFFFFF }; CollisionShape shape; - float mass = 1.0f; + float mass = 1.0f; // Set to 0 to make body static float friction = 0.2f; float restitution = 0.1f; float damping_linear = 0.05f; @@ -947,9 +948,11 @@ namespace wi::scene inline void SetDisableDeactivation(bool value) { if (value) { _flags |= DISABLE_DEACTIVATION; } else { _flags &= ~DISABLE_DEACTIVATION; } } inline void SetKinematic(bool value) { if (value) { _flags |= KINEMATIC; } else { _flags &= ~KINEMATIC; } } + inline void SetStartDeactivated(bool value) { if (value) { _flags |= START_DEACTIVATED; } else { _flags &= ~START_DEACTIVATED; } } inline bool IsDisableDeactivation() const { return _flags & DISABLE_DEACTIVATION; } inline bool IsKinematic() const { return _flags & KINEMATIC; } + inline bool IsStartDeactivated() const { return _flags & START_DEACTIVATED; } void Serialize(wi::Archive& archive, wi::ecs::EntitySerializer& seri); }; diff --git a/WickedEngine/wiTerrain.cpp b/WickedEngine/wiTerrain.cpp index 56b29c361..0e8bbd147 100644 --- a/WickedEngine/wiTerrain.cpp +++ b/WickedEngine/wiTerrain.cpp @@ -808,18 +808,6 @@ namespace wi::terrain rigidbody->mesh_lod = lod_required; rigidbody->physicsobject = {}; // will be recreated } - else - { - if (dist < physics_generation) - { - wi::physics::SetActivationState(*rigidbody, wi::physics::ActivationState::Active); - } - else - { - //scene->rigidbodies.Remove(chunk_data.entity); - wi::physics::SetActivationState(*rigidbody, wi::physics::ActivationState::Inactive); - } - } } else { @@ -827,8 +815,7 @@ namespace wi::terrain { RigidBodyPhysicsComponent& newrigidbody = scene->rigidbodies.Create(chunk_data.entity); newrigidbody.shape = RigidBodyPhysicsComponent::TRIANGLE_MESH; - //newrigidbody.SetDisableDeactivation(true); - newrigidbody.SetKinematic(true); + newrigidbody.mass = 0; // terrain chunks are static newrigidbody.mesh_lod = lod_required; } } diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index e8dcda0fd..86b4dea5a 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 = 494; + const int revision = 495; const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);