diff --git a/Documentation/WickedEngine-Documentation.md b/Documentation/WickedEngine-Documentation.md
index 878a52f63..103f16ed2 100644
--- a/Documentation/WickedEngine-Documentation.md
+++ b/Documentation/WickedEngine-Documentation.md
@@ -800,8 +800,8 @@ The custom GUI, implemented with engine features
[[Header]](../WickedEngine/wiGUI.h) [[Cpp]](../WickedEngine/wiGUI.cpp)
The wiGUI is responsible to run a GUI interface and manage widgets.
-GUI Scaling: The wiGUI is created with a default size of (1920*1080), so by default, placing elements (widgets) onto the GUI will be relative to this resolution. This can be freely modified by calling the `wiGUI::SetSize()` function.
-When the GUI is updated (usually done by [RenderPath2D](#renderpath2d) automatically), the GUI size will take the current screen size, and scale the contents accordingly. When the application window is resized, the GUI scaling will take effect automatically. When adding widgets to the GUI, they are always placed relative to the current GUI size, which could be different from the starting GUI size, if the GUI was updated and the application resolution is different from the default GUI size.
+GUI Scaling: The wiGUI is created with a default size of the application window size, so by default, placing elements (widgets) onto the GUI will be relative to this resolution. This can be modified by calling the `wiGUI::SetDesignSize()` function.
+When the GUI is updated (usually done by [RenderPath2D](#renderpath2d) automatically), the GUI size will take the current screen size, and scale the contents accordingly. When the application window is resized, the GUI scaling will take effect automatically. When adding widgets to the GUI, they are always placed relative to the current GUI size, which could be different from the design GUI size, if the GUI was updated and the application resolution is different from the design GUI size.
### wiEventArgs
[[Header]](../WickedEngine/wiWidget.h) [[Cpp]](../WickedEngine/wiWidget.cpp)
diff --git a/Editor/CameraWindow.cpp b/Editor/CameraWindow.cpp
index a66bec60f..730a480fd 100644
--- a/Editor/CameraWindow.cpp
+++ b/Editor/CameraWindow.cpp
@@ -137,7 +137,7 @@ CameraWindow::CameraWindow(wiGUI* gui) :GUI(gui)
SetEntity(INVALID_ENTITY);
- cameraWindow->Translate(XMFLOAT3(gui->GetSize().x - 720, 500, 0));
+ cameraWindow->Translate(XMFLOAT3((float)wiRenderer::GetDevice()->GetScreenWidth() - 720, 500, 0));
cameraWindow->SetVisible(false);
}
diff --git a/Editor/Editor.cpp b/Editor/Editor.cpp
index 6e5df68f7..2d0edb1b5 100644
--- a/Editor/Editor.cpp
+++ b/Editor/Editor.cpp
@@ -216,7 +216,6 @@ void EditorComponent::Load()
float screenW = (float)wiRenderer::GetDevice()->GetScreenWidth();
float screenH = (float)wiRenderer::GetDevice()->GetScreenHeight();
- GetGUI().SetSize(screenW, screenH);
XMFLOAT2 option_size = XMFLOAT2(100, 28);
float step = (option_size.y + 5) * -1, x = screenW - option_size.x, y = screenH - option_size.y;
@@ -2190,52 +2189,21 @@ void EditorComponent::EndTranslate()
Scene& scene = wiScene::GetScene();
+ scene.Component_DetachChildren(translator.entityID);
+
// Remove translator from scene:
scene.Entity_Remove(translator.entityID);
- // Translation ended, apply all final transformations as local pose:
- for (size_t i = 0; i < scene.hierarchy.GetCount(); ++i)
- {
- HierarchyComponent& parent = scene.hierarchy[i];
-
- if (parent.parentID == translator.entityID) // only to entities that were attached to translator!
- {
- Entity entity = scene.hierarchy.GetEntity(i);
- TransformComponent* transform = scene.transforms.GetComponent(entity);
- if (transform != nullptr)
- {
- transform->ApplyTransform(); // (**)
- }
- }
- }
-
- // Restore scene hierarchy from before translation:
- scene.hierarchy.Copy(savedHierarchy);
-
- // If an attached entity got moved, then the world transform was applied to it (**),
- // so we need to reattach it properly to the parent matrix:
+ // Restore parents before selections were attached to translator:
for (const wiScene::PickResult& x : selected)
{
- HierarchyComponent* parent = scene.hierarchy.GetComponent(x.entity);
- if (parent != nullptr)
+ HierarchyComponent* hierarchy_prev = savedHierarchy.GetComponent(x.entity);
+ if (hierarchy_prev != nullptr)
{
- TransformComponent* transform_parent = scene.transforms.GetComponent(parent->parentID);
- if (transform_parent != nullptr)
- {
- // Save the parent's inverse worldmatrix:
- XMStoreFloat4x4(&parent->world_parent_inverse_bind, XMMatrixInverse(nullptr, XMLoadFloat4x4(&transform_parent->world)));
-
- TransformComponent* transform_child = scene.transforms.GetComponent(x.entity);
- if (transform_child != nullptr)
- {
- // Child updated immediately, to that it can be immediately attached to afterwards:
- transform_child->UpdateTransform_Parented(*transform_parent, parent->world_parent_inverse_bind);
- }
- }
-
+ scene.Component_Attach(x.entity, hierarchy_prev->parentID);
}
}
-
+ savedHierarchy.Clear();
selected.clear();
}
void EditorComponent::AddSelected(const wiScene::PickResult& picked)
diff --git a/Editor/ForceFieldWindow.cpp b/Editor/ForceFieldWindow.cpp
index 64f991d61..dff490e4d 100644
--- a/Editor/ForceFieldWindow.cpp
+++ b/Editor/ForceFieldWindow.cpp
@@ -107,7 +107,7 @@ ForceFieldWindow::ForceFieldWindow(wiGUI* gui) : GUI(gui)
- forceFieldWindow->Translate(XMFLOAT3(gui->GetSize().x - 720, 50, 0));
+ forceFieldWindow->Translate(XMFLOAT3((float)wiRenderer::GetDevice()->GetScreenWidth() - 720, 50, 0));
forceFieldWindow->SetVisible(false);
SetEntity(INVALID_ENTITY);
diff --git a/Editor/MaterialWindow.cpp b/Editor/MaterialWindow.cpp
index 7dd7b81b1..91bd70bd2 100644
--- a/Editor/MaterialWindow.cpp
+++ b/Editor/MaterialWindow.cpp
@@ -750,7 +750,7 @@ MaterialWindow::MaterialWindow(wiGUI* gui) : GUI(gui)
materialWindow->AddWidget(texture_occlusion_uvset_Field);
- materialWindow->Translate(XMFLOAT3(gui->GetSize().x - 880, 120, 0));
+ materialWindow->Translate(XMFLOAT3((float)wiRenderer::GetDevice()->GetScreenWidth() - 880, 120, 0));
materialWindow->SetVisible(false);
SetEntity(INVALID_ENTITY);
diff --git a/Editor/MeshWindow.cpp b/Editor/MeshWindow.cpp
index 9913056d2..b5bb87bfa 100644
--- a/Editor/MeshWindow.cpp
+++ b/Editor/MeshWindow.cpp
@@ -220,7 +220,7 @@ MeshWindow::MeshWindow(wiGUI* gui) : GUI(gui)
- meshWindow->Translate(XMFLOAT3(gui->GetSize().x - 910, 520, 0));
+ meshWindow->Translate(XMFLOAT3((float)wiRenderer::GetDevice()->GetScreenWidth() - 910, 520, 0));
meshWindow->SetVisible(false);
SetEntity(INVALID_ENTITY);
diff --git a/Editor/ModelImporter_GLTF.cpp b/Editor/ModelImporter_GLTF.cpp
index b7d62bc2f..0bba82f9e 100644
--- a/Editor/ModelImporter_GLTF.cpp
+++ b/Editor/ModelImporter_GLTF.cpp
@@ -204,7 +204,7 @@ void LoadNode(int nodeIndex, Entity parent, LoaderState& state)
Entity objectEntity = scene.Entity_CreateObject(node.name);
ObjectComponent& object = *scene.objects.GetComponent(objectEntity);
object.meshID = scene.meshes.GetEntity(node.mesh);
- scene.Component_Attach(objectEntity, entity);
+ scene.Component_Attach(objectEntity, entity, true);
}
else
{
@@ -270,14 +270,11 @@ void LoadNode(int nodeIndex, Entity parent, LoaderState& state)
transform.ApplyTransform(); // this creates S, R, T vectors from world matrix
}
- // Important:
- // Do NOT call UpdateTransform, because Attach will query parent world matrix, and invert it for bind matrix
- // But here we load everything in bind space (relative to parent) already, so it must be IDENTITY!
- transform.world = IDENTITYMATRIX;
+ transform.UpdateTransform();
if (parent != INVALID_ENTITY)
{
- scene.Component_Attach(entity, parent);
+ scene.Component_Attach(entity, parent, true);
}
if (!node.children.empty())
diff --git a/Editor/ObjectWindow.cpp b/Editor/ObjectWindow.cpp
index 2c25cc232..ac924a7e8 100644
--- a/Editor/ObjectWindow.cpp
+++ b/Editor/ObjectWindow.cpp
@@ -570,7 +570,7 @@ ObjectWindow::ObjectWindow(EditorComponent* editor) : editor(editor)
- objectWindow->Translate(XMFLOAT3(GUI->GetSize().x - 720, 120, 0));
+ objectWindow->Translate(XMFLOAT3((float)wiRenderer::GetDevice()->GetScreenWidth() - 720, 120, 0));
objectWindow->SetVisible(false);
SetEntity(INVALID_ENTITY);
diff --git a/Editor/PostprocessWindow.cpp b/Editor/PostprocessWindow.cpp
index 60a9e7fa2..0bbec917a 100644
--- a/Editor/PostprocessWindow.cpp
+++ b/Editor/PostprocessWindow.cpp
@@ -332,7 +332,7 @@ PostprocessWindow::PostprocessWindow(wiGUI* gui, RenderPath3D* comp) : GUI(gui),
ppWindow->AddWidget(chromaticaberrationSlider);
- ppWindow->Translate(XMFLOAT3(gui->GetSize().x - 550, 50, 0));
+ ppWindow->Translate(XMFLOAT3((float)wiRenderer::GetDevice()->GetScreenWidth() - 550, 50, 0));
ppWindow->SetVisible(false);
}
diff --git a/Tests/Tests.cpp b/Tests/Tests.cpp
index b913b394c..28b7f3857 100644
--- a/Tests/Tests.cpp
+++ b/Tests/Tests.cpp
@@ -31,7 +31,6 @@ void TestsRenderer::Load()
float screenW = (float)wiRenderer::GetDevice()->GetScreenWidth();
float screenH = (float)wiRenderer::GetDevice()->GetScreenHeight();
- GetGUI().SetSize(screenW, screenH);
wiLabel* label = new wiLabel("Label1");
label->SetText("Wicked Engine Test Framework");
diff --git a/WickedEngine/ArchiveVersionHistory.txt b/WickedEngine/ArchiveVersionHistory.txt
index f997b1e0a..7e2852f80 100644
--- a/WickedEngine/ArchiveVersionHistory.txt
+++ b/WickedEngine/ArchiveVersionHistory.txt
@@ -1,5 +1,6 @@
This file contains changelog of wiArchive versions
+36: Removed HierarchyComponent::world_parent_inverse_bind
35: Roughness remapped to corrected brdf
34: Removed restPose from SoftBodyPhysicsComponent
33: LightComponent shadow bias behaviour changed
diff --git a/WickedEngine/wiArchive.cpp b/WickedEngine/wiArchive.cpp
index c81b79420..e55c8d882 100644
--- a/WickedEngine/wiArchive.cpp
+++ b/WickedEngine/wiArchive.cpp
@@ -7,7 +7,7 @@
using namespace std;
// this should always be only INCREMENTED and only if a new serialization is implemeted somewhere!
-uint64_t __archiveVersion = 35;
+uint64_t __archiveVersion = 36;
// this is the version number of which below the archive is not compatible with the current version
uint64_t __archiveVersionBarrier = 22;
diff --git a/WickedEngine/wiGUI.cpp b/WickedEngine/wiGUI.cpp
index da7e3ed5c..608e1ecab 100644
--- a/WickedEngine/wiGUI.cpp
+++ b/WickedEngine/wiGUI.cpp
@@ -12,7 +12,11 @@ void wiGUIElement::AttachTo(wiGUIElement* parent)
this->parent = parent;
this->parent->UpdateTransform();
- XMStoreFloat4x4(&world_parent_bind, XMMatrixInverse(nullptr, XMLoadFloat4x4(&parent->world)));
+ XMMATRIX B = XMMatrixInverse(nullptr, XMLoadFloat4x4(&parent->world));
+
+ MatrixTransform(B);
+ UpdateTransform();
+ UpdateTransform_Parented(*parent);
}
void wiGUIElement::Detach()
{
@@ -66,7 +70,15 @@ void wiGUI::Update(float dt)
return;
}
- SetSize((float)wiRenderer::GetDevice()->GetScreenWidth(), (float)wiRenderer::GetDevice()->GetScreenHeight());
+ XMFLOAT2 size_screen = XMFLOAT2((float)wiRenderer::GetDevice()->GetScreenWidth(), (float)wiRenderer::GetDevice()->GetScreenHeight());
+ if (size_design.x == 0 || size_design.y == 0)
+ {
+ size_design = size_screen;
+ }
+ scale_local.x = size_screen.x / size_design.x;
+ scale_local.y = size_screen.y / size_design.y;
+ SetDirty();
+ UpdateTransform();
XMFLOAT4 _p = wiInput::GetPointer();
pointerpos.x = _p.x;
diff --git a/WickedEngine/wiGUI.h b/WickedEngine/wiGUI.h
index 41aa1826e..3616d41f7 100644
--- a/WickedEngine/wiGUI.h
+++ b/WickedEngine/wiGUI.h
@@ -17,7 +17,6 @@ public:
wiGraphics::Rect scissorRect;
wiGUIElement* parent = nullptr;
- XMFLOAT4X4 world_parent_bind = IDENTITYMATRIX;
void AttachTo(wiGUIElement* parent);
void Detach();
};
@@ -31,11 +30,8 @@ private:
bool focus = false;
bool visible = true;
XMFLOAT2 pointerpos = XMFLOAT2(0, 0);
+ XMFLOAT2 size_design = XMFLOAT2(0, 0);
public:
- wiGUI()
- {
- SetSize(1920, 1080); // default size
- }
~wiGUI();
void Update(float dt);
@@ -57,14 +53,8 @@ public:
void SetVisible(bool value) { visible = value; }
bool IsVisible() { return visible; }
- XMFLOAT2 GetSize() const { return XMFLOAT2(scale_local.x, scale_local.y); }
- void SetSize(float width, float height)
- {
- SetDirty();
- scale_local.x = width;
- scale_local.y = height;
- UpdateTransform();
- }
+ void SetDesignSize(float width, float height) { size_design = XMFLOAT2(width, height); }
+ const XMFLOAT2& GetDesignSize() const { return size_design; }
const XMFLOAT2& GetPointerPos() const
{
diff --git a/WickedEngine/wiScene.cpp b/WickedEngine/wiScene.cpp
index f628aba52..9e161223b 100644
--- a/WickedEngine/wiScene.cpp
+++ b/WickedEngine/wiScene.cpp
@@ -70,14 +70,13 @@ namespace wiScene
XMStoreFloat4x4(&world, GetLocalMatrix());
}
}
- void TransformComponent::UpdateTransform_Parented(const TransformComponent& parent, const XMFLOAT4X4& inverseParentBindMatrix)
+ void TransformComponent::UpdateTransform_Parented(const TransformComponent& parent)
{
- SetDirty();
+ //SetDirty();
XMMATRIX W = GetLocalMatrix();
XMMATRIX W_parent = XMLoadFloat4x4(&parent.world);
- XMMATRIX B = XMLoadFloat4x4(&inverseParentBindMatrix);
- W = W * B * W_parent;
+ W = W * W_parent;
XMStoreFloat4x4(&world, W);
}
@@ -1395,7 +1394,7 @@ namespace wiScene
return entity;
}
- void Scene::Component_Attach(Entity entity, Entity parent)
+ void Scene::Component_Attach(Entity entity, Entity parent, bool child_already_in_local_space)
{
assert(entity != parent);
@@ -1437,14 +1436,20 @@ namespace wiScene
{
transform_parent = &transforms.Create(parent);
}
- // Save the parent's inverse worldmatrix:
- XMStoreFloat4x4(&parentcomponent.world_parent_inverse_bind, XMMatrixInverse(nullptr, XMLoadFloat4x4(&transform_parent->world)));
TransformComponent* transform_child = transforms.GetComponent(entity);
if (transform_child == nullptr)
{
- transform_child = &transforms.Create(entity);
+ transform_child = &transforms.Create(entity);
+ transform_parent = transforms.GetComponent(parent); // after transforms.Create(), transform_parent pointer could have become invalidated!
}
+ if (!child_already_in_local_space)
+ {
+ XMMATRIX B = XMMatrixInverse(nullptr, XMLoadFloat4x4(&transform_parent->world));
+ transform_child->MatrixTransform(B);
+ transform_child->UpdateTransform();
+ }
+ transform_child->UpdateTransform_Parented(*transform_parent);
LayerComponent* layer_parent = layers.GetComponent(parent);
if (layer_parent == nullptr)
@@ -1666,7 +1671,7 @@ namespace wiScene
TransformComponent* transform_parent = transforms.GetComponent(parentcomponent.parentID);
if (transform_child != nullptr && transform_parent != nullptr)
{
- transform_child->UpdateTransform_Parented(*transform_parent, parentcomponent.world_parent_inverse_bind);
+ transform_child->UpdateTransform_Parented(*transform_parent);
}
diff --git a/WickedEngine/wiScene.h b/WickedEngine/wiScene.h
index d46756754..cfb56e4bc 100644
--- a/WickedEngine/wiScene.h
+++ b/WickedEngine/wiScene.h
@@ -68,7 +68,7 @@ namespace wiScene
XMVECTOR GetScaleV() const;
XMMATRIX GetLocalMatrix() const;
void UpdateTransform();
- void UpdateTransform_Parented(const TransformComponent& parent, const XMFLOAT4X4& inverseParentBindMatrix = IDENTITYMATRIX);
+ void UpdateTransform_Parented(const TransformComponent& parent);
void ApplyTransform();
void ClearTransform();
void Translate(const XMFLOAT3& value);
@@ -95,7 +95,6 @@ namespace wiScene
{
wiECS::Entity parentID = wiECS::INVALID_ENTITY;
uint32_t layerMask_bind; // saved child layermask at the time of binding
- XMFLOAT4X4 world_parent_inverse_bind; // saved parent inverse worldmatrix at the time of binding
void Serialize(wiArchive& archive, uint32_t seed = 0);
};
@@ -1090,7 +1089,8 @@ namespace wiScene
);
// Attaches an entity to a parent:
- void Component_Attach(wiECS::Entity entity, wiECS::Entity parent);
+ // child_already_in_local_space : child won't be transformed from world space to local space
+ void Component_Attach(wiECS::Entity entity, wiECS::Entity parent, bool child_already_in_local_space = false);
// Detaches the entity from its parent (if it is attached):
void Component_Detach(wiECS::Entity entity);
// Detaches all children from an entity (if there are any):
diff --git a/WickedEngine/wiScene_Serializers.cpp b/WickedEngine/wiScene_Serializers.cpp
index d2576d6a6..2a673bc43 100644
--- a/WickedEngine/wiScene_Serializers.cpp
+++ b/WickedEngine/wiScene_Serializers.cpp
@@ -63,12 +63,15 @@ namespace wiScene
if (archive.IsReadMode())
{
archive >> layerMask_bind;
- archive >> world_parent_inverse_bind;
+ if (archive.GetVersion() < 36)
+ {
+ XMFLOAT4X4 world_parent_inverse_bind;
+ archive >> world_parent_inverse_bind;
+ }
}
else
{
archive << layerMask_bind;
- archive << world_parent_inverse_bind;
}
}
void MaterialComponent::Serialize(wiArchive& archive, uint32_t seed)
diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp
index 6cbf8b807..dcf1facb1 100644
--- a/WickedEngine/wiVersion.cpp
+++ b/WickedEngine/wiVersion.cpp
@@ -9,7 +9,7 @@ namespace wiVersion
// minor features, major updates
const int minor = 38;
// minor bug fixes, alterations, refactors, updates
- const int revision = 6;
+ const int revision = 7;
long GetVersion()
diff --git a/WickedEngine/wiWidget.cpp b/WickedEngine/wiWidget.cpp
index aa5331b83..1eba3f0e1 100644
--- a/WickedEngine/wiWidget.cpp
+++ b/WickedEngine/wiWidget.cpp
@@ -39,7 +39,7 @@ void wiWidget::Update(wiGUI* gui, float dt)
if (parent != nullptr)
{
- this->UpdateTransform_Parented(*parent, world_parent_bind);
+ this->UpdateTransform_Parented(*parent);
}
XMVECTOR S, R, T;
@@ -1365,12 +1365,15 @@ wiWindow::wiWindow(wiGUI* gui, const std::string& name, bool window_controls) :
moveDragger->SetSize(XMFLOAT2(scale.x - windowcontrolSize * 3, windowcontrolSize));
moveDragger->SetPos(XMFLOAT2(windowcontrolSize, 0));
moveDragger->OnDrag([this, gui](wiEventArgs args) {
+ auto saved_parent = this->parent;
+ this->Detach();
this->Translate(XMFLOAT3(args.deltaPos.x, args.deltaPos.y, 0));
this->wiWidget::Update(gui, 0);
for (auto& x : this->childrenWidgets)
{
x->wiWidget::Update(gui, 0);
}
+ this->AttachTo(saved_parent);
});
AddWidget(moveDragger);
@@ -1402,6 +1405,8 @@ wiWindow::wiWindow(wiGUI* gui, const std::string& name, bool window_controls) :
resizeDragger_UpperLeft->SetSize(XMFLOAT2(windowcontrolSize, windowcontrolSize));
resizeDragger_UpperLeft->SetPos(XMFLOAT2(0, 0));
resizeDragger_UpperLeft->OnDrag([this, gui](wiEventArgs args) {
+ auto saved_parent = this->parent;
+ this->Detach();
XMFLOAT2 scaleDiff;
scaleDiff.x = (scale.x - args.deltaPos.x) / scale.x;
scaleDiff.y = (scale.y - args.deltaPos.y) / scale.y;
@@ -1412,6 +1417,7 @@ wiWindow::wiWindow(wiGUI* gui, const std::string& name, bool window_controls) :
{
x->wiWidget::Update(gui, 0);
}
+ this->AttachTo(saved_parent);
});
AddWidget(resizeDragger_UpperLeft);
@@ -1421,6 +1427,8 @@ wiWindow::wiWindow(wiGUI* gui, const std::string& name, bool window_controls) :
resizeDragger_BottomRight->SetSize(XMFLOAT2(windowcontrolSize, windowcontrolSize));
resizeDragger_BottomRight->SetPos(XMFLOAT2(translation.x + scale.x - windowcontrolSize, translation.y + scale.y - windowcontrolSize));
resizeDragger_BottomRight->OnDrag([this, gui](wiEventArgs args) {
+ auto saved_parent = this->parent;
+ this->Detach();
XMFLOAT2 scaleDiff;
scaleDiff.x = (scale.x + args.deltaPos.x) / scale.x;
scaleDiff.y = (scale.y + args.deltaPos.y) / scale.y;
@@ -1430,6 +1438,7 @@ wiWindow::wiWindow(wiGUI* gui, const std::string& name, bool window_controls) :
{
x->wiWidget::Update(gui, 0);
}
+ this->AttachTo(saved_parent);
});
AddWidget(resizeDragger_BottomRight);
}
diff --git a/models/Havoc/havoc.wiscene b/models/Havoc/havoc.wiscene
index 4ab34cea3..99bd7ea86 100644
Binary files a/models/Havoc/havoc.wiscene and b/models/Havoc/havoc.wiscene differ
diff --git a/models/girl.wiscene b/models/girl.wiscene
index 9d73b287e..ac875437c 100644
Binary files a/models/girl.wiscene and b/models/girl.wiscene differ