Editor gui v2 (#843)
This commit is contained in:
@@ -21,7 +21,7 @@ void AnimationWindow::Create(EditorComponent* _editor)
|
||||
|
||||
editor->RecordEntity(archive, entity);
|
||||
|
||||
editor->optionsWnd.RefreshEntityTree();
|
||||
editor->componentsWnd.RefreshEntityTree();
|
||||
});
|
||||
|
||||
float x = 80;
|
||||
@@ -922,7 +922,7 @@ void AnimationWindow::Create(EditorComponent* _editor)
|
||||
}
|
||||
scene.names.Create(retarget_entity) = name;
|
||||
|
||||
editor->optionsWnd.RefreshEntityTree();
|
||||
editor->componentsWnd.RefreshEntityTree();
|
||||
}
|
||||
});
|
||||
AddWidget(&retargetCombo);
|
||||
|
||||
@@ -22,7 +22,7 @@ void ArmatureWindow::Create(EditorComponent* _editor)
|
||||
|
||||
editor->RecordEntity(archive, entity);
|
||||
|
||||
editor->optionsWnd.RefreshEntityTree();
|
||||
editor->componentsWnd.RefreshEntityTree();
|
||||
});
|
||||
|
||||
float x = 60;
|
||||
@@ -217,7 +217,7 @@ void ArmatureWindow::Create(EditorComponent* _editor)
|
||||
// record NEW selection state...
|
||||
editor->RecordSelection(archive);
|
||||
|
||||
editor->optionsWnd.RefreshEntityTree();
|
||||
editor->componentsWnd.RefreshEntityTree();
|
||||
|
||||
});
|
||||
AddWidget(&boneList);
|
||||
|
||||
@@ -38,7 +38,6 @@ set (SOURCE_FILES
|
||||
HierarchyWindow.cpp
|
||||
ExpressionWindow.cpp
|
||||
ArmatureWindow.cpp
|
||||
OptionsWindow.cpp
|
||||
ComponentsWindow.cpp
|
||||
TerrainWindow.cpp
|
||||
HumanoidWindow.cpp
|
||||
|
||||
@@ -81,7 +81,7 @@ void CameraComponentWindow::Create(EditorComponent* _editor)
|
||||
|
||||
editor->RecordEntity(archive, entity);
|
||||
|
||||
editor->optionsWnd.RefreshEntityTree();
|
||||
editor->componentsWnd.RefreshEntityTree();
|
||||
});
|
||||
|
||||
float x = 140;
|
||||
|
||||
@@ -33,11 +33,13 @@ void CameraWindow::ResetCam()
|
||||
void CameraWindow::Create(EditorComponent* _editor)
|
||||
{
|
||||
editor = _editor;
|
||||
wi::gui::Window::Create("Camera", wi::gui::Window::WindowControls::COLLAPSE);
|
||||
wi::gui::Window::Create("Camera", wi::gui::Window::WindowControls::CLOSE | wi::gui::Window::WindowControls::RESIZE_RIGHT);
|
||||
SetText("Camera " ICON_CAMERAOPTIONS);
|
||||
|
||||
editor->GetCurrentEditorScene().camera_transform.MatrixTransform(editor->GetCurrentEditorScene().camera.GetInvView());
|
||||
editor->GetCurrentEditorScene().camera_transform.UpdateTransform();
|
||||
|
||||
SetSize(XMFLOAT2(320, 390));
|
||||
SetSize(XMFLOAT2(300, 390));
|
||||
|
||||
float x = 140;
|
||||
float y = 0;
|
||||
@@ -257,7 +259,7 @@ void CameraWindow::Create(EditorComponent* _editor)
|
||||
editor->RecordSelection(archive);
|
||||
editor->RecordEntity(archive, entity);
|
||||
|
||||
editor->optionsWnd.RefreshEntityTree();
|
||||
editor->componentsWnd.RefreshEntityTree();
|
||||
SetEntity(entity);
|
||||
});
|
||||
AddWidget(&proxyButton);
|
||||
@@ -277,9 +279,7 @@ void CameraWindow::Create(EditorComponent* _editor)
|
||||
|
||||
SetEntity(INVALID_ENTITY);
|
||||
|
||||
SetPos(XMFLOAT2(100, 100));
|
||||
|
||||
SetMinimized(true);
|
||||
SetVisible(false);
|
||||
}
|
||||
|
||||
void CameraWindow::SetEntity(Entity entity)
|
||||
|
||||
@@ -22,7 +22,7 @@ void ColliderWindow::Create(EditorComponent* _editor)
|
||||
|
||||
editor->RecordEntity(archive, entity);
|
||||
|
||||
editor->optionsWnd.RefreshEntityTree();
|
||||
editor->componentsWnd.RefreshEntityTree();
|
||||
});
|
||||
|
||||
float x = 60;
|
||||
|
||||
+446
-19
File diff suppressed because it is too large
Load Diff
@@ -74,4 +74,53 @@ public:
|
||||
SpriteWindow spriteWnd;
|
||||
FontWindow fontWnd;
|
||||
VoxelGridWindow voxelGridWnd;
|
||||
|
||||
enum class Filter : uint64_t
|
||||
{
|
||||
Transform = 1 << 0,
|
||||
Material = 1 << 1,
|
||||
Mesh = 1 << 2,
|
||||
Object = 1 << 3,
|
||||
EnvironmentProbe = 1 << 4,
|
||||
Decal = 1 << 5,
|
||||
Sound = 1 << 6,
|
||||
Weather = 1 << 7,
|
||||
Light = 1 << 8,
|
||||
Animation = 1 << 9,
|
||||
Force = 1 << 10,
|
||||
Emitter = 1 << 11,
|
||||
Hairparticle = 1 << 12,
|
||||
IK = 1 << 13,
|
||||
Camera = 1 << 14,
|
||||
Armature = 1 << 15,
|
||||
Collider = 1 << 16,
|
||||
Script = 1 << 17,
|
||||
Expression = 1 << 18,
|
||||
Terrain = 1 << 19,
|
||||
Spring = 1 << 20,
|
||||
Humanoid = 1 << 21,
|
||||
Video = 1 << 22,
|
||||
Sprite = 1 << 23,
|
||||
Font = 1 << 24,
|
||||
VoxelGrid = 1 << 25,
|
||||
RigidBody = 1 << 26,
|
||||
SoftBody = 1 << 27,
|
||||
|
||||
All = ~0ull,
|
||||
} filter = Filter::All;
|
||||
wi::gui::ComboBox filterCombo;
|
||||
wi::gui::TextInputField filterInput;
|
||||
wi::gui::CheckBox filterCaseCheckBox;
|
||||
wi::gui::TreeList entityTree;
|
||||
wi::unordered_set<wi::ecs::Entity> entitytree_temp_items;
|
||||
wi::unordered_set<wi::ecs::Entity> entitytree_added_items;
|
||||
wi::unordered_set<wi::ecs::Entity> entitytree_opened_items;
|
||||
void PushToEntityTree(wi::ecs::Entity entity, int level);
|
||||
void RefreshEntityTree();
|
||||
bool CheckEntityFilter(wi::ecs::Entity entity);
|
||||
};
|
||||
|
||||
template<>
|
||||
struct enable_bitmask_operators<ComponentsWindow::Filter> {
|
||||
static const bool enable = true;
|
||||
};
|
||||
|
||||
@@ -9,9 +9,7 @@ void ContentBrowserWindow::Create(EditorComponent* _editor)
|
||||
editor = _editor;
|
||||
control_size = 30;
|
||||
|
||||
wi::gui::Window::WindowControls controls = wi::gui::Window::WindowControls::ALL;
|
||||
controls &= ~wi::gui::Window::WindowControls::RESIZE_BOTTOMLEFT;
|
||||
wi::gui::Window::Create("Content Browser", controls);
|
||||
wi::gui::Window::Create("Content Browser");
|
||||
|
||||
RemoveWidget(&scrollbar_horizontal);
|
||||
|
||||
@@ -49,25 +47,6 @@ void ContentBrowserWindow::Update(const wi::Canvas& canvas, float dt)
|
||||
sprites[i].params.corners_rounding[1].radius = radius;
|
||||
sprites[i].params.corners_rounding[2].radius = radius;
|
||||
sprites[i].params.corners_rounding[3].radius = radius;
|
||||
resizeDragger_UpperLeft.sprites[i].params.enableCornerRounding();
|
||||
resizeDragger_UpperLeft.sprites[i].params.corners_rounding[0].radius = radius;
|
||||
resizeDragger_UpperRight.sprites[i].params.enableCornerRounding();
|
||||
resizeDragger_UpperRight.sprites[i].params.corners_rounding[1].radius = radius;
|
||||
resizeDragger_BottomLeft.sprites[i].params.enableCornerRounding();
|
||||
resizeDragger_BottomLeft.sprites[i].params.corners_rounding[2].radius = radius;
|
||||
resizeDragger_BottomRight.sprites[i].params.enableCornerRounding();
|
||||
resizeDragger_BottomRight.sprites[i].params.corners_rounding[3].radius = radius;
|
||||
|
||||
if (IsCollapsed())
|
||||
{
|
||||
resizeDragger_UpperLeft.sprites[i].params.corners_rounding[2].radius = radius;
|
||||
resizeDragger_UpperRight.sprites[i].params.corners_rounding[3].radius = radius;
|
||||
}
|
||||
else
|
||||
{
|
||||
resizeDragger_UpperLeft.sprites[i].params.corners_rounding[2].radius = 0;
|
||||
resizeDragger_UpperRight.sprites[i].params.corners_rounding[3].radius = 0;
|
||||
}
|
||||
|
||||
openFolderButton.sprites[i].params.enableCornerRounding();
|
||||
openFolderButton.sprites[i].params.corners_rounding[0].radius = radius;
|
||||
@@ -353,7 +332,7 @@ void ContentBrowserWindow::SetSelection(SELECTION selection)
|
||||
}
|
||||
|
||||
// Refresh theme:
|
||||
editor->optionsWnd.generalWnd.themeCombo.SetSelected(editor->optionsWnd.generalWnd.themeCombo.GetSelected());
|
||||
editor->generalWnd.themeCombo.SetSelected(editor->generalWnd.themeCombo.GetSelected());
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ void DecalWindow::Create(EditorComponent* _editor)
|
||||
|
||||
editor->RecordEntity(archive, entity);
|
||||
|
||||
editor->optionsWnd.RefreshEntityTree();
|
||||
editor->componentsWnd.RefreshEntityTree();
|
||||
});
|
||||
|
||||
float x = 200;
|
||||
|
||||
+951
-402
File diff suppressed because it is too large
Load Diff
+34
-22
@@ -1,22 +1,16 @@
|
||||
#pragma once
|
||||
#include "Translator.h"
|
||||
#include "wiScene_BindLua.h"
|
||||
#include "OptionsWindow.h"
|
||||
#include "ComponentsWindow.h"
|
||||
#include "ProfilerWindow.h"
|
||||
#include "ContentBrowserWindow.h"
|
||||
#include "GraphicsWindow.h"
|
||||
#include "CameraWindow.h"
|
||||
#include "MaterialPickerWindow.h"
|
||||
#include "PaintToolWindow.h"
|
||||
#include "GeneralWindow.h"
|
||||
#include "IconDefinitions.h"
|
||||
|
||||
class EditorLoadingScreen : public wi::LoadingScreen
|
||||
{
|
||||
private:
|
||||
wi::Sprite sprite;
|
||||
wi::SpriteFont font;
|
||||
public:
|
||||
void Load() override;
|
||||
void Update(float dt) override;
|
||||
};
|
||||
|
||||
class Editor;
|
||||
class EditorComponent : public wi::RenderPath2D
|
||||
{
|
||||
@@ -25,6 +19,8 @@ public:
|
||||
|
||||
wi::gui::Button newSceneButton;
|
||||
|
||||
wi::gui::ComboBox newEntityCombo;
|
||||
|
||||
wi::gui::Button translateButton;
|
||||
wi::gui::Button rotateButton;
|
||||
wi::gui::Button scaleButton;
|
||||
@@ -58,10 +54,22 @@ public:
|
||||
wi::gui::Window aboutWindow;
|
||||
wi::gui::Label aboutLabel;
|
||||
|
||||
OptionsWindow optionsWnd;
|
||||
ComponentsWindow componentsWnd;
|
||||
ProfilerWindow profilerWnd;
|
||||
ContentBrowserWindow contentBrowserWnd;
|
||||
wi::gui::Window topmenuWnd;
|
||||
|
||||
wi::gui::Button generalButton;
|
||||
wi::gui::Button graphicsButton;
|
||||
wi::gui::Button cameraButton;
|
||||
wi::gui::Button materialsButton;
|
||||
wi::gui::Button paintToolButton;
|
||||
|
||||
GeneralWindow generalWnd;
|
||||
GraphicsWindow graphicsWnd;
|
||||
CameraWindow cameraWnd;
|
||||
MaterialPickerWindow materialPickerWnd;
|
||||
PaintToolWindow paintToolWnd;
|
||||
|
||||
wi::primitive::Ray pickRay;
|
||||
wi::physics::PickDragOperation physicsDragOp;
|
||||
@@ -80,6 +88,12 @@ public:
|
||||
void Render() const override;
|
||||
void Compose(wi::graphics::CommandList cmd) const override;
|
||||
|
||||
wi::graphics::Viewport viewport3D;
|
||||
void ResizeViewport3D();
|
||||
|
||||
bool camControlStart = true;
|
||||
XMFLOAT4 originalMouse = XMFLOAT4(0, 0, 0, 0);
|
||||
XMFLOAT4 currentMouse = XMFLOAT4(0, 0, 0, 0);
|
||||
|
||||
enum EDITORSTENCILREF
|
||||
{
|
||||
@@ -119,7 +133,7 @@ public:
|
||||
bool bone_picking = false;
|
||||
void CheckBonePickingEnabled();
|
||||
|
||||
void UpdateTopMenuAnimation();
|
||||
void UpdateDynamicWidgets();
|
||||
|
||||
wi::Archive clipboard;
|
||||
|
||||
@@ -200,13 +214,15 @@ public:
|
||||
wi::vector<uint8_t> filedata;
|
||||
};
|
||||
wi::vector<FontData> font_datas;
|
||||
|
||||
wi::jobsystem::context loadmodel_workload;
|
||||
wi::SpriteFont loadmodel_font;
|
||||
};
|
||||
|
||||
class Editor : public wi::Application
|
||||
{
|
||||
public:
|
||||
EditorComponent renderComponent;
|
||||
EditorLoadingScreen loader;
|
||||
wi::config::File config;
|
||||
|
||||
void Initialize() override;
|
||||
@@ -223,18 +239,16 @@ enum class EditorLocalization
|
||||
// Top menu:
|
||||
Save,
|
||||
Open,
|
||||
ContentBrowser,
|
||||
Backlog,
|
||||
Profiler,
|
||||
Cinema,
|
||||
__REMOVED_Cinema,
|
||||
FullScreen,
|
||||
Windowed,
|
||||
BugReport,
|
||||
About,
|
||||
Exit,
|
||||
|
||||
// Other:
|
||||
UntitledScene,
|
||||
ContentBrowser,
|
||||
|
||||
Count
|
||||
};
|
||||
@@ -242,7 +256,6 @@ static const char* EditorLocalizationStrings[] = {
|
||||
// Top menu:
|
||||
"Save",
|
||||
"Open",
|
||||
"Content",
|
||||
"Backlog",
|
||||
"Profiler",
|
||||
"Cinema",
|
||||
@@ -251,8 +264,7 @@ static const char* EditorLocalizationStrings[] = {
|
||||
"Bug report",
|
||||
"About",
|
||||
"Exit",
|
||||
|
||||
// Other:
|
||||
"Untitled scene"
|
||||
"Untitled scene",
|
||||
"Content",
|
||||
};
|
||||
static_assert(arraysize(EditorLocalizationStrings) == size_t(EditorLocalization::Count));
|
||||
|
||||
@@ -103,7 +103,6 @@
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)ModelImporter_OBJ.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)NameWindow.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)ObjectWindow.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)OptionsWindow.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)PaintToolWindow.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)GraphicsWindow.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)ProfilerWindow.cpp" />
|
||||
@@ -173,7 +172,6 @@
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)ModelImporter.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)NameWindow.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)ObjectWindow.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)OptionsWindow.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)PaintToolWindow.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)GraphicsWindow.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)ProfilerWindow.h" />
|
||||
|
||||
@@ -74,7 +74,6 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)TerrainWindow.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)MaterialPickerWindow.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)OptionsWindow.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)ComponentsWindow.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)ScriptWindow.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)RigidBodyWindow.cpp" />
|
||||
@@ -132,7 +131,6 @@
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)IconsFontAwesome6.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)IconDefinitions.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)MaterialPickerWindow.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)OptionsWindow.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)ComponentsWindow.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)ScriptWindow.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)RigidBodyWindow.h" />
|
||||
|
||||
@@ -21,7 +21,7 @@ void EmitterWindow::Create(EditorComponent* _editor)
|
||||
|
||||
editor->RecordEntity(archive, entity);
|
||||
|
||||
editor->optionsWnd.RefreshEntityTree();
|
||||
editor->componentsWnd.RefreshEntityTree();
|
||||
});
|
||||
|
||||
float x = 130;
|
||||
|
||||
@@ -23,7 +23,7 @@ void EnvProbeWindow::Create(EditorComponent* _editor)
|
||||
|
||||
editor->RecordEntity(archive, entity);
|
||||
|
||||
editor->optionsWnd.RefreshEntityTree();
|
||||
editor->componentsWnd.RefreshEntityTree();
|
||||
});
|
||||
|
||||
float x = 5, y = 0, step = 35;
|
||||
|
||||
@@ -22,7 +22,7 @@ void ExpressionWindow::Create(EditorComponent* _editor)
|
||||
|
||||
editor->RecordEntity(archive, entity);
|
||||
|
||||
editor->optionsWnd.RefreshEntityTree();
|
||||
editor->componentsWnd.RefreshEntityTree();
|
||||
});
|
||||
|
||||
float x = 60;
|
||||
|
||||
@@ -22,7 +22,7 @@ void FontWindow::Create(EditorComponent* _editor)
|
||||
|
||||
editor->RecordEntity(archive, entity);
|
||||
|
||||
editor->optionsWnd.RefreshEntityTree();
|
||||
editor->componentsWnd.RefreshEntityTree();
|
||||
});
|
||||
|
||||
float x = 60;
|
||||
|
||||
@@ -21,7 +21,7 @@ void ForceFieldWindow::Create(EditorComponent* _editor)
|
||||
|
||||
editor->RecordEntity(archive, entity);
|
||||
|
||||
editor->optionsWnd.RefreshEntityTree();
|
||||
editor->componentsWnd.RefreshEntityTree();
|
||||
});
|
||||
|
||||
float x = 60;
|
||||
|
||||
+102
-45
@@ -11,9 +11,10 @@ void GeneralWindow::Create(EditorComponent* _editor)
|
||||
{
|
||||
editor = _editor;
|
||||
|
||||
wi::gui::Window::Create("General", wi::gui::Window::WindowControls::COLLAPSE);
|
||||
wi::gui::Window::Create("General", wi::gui::Window::WindowControls::CLOSE | wi::gui::Window::WindowControls::RESIZE_RIGHT);
|
||||
SetText("General Options " ICON_GENERALOPTIONS);
|
||||
|
||||
SetSize(XMFLOAT2(580, 700));
|
||||
SetSize(XMFLOAT2(300, 700));
|
||||
|
||||
physicsDebugCheckBox.Create("Physics visualizer: ");
|
||||
physicsDebugCheckBox.SetTooltip("Visualize the physics world");
|
||||
@@ -370,7 +371,7 @@ void GeneralWindow::Create(EditorComponent* _editor)
|
||||
theme_color_idle = wi::Color(46, 52, 64, 255);
|
||||
theme_color_focus = wi::Color(59, 66, 82, 255);
|
||||
dark_point = wi::Color(46, 52, 64, 255);
|
||||
theme.shadow_color = wi::Color(46, 52, 64, 200);
|
||||
theme.shadow_color = wi::Color(106, 112, 124, 200);
|
||||
theme.font.color = wi::Color(236, 239, 244, 255);
|
||||
theme.font.shadow_color = wi::Color::Shadow();
|
||||
break;
|
||||
@@ -432,39 +433,33 @@ void GeneralWindow::Create(EditorComponent* _editor)
|
||||
}
|
||||
|
||||
// customize individual elements:
|
||||
editor->loadmodel_font.params.color = theme.font.color;
|
||||
XMFLOAT4 highlight = theme_color_focus;
|
||||
highlight.x *= 2;
|
||||
highlight.y *= 2;
|
||||
highlight.z *= 2;
|
||||
editor->newEntityCombo.SetAngularHighlightColor(highlight);
|
||||
editor->componentsWnd.newComponentCombo.SetAngularHighlightColor(highlight);
|
||||
editor->componentsWnd.materialWnd.textureSlotButton.SetColor(wi::Color::White(), wi::gui::IDLE);
|
||||
editor->componentsWnd.spriteWnd.textureButton.SetColor(wi::Color::White(), wi::gui::IDLE);
|
||||
editor->optionsWnd.paintToolWnd.brushTextureButton.SetColor(wi::Color::White(), wi::gui::IDLE);
|
||||
editor->optionsWnd.paintToolWnd.revealTextureButton.SetColor(wi::Color::White(), wi::gui::IDLE);
|
||||
editor->paintToolWnd.brushTextureButton.SetColor(wi::Color::White(), wi::gui::IDLE);
|
||||
editor->paintToolWnd.revealTextureButton.SetColor(wi::Color::White(), wi::gui::IDLE);
|
||||
editor->aboutLabel.sprites[wi::gui::FOCUS] = editor->aboutLabel.sprites[wi::gui::IDLE];
|
||||
for (int i = 0; i < arraysize(wi::gui::Widget::sprites); ++i)
|
||||
{
|
||||
editor->optionsWnd.sprites[i].params.enableCornerRounding();
|
||||
editor->optionsWnd.sprites[i].params.corners_rounding[1].radius = 10;
|
||||
editor->optionsWnd.resizeDragger_UpperRight.sprites[i].params.enableCornerRounding();
|
||||
editor->optionsWnd.resizeDragger_UpperRight.sprites[i].params.corners_rounding[1].radius = 10;
|
||||
}
|
||||
for (int i = 0; i < arraysize(wi::gui::Widget::sprites); ++i)
|
||||
{
|
||||
editor->componentsWnd.sprites[i].params.enableCornerRounding();
|
||||
editor->componentsWnd.sprites[i].params.corners_rounding[0].radius = 10;
|
||||
editor->componentsWnd.resizeDragger_UpperLeft.sprites[i].params.enableCornerRounding();
|
||||
editor->componentsWnd.resizeDragger_UpperLeft.sprites[i].params.corners_rounding[0].radius = 10;
|
||||
}
|
||||
int scene_id = 0;
|
||||
for (auto& editorscene : editor->scenes)
|
||||
{
|
||||
for (int i = 0; i < arraysize(editorscene->tabSelectButton.sprites); ++i)
|
||||
if (scene_id > 0)
|
||||
{
|
||||
editorscene->tabSelectButton.sprites[i].params.enableCornerRounding();
|
||||
editorscene->tabSelectButton.sprites[i].params.corners_rounding[0].radius = 10;
|
||||
editorscene->tabSelectButton.sprites[i].params.corners_rounding[2].radius = 10;
|
||||
for (int i = 0; i < arraysize(editorscene->tabSelectButton.sprites); ++i)
|
||||
{
|
||||
editorscene->tabSelectButton.sprites[i].params.enableCornerRounding();
|
||||
editorscene->tabSelectButton.sprites[i].params.corners_rounding[0].radius = 10;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < arraysize(editorscene->tabCloseButton.sprites); ++i)
|
||||
{
|
||||
editorscene->tabCloseButton.sprites[i].params.enableCornerRounding();
|
||||
editorscene->tabCloseButton.sprites[i].params.corners_rounding[1].radius = 10;
|
||||
editorscene->tabCloseButton.sprites[i].params.corners_rounding[3].radius = 10;
|
||||
}
|
||||
|
||||
if (editor->current_scene == scene_id)
|
||||
@@ -481,10 +476,76 @@ void GeneralWindow::Create(EditorComponent* _editor)
|
||||
for (int i = 0; i < arraysize(editor->newSceneButton.sprites); ++i)
|
||||
{
|
||||
editor->newSceneButton.sprites[i].params.enableCornerRounding();
|
||||
editor->newSceneButton.sprites[i].params.corners_rounding[0].radius = 10;
|
||||
editor->newSceneButton.sprites[i].params.corners_rounding[1].radius = 10;
|
||||
editor->newSceneButton.sprites[i].params.corners_rounding[2].radius = 10;
|
||||
editor->newSceneButton.sprites[i].params.corners_rounding[3].radius = 10;
|
||||
editor->newSceneButton.sprites[i].params.corners_rounding[0].radius = 20;
|
||||
editor->newSceneButton.sprites[i].params.corners_rounding[1].radius = 20;
|
||||
editor->newSceneButton.sprites[i].params.corners_rounding[2].radius = 20;
|
||||
editor->newSceneButton.sprites[i].params.corners_rounding[3].radius = 20;
|
||||
|
||||
editor->newEntityCombo.sprites[i].params.enableCornerRounding();
|
||||
editor->newEntityCombo.sprites[i].params.corners_rounding[0].radius = 20;
|
||||
editor->newEntityCombo.sprites[i].params.corners_rounding[1].radius = 20;
|
||||
editor->newEntityCombo.sprites[i].params.corners_rounding[2].radius = 20;
|
||||
editor->newEntityCombo.sprites[i].params.corners_rounding[3].radius = 20;
|
||||
|
||||
editor->generalButton.sprites[i].params.enableCornerRounding();
|
||||
editor->generalButton.sprites[i].params.corners_rounding[0].radius = 20;
|
||||
editor->generalButton.sprites[i].params.corners_rounding[1].radius = 20;
|
||||
editor->generalButton.sprites[i].params.corners_rounding[2].radius = 20;
|
||||
editor->generalButton.sprites[i].params.corners_rounding[3].radius = 20;
|
||||
|
||||
editor->graphicsButton.sprites[i].params.enableCornerRounding();
|
||||
editor->graphicsButton.sprites[i].params.corners_rounding[0].radius = 20;
|
||||
editor->graphicsButton.sprites[i].params.corners_rounding[1].radius = 20;
|
||||
editor->graphicsButton.sprites[i].params.corners_rounding[2].radius = 20;
|
||||
editor->graphicsButton.sprites[i].params.corners_rounding[3].radius = 20;
|
||||
|
||||
editor->cameraButton.sprites[i].params.enableCornerRounding();
|
||||
editor->cameraButton.sprites[i].params.corners_rounding[0].radius = 20;
|
||||
editor->cameraButton.sprites[i].params.corners_rounding[1].radius = 20;
|
||||
editor->cameraButton.sprites[i].params.corners_rounding[2].radius = 20;
|
||||
editor->cameraButton.sprites[i].params.corners_rounding[3].radius = 20;
|
||||
|
||||
editor->materialsButton.sprites[i].params.enableCornerRounding();
|
||||
editor->materialsButton.sprites[i].params.corners_rounding[0].radius = 20;
|
||||
editor->materialsButton.sprites[i].params.corners_rounding[1].radius = 20;
|
||||
editor->materialsButton.sprites[i].params.corners_rounding[2].radius = 20;
|
||||
editor->materialsButton.sprites[i].params.corners_rounding[3].radius = 20;
|
||||
|
||||
editor->paintToolButton.sprites[i].params.enableCornerRounding();
|
||||
editor->paintToolButton.sprites[i].params.corners_rounding[0].radius = 20;
|
||||
editor->paintToolButton.sprites[i].params.corners_rounding[1].radius = 20;
|
||||
editor->paintToolButton.sprites[i].params.corners_rounding[2].radius = 20;
|
||||
editor->paintToolButton.sprites[i].params.corners_rounding[3].radius = 20;
|
||||
|
||||
editor->componentsWnd.newComponentCombo.sprites[i].params.enableCornerRounding();
|
||||
editor->componentsWnd.newComponentCombo.sprites[i].params.corners_rounding[0].radius = 20;
|
||||
editor->componentsWnd.newComponentCombo.sprites[i].params.corners_rounding[1].radius = 20;
|
||||
editor->componentsWnd.newComponentCombo.sprites[i].params.corners_rounding[2].radius = 20;
|
||||
editor->componentsWnd.newComponentCombo.sprites[i].params.corners_rounding[3].radius = 20;
|
||||
|
||||
editor->dummyButton.sprites[i].params.enableCornerRounding();
|
||||
editor->dummyButton.sprites[i].params.corners_rounding[0].radius = 10;
|
||||
editor->dummyButton.sprites[i].params.corners_rounding[1].radius = 10;
|
||||
editor->dummyButton.sprites[i].params.corners_rounding[2].radius = 10;
|
||||
editor->dummyButton.sprites[i].params.corners_rounding[3].radius = 10;
|
||||
|
||||
editor->physicsButton.sprites[i].params.enableCornerRounding();
|
||||
editor->physicsButton.sprites[i].params.corners_rounding[0].radius = 10;
|
||||
editor->physicsButton.sprites[i].params.corners_rounding[1].radius = 10;
|
||||
editor->physicsButton.sprites[i].params.corners_rounding[2].radius = 10;
|
||||
editor->physicsButton.sprites[i].params.corners_rounding[3].radius = 10;
|
||||
|
||||
editor->navtestButton.sprites[i].params.enableCornerRounding();
|
||||
editor->navtestButton.sprites[i].params.corners_rounding[0].radius = 10;
|
||||
editor->navtestButton.sprites[i].params.corners_rounding[1].radius = 10;
|
||||
editor->navtestButton.sprites[i].params.corners_rounding[2].radius = 10;
|
||||
editor->navtestButton.sprites[i].params.corners_rounding[3].radius = 10;
|
||||
|
||||
editor->cinemaButton.sprites[i].params.enableCornerRounding();
|
||||
editor->cinemaButton.sprites[i].params.corners_rounding[0].radius = 10;
|
||||
editor->cinemaButton.sprites[i].params.corners_rounding[1].radius = 10;
|
||||
editor->cinemaButton.sprites[i].params.corners_rounding[2].radius = 10;
|
||||
editor->cinemaButton.sprites[i].params.corners_rounding[3].radius = 10;
|
||||
}
|
||||
for (int i = 0; i < arraysize(wi::gui::Widget::sprites); ++i)
|
||||
{
|
||||
@@ -511,41 +572,35 @@ void GeneralWindow::Create(EditorComponent* _editor)
|
||||
editor->aboutWindow.sprites[i].params.corners_rounding[1].radius = 10;
|
||||
editor->aboutWindow.sprites[i].params.corners_rounding[2].radius = 10;
|
||||
editor->aboutWindow.sprites[i].params.corners_rounding[3].radius = 10;
|
||||
editor->aboutWindow.resizeDragger_UpperLeft.sprites[i].params.enableCornerRounding();
|
||||
editor->aboutWindow.resizeDragger_UpperLeft.sprites[i].params.corners_rounding[0].radius = 10;
|
||||
editor->aboutWindow.resizeDragger_UpperRight.sprites[i].params.enableCornerRounding();
|
||||
editor->aboutWindow.resizeDragger_UpperRight.sprites[i].params.corners_rounding[1].radius = 10;
|
||||
editor->aboutWindow.resizeDragger_BottomLeft.sprites[i].params.enableCornerRounding();
|
||||
editor->aboutWindow.resizeDragger_BottomLeft.sprites[i].params.corners_rounding[2].radius = 10;
|
||||
editor->aboutWindow.resizeDragger_BottomRight.sprites[i].params.enableCornerRounding();
|
||||
editor->aboutWindow.resizeDragger_BottomRight.sprites[i].params.corners_rounding[3].radius = 10;
|
||||
}
|
||||
for (int i = 0; i < arraysize(wi::gui::Widget::sprites); ++i)
|
||||
{
|
||||
editor->saveButton.sprites[i].params.enableCornerRounding();
|
||||
editor->saveButton.sprites[i].params.corners_rounding[2].radius = 10;
|
||||
editor->saveButton.sprites[i].params.corners_rounding[0].radius = 10;
|
||||
|
||||
editor->playButton.sprites[i].params.enableCornerRounding();
|
||||
editor->playButton.sprites[i].params.corners_rounding[2].radius = 40;
|
||||
editor->playButton.sprites[i].params.corners_rounding[0].radius = 10;
|
||||
|
||||
editor->stopButton.sprites[i].params.enableCornerRounding();
|
||||
editor->stopButton.sprites[i].params.corners_rounding[3].radius = 40;
|
||||
editor->stopButton.sprites[i].params.corners_rounding[1].radius = 10;
|
||||
|
||||
editor->translateButton.sprites[i].params.enableCornerRounding();
|
||||
editor->translateButton.sprites[i].params.corners_rounding[2].radius = 40;
|
||||
editor->translateButton.sprites[i].params.corners_rounding[0].radius = 10;
|
||||
editor->translateButton.sprites[i].params.corners_rounding[1].radius = 10;
|
||||
|
||||
editor->scaleButton.sprites[i].params.enableCornerRounding();
|
||||
editor->scaleButton.sprites[i].params.corners_rounding[3].radius = 40;
|
||||
editor->scaleButton.sprites[i].params.corners_rounding[2].radius = 10;
|
||||
editor->scaleButton.sprites[i].params.corners_rounding[3].radius = 10;
|
||||
|
||||
editor->dummyButton.sprites[i].params.enableCornerRounding();
|
||||
editor->dummyButton.sprites[i].params.corners_rounding[3].radius = 40;
|
||||
editor->dummyButton.sprites[i].params.corners_rounding[3].radius = 10;
|
||||
|
||||
editor->navtestButton.sprites[i].params.enableCornerRounding();
|
||||
editor->navtestButton.sprites[i].params.corners_rounding[2].radius = 40;
|
||||
editor->navtestButton.sprites[i].params.corners_rounding[2].radius = 10;
|
||||
|
||||
editor->physicsButton.sprites[i].params.enableCornerRounding();
|
||||
editor->physicsButton.sprites[i].params.corners_rounding[2].radius = 40;
|
||||
editor->physicsButton.sprites[i].params.corners_rounding[3].radius = 40;
|
||||
editor->physicsButton.sprites[i].params.corners_rounding[2].radius = 10;
|
||||
editor->physicsButton.sprites[i].params.corners_rounding[3].radius = 10;
|
||||
}
|
||||
editor->componentsWnd.weatherWnd.default_sky_horizon = dark_point;
|
||||
editor->componentsWnd.weatherWnd.default_sky_zenith = theme_color_idle;
|
||||
@@ -676,6 +731,8 @@ void GeneralWindow::Create(EditorComponent* _editor)
|
||||
|
||||
});
|
||||
AddWidget(&ktxConvButton);
|
||||
|
||||
SetVisible(false);
|
||||
}
|
||||
|
||||
void GeneralWindow::RefreshLanguageSelectionAfterWholeGUIWasInitialized()
|
||||
|
||||
@@ -7,13 +7,14 @@ using namespace wi::graphics;
|
||||
void GraphicsWindow::Create(EditorComponent* _editor)
|
||||
{
|
||||
editor = _editor;
|
||||
wi::gui::Window::Create("Graphics", wi::gui::Window::WindowControls::COLLAPSE);
|
||||
wi::gui::Window::Create("Graphics", wi::gui::Window::WindowControls::CLOSE | wi::gui::Window::WindowControls::RESIZE_RIGHT);
|
||||
SetText("Graphics Options " ICON_GRAPHICSOPTIONS);
|
||||
|
||||
wi::renderer::SetToDrawDebugEnvProbes(true);
|
||||
wi::renderer::SetToDrawGridHelper(true);
|
||||
wi::renderer::SetToDrawDebugCameras(true);
|
||||
|
||||
SetSize(XMFLOAT2(580, 1660));
|
||||
SetSize(XMFLOAT2(300, 1660));
|
||||
|
||||
float step = 21;
|
||||
float itemheight = 18;
|
||||
@@ -1417,8 +1418,7 @@ void GraphicsWindow::Create(EditorComponent* _editor)
|
||||
fsr2Combo.SetSelected(fsr2_preset);
|
||||
AddWidget(&fsr2Combo);
|
||||
|
||||
Translate(XMFLOAT3(100, 50, 0));
|
||||
SetMinimized(true);
|
||||
SetVisible(false);
|
||||
}
|
||||
|
||||
void GraphicsWindow::UpdateSwapChainFormats(wi::graphics::SwapChain* swapChain)
|
||||
@@ -1632,7 +1632,7 @@ void GraphicsWindow::ResizeLayout()
|
||||
if (!widget.IsVisible())
|
||||
return;
|
||||
const float margin_left = 155;
|
||||
const float margin_right = 45;
|
||||
const float margin_right = 50;
|
||||
widget.SetPos(XMFLOAT2(margin_left, y));
|
||||
widget.SetSize(XMFLOAT2(width - margin_left - margin_right, widget.GetScale().y));
|
||||
y += widget.GetSize().y;
|
||||
@@ -1641,7 +1641,7 @@ void GraphicsWindow::ResizeLayout()
|
||||
auto add_right = [&](wi::gui::Widget& widget) {
|
||||
if (!widget.IsVisible())
|
||||
return;
|
||||
const float margin_right = 45;
|
||||
const float margin_right = 50;
|
||||
widget.SetPos(XMFLOAT2(width - margin_right - widget.GetSize().x, y));
|
||||
y += widget.GetSize().y;
|
||||
y += padding;
|
||||
|
||||
@@ -21,7 +21,7 @@ void HairParticleWindow::Create(EditorComponent* _editor)
|
||||
|
||||
editor->RecordEntity(archive, entity);
|
||||
|
||||
editor->optionsWnd.RefreshEntityTree();
|
||||
editor->componentsWnd.RefreshEntityTree();
|
||||
});
|
||||
|
||||
float x = 120;
|
||||
|
||||
@@ -21,7 +21,7 @@ void HierarchyWindow::Create(EditorComponent* _editor)
|
||||
|
||||
editor->RecordEntity(archive, entity);
|
||||
|
||||
editor->optionsWnd.RefreshEntityTree();
|
||||
editor->componentsWnd.RefreshEntityTree();
|
||||
});
|
||||
|
||||
float x = 80;
|
||||
@@ -53,7 +53,7 @@ void HierarchyWindow::Create(EditorComponent* _editor)
|
||||
|
||||
editor->RecordEntity(archive, entity);
|
||||
|
||||
editor->optionsWnd.RefreshEntityTree();
|
||||
editor->componentsWnd.RefreshEntityTree();
|
||||
|
||||
});
|
||||
parentCombo.SetTooltip("Choose a parent entity (also works if selected entity has no transform)");
|
||||
|
||||
@@ -22,7 +22,7 @@ void HumanoidWindow::Create(EditorComponent* _editor)
|
||||
|
||||
editor->RecordEntity(archive, entity);
|
||||
|
||||
editor->optionsWnd.RefreshEntityTree();
|
||||
editor->componentsWnd.RefreshEntityTree();
|
||||
});
|
||||
|
||||
float x = 60;
|
||||
@@ -228,7 +228,7 @@ void HumanoidWindow::Create(EditorComponent* _editor)
|
||||
// record NEW selection state...
|
||||
editor->RecordSelection(archive);
|
||||
|
||||
editor->optionsWnd.RefreshEntityTree();
|
||||
editor->componentsWnd.RefreshEntityTree();
|
||||
|
||||
});
|
||||
AddWidget(&boneList);
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ void IKWindow::Create(EditorComponent* _editor)
|
||||
|
||||
editor->RecordEntity(archive, entity);
|
||||
|
||||
editor->optionsWnd.RefreshEntityTree();
|
||||
editor->componentsWnd.RefreshEntityTree();
|
||||
});
|
||||
|
||||
float x = 120;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
// These map the Font Awesome icon definitions to editor:
|
||||
// These definitions will help to change icons that are scattered throughout the editor code
|
||||
// Search available icons: https://fontawesome.com/search?q=paper&o=r&m=free
|
||||
#define ICON_LAYER ICON_FA_LAYER_GROUP
|
||||
#define ICON_TRANSFORM ICON_FA_LOCATION_DOT
|
||||
#define ICON_MESH ICON_FA_CUBE
|
||||
@@ -73,6 +74,7 @@
|
||||
#define ICON_STOP ICON_FA_STOP
|
||||
#define ICON_PEN ICON_FA_PEN
|
||||
#define ICON_FILTER ICON_FA_FILTER
|
||||
#define ICON_SEARCH ICON_FA_MAGNIFYING_GLASS
|
||||
#define ICON_SAVE_EMBED ICON_FA_FILE_ZIPPER
|
||||
#define ICON_SAVE_NO_EMBED ICON_FA_FILE
|
||||
#define ICON_SAVE_HEADER ICON_FA_FILE_CODE
|
||||
@@ -83,3 +85,9 @@
|
||||
#define ICON_SOFT ICON_FA_LEAF
|
||||
#define ICON_HACKING ICON_FA_COMPUTER
|
||||
#define ICON_NORD ICON_FA_MOUNTAIN
|
||||
|
||||
#define ICON_GENERALOPTIONS ICON_FA_GEAR
|
||||
#define ICON_GRAPHICSOPTIONS ICON_FA_DISPLAY
|
||||
#define ICON_CAMERAOPTIONS ICON_CAMERA
|
||||
#define ICON_MATERIALBROWSER ICON_MATERIAL
|
||||
#define ICON_PAINTTOOL ICON_FA_PAINTBRUSH
|
||||
|
||||
@@ -21,7 +21,7 @@ void LayerWindow::Create(EditorComponent* _editor)
|
||||
|
||||
editor->RecordEntity(archive, entity);
|
||||
|
||||
editor->optionsWnd.RefreshEntityTree();
|
||||
editor->componentsWnd.RefreshEntityTree();
|
||||
});
|
||||
|
||||
float x = 30;
|
||||
|
||||
@@ -22,7 +22,7 @@ void LightWindow::Create(EditorComponent* _editor)
|
||||
|
||||
editor->RecordEntity(archive, entity);
|
||||
|
||||
editor->optionsWnd.RefreshEntityTree();
|
||||
editor->componentsWnd.RefreshEntityTree();
|
||||
});
|
||||
|
||||
float x = 130;
|
||||
@@ -463,7 +463,7 @@ void LightWindow::RefreshCascades()
|
||||
addCascadeButton.SetEnabled(true);
|
||||
|
||||
// refresh theme:
|
||||
editor->optionsWnd.generalWnd.themeCombo.SetSelected(editor->optionsWnd.generalWnd.themeCombo.GetSelected());
|
||||
editor->generalWnd.themeCombo.SetSelected(editor->generalWnd.themeCombo.GetSelected());
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -8,13 +8,14 @@ using namespace wi::scene;
|
||||
void MaterialPickerWindow::Create(EditorComponent* _editor)
|
||||
{
|
||||
editor = _editor;
|
||||
wi::gui::Window::Create("Materials", wi::gui::Window::WindowControls::COLLAPSE);
|
||||
wi::gui::Window::Create("Materials", wi::gui::Window::WindowControls::CLOSE | wi::gui::Window::WindowControls::RESIZE_RIGHT);
|
||||
SetText("Materials " ICON_MATERIALBROWSER);
|
||||
SetSize(XMFLOAT2(300, 400));
|
||||
|
||||
zoomSlider.Create(10, 100, 100, 100 - 10, "Zoom: ");
|
||||
AddWidget(&zoomSlider);
|
||||
|
||||
SetCollapsed(true);
|
||||
SetVisible(false);
|
||||
}
|
||||
|
||||
void MaterialPickerWindow::RecreateButtons()
|
||||
|
||||
@@ -22,7 +22,7 @@ void MaterialWindow::Create(EditorComponent* _editor)
|
||||
|
||||
editor->RecordEntity(archive, entity);
|
||||
|
||||
editor->optionsWnd.RefreshEntityTree();
|
||||
editor->componentsWnd.RefreshEntityTree();
|
||||
});
|
||||
|
||||
float hei = 18;
|
||||
@@ -505,7 +505,7 @@ void MaterialWindow::Create(EditorComponent* _editor)
|
||||
{
|
||||
*name = args.sValue;
|
||||
|
||||
editor->optionsWnd.RefreshEntityTree();
|
||||
editor->componentsWnd.RefreshEntityTree();
|
||||
}
|
||||
});
|
||||
AddWidget(&materialNameField);
|
||||
|
||||
@@ -25,7 +25,7 @@ void MeshWindow::Create(EditorComponent* _editor)
|
||||
|
||||
editor->RecordEntity(archive, entity);
|
||||
|
||||
editor->optionsWnd.RefreshEntityTree();
|
||||
editor->componentsWnd.RefreshEntityTree();
|
||||
});
|
||||
|
||||
float x = 95;
|
||||
|
||||
@@ -21,7 +21,7 @@ void NameWindow::Create(EditorComponent* _editor)
|
||||
|
||||
editor->RecordEntity(archive, entity);
|
||||
|
||||
editor->optionsWnd.RefreshEntityTree();
|
||||
editor->componentsWnd.RefreshEntityTree();
|
||||
});
|
||||
|
||||
float x = 60;
|
||||
@@ -42,7 +42,7 @@ void NameWindow::Create(EditorComponent* _editor)
|
||||
}
|
||||
name->name = args.sValue;
|
||||
|
||||
editor->optionsWnd.RefreshEntityTree();
|
||||
editor->componentsWnd.RefreshEntityTree();
|
||||
});
|
||||
AddWidget(&nameInput);
|
||||
|
||||
|
||||
@@ -270,7 +270,7 @@ void ObjectWindow::Create(EditorComponent* _editor)
|
||||
|
||||
editor->RecordEntity(archive, entity);
|
||||
|
||||
editor->optionsWnd.RefreshEntityTree();
|
||||
editor->componentsWnd.RefreshEntityTree();
|
||||
});
|
||||
|
||||
float x = 140;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,75 +0,0 @@
|
||||
#pragma once
|
||||
#include "GraphicsWindow.h"
|
||||
#include "CameraWindow.h"
|
||||
#include "MaterialPickerWindow.h"
|
||||
#include "PaintToolWindow.h"
|
||||
#include "GeneralWindow.h"
|
||||
|
||||
class EditorComponent;
|
||||
|
||||
class OptionsWindow : public wi::gui::Window
|
||||
{
|
||||
public:
|
||||
void Create(EditorComponent* editor);
|
||||
void Update(float dt);
|
||||
|
||||
void ResizeLayout() override;
|
||||
|
||||
EditorComponent* editor = nullptr;
|
||||
GeneralWindow generalWnd;
|
||||
GraphicsWindow graphicsWnd;
|
||||
CameraWindow cameraWnd;
|
||||
MaterialPickerWindow materialPickerWnd;
|
||||
PaintToolWindow paintToolWnd;
|
||||
|
||||
enum class Filter : uint64_t
|
||||
{
|
||||
Transform = 1 << 0,
|
||||
Material = 1 << 1,
|
||||
Mesh = 1 << 2,
|
||||
Object = 1 << 3,
|
||||
EnvironmentProbe = 1 << 4,
|
||||
Decal = 1 << 5,
|
||||
Sound = 1 << 6,
|
||||
Weather = 1 << 7,
|
||||
Light = 1 << 8,
|
||||
Animation = 1 << 9,
|
||||
Force = 1 << 10,
|
||||
Emitter = 1 << 11,
|
||||
Hairparticle = 1 << 12,
|
||||
IK = 1 << 13,
|
||||
Camera = 1 << 14,
|
||||
Armature = 1 << 15,
|
||||
Collider = 1 << 16,
|
||||
Script = 1 << 17,
|
||||
Expression = 1 << 18,
|
||||
Terrain = 1 << 19,
|
||||
Spring = 1 << 20,
|
||||
Humanoid = 1 << 21,
|
||||
Video = 1 << 22,
|
||||
Sprite = 1 << 23,
|
||||
Font = 1 << 24,
|
||||
VoxelGrid = 1 << 25,
|
||||
RigidBody = 1 << 26,
|
||||
SoftBody = 1 << 27,
|
||||
|
||||
All = ~0ull,
|
||||
} filter = Filter::All;
|
||||
wi::gui::ComboBox newCombo;
|
||||
wi::gui::ComboBox filterCombo;
|
||||
wi::gui::TextInputField filterInput;
|
||||
wi::gui::CheckBox filterCaseCheckBox;
|
||||
wi::gui::TreeList entityTree;
|
||||
wi::unordered_set<wi::ecs::Entity> entitytree_temp_items;
|
||||
wi::unordered_set<wi::ecs::Entity> entitytree_added_items;
|
||||
wi::unordered_set<wi::ecs::Entity> entitytree_opened_items;
|
||||
void PushToEntityTree(wi::ecs::Entity entity, int level);
|
||||
void RefreshEntityTree();
|
||||
|
||||
bool CheckEntityFilter(wi::ecs::Entity entity);
|
||||
};
|
||||
|
||||
template<>
|
||||
struct enable_bitmask_operators<OptionsWindow::Filter> {
|
||||
static const bool enable = true;
|
||||
};
|
||||
+17
-16
@@ -11,8 +11,9 @@ void PaintToolWindow::Create(EditorComponent* _editor)
|
||||
{
|
||||
editor = _editor;
|
||||
|
||||
wi::gui::Window::Create("Paint Tool", wi::gui::Window::WindowControls::COLLAPSE);
|
||||
SetSize(XMFLOAT2(360, 800));
|
||||
wi::gui::Window::Create("Paint Tool", wi::gui::Window::WindowControls::CLOSE | wi::gui::Window::WindowControls::RESIZE_RIGHT);
|
||||
SetText("Paint Tool " ICON_PAINTTOOL);
|
||||
SetSize(XMFLOAT2(300, 800));
|
||||
|
||||
float x = 105;
|
||||
float y = 0;
|
||||
@@ -388,9 +389,7 @@ void PaintToolWindow::Create(EditorComponent* _editor)
|
||||
});
|
||||
AddWidget(&revealTextureButton);
|
||||
|
||||
Translate(XMFLOAT3((float)editor->GetLogicalWidth() - 550, 50, 0));
|
||||
|
||||
SetMinimized(true);
|
||||
SetVisible(false);
|
||||
}
|
||||
|
||||
void PaintToolWindow::Update(float dt)
|
||||
@@ -469,9 +468,8 @@ void PaintToolWindow::Update(float dt)
|
||||
}
|
||||
}
|
||||
|
||||
auto pointer = wi::input::GetPointer();
|
||||
posNew = XMFLOAT2(pointer.x, pointer.y);
|
||||
float pressureNew = pressureCheckBox.GetCheck() ? pointer.w : 1.0f;
|
||||
posNew = XMFLOAT2(editor->currentMouse.x, editor->currentMouse.y);
|
||||
float pressureNew = pressureCheckBox.GetCheck() ? editor->currentMouse.w : 1.0f;
|
||||
|
||||
const MODE mode = GetMode();
|
||||
const float radius = radiusSlider.GetValue();
|
||||
@@ -549,7 +547,7 @@ void PaintToolWindow::Update(float dt)
|
||||
{
|
||||
case MODE_TEXTURE:
|
||||
{
|
||||
wi::primitive::Ray pickRay = wi::renderer::GetPickRay((long)pos.x, (long)pos.y, *editor, camera);
|
||||
wi::primitive::Ray pickRay = wi::renderer::GetPickRay((long)pos.x, (long)pos.y, *editor->renderPath, camera);
|
||||
brushIntersect = wi::scene::Pick(pickRay, ~0u, ~0u, scene);
|
||||
|
||||
ObjectComponent* object = scene.objects.GetComponent(brushIntersect.entity);
|
||||
@@ -669,7 +667,7 @@ void PaintToolWindow::Update(float dt)
|
||||
|
||||
case MODE_TERRAIN_MATERIAL:
|
||||
{
|
||||
Ray pickRay = wi::renderer::GetPickRay((long)pos.x, (long)pos.y, *editor, camera);
|
||||
Ray pickRay = wi::renderer::GetPickRay((long)pos.x, (long)pos.y, *editor->renderPath, camera);
|
||||
brushIntersect = wi::scene::Pick(pickRay, wi::enums::FILTER_TERRAIN, ~0u, scene);
|
||||
if (brushIntersect.entity == INVALID_ENTITY)
|
||||
break;
|
||||
@@ -768,7 +766,7 @@ void PaintToolWindow::Update(float dt)
|
||||
case MODE_VERTEXCOLOR:
|
||||
case MODE_WIND:
|
||||
{
|
||||
Ray pickRay = wi::renderer::GetPickRay((long)pos.x, (long)pos.y, *editor, camera);
|
||||
Ray pickRay = wi::renderer::GetPickRay((long)pos.x, (long)pos.y, *editor->renderPath, camera);
|
||||
brushIntersect = wi::scene::Pick(pickRay, wi::enums::FILTER_OBJECT_ALL, ~0u, scene);
|
||||
if (brushIntersect.entity == INVALID_ENTITY)
|
||||
break;
|
||||
@@ -939,7 +937,7 @@ void PaintToolWindow::Update(float dt)
|
||||
case MODE_SCULPTING_ADD:
|
||||
case MODE_SCULPTING_SUBTRACT:
|
||||
{
|
||||
Ray pickRay = wi::renderer::GetPickRay((long)pos.x, (long)pos.y, *editor, camera);
|
||||
Ray pickRay = wi::renderer::GetPickRay((long)pos.x, (long)pos.y, *editor->renderPath, camera);
|
||||
brushIntersect = wi::scene::Pick(pickRay, terrain_only ? wi::enums::FILTER_TERRAIN : wi::enums::FILTER_OBJECT_ALL, ~0u, scene);
|
||||
if (brushIntersect.entity == INVALID_ENTITY)
|
||||
break;
|
||||
@@ -979,7 +977,7 @@ void PaintToolWindow::Update(float dt)
|
||||
case PaintToolWindow::AxisLock::Disabled:
|
||||
if (sculpting_normal.x < FLT_EPSILON && sculpting_normal.y < FLT_EPSILON && sculpting_normal.z < FLT_EPSILON)
|
||||
{
|
||||
sculpting_normal = editor->hovered.normal;
|
||||
sculpting_normal = brushIntersect.normal;
|
||||
}
|
||||
sculptDir = XMVector3TransformNormal(XMVector3Normalize(XMLoadFloat3(&sculpting_normal)), XMMatrixInverse(nullptr, W));
|
||||
break;
|
||||
@@ -1123,7 +1121,7 @@ void PaintToolWindow::Update(float dt)
|
||||
wi::renderer::RenderableLine sculpt_dir_line;
|
||||
sculpt_dir_line.color_start = XMFLOAT4(0, 1, 0, 1);
|
||||
sculpt_dir_line.color_end = XMFLOAT4(0, 1, 0, 1);
|
||||
sculpt_dir_line.start = editor->hovered.position;
|
||||
sculpt_dir_line.start = brushIntersect.position;
|
||||
XMStoreFloat3(
|
||||
&sculpt_dir_line.end,
|
||||
XMLoadFloat3(&sculpt_dir_line.start) +
|
||||
@@ -1146,7 +1144,7 @@ void PaintToolWindow::Update(float dt)
|
||||
case MODE_SOFTBODY_PINNING:
|
||||
case MODE_SOFTBODY_PHYSICS:
|
||||
{
|
||||
Ray pickRay = wi::renderer::GetPickRay((long)pos.x, (long)pos.y, *editor, camera);
|
||||
Ray pickRay = wi::renderer::GetPickRay((long)pos.x, (long)pos.y, *editor->renderPath, camera);
|
||||
brushIntersect = wi::scene::Pick(pickRay, wi::enums::FILTER_OBJECT_ALL, ~0u, scene);
|
||||
if (brushIntersect.entity == INVALID_ENTITY)
|
||||
break;
|
||||
@@ -1254,7 +1252,7 @@ void PaintToolWindow::Update(float dt)
|
||||
case MODE_HAIRPARTICLE_REMOVE_TRIANGLE:
|
||||
case MODE_HAIRPARTICLE_LENGTH:
|
||||
{
|
||||
Ray pickRay = wi::renderer::GetPickRay((long)pos.x, (long)pos.y, *editor, camera);
|
||||
Ray pickRay = wi::renderer::GetPickRay((long)pos.x, (long)pos.y, *editor->renderPath, camera);
|
||||
brushIntersect = wi::scene::Pick(pickRay, wi::enums::FILTER_OBJECT_ALL, ~0u, scene);
|
||||
if (brushIntersect.entity == INVALID_ENTITY)
|
||||
break;
|
||||
@@ -1508,6 +1506,8 @@ void PaintToolWindow::DrawBrush(const wi::Canvas& canvas, CommandList cmd) const
|
||||
|
||||
PaintToolWindow::MODE PaintToolWindow::GetMode() const
|
||||
{
|
||||
if (!IsVisible())
|
||||
return MODE_DISABLED;
|
||||
return (MODE)modeComboBox.GetSelectedUserdata();
|
||||
}
|
||||
|
||||
@@ -2040,6 +2040,7 @@ void PaintToolWindow::RecreateTerrainMaterialButtons()
|
||||
button.Create("");
|
||||
AddWidget(&button);
|
||||
button.SetVisible(false);
|
||||
button.SetEnabled(true);
|
||||
button.SetText("");
|
||||
button.SetTooltip("");
|
||||
|
||||
|
||||
@@ -49,25 +49,6 @@ void ProfilerWindow::Update(const wi::Canvas& canvas, float dt)
|
||||
sprites[i].params.corners_rounding[1].radius = 10;
|
||||
sprites[i].params.corners_rounding[2].radius = 10;
|
||||
sprites[i].params.corners_rounding[3].radius = 10;
|
||||
resizeDragger_UpperLeft.sprites[i].params.enableCornerRounding();
|
||||
resizeDragger_UpperLeft.sprites[i].params.corners_rounding[0].radius = 10;
|
||||
resizeDragger_UpperRight.sprites[i].params.enableCornerRounding();
|
||||
resizeDragger_UpperRight.sprites[i].params.corners_rounding[1].radius = 10;
|
||||
resizeDragger_BottomLeft.sprites[i].params.enableCornerRounding();
|
||||
resizeDragger_BottomLeft.sprites[i].params.corners_rounding[2].radius = 10;
|
||||
resizeDragger_BottomRight.sprites[i].params.enableCornerRounding();
|
||||
resizeDragger_BottomRight.sprites[i].params.corners_rounding[3].radius = 10;
|
||||
|
||||
if (IsCollapsed())
|
||||
{
|
||||
resizeDragger_UpperLeft.sprites[i].params.corners_rounding[2].radius = 10;
|
||||
resizeDragger_UpperRight.sprites[i].params.corners_rounding[3].radius = 10;
|
||||
}
|
||||
else
|
||||
{
|
||||
resizeDragger_UpperLeft.sprites[i].params.corners_rounding[2].radius = 0;
|
||||
resizeDragger_UpperRight.sprites[i].params.corners_rounding[3].radius = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
void ProfilerWindow::ResizeLayout()
|
||||
|
||||
@@ -22,7 +22,7 @@ void RigidBodyWindow::Create(EditorComponent* _editor)
|
||||
|
||||
editor->RecordEntity(archive, entity);
|
||||
|
||||
editor->optionsWnd.RefreshEntityTree();
|
||||
editor->componentsWnd.RefreshEntityTree();
|
||||
});
|
||||
|
||||
float x = 140;
|
||||
|
||||
@@ -18,7 +18,7 @@ void ScriptWindow::Create(EditorComponent* _editor)
|
||||
|
||||
editor->RecordEntity(archive, entity);
|
||||
|
||||
editor->optionsWnd.RefreshEntityTree();
|
||||
editor->componentsWnd.RefreshEntityTree();
|
||||
});
|
||||
|
||||
float hei = 20;
|
||||
|
||||
@@ -21,7 +21,7 @@ void SoftBodyWindow::Create(EditorComponent* _editor)
|
||||
|
||||
editor->RecordEntity(archive, entity);
|
||||
|
||||
editor->optionsWnd.RefreshEntityTree();
|
||||
editor->componentsWnd.RefreshEntityTree();
|
||||
});
|
||||
|
||||
float x = 95;
|
||||
|
||||
@@ -48,7 +48,7 @@ void SoundWindow::Create(EditorComponent* _editor)
|
||||
|
||||
editor->RecordEntity(archive, entity);
|
||||
|
||||
editor->optionsWnd.RefreshEntityTree();
|
||||
editor->componentsWnd.RefreshEntityTree();
|
||||
});
|
||||
|
||||
float x = 60;
|
||||
|
||||
@@ -21,7 +21,7 @@ void SpringWindow::Create(EditorComponent* _editor)
|
||||
|
||||
editor->RecordEntity(archive, entity);
|
||||
|
||||
editor->optionsWnd.RefreshEntityTree();
|
||||
editor->componentsWnd.RefreshEntityTree();
|
||||
});
|
||||
|
||||
float x = 120;
|
||||
|
||||
@@ -23,7 +23,7 @@ void SpriteWindow::Create(EditorComponent* _editor)
|
||||
|
||||
editor->RecordEntity(archive, entity);
|
||||
|
||||
editor->optionsWnd.RefreshEntityTree();
|
||||
editor->componentsWnd.RefreshEntityTree();
|
||||
});
|
||||
|
||||
textureButton.Create("Base Texture");
|
||||
|
||||
@@ -67,6 +67,7 @@ PerlinModifierWindow::PerlinModifierWindow() : ModifierWindow("Perlin Noise")
|
||||
AddWidget(&octavesSlider);
|
||||
|
||||
SetSize(XMFLOAT2(200, 140));
|
||||
SetCollapsed(true);
|
||||
}
|
||||
void PerlinModifierWindow::ResizeLayout()
|
||||
{
|
||||
@@ -140,6 +141,7 @@ VoronoiModifierWindow::VoronoiModifierWindow() : ModifierWindow("Voronoi Noise")
|
||||
AddWidget(&perturbationSlider);
|
||||
|
||||
SetSize(XMFLOAT2(200, 200));
|
||||
SetCollapsed(true);
|
||||
}
|
||||
void VoronoiModifierWindow::ResizeLayout()
|
||||
{
|
||||
@@ -238,6 +240,7 @@ HeightmapModifierWindow::HeightmapModifierWindow() : ModifierWindow("Heightmap")
|
||||
AddWidget(&loadButton);
|
||||
|
||||
SetSize(XMFLOAT2(200, 180));
|
||||
SetCollapsed(true);
|
||||
}
|
||||
void HeightmapModifierWindow::ResizeLayout()
|
||||
{
|
||||
@@ -545,7 +548,7 @@ void PropsWindow::AddWindow(wi::terrain::Prop& prop)
|
||||
|
||||
windows.emplace_back().reset(wnd);
|
||||
|
||||
editor->optionsWnd.generalWnd.themeCombo.SetSelected(editor->optionsWnd.generalWnd.themeCombo.GetSelected()); // theme refresh
|
||||
editor->generalWnd.themeCombo.SetSelected(editor->generalWnd.themeCombo.GetSelected()); // theme refresh
|
||||
}
|
||||
|
||||
void PropsWindow::Update(const wi::Canvas& canvas, float dt)
|
||||
@@ -604,6 +607,17 @@ void PropsWindow::ResizeLayout()
|
||||
y += padding;
|
||||
};
|
||||
|
||||
auto add_fullwidth = [&](wi::gui::Widget& widget) {
|
||||
if (!widget.IsVisible())
|
||||
return;
|
||||
const float margin_left = padding;
|
||||
const float margin_right = padding;
|
||||
widget.SetPos(XMFLOAT2(margin_left, y));
|
||||
widget.SetSize(XMFLOAT2(width - margin_left - margin_right, widget.GetScale().y));
|
||||
y += widget.GetSize().y;
|
||||
y += padding;
|
||||
};
|
||||
|
||||
auto add_window = [&](wi::gui::Window& widget) {
|
||||
const float margin_left = padding;
|
||||
const float margin_right = padding;
|
||||
@@ -614,7 +628,7 @@ void PropsWindow::ResizeLayout()
|
||||
widget.SetEnabled(true);
|
||||
};
|
||||
|
||||
add(addButton);
|
||||
add_fullwidth(addButton);
|
||||
|
||||
for(auto& window : windows)
|
||||
{
|
||||
@@ -646,7 +660,7 @@ void TerrainWindow::Create(EditorComponent* _editor)
|
||||
|
||||
editor->RecordEntity(archive, entity);
|
||||
|
||||
editor->optionsWnd.RefreshEntityTree();
|
||||
editor->componentsWnd.RefreshEntityTree();
|
||||
});
|
||||
|
||||
float x = 140;
|
||||
@@ -937,7 +951,7 @@ void TerrainWindow::Create(EditorComponent* _editor)
|
||||
|
||||
generate_callback();
|
||||
|
||||
editor->optionsWnd.RefreshEntityTree();
|
||||
editor->componentsWnd.RefreshEntityTree();
|
||||
|
||||
});
|
||||
AddWidget(&presetCombo);
|
||||
@@ -1102,7 +1116,7 @@ void TerrainWindow::Create(EditorComponent* _editor)
|
||||
{
|
||||
terrain->materialEntities[i] = INVALID_ENTITY;
|
||||
}
|
||||
editor->optionsWnd.paintToolWnd.RecreateTerrainMaterialButtons();
|
||||
editor->paintToolWnd.RecreateTerrainMaterialButtons();
|
||||
});
|
||||
|
||||
AddWidget(&materialCombos[i]);
|
||||
@@ -1410,7 +1424,7 @@ void TerrainWindow::AddModifier(ModifierWindow* modifier_window)
|
||||
modifiers_to_remove.push_back(modifier_window);
|
||||
});
|
||||
|
||||
editor->optionsWnd.generalWnd.themeCombo.SetSelected(editor->optionsWnd.generalWnd.themeCombo.GetSelected()); // theme refresh
|
||||
editor->generalWnd.themeCombo.SetSelected(editor->generalWnd.themeCombo.GetSelected()); // theme refresh
|
||||
}
|
||||
void TerrainWindow::SetupAssets()
|
||||
{
|
||||
@@ -1722,7 +1736,7 @@ void TerrainWindow::SetupAssets()
|
||||
terrain = &terrain_preset;
|
||||
presetCombo.SetSelected(0);
|
||||
|
||||
editor->optionsWnd.paintToolWnd.RecreateTerrainMaterialButtons();
|
||||
editor->paintToolWnd.RecreateTerrainMaterialButtons();
|
||||
}
|
||||
|
||||
void TerrainWindow::Update(const wi::Canvas& canvas, float dt)
|
||||
|
||||
@@ -21,7 +21,7 @@ void TransformWindow::Create(EditorComponent* _editor)
|
||||
|
||||
editor->RecordEntity(archive, entity);
|
||||
|
||||
editor->optionsWnd.RefreshEntityTree();
|
||||
editor->componentsWnd.RefreshEntityTree();
|
||||
});
|
||||
|
||||
float x = 80;
|
||||
|
||||
+16
-17
@@ -104,7 +104,7 @@ namespace Translator_Internal
|
||||
}
|
||||
using namespace Translator_Internal;
|
||||
|
||||
void Translator::Update(const CameraComponent& camera, const wi::Canvas& canvas)
|
||||
void Translator::Update(const CameraComponent& camera, const XMFLOAT4& currentMouse, const wi::Canvas& canvas)
|
||||
{
|
||||
if (selected.empty())
|
||||
{
|
||||
@@ -116,7 +116,6 @@ void Translator::Update(const CameraComponent& camera, const wi::Canvas& canvas)
|
||||
dragStarted = false;
|
||||
dragEnded = false;
|
||||
|
||||
XMFLOAT4 pointer = wi::input::GetPointer();
|
||||
XMVECTOR pos = transform.GetPositionV();
|
||||
|
||||
// Non recursive selection will be computed to not apply recursive operations two times
|
||||
@@ -144,7 +143,7 @@ void Translator::Update(const CameraComponent& camera, const wi::Canvas& canvas)
|
||||
if (!has_selected_transform)
|
||||
return;
|
||||
|
||||
const Ray ray = wi::renderer::GetPickRay((long)pointer.x, (long)pointer.y, canvas, camera);
|
||||
const Ray ray = wi::renderer::GetPickRay((long)currentMouse.x, (long)currentMouse.y, canvas, camera);
|
||||
const XMVECTOR rayOrigin = XMLoadFloat3(&ray.origin);
|
||||
const XMVECTOR rayDir = XMLoadFloat3(&ray.direction);
|
||||
|
||||
@@ -286,7 +285,7 @@ void Translator::Update(const CameraComponent& camera, const wi::Canvas& canvas)
|
||||
}
|
||||
}
|
||||
|
||||
if (dragging || (state != TRANSLATOR_IDLE && wi::input::Press(wi::input::MOUSE_BUTTON_LEFT) && interactable))
|
||||
if (dragging || (state != TRANSLATOR_IDLE && wi::input::Press(wi::input::MOUSE_BUTTON_LEFT)))
|
||||
{
|
||||
// Dragging operation:
|
||||
if (isRotator)
|
||||
@@ -491,7 +490,7 @@ void Translator::Update(const CameraComponent& camera, const wi::Canvas& canvas)
|
||||
dragging = false;
|
||||
}
|
||||
}
|
||||
void Translator::Draw(const CameraComponent& camera, CommandList cmd) const
|
||||
void Translator::Draw(const CameraComponent& camera, const XMFLOAT4& currentMouse, CommandList cmd) const
|
||||
{
|
||||
if (!IsEnabled() || selected.empty() || !has_selected_transform)
|
||||
{
|
||||
@@ -1025,47 +1024,47 @@ void Translator::Draw(const CameraComponent& camera, CommandList cmd) const
|
||||
device->Draw(vertexCount, 0, cmd);
|
||||
}
|
||||
|
||||
XMFLOAT4 pointer = wi::input::GetPointer();
|
||||
wi::font::Params params;
|
||||
params.posX = pointer.x - 20;
|
||||
params.posY = pointer.y + 20;
|
||||
params.posX = currentMouse.x - 20;
|
||||
params.posY = currentMouse.y + 20;
|
||||
params.v_align = wi::font::WIFALIGN_TOP;
|
||||
params.h_align = wi::font::WIFALIGN_RIGHT;
|
||||
params.scaling = 0.8f;
|
||||
params.shadowColor = wi::Color::Black();
|
||||
std::string str;
|
||||
|
||||
char text[256] = {};
|
||||
|
||||
if (isTranslator)
|
||||
{
|
||||
str += "Offset = " + std::to_string(transform.translation_local.x - transform_start.translation_local.x) + ", " + std::to_string(transform.translation_local.y - transform_start.translation_local.y) + ", " + std::to_string(transform.translation_local.z - transform_start.translation_local.z);
|
||||
snprintf(text, arraysize(text), "Offset = %.2f, %.2f, %.2f", transform.translation_local.x - transform_start.translation_local.x, transform.translation_local.y - transform_start.translation_local.y, transform.translation_local.z - transform_start.translation_local.z);
|
||||
}
|
||||
if (isRotator)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case Translator::TRANSLATOR_X:
|
||||
str += "Axis = X";
|
||||
snprintf(text, arraysize(text), "Axis = X\nAngle = %.2f degrees", wi::math::RadiansToDegrees(angle));
|
||||
break;
|
||||
case Translator::TRANSLATOR_Y:
|
||||
str += "Axis = Y";
|
||||
snprintf(text, arraysize(text), "Axis = Y\nAngle = %.2f degrees", wi::math::RadiansToDegrees(angle));
|
||||
break;
|
||||
case Translator::TRANSLATOR_Z:
|
||||
str += "Axis = Z";
|
||||
snprintf(text, arraysize(text), "Axis = Z\nAngle = %.2f degrees", wi::math::RadiansToDegrees(angle));
|
||||
break;
|
||||
case Translator::TRANSLATOR_XYZ:
|
||||
str += "Axis = Screen";
|
||||
snprintf(text, arraysize(text), "Axis = Screen\nAngle = %.2f degrees", wi::math::RadiansToDegrees(angle));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
str += "\nAngle = " + std::to_string(int(angle / XM_PI * 180)) + " degrees";
|
||||
}
|
||||
if (isScalator)
|
||||
{
|
||||
str += "Scaling = " + std::to_string(transform.scale_local.x / transform_start.scale_local.x) + ", " + std::to_string(transform.scale_local.y / transform_start.scale_local.y) + ", " + std::to_string(transform.scale_local.z / transform_start.scale_local.z);
|
||||
snprintf(text, arraysize(text), "Scaling = %.2f, %.2f, %.2f", transform.scale_local.x / transform_start.scale_local.x, transform.scale_local.y / transform_start.scale_local.y, transform.scale_local.z / transform_start.scale_local.z);
|
||||
}
|
||||
params.shadowColor.setA(uint8_t(opacity * 255.0f));
|
||||
params.color.setA(uint8_t(opacity * 255.0f));
|
||||
wi::font::Draw(str, params, cmd);
|
||||
wi::font::Draw(text, params, cmd);
|
||||
}
|
||||
|
||||
device->EventEnd(cmd);
|
||||
|
||||
+4
-3
@@ -13,8 +13,8 @@ private:
|
||||
bool has_selected_transform = false;
|
||||
public:
|
||||
|
||||
void Update(const wi::scene::CameraComponent& camera, const wi::Canvas& canvas);
|
||||
void Draw(const wi::scene::CameraComponent& camera, wi::graphics::CommandList cmd) const;
|
||||
void Update(const wi::scene::CameraComponent& camera, const XMFLOAT4& currentMouse, const wi::Canvas& canvas);
|
||||
void Draw(const wi::scene::CameraComponent& camera, const XMFLOAT4& currentMouse, wi::graphics::CommandList cmd) const;
|
||||
|
||||
// Attach selection to translator temporarily
|
||||
void PreTranslate();
|
||||
@@ -49,7 +49,6 @@ public:
|
||||
|
||||
float dist = 1;
|
||||
|
||||
bool interactable = true;
|
||||
bool isTranslator = true;
|
||||
bool isScalator = false;
|
||||
bool isRotator = false;
|
||||
@@ -74,6 +73,8 @@ public:
|
||||
// Check if the drag ended in this exact frame
|
||||
bool IsDragEnded() const { return dragEnded; };
|
||||
|
||||
bool IsInteracting() const { return state != TRANSLATOR_IDLE; }
|
||||
|
||||
wi::scene::TransformComponent transform_start;
|
||||
wi::vector<XMFLOAT4X4> matrices_start;
|
||||
wi::vector<XMFLOAT4X4> matrices_current;
|
||||
|
||||
@@ -44,7 +44,7 @@ void VideoWindow::Create(EditorComponent* _editor)
|
||||
|
||||
editor->RecordEntity(archive, entity);
|
||||
|
||||
editor->optionsWnd.RefreshEntityTree();
|
||||
editor->componentsWnd.RefreshEntityTree();
|
||||
});
|
||||
|
||||
float x = 60;
|
||||
|
||||
@@ -21,7 +21,7 @@ void VoxelGridWindow::Create(EditorComponent* _editor)
|
||||
|
||||
editor->RecordEntity(archive, entity);
|
||||
|
||||
editor->optionsWnd.RefreshEntityTree();
|
||||
editor->componentsWnd.RefreshEntityTree();
|
||||
});
|
||||
|
||||
float x = 80;
|
||||
|
||||
@@ -22,7 +22,7 @@ void WeatherWindow::Create(EditorComponent* _editor)
|
||||
|
||||
editor->RecordEntity(archive, entity);
|
||||
|
||||
editor->optionsWnd.RefreshEntityTree();
|
||||
editor->componentsWnd.RefreshEntityTree();
|
||||
});
|
||||
|
||||
float x = 150;
|
||||
|
||||
+704
-706
File diff suppressed because it is too large
Load Diff
+704
-706
File diff suppressed because it is too large
Load Diff
@@ -179,6 +179,7 @@ BOOL CreateEditorWindow(int nCmdShow)
|
||||
editor.SetWindow(hWnd);
|
||||
|
||||
ShowWindow(hWnd, nCmdShow);
|
||||
//SendMessage(hWnd, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
|
||||
UpdateWindow(hWnd);
|
||||
|
||||
DragAcceptFiles(hWnd, TRUE);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
[](https://github.com/turanszkij/WickedEngine/actions)
|
||||
[](https://discord.gg/CFjRYmE)
|
||||
[](https://wickedengine.net/forum/)
|
||||
<a href="https://twitter.com/intent/follow?screen_name=turanszkij"><img src="https://img.shields.io/twitter/follow/turanszkij.svg?style=social" alt="follow on Twitter"></a>
|
||||
<br/>
|
||||
[](https://store.steampowered.com/app/1967460/Wicked_Engine/)
|
||||
@@ -13,15 +14,15 @@
|
||||
<br/>
|
||||
<img align="right" src="https://github.com/turanszkij/wickedengine-gifs/raw/main/videoprojectors.gif" width="320px"/>
|
||||
Wicked Engine is an open-source 3D engine with modern graphics. Use this as a C++ framework for your graphics projects, a standalone 3D editor, LUA scripting or just for learning.<br/>
|
||||
This project is hosted on <a href="https://github.com/turanszkij/WickedEngine/">GitHub</a>.
|
||||
|
||||
- [Documentation](Content/Documentation/WickedEngine-Documentation.md)<br/>
|
||||
- [Scripting API Documentation](Content/Documentation/ScriptingAPI-Documentation.md)<br/>
|
||||
- [Website](https://wickedengine.net/)<br/>
|
||||
- [Forum](https://wickedengine.net/forum/)<br/>
|
||||
- [Features](features.txt)<br/>
|
||||
- [Devblog](https://wickedengine.net/)<br/>
|
||||
- [Videos](https://www.youtube.com/playlist?list=PLLN-1FTGyLU_HJoC5zx6hJkB3D2XLiaxS)<br/>
|
||||
- [C++ Documentation](Content/Documentation/WickedEngine-Documentation.md)<br/>
|
||||
- [Lua Documentation](Content/Documentation/ScriptingAPI-Documentation.md)<br/>
|
||||
|
||||
You can get the full source code by using Git version control and cloning https://github.com/turanszkij/WickedEngine.git, or downloading it as zip. You can also download prebuilt and packaged version of the Editor here (requires Github sign in): [](https://github.com/turanszkij/WickedEngine/actions)
|
||||
You can get the full source code by using Git version control and cloning https://github.com/turanszkij/WickedEngine.git, or downloading it as zip. You can also download nightly packaged builds of the Editor here (requires Github sign in): [](https://github.com/turanszkij/WickedEngine/actions)
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
@@ -203,7 +204,7 @@ The native model format is the <b>WISCENE</b> format. Any application using Wick
|
||||
|
||||
<img align="right" src="https://github.com/turanszkij/wickedengine-gifs/raw/main/character_lookat.gif" width="320px"/>
|
||||
|
||||
In addition, the Editor supports the importing of some common model formats (the list will potentially grow):
|
||||
In addition, the Editor supports importing some common model formats:
|
||||
- <b>OBJ</b>
|
||||
- <b>GLTF 2.0</b>
|
||||
- <b>VRM</b>
|
||||
@@ -214,24 +215,20 @@ The preferred workflow is to import models into the Editor, and save them as <b>
|
||||
<img align="right" src="https://github.com/turanszkij/wickedengine-gifs/raw/main/snowstorm.gif" width="320px"/>
|
||||
|
||||
### Graphics API:
|
||||
The default renderer is `DirectX 12` on Windows and `Vulkan` on Linux. The `DirectX 11` renderer is no longer available starting from version 0.57.0, but it can be found on the <a href="https://github.com/turanszkij/WickedEngine/tree/dx11-backup">dx11-backup branch</a>.
|
||||
The default renderer is `DirectX 12` on Windows and `Vulkan` on Linux.
|
||||
You can specify command line arguments (without any prefix) to switch between render devices or other settings. Currently the list of options:
|
||||
<table>
|
||||
<tr>
|
||||
<th>Argument</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>dx12</td>
|
||||
<td>Use DirectX 12 rendering device</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>vulkan</td>
|
||||
<td>Use Vulkan rendering device</td>
|
||||
<td>Use the Vulkan rendering device on Windows</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>debugdevice</td>
|
||||
<td>Use debug layer for graphics API validation. Performance will be degraded, but graphics warnings and errors will be written to "Output" window</td>
|
||||
<td>Use debug layer for graphics API validation. Performance will be degraded, but graphics warnings and errors will be written to the "Output" window</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>gpuvalidation</td>
|
||||
@@ -271,9 +268,10 @@ If you are having trouble getting the applications to run, make sure that you sa
|
||||
|
||||
<img align="right" src="https://github.com/turanszkij/wickedengine-gifs/raw/main/weather.gif" width="320px"/>
|
||||
|
||||
- If you experience crashes, follow these steps to find out the problem:
|
||||
- If you experience crashes, you can try these to find out the problem:
|
||||
- make sure your environment is up to date, with latest graphics drivers and operating system updates.
|
||||
- see if there is a wiBackLog.txt in your user temp folder (for example: C:\Users\username\AppData\Local\Temp), and request help on Discord or Github issue
|
||||
- build the engine in Debug mode and try to run it, see where it crashes, provide call stack on Discord or Github issue
|
||||
- see if there is a wiBackLog.txt in your user temp folder (for example: C:\Users\username\AppData\Local\Temp)
|
||||
- request help on the [Forum](https://wickedengine.net/forum/), [Discord](https://discord.gg/CFjRYmE) or [Github issue](https://github.com/turanszkij/WickedEngine/issues)
|
||||
- build the engine in Debug mode and try to run it, see where it crashes
|
||||
- run the engine with the `debugdevice` command argument and post the text from your console output window when the crash happens
|
||||
- for very advanced users, using `gpuvalidation` with `debugdevice` will print additional graphics debug information
|
||||
|
||||
@@ -8,6 +8,8 @@ static const uint IMAGE_FLAG_OUTPUT_COLOR_SPACE_LINEAR = 1u << 2u;
|
||||
static const uint IMAGE_FLAG_FULLSCREEN = 1u << 3u;
|
||||
static const uint IMAGE_FLAG_MIRROR = 1u << 4u;
|
||||
static const uint IMAGE_FLAG_CORNER_ROUNDING = 1u << 5u;
|
||||
static const uint IMAGE_FLAG_ANGULAR_DOUBLESIDED = 1u << 6u;
|
||||
static const uint IMAGE_FLAG_ANGULAR_INVERSE = 1u << 7u;
|
||||
|
||||
struct ImageConstants
|
||||
{
|
||||
@@ -33,6 +35,10 @@ struct ImageConstants
|
||||
float2 b1;
|
||||
float2 b2;
|
||||
float2 b3;
|
||||
|
||||
float2 angular_softness_direction;
|
||||
float angular_softness_scale;
|
||||
float angular_softness_offset;
|
||||
};
|
||||
CONSTANTBUFFER(image, ImageConstants, CBSLOT_IMAGE);
|
||||
|
||||
|
||||
@@ -125,11 +125,7 @@ static const uint TONEMAP_FLAG_ACES = 1 << 1;
|
||||
struct PushConstantsTonemap
|
||||
{
|
||||
float2 resolution_rcp;
|
||||
float exposure;
|
||||
uint flags;
|
||||
float brightness;
|
||||
float contrast;
|
||||
float saturation;
|
||||
uint2 exposure_brightness_contrast_saturation;
|
||||
|
||||
int texture_input;
|
||||
int buffer_input_luminance;
|
||||
@@ -139,6 +135,7 @@ struct PushConstantsTonemap
|
||||
int texture_bloom;
|
||||
int texture_output;
|
||||
uint display_colorspace;
|
||||
uint flags;
|
||||
};
|
||||
|
||||
struct PostprocessTileStatistics
|
||||
|
||||
@@ -56,12 +56,35 @@ float4 main(VertextoPixel input) : SV_TARGET
|
||||
color.rgb = RemoveSRGBCurve_Fast(color.rgb);
|
||||
color.rgb *= image.hdr_scaling;
|
||||
}
|
||||
|
||||
|
||||
[branch]
|
||||
if (image.border_soften > 0)
|
||||
{
|
||||
float edge = max(abs(input.edge.x), abs(input.edge.y));
|
||||
color.a *= smoothstep(0, image.border_soften, 1 - edge);
|
||||
}
|
||||
|
||||
[branch]
|
||||
if (image.angular_softness_scale > 0)
|
||||
{
|
||||
float2 direction = normalize(uvsets.xy - 0.5);
|
||||
float dp = dot(direction, image.angular_softness_direction);
|
||||
if (image.flags & IMAGE_FLAG_ANGULAR_DOUBLESIDED)
|
||||
{
|
||||
dp = abs(dp);
|
||||
}
|
||||
else
|
||||
{
|
||||
dp = saturate(dp);
|
||||
}
|
||||
float angular = saturate(mad(dp, image.angular_softness_scale, image.angular_softness_offset));
|
||||
if (image.flags & IMAGE_FLAG_ANGULAR_INVERSE)
|
||||
{
|
||||
angular = 1 - angular;
|
||||
}
|
||||
angular = smoothstep(0, 1, angular);
|
||||
color.a *= angular;
|
||||
}
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
@@ -59,53 +59,19 @@ float4x4 saturationMatrix(float saturation)
|
||||
return float4x4(red, 0, green, 0, blue, 0, 0, 0, 0, 1);
|
||||
}
|
||||
|
||||
#ifndef __PSSL__
|
||||
#undef WICKED_ENGINE_DEFAULT_ROOTSIGNATURE // don't use auto root signature!
|
||||
[RootSignature(
|
||||
"RootConstants(num32BitConstants=16, b999),"
|
||||
"DescriptorTable( "
|
||||
"SRV(t0, space = 2, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"SRV(t0, space = 3, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"SRV(t0, space = 4, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"SRV(t0, space = 5, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"SRV(t0, space = 6, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"SRV(t0, space = 7, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"SRV(t0, space = 8, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"SRV(t0, space = 9, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"SRV(t0, space = 10, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"SRV(t0, space = 11, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"SRV(t0, space = 12, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"SRV(t0, space = 13, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"SRV(t0, space = 14, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"SRV(t0, space = 15, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"SRV(t0, space = 16, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"SRV(t0, space = 17, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"SRV(t0, space = 18, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"SRV(t0, space = 19, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"SRV(t0, space = 20, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"UAV(u0, space = 21, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"UAV(u0, space = 22, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"UAV(u0, space = 23, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"UAV(u0, space = 24, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"UAV(u0, space = 25, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"UAV(u0, space = 26, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"UAV(u0, space = 27, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"UAV(u0, space = 28, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"UAV(u0, space = 29, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"UAV(u0, space = 30, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"UAV(u0, space = 31, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"UAV(u0, space = 32, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
|
||||
"UAV(u0, space = 33, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)"
|
||||
"), "
|
||||
"StaticSampler(s100, addressU = TEXTURE_ADDRESS_CLAMP, addressV = TEXTURE_ADDRESS_CLAMP, addressW = TEXTURE_ADDRESS_CLAMP, filter = FILTER_MIN_MAG_MIP_LINEAR)"
|
||||
)]
|
||||
#endif // __PSSL__
|
||||
|
||||
[numthreads(POSTPROCESS_BLOCKSIZE, POSTPROCESS_BLOCKSIZE, 1)]
|
||||
void main(uint3 DTid : SV_DispatchThreadID)
|
||||
{
|
||||
if(!GetCamera().is_pixel_inside_scissor(DTid.xy))
|
||||
return;
|
||||
|
||||
float2 uv = (DTid.xy + 0.5f) * tonemap_push.resolution_rcp;
|
||||
float exposure = tonemap_push.exposure;
|
||||
|
||||
float4 exposure_brightness_contrast_saturation = unpack_half4(tonemap_push.exposure_brightness_contrast_saturation);
|
||||
float exposure = exposure_brightness_contrast_saturation.x;
|
||||
float brightness = exposure_brightness_contrast_saturation.y;
|
||||
float contrast = exposure_brightness_contrast_saturation.z;
|
||||
float saturation = exposure_brightness_contrast_saturation.w;
|
||||
|
||||
[branch]
|
||||
if (tonemap_push.texture_input_distortion >= 0)
|
||||
@@ -164,8 +130,8 @@ void main(uint3 DTid : SV_DispatchThreadID)
|
||||
result.rgb += (dither((float2)DTid.xy) - 0.5f) / 64.0f;
|
||||
}
|
||||
|
||||
result.rgb = (result.rgb - 0.5f) * tonemap_push.contrast + 0.5f + tonemap_push.brightness;
|
||||
result.rgb = (float3)(mul(saturationMatrix(tonemap_push.saturation), result));
|
||||
result.rgb = (result.rgb - 0.5f) * contrast + 0.5f + brightness;
|
||||
result.rgb = (float3)(mul(saturationMatrix(saturation), result));
|
||||
|
||||
[branch]
|
||||
if (tonemap_push.texture_output >= 0)
|
||||
|
||||
@@ -256,6 +256,8 @@ namespace wi
|
||||
{
|
||||
auto range = wi::profiler::BeginRangeCPU("Update");
|
||||
|
||||
infoDisplay.rect = {};
|
||||
|
||||
wi::lua::SetDeltaTime(double(dt));
|
||||
wi::lua::Update();
|
||||
|
||||
@@ -317,6 +319,11 @@ namespace wi
|
||||
// Draw the information display
|
||||
if (infoDisplay.active)
|
||||
{
|
||||
if (infoDisplay.rect.right > 0)
|
||||
{
|
||||
graphicsDevice->BindScissorRects(1, &infoDisplay.rect, cmd);
|
||||
}
|
||||
|
||||
infodisplay_str.clear();
|
||||
if (infoDisplay.watermark)
|
||||
{
|
||||
@@ -445,8 +452,8 @@ namespace wi
|
||||
}
|
||||
|
||||
wi::font::Params params = wi::font::Params(
|
||||
4,
|
||||
4,
|
||||
4 + canvas.PhysicalToLogical((uint32_t)infoDisplay.rect.left),
|
||||
4 + canvas.PhysicalToLogical((uint32_t)infoDisplay.rect.top),
|
||||
infoDisplay.size,
|
||||
wi::font::WIFALIGN_LEFT,
|
||||
wi::font::WIFALIGN_TOP,
|
||||
@@ -506,10 +513,26 @@ namespace wi
|
||||
params.cursor = wi::font::Draw(std::to_string(wi::renderer::GetShaderErrorCount()) + " shader compilation errors! Check the backlog for more information!\n", params, cmd);
|
||||
}
|
||||
|
||||
|
||||
if (infoDisplay.colorgrading_helper)
|
||||
{
|
||||
wi::image::Draw(wi::texturehelper::getColorGradeDefault(), wi::image::Params(0, 0, 256.0f / canvas.GetDPIScaling(), 16.0f / canvas.GetDPIScaling()), cmd);
|
||||
wi::image::Draw(
|
||||
wi::texturehelper::getColorGradeDefault(),
|
||||
wi::image::Params(
|
||||
canvas.PhysicalToLogical((uint32_t)infoDisplay.rect.left),
|
||||
canvas.PhysicalToLogical((uint32_t)infoDisplay.rect.top),
|
||||
canvas.PhysicalToLogical(256),
|
||||
canvas.PhysicalToLogical(16)
|
||||
),
|
||||
cmd
|
||||
);
|
||||
}
|
||||
|
||||
if (infoDisplay.rect.right > 0)
|
||||
{
|
||||
Rect rect;
|
||||
rect.right = canvas.width;
|
||||
rect.bottom = canvas.height;
|
||||
graphicsDevice->BindScissorRects(1, &rect, cmd);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -116,6 +116,8 @@ namespace wi
|
||||
int size = 16;
|
||||
// display default color grading helper texture in top left corner of the screen
|
||||
bool colorgrading_helper = false;
|
||||
// rect to specify where to render the information
|
||||
wi::graphics::Rect rect;
|
||||
};
|
||||
// display all-time engine information text
|
||||
InfoDisplayer infoDisplay;
|
||||
|
||||
@@ -46,6 +46,7 @@ namespace wi::backlog
|
||||
bool locked = false;
|
||||
bool blockLuaExec = false;
|
||||
LogLevel logLevel = LogLevel::Default;
|
||||
LogLevel unseen = LogLevel::None;
|
||||
|
||||
std::string getTextWithoutLock()
|
||||
{
|
||||
@@ -321,6 +322,7 @@ namespace wi::backlog
|
||||
}
|
||||
params.cursor = wi::font::Draw(x.text, params, cmd);
|
||||
}
|
||||
unseen = LogLevel::None;
|
||||
}
|
||||
|
||||
std::string getText()
|
||||
@@ -385,6 +387,8 @@ namespace wi::backlog
|
||||
break;
|
||||
}
|
||||
|
||||
unseen = std::max(unseen, level);
|
||||
|
||||
// lock released on block end
|
||||
}
|
||||
|
||||
@@ -463,4 +467,9 @@ namespace wi::backlog
|
||||
{
|
||||
logLevel = newLevel;
|
||||
}
|
||||
|
||||
LogLevel GetUnseenLogLevelMax()
|
||||
{
|
||||
return unseen;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,6 +53,8 @@ namespace wi::backlog
|
||||
|
||||
void SetLogLevel(LogLevel newLevel);
|
||||
|
||||
LogLevel GetUnseenLogLevelMax();
|
||||
|
||||
|
||||
// These are no longer used, but kept here to not break user code:
|
||||
inline void input(const char input) {}
|
||||
|
||||
+773
-317
File diff suppressed because it is too large
Load Diff
+64
-14
@@ -264,6 +264,9 @@ namespace wi::gui
|
||||
mutable wi::Sprite tooltipSprite;
|
||||
mutable wi::SpriteFont tooltipFont;
|
||||
mutable wi::SpriteFont scripttipFont;
|
||||
float angular_highlight_width = 0;
|
||||
float angular_highlight_timer = 0;
|
||||
XMFLOAT4 angular_highlight_color = XMFLOAT4(1, 1, 1, 1);
|
||||
|
||||
public:
|
||||
Widget();
|
||||
@@ -295,7 +298,7 @@ namespace wi::gui
|
||||
|
||||
virtual void ResizeLayout() {};
|
||||
virtual void Update(const wi::Canvas& canvas, float dt);
|
||||
virtual void Render(const wi::Canvas& canvas, wi::graphics::CommandList cmd) const {}
|
||||
virtual void Render(const wi::Canvas& canvas, wi::graphics::CommandList cmd) const;
|
||||
virtual void RenderTooltip(const wi::Canvas& canvas, wi::graphics::CommandList cmd) const;
|
||||
|
||||
// last param default: set color for all states
|
||||
@@ -338,6 +341,11 @@ namespace wi::gui
|
||||
void SetLocalizationEnabled(bool value) { localization_enabled = value ? LocalizationEnabled::All : LocalizationEnabled::None; }
|
||||
virtual void ExportLocalization(wi::Localization& localization) const;
|
||||
virtual void ImportLocalization(const wi::Localization& localization);
|
||||
|
||||
void SetAngularHighlightWidth(float value) { angular_highlight_width = value; };
|
||||
float GetAngularHighlightWidth() const { return angular_highlight_width; };
|
||||
void SetAngularHighlightColor(const XMFLOAT4& value) { angular_highlight_color = value; };
|
||||
XMFLOAT4 GetAngularHighlightColor() const { return angular_highlight_color; };
|
||||
};
|
||||
|
||||
// Clickable, draggable box
|
||||
@@ -396,7 +404,7 @@ namespace wi::gui
|
||||
// 1: full extra offset
|
||||
void SetOverScroll(float amount) { overscroll = amount; }
|
||||
// Check whether the scrollbar is required (when the items don't fit and scrolling could be used)
|
||||
bool IsScrollbarRequired() const { return scrollbar_granularity < 0.999f; }
|
||||
bool IsScrollbarRequired() const { return scrollbar_granularity < 1; }
|
||||
void SetSafeArea(float value) { safe_area = value; }
|
||||
|
||||
enum SCROLLBAR_STATE
|
||||
@@ -423,6 +431,7 @@ namespace wi::gui
|
||||
class Label : public Widget
|
||||
{
|
||||
protected:
|
||||
bool wrap_enabled = true;
|
||||
public:
|
||||
void Create(const std::string& name);
|
||||
|
||||
@@ -434,6 +443,8 @@ namespace wi::gui
|
||||
|
||||
float scrollbar_width = 18;
|
||||
ScrollBar scrollbar;
|
||||
|
||||
void SetWrapEnabled(bool value) { wrap_enabled = value; }
|
||||
};
|
||||
|
||||
// Text input box
|
||||
@@ -547,6 +558,8 @@ namespace wi::gui
|
||||
int selected = -1;
|
||||
int maxVisibleItemCount = 8;
|
||||
int firstItemVisible = 0;
|
||||
bool drop_arrow = true;
|
||||
float fixed_drop_width = 0; // 0 = not fixed, takes width from base scale
|
||||
|
||||
// While the widget is active (rolled down) these are the inner states that control behaviour
|
||||
enum COMBOSTATE
|
||||
@@ -573,6 +586,7 @@ namespace wi::gui
|
||||
std::wstring invalid_selection_text;
|
||||
|
||||
float GetDropOffset(const wi::Canvas& canvas) const;
|
||||
float GetDropX(const wi::Canvas& canvas) const;
|
||||
float GetItemOffset(const wi::Canvas& canvas, int index) const;
|
||||
public:
|
||||
void Create(const std::string& name);
|
||||
@@ -608,6 +622,11 @@ namespace wi::gui
|
||||
|
||||
void ExportLocalization(wi::Localization& localization) const override;
|
||||
void ImportLocalization(const wi::Localization& localization) override;
|
||||
|
||||
void SetDropArrowEnabled(bool value) { drop_arrow = value; }
|
||||
bool IsDropArrowEnabled() const { return drop_arrow; }
|
||||
void SetFixedDropWidth(float value) { fixed_drop_width = value; }
|
||||
float GetFixedDropWidth() const { return fixed_drop_width; }
|
||||
};
|
||||
|
||||
// Widget container
|
||||
@@ -622,19 +641,41 @@ namespace wi::gui
|
||||
std::function<void(EventArgs args)> onCollapse;
|
||||
std::function<void()> onResize;
|
||||
|
||||
float resizehitboxwidth = 6;
|
||||
enum RESIZE_STATE
|
||||
{
|
||||
RESIZE_STATE_NONE,
|
||||
|
||||
RESIZE_STATE_LEFT,
|
||||
RESIZE_STATE_TOP,
|
||||
RESIZE_STATE_RIGHT,
|
||||
RESIZE_STATE_BOTTOM,
|
||||
|
||||
RESIZE_STATE_TOPLEFT,
|
||||
RESIZE_STATE_TOPRIGHT,
|
||||
RESIZE_STATE_BOTTOMRIGHT,
|
||||
RESIZE_STATE_BOTTOMLEFT,
|
||||
} resize_state = RESIZE_STATE_NONE;
|
||||
XMFLOAT2 resize_begin = XMFLOAT2(0, 0);
|
||||
float resize_blink_timer = 0;
|
||||
|
||||
public:
|
||||
enum class WindowControls
|
||||
{
|
||||
NONE = 0,
|
||||
RESIZE_TOPLEFT = 1 << 0,
|
||||
RESIZE_TOPRIGHT = 1 << 1,
|
||||
RESIZE_BOTTOMLEFT = 1 << 2,
|
||||
RESIZE_BOTTOMRIGHT = 1 << 3,
|
||||
MOVE = 1 << 4,
|
||||
CLOSE = 1 << 5,
|
||||
COLLAPSE = 1 << 6,
|
||||
RESIZE_LEFT = 1 << 0,
|
||||
RESIZE_TOP = 1 << 1,
|
||||
RESIZE_RIGHT = 1 << 2,
|
||||
RESIZE_BOTTOM = 1 << 3,
|
||||
RESIZE_TOPLEFT = 1 << 4,
|
||||
RESIZE_TOPRIGHT = 1 << 5,
|
||||
RESIZE_BOTTOMLEFT = 1 << 6,
|
||||
RESIZE_BOTTOMRIGHT = 1 << 7,
|
||||
MOVE = 1 << 8,
|
||||
CLOSE = 1 << 9,
|
||||
COLLAPSE = 1 << 10,
|
||||
|
||||
RESIZE = RESIZE_TOPLEFT | RESIZE_TOPRIGHT | RESIZE_BOTTOMLEFT | RESIZE_BOTTOMRIGHT,
|
||||
RESIZE = RESIZE_LEFT | RESIZE_TOP | RESIZE_RIGHT | RESIZE_BOTTOM | RESIZE_TOPLEFT | RESIZE_TOPRIGHT | RESIZE_BOTTOMLEFT | RESIZE_BOTTOMRIGHT,
|
||||
CLOSE_AND_COLLAPSE = CLOSE | COLLAPSE,
|
||||
ALL = RESIZE | MOVE | CLOSE | COLLAPSE,
|
||||
};
|
||||
@@ -675,14 +716,11 @@ namespace wi::gui
|
||||
|
||||
Button closeButton;
|
||||
Button collapseButton;
|
||||
Button resizeDragger_UpperLeft;
|
||||
Button resizeDragger_UpperRight;
|
||||
Button resizeDragger_BottomLeft;
|
||||
Button resizeDragger_BottomRight;
|
||||
Button moveDragger;
|
||||
Label label;
|
||||
ScrollBar scrollbar_vertical;
|
||||
ScrollBar scrollbar_horizontal;
|
||||
WindowControls controls;
|
||||
|
||||
void ExportLocalization(wi::Localization& localization) const override;
|
||||
void ImportLocalization(const wi::Localization& localization) override;
|
||||
@@ -742,6 +780,7 @@ namespace wi::gui
|
||||
protected:
|
||||
std::function<void(EventArgs args)> onSelect;
|
||||
std::function<void(EventArgs args)> onDelete;
|
||||
std::function<void(EventArgs args)> onDoubleClick;
|
||||
int item_highlight = -1;
|
||||
int opener_highlight = -1;
|
||||
|
||||
@@ -753,6 +792,16 @@ namespace wi::gui
|
||||
|
||||
float GetItemOffset(int index) const;
|
||||
bool DoesItemHaveChildren(int index) const;
|
||||
|
||||
float resizehitboxwidth = 6;
|
||||
enum RESIZE_STATE
|
||||
{
|
||||
RESIZE_STATE_NONE,
|
||||
RESIZE_STATE_BOTTOM,
|
||||
} resize_state = RESIZE_STATE_NONE;
|
||||
XMFLOAT2 resize_begin = XMFLOAT2(0, 0);
|
||||
float resize_blink_timer = 0;
|
||||
|
||||
public:
|
||||
void Create(const std::string& name);
|
||||
|
||||
@@ -775,6 +824,7 @@ namespace wi::gui
|
||||
|
||||
void OnSelect(std::function<void(EventArgs args)> func);
|
||||
void OnDelete(std::function<void(EventArgs args)> func);
|
||||
void OnDoubleClick(std::function<void(EventArgs args)> func);
|
||||
|
||||
ScrollBar scrollbar;
|
||||
};
|
||||
|
||||
@@ -769,6 +769,14 @@ namespace wi::graphics
|
||||
int32_t top = 0;
|
||||
int32_t right = 0;
|
||||
int32_t bottom = 0;
|
||||
|
||||
constexpr void from_viewport(const Viewport& vp)
|
||||
{
|
||||
left = int32_t(vp.top_left_x);
|
||||
right = int32_t(vp.top_left_x + vp.width);
|
||||
top = int32_t(vp.top_left_y);
|
||||
bottom = int32_t(vp.top_left_y + vp.height);
|
||||
}
|
||||
};
|
||||
|
||||
struct Box
|
||||
|
||||
@@ -1173,10 +1173,7 @@ namespace vulkan_internal
|
||||
// the color space change will not be applied
|
||||
res = vkDeviceWaitIdle(device);
|
||||
assert(res == VK_SUCCESS);
|
||||
{
|
||||
std::scoped_lock lock(allocationhandler->destroylocker);
|
||||
allocationhandler->destroyer_swapchains.emplace_back(internal_state->swapChain, allocationhandler->framecount);
|
||||
}
|
||||
vkDestroySwapchainKHR(device, internal_state->swapChain, nullptr);
|
||||
internal_state->swapChain = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,6 +114,18 @@ namespace wi::image
|
||||
image.packed_color.x = uint(packed_color.v);
|
||||
image.packed_color.y = uint(packed_color.v >> 32ull);
|
||||
|
||||
if (params.angular_softness_outer_angle > 0)
|
||||
{
|
||||
const float innerConeAngleCos = std::cos(params.angular_softness_inner_angle);
|
||||
const float outerConeAngleCos = std::cos(params.angular_softness_outer_angle);
|
||||
// https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_lights_punctual#inner-and-outer-cone-angles
|
||||
const float lightAngleScale = 1.0f / std::max(0.001f, innerConeAngleCos - outerConeAngleCos);
|
||||
const float lightAngleOffset = -outerConeAngleCos * lightAngleScale;
|
||||
image.angular_softness_direction = params.angular_softness_direction;
|
||||
image.angular_softness_scale = lightAngleScale;
|
||||
image.angular_softness_offset = lightAngleOffset;
|
||||
}
|
||||
|
||||
image.flags = 0;
|
||||
if (params.isExtractNormalMapEnabled())
|
||||
{
|
||||
@@ -132,6 +144,14 @@ namespace wi::image
|
||||
{
|
||||
image.flags |= IMAGE_FLAG_FULLSCREEN;
|
||||
}
|
||||
if (params.isAngularSoftnessDoubleSided())
|
||||
{
|
||||
image.flags |= IMAGE_FLAG_ANGULAR_DOUBLESIDED;
|
||||
}
|
||||
if (params.isAngularSoftnessInverse())
|
||||
{
|
||||
image.flags |= IMAGE_FLAG_ANGULAR_INVERSE;
|
||||
}
|
||||
|
||||
image.border_soften = params.border_soften;
|
||||
image.mask_alpha_range = XMConvertFloatToHalf(params.mask_alpha_range_start) | (XMConvertFloatToHalf(params.mask_alpha_range_end) << 16u);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "wiEnums.h"
|
||||
#include "wiColor.h"
|
||||
#include "wiCanvas.h"
|
||||
#include "wiPrimitive.h"
|
||||
|
||||
namespace wi::image
|
||||
{
|
||||
@@ -57,6 +58,8 @@ namespace wi::image
|
||||
OUTPUT_COLOR_SPACE_LINEAR = 1 << 7,
|
||||
CORNER_ROUNDING = 1 << 8,
|
||||
DEPTH_TEST = 1 << 9,
|
||||
ANGULAR_DOUBLESIDED = 1 << 10,
|
||||
ANGULAR_INVERSE = 1 << 11,
|
||||
};
|
||||
uint32_t _flags = EMPTY;
|
||||
|
||||
@@ -76,6 +79,9 @@ namespace wi::image
|
||||
float hdr_scaling = 1.0f; // a scaling value for use by linear output mapping
|
||||
float mask_alpha_range_start = 0; // constrain mask alpha to not go below this level
|
||||
float mask_alpha_range_end = 1; // constrain mask alpha to not go above this level
|
||||
XMFLOAT2 angular_softness_direction = XMFLOAT2(0, 1);
|
||||
float angular_softness_inner_angle = 0;
|
||||
float angular_softness_outer_angle = 0;
|
||||
|
||||
// you can deform the image by its corners (0: top left, 1: top right, 2: bottom left, 3: bottom right)
|
||||
XMFLOAT2 corners[4] = {
|
||||
@@ -117,6 +123,8 @@ namespace wi::image
|
||||
constexpr bool isLinearOutputMappingEnabled() const { return _flags & OUTPUT_COLOR_SPACE_LINEAR; }
|
||||
constexpr bool isCornerRoundingEnabled() const { return _flags & CORNER_ROUNDING; }
|
||||
constexpr bool isDepthTestEnabled() const { return _flags & DEPTH_TEST; }
|
||||
constexpr bool isAngularSoftnessDoubleSided() const { return _flags & ANGULAR_DOUBLESIDED; }
|
||||
constexpr bool isAngularSoftnessInverse() const { return _flags & ANGULAR_INVERSE; }
|
||||
|
||||
// enables draw rectangle for base texture (cutout texture outside draw rectangle)
|
||||
constexpr void enableDrawRect(const XMFLOAT4& rect) { _flags |= DRAWRECT; drawRect = rect; }
|
||||
@@ -137,6 +145,8 @@ namespace wi::image
|
||||
constexpr void enableLinearOutputMapping(float scaling = 1.0f) { _flags |= OUTPUT_COLOR_SPACE_LINEAR; hdr_scaling = scaling; }
|
||||
constexpr void enableCornerRounding() { _flags |= CORNER_ROUNDING; }
|
||||
constexpr void enableDepthTest() { _flags |= DEPTH_TEST; }
|
||||
constexpr void enableAngularSoftnessDoubleSided() { _flags |= ANGULAR_DOUBLESIDED; }
|
||||
constexpr void enableAngularSoftnessInverse() { _flags |= ANGULAR_INVERSE; }
|
||||
|
||||
// disable draw rectangle for base texture (whole texture will be drawn, no cutout)
|
||||
constexpr void disableDrawRect() { _flags &= ~DRAWRECT; }
|
||||
@@ -150,6 +160,8 @@ namespace wi::image
|
||||
constexpr void disableLinearOutputMapping() { _flags &= ~OUTPUT_COLOR_SPACE_LINEAR; }
|
||||
constexpr void disableCornerRounding() { _flags &= ~CORNER_ROUNDING; }
|
||||
constexpr void disableDepthTest() { _flags &= ~DEPTH_TEST; }
|
||||
constexpr void disableAngularSoftnessDoubleSided() { _flags &= ~ANGULAR_DOUBLESIDED; }
|
||||
constexpr void disableAngularSoftnessInverse() { _flags &= ~ANGULAR_INVERSE; }
|
||||
|
||||
Params() = default;
|
||||
|
||||
@@ -185,6 +197,14 @@ namespace wi::image
|
||||
enableBackground();
|
||||
}
|
||||
}
|
||||
|
||||
Params(
|
||||
const wi::primitive::Hitbox2D& hitbox, const XMFLOAT4& color = XMFLOAT4(1, 1, 1, 1)
|
||||
) :
|
||||
pos(XMFLOAT3(hitbox.pos.x, hitbox.pos.y, 0)),
|
||||
siz(hitbox.siz),
|
||||
color(color)
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -50,6 +50,11 @@ namespace wi::input
|
||||
MouseState mouse;
|
||||
Pen pen;
|
||||
bool pen_override = false;
|
||||
bool double_click = false;
|
||||
wi::Timer doubleclick_timer;
|
||||
XMFLOAT2 doubleclick_prevpos = XMFLOAT2(0, 0);
|
||||
CURSOR cursor_current = CURSOR_DEFAULT;
|
||||
CURSOR cursor_next = CURSOR_DEFAULT;
|
||||
|
||||
const KeyboardState& GetKeyboardState() { return keyboard; }
|
||||
const MouseState& GetMouseState() { return mouse; }
|
||||
@@ -429,6 +434,55 @@ namespace wi::input
|
||||
}
|
||||
}
|
||||
|
||||
double_click = false;
|
||||
if (Press(MOUSE_BUTTON_LEFT))
|
||||
{
|
||||
XMFLOAT2 pos = mouse.position;
|
||||
double elapsed = doubleclick_timer.record_elapsed_seconds();
|
||||
if (elapsed < 0.5 && wi::math::Distance(doubleclick_prevpos, pos) < 5)
|
||||
{
|
||||
double_click = true;
|
||||
}
|
||||
doubleclick_prevpos = pos;
|
||||
}
|
||||
|
||||
// Cursor update:
|
||||
if(cursor_next != cursor_current || cursor_next != CURSOR_DEFAULT)
|
||||
{
|
||||
#ifdef PLATFORM_WINDOWS_DESKTOP
|
||||
static HCURSOR cursor_table[] = {
|
||||
::LoadCursor(nullptr, IDC_ARROW),
|
||||
::LoadCursor(nullptr, IDC_IBEAM),
|
||||
::LoadCursor(nullptr, IDC_SIZEALL),
|
||||
::LoadCursor(nullptr, IDC_SIZENS),
|
||||
::LoadCursor(nullptr, IDC_SIZEWE),
|
||||
::LoadCursor(nullptr, IDC_SIZENESW),
|
||||
::LoadCursor(nullptr, IDC_SIZENWSE),
|
||||
::LoadCursor(nullptr, IDC_HAND),
|
||||
::LoadCursor(nullptr, IDC_NO)
|
||||
};
|
||||
::SetCursor(cursor_table[cursor_next]);
|
||||
#endif // PLATFORM_WINDOWS_DESKTOP
|
||||
|
||||
#ifdef SDL2
|
||||
static SDL_Cursor* cursor_table[] = {
|
||||
SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW),
|
||||
SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM),
|
||||
SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEALL),
|
||||
SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENS),
|
||||
SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEWE),
|
||||
SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENESW),
|
||||
SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENWSE),
|
||||
SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND),
|
||||
SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NO),
|
||||
};
|
||||
SDL_SetCursor(cursor_table[cursor_next] ? cursor_table[cursor_next] : cursor_table[CURSOR_DEFAULT]);
|
||||
#endif // SDL2
|
||||
|
||||
cursor_current = cursor_next;
|
||||
}
|
||||
cursor_next = CURSOR_DEFAULT;
|
||||
|
||||
wi::profiler::EndRange(range);
|
||||
}
|
||||
|
||||
@@ -749,6 +803,11 @@ namespace wi::input
|
||||
#endif // _WIN32
|
||||
}
|
||||
|
||||
bool IsDoubleClicked()
|
||||
{
|
||||
return double_click;
|
||||
}
|
||||
|
||||
XMFLOAT4 GetAnalog(GAMEPAD_ANALOG analog, int playerindex)
|
||||
{
|
||||
if (playerindex < (int)controllers.size())
|
||||
@@ -805,4 +864,9 @@ namespace wi::input
|
||||
return touches;
|
||||
}
|
||||
|
||||
void SetCursor(CURSOR cursor)
|
||||
{
|
||||
cursor_next = cursor;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -181,6 +181,9 @@ namespace wi::input
|
||||
// send various feedback to the controller
|
||||
void SetControllerFeedback(const ControllerFeedback& data, int playerindex = 0);
|
||||
|
||||
// Check if left mouse button was double clicked in the current frame:
|
||||
bool IsDoubleClicked();
|
||||
|
||||
struct Pen
|
||||
{
|
||||
XMFLOAT2 position = {};
|
||||
@@ -203,5 +206,19 @@ namespace wi::input
|
||||
};
|
||||
const wi::vector<Touch>& GetTouches();
|
||||
|
||||
enum CURSOR
|
||||
{
|
||||
CURSOR_DEFAULT,
|
||||
CURSOR_TEXTINPUT,
|
||||
CURSOR_RESIZEALL,
|
||||
CURSOR_RESIZE_NS,
|
||||
CURSOR_RESIZE_EW,
|
||||
CURSOR_RESIZE_NESW,
|
||||
CURSOR_RESIZE_NWSE,
|
||||
CURSOR_HAND,
|
||||
CURSOR_NOTALLOWED,
|
||||
};
|
||||
void SetCursor(CURSOR cursor);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -62,12 +62,12 @@ namespace wi::jobsystem
|
||||
{
|
||||
uint32_t numCores = 0;
|
||||
uint32_t numThreads = 0;
|
||||
std::unique_ptr<JobQueue[]> jobQueuePerThread;
|
||||
std::unique_ptr<JobQueue[]> jobQueuePerThread[int(Priority::Count)];
|
||||
std::atomic_bool alive{ true };
|
||||
std::condition_variable wakeCondition;
|
||||
std::mutex wakeMutex;
|
||||
std::atomic<uint32_t> nextQueue{ 0 };
|
||||
wi::vector<std::thread> threads;
|
||||
wi::vector<std::thread> threads[int(Priority::Count)];
|
||||
void ShutDown()
|
||||
{
|
||||
alive.store(false); // indicate that new jobs cannot be started from this point
|
||||
@@ -78,14 +78,20 @@ namespace wi::jobsystem
|
||||
wakeCondition.notify_all(); // wakes up sleeping worker threads
|
||||
}
|
||||
});
|
||||
for (auto& thread : threads)
|
||||
for (auto& thread : threads[int(Priority::High)])
|
||||
{
|
||||
thread.join();
|
||||
}
|
||||
for (auto& thread : threads[int(Priority::Low)])
|
||||
{
|
||||
thread.join();
|
||||
}
|
||||
wake_loop = false;
|
||||
waker.join();
|
||||
jobQueuePerThread.reset();
|
||||
threads.clear();
|
||||
jobQueuePerThread[int(Priority::High)].reset();
|
||||
jobQueuePerThread[int(Priority::Low)].reset();
|
||||
threads[int(Priority::High)].clear();
|
||||
threads[int(Priority::Low)].clear();
|
||||
numCores = 0;
|
||||
numThreads = 0;
|
||||
}
|
||||
@@ -97,12 +103,12 @@ namespace wi::jobsystem
|
||||
|
||||
// Start working on a job queue
|
||||
// After the job queue is finished, it can switch to an other queue and steal jobs from there
|
||||
inline void work(uint32_t startingQueue)
|
||||
inline void work(uint32_t startingQueue, Priority priority)
|
||||
{
|
||||
Job job;
|
||||
for (uint32_t i = 0; i < internal_state.numThreads; ++i)
|
||||
{
|
||||
JobQueue& job_queue = internal_state.jobQueuePerThread[startingQueue % internal_state.numThreads];
|
||||
JobQueue& job_queue = internal_state.jobQueuePerThread[int(priority)][startingQueue % internal_state.numThreads];
|
||||
while (job_queue.pop_front(job))
|
||||
{
|
||||
JobArgs args;
|
||||
@@ -146,65 +152,95 @@ namespace wi::jobsystem
|
||||
|
||||
// Calculate the actual number of worker threads we want (-1 main thread):
|
||||
internal_state.numThreads = std::min(maxThreadCount, std::max(1u, internal_state.numCores - 1));
|
||||
internal_state.jobQueuePerThread.reset(new JobQueue[internal_state.numThreads]);
|
||||
internal_state.threads.reserve(internal_state.numThreads);
|
||||
internal_state.jobQueuePerThread[int(Priority::High)].reset(new JobQueue[internal_state.numThreads]);
|
||||
internal_state.jobQueuePerThread[int(Priority::Low)].reset(new JobQueue[internal_state.numThreads]);
|
||||
internal_state.threads[int(Priority::High)].reserve(internal_state.numThreads);
|
||||
internal_state.threads[int(Priority::Low)].reserve(internal_state.numThreads);
|
||||
|
||||
for (uint32_t threadID = 0; threadID < internal_state.numThreads; ++threadID)
|
||||
{
|
||||
internal_state.threads.emplace_back([threadID] {
|
||||
for (int prio = 0; prio < int(Priority::Count); ++prio)
|
||||
{
|
||||
const Priority priority = (Priority)prio;
|
||||
internal_state.threads[prio].emplace_back([threadID, priority] {
|
||||
|
||||
while (internal_state.alive.load())
|
||||
{
|
||||
work(threadID);
|
||||
while (internal_state.alive.load())
|
||||
{
|
||||
work(threadID, priority);
|
||||
|
||||
// finished with jobs, put to sleep
|
||||
std::unique_lock<std::mutex> lock(internal_state.wakeMutex);
|
||||
internal_state.wakeCondition.wait(lock);
|
||||
}
|
||||
// finished with jobs, put to sleep
|
||||
std::unique_lock<std::mutex> lock(internal_state.wakeMutex);
|
||||
internal_state.wakeCondition.wait(lock);
|
||||
}
|
||||
|
||||
});
|
||||
std::thread& worker = internal_state.threads.back();
|
||||
});
|
||||
std::thread& worker = internal_state.threads[prio].back();
|
||||
|
||||
#ifdef _WIN32
|
||||
// Do Windows-specific thread setup:
|
||||
HANDLE handle = (HANDLE)worker.native_handle();
|
||||
// Do Windows-specific thread setup:
|
||||
HANDLE handle = (HANDLE)worker.native_handle();
|
||||
|
||||
// Put each thread on to dedicated core:
|
||||
DWORD_PTR affinityMask = 1ull << threadID;
|
||||
DWORD_PTR affinity_result = SetThreadAffinityMask(handle, affinityMask);
|
||||
assert(affinity_result > 0);
|
||||
// Put each thread on to dedicated core:
|
||||
DWORD_PTR affinityMask = 1ull << threadID;
|
||||
DWORD_PTR affinity_result = SetThreadAffinityMask(handle, affinityMask);
|
||||
assert(affinity_result > 0);
|
||||
|
||||
//// Increase thread priority:
|
||||
//BOOL priority_result = SetThreadPriority(handle, THREAD_PRIORITY_HIGHEST);
|
||||
//assert(priority_result != 0);
|
||||
if (priority == Priority::High)
|
||||
{
|
||||
BOOL priority_result = SetThreadPriority(handle, THREAD_PRIORITY_NORMAL);
|
||||
assert(priority_result != 0);
|
||||
|
||||
std::wstring wthreadname = L"wi::jobsystem_" + std::to_wstring(threadID);
|
||||
HRESULT hr = SetThreadDescription(handle, wthreadname.c_str());
|
||||
assert(SUCCEEDED(hr));
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOL priority_result = SetThreadPriority(handle, THREAD_PRIORITY_LOWEST);
|
||||
assert(priority_result != 0);
|
||||
|
||||
std::wstring wthreadname = L"wi::jobsystem_lowprio_" + std::to_wstring(threadID);
|
||||
HRESULT hr = SetThreadDescription(handle, wthreadname.c_str());
|
||||
assert(SUCCEEDED(hr));
|
||||
}
|
||||
|
||||
// Name the thread:
|
||||
std::wstring wthreadname = L"wi::jobsystem_" + std::to_wstring(threadID);
|
||||
HRESULT hr = SetThreadDescription(handle, wthreadname.c_str());
|
||||
assert(SUCCEEDED(hr));
|
||||
#elif defined(PLATFORM_LINUX)
|
||||
#define handle_error_en(en, msg) \
|
||||
do { errno = en; perror(msg); } while (0)
|
||||
|
||||
int ret;
|
||||
cpu_set_t cpuset;
|
||||
CPU_ZERO(&cpuset);
|
||||
size_t cpusetsize = sizeof(cpuset);
|
||||
int ret;
|
||||
cpu_set_t cpuset;
|
||||
CPU_ZERO(&cpuset);
|
||||
size_t cpusetsize = sizeof(cpuset);
|
||||
|
||||
CPU_SET(threadID, &cpuset);
|
||||
ret = pthread_setaffinity_np(worker.native_handle(), cpusetsize, &cpuset);
|
||||
if (ret != 0)
|
||||
handle_error_en(ret, std::string(" pthread_setaffinity_np[" + std::to_string(threadID) + ']').c_str());
|
||||
CPU_SET(threadID, &cpuset);
|
||||
ret = pthread_setaffinity_np(worker.native_handle(), cpusetsize, &cpuset);
|
||||
if (ret != 0)
|
||||
handle_error_en(ret, std::string(" pthread_setaffinity_np[" + std::to_string(threadID) + ']').c_str());
|
||||
|
||||
|
||||
if (priority == Priority::High)
|
||||
{
|
||||
std::string thread_name = "wi::job::" + std::to_string(threadID);
|
||||
ret = pthread_setname_np(worker.native_handle(), thread_name.c_str());
|
||||
if (ret != 0)
|
||||
handle_error_en(ret, std::string(" pthread_setname_np[" + std::to_string(threadID) + ']').c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: set lower priority
|
||||
|
||||
std::string thread_name = "wi::job_low::" + std::to_string(threadID);
|
||||
ret = pthread_setname_np(worker.native_handle(), thread_name.c_str());
|
||||
if (ret != 0)
|
||||
handle_error_en(ret, std::string(" pthread_setname_np[" + std::to_string(threadID) + ']').c_str());
|
||||
}
|
||||
|
||||
// Name the thread
|
||||
std::string thread_name = "wi::job::" + std::to_string(threadID);
|
||||
ret = pthread_setname_np(worker.native_handle(), thread_name.c_str());
|
||||
if (ret != 0)
|
||||
handle_error_en(ret, std::string(" pthread_setname_np[" + std::to_string(threadID) + ']').c_str());
|
||||
#undef handle_error_en
|
||||
#elif defined(PLATFORM_PS5)
|
||||
wi::jobsystem::ps5::SetupWorker(worker, threadID);
|
||||
wi::jobsystem::ps5::SetupWorker(worker, threadID);
|
||||
#endif // _WIN32
|
||||
}
|
||||
}
|
||||
|
||||
wi::backlog::post("wi::jobsystem Initialized with [" + std::to_string(internal_state.numCores) + " cores] [" + std::to_string(internal_state.numThreads) + " threads] (" + std::to_string((int)std::round(timer.elapsed())) + " ms)");
|
||||
@@ -233,7 +269,7 @@ namespace wi::jobsystem
|
||||
job.groupJobEnd = 1;
|
||||
job.sharedmemory_size = 0;
|
||||
|
||||
internal_state.jobQueuePerThread[internal_state.nextQueue.fetch_add(1) % internal_state.numThreads].push_back(job);
|
||||
internal_state.jobQueuePerThread[int(ctx.priority)][internal_state.nextQueue.fetch_add(1) % internal_state.numThreads].push_back(job);
|
||||
internal_state.wakeCondition.notify_one();
|
||||
}
|
||||
|
||||
@@ -261,7 +297,7 @@ namespace wi::jobsystem
|
||||
job.groupJobOffset = groupID * groupSize;
|
||||
job.groupJobEnd = std::min(job.groupJobOffset + groupSize, jobCount);
|
||||
|
||||
internal_state.jobQueuePerThread[internal_state.nextQueue.fetch_add(1) % internal_state.numThreads].push_back(job);
|
||||
internal_state.jobQueuePerThread[int(ctx.priority)][internal_state.nextQueue.fetch_add(1) % internal_state.numThreads].push_back(job);
|
||||
}
|
||||
|
||||
internal_state.wakeCondition.notify_all();
|
||||
@@ -287,7 +323,7 @@ namespace wi::jobsystem
|
||||
internal_state.wakeCondition.notify_all();
|
||||
|
||||
// work() will pick up any jobs that are on stand by and execute them on this thread:
|
||||
work(internal_state.nextQueue.fetch_add(1) % internal_state.numThreads);
|
||||
work(internal_state.nextQueue.fetch_add(1) % internal_state.numThreads, ctx.priority);
|
||||
|
||||
while (IsBusy(ctx))
|
||||
{
|
||||
|
||||
@@ -20,10 +20,18 @@ namespace wi::jobsystem
|
||||
|
||||
uint32_t GetThreadCount();
|
||||
|
||||
enum class Priority
|
||||
{
|
||||
High, // Default
|
||||
Low, // Use this when you need the results after a few frames, not blocking high priority tasks
|
||||
Count
|
||||
};
|
||||
|
||||
// Defines a state of execution, can be waited on
|
||||
struct context
|
||||
{
|
||||
std::atomic<uint32_t> counter{ 0 };
|
||||
Priority priority = Priority::High;
|
||||
};
|
||||
|
||||
// Add a task to execute asynchronously. Any idle thread will execute this.
|
||||
|
||||
@@ -1635,11 +1635,6 @@ namespace wi
|
||||
{
|
||||
GraphicsDevice* device = wi::graphics::GetDevice();
|
||||
|
||||
// Set scissor on Compose, because some post processes don't handle scissoring (eg. Bloom) and those should be cut off:
|
||||
// Note that on expensive render operations we also used scissor to avoid wasted processing
|
||||
Rect scissor = GetScissorNativeResolution();
|
||||
device->BindScissorRects(1, &scissor, cmd);
|
||||
|
||||
wi::image::Params fx;
|
||||
fx.blendFlag = BLENDMODE_OPAQUE;
|
||||
fx.quality = wi::image::QUALITY_LINEAR;
|
||||
@@ -1660,13 +1655,6 @@ namespace wi
|
||||
wi::image::Draw(&debugUAV, fx, cmd);
|
||||
}
|
||||
|
||||
// Restore full resolution scissor:
|
||||
scissor.left = 0;
|
||||
scissor.top = 0;
|
||||
scissor.right = GetPhysicalWidth();
|
||||
scissor.bottom = GetPhysicalHeight();
|
||||
device->BindScissorRects(1, &scissor, cmd);
|
||||
|
||||
RenderPath2D::Compose(cmd);
|
||||
}
|
||||
|
||||
@@ -2346,6 +2334,9 @@ namespace wi
|
||||
{
|
||||
ao = value;
|
||||
|
||||
if (!rtParticleDistortion.IsValid())
|
||||
return; // ResizeBuffers hasn't been called yet
|
||||
|
||||
rtAO = {};
|
||||
ssaoResources = {};
|
||||
msaoResources = {};
|
||||
|
||||
@@ -6392,7 +6392,7 @@ void DrawDebugWorld(
|
||||
device->CreateBuffer(&bd, indices, &wirecamIB);
|
||||
}
|
||||
|
||||
device->BindPipelineState(&PSO_debug[DEBUGRENDERING_CUBE], cmd);
|
||||
device->BindPipelineState(&PSO_debug[DEBUGRENDERING_CUBE_DEPTH], cmd);
|
||||
|
||||
const GPUBuffer* vbs[] = {
|
||||
&wirecamVB,
|
||||
@@ -6528,7 +6528,7 @@ void DrawDebugWorld(
|
||||
{
|
||||
device->EventBegin("DebugPartitionTree", cmd);
|
||||
|
||||
device->BindPipelineState(&PSO_debug[DEBUGRENDERING_CUBE], cmd);
|
||||
device->BindPipelineState(&PSO_debug[DEBUGRENDERING_CUBE_DEPTH], cmd);
|
||||
|
||||
const GPUBuffer* vbs[] = {
|
||||
&wirecubeVB,
|
||||
@@ -7221,7 +7221,7 @@ void DrawDebugWorld(
|
||||
|
||||
// Local proxy boxes:
|
||||
|
||||
device->BindPipelineState(&PSO_debug[DEBUGRENDERING_CUBE], cmd);
|
||||
device->BindPipelineState(&PSO_debug[DEBUGRENDERING_CUBE_DEPTH], cmd);
|
||||
|
||||
const GPUBuffer* vbs[] = {
|
||||
&wirecubeVB,
|
||||
@@ -7375,7 +7375,7 @@ void DrawDebugWorld(
|
||||
if (mesh == nullptr)
|
||||
{
|
||||
// No mesh, just draw a box:
|
||||
device->BindPipelineState(&PSO_debug[DEBUGRENDERING_CUBE], cmd);
|
||||
device->BindPipelineState(&PSO_debug[DEBUGRENDERING_CUBE_DEPTH], cmd);
|
||||
const GPUBuffer* vbs[] = {
|
||||
&wirecubeVB,
|
||||
};
|
||||
@@ -15807,10 +15807,13 @@ void Postprocess_Tonemap(
|
||||
|
||||
assert(texture_colorgradinglut == nullptr || texture_colorgradinglut->desc.type == TextureDesc::Type::TEXTURE_3D); // This must be a 3D lut
|
||||
|
||||
XMHALF4 exposure_brightness_contrast_saturation = XMHALF4(exposure, brightness, contrast, saturation);
|
||||
|
||||
PushConstantsTonemap tonemap_push = {};
|
||||
tonemap_push.resolution_rcp.x = 1.0f / desc.width;
|
||||
tonemap_push.resolution_rcp.y = 1.0f / desc.height;
|
||||
tonemap_push.exposure = exposure;
|
||||
tonemap_push.exposure_brightness_contrast_saturation.x = uint(exposure_brightness_contrast_saturation.v);
|
||||
tonemap_push.exposure_brightness_contrast_saturation.y = uint(exposure_brightness_contrast_saturation.v >> 32ull);
|
||||
tonemap_push.flags = 0;
|
||||
if (dither)
|
||||
{
|
||||
@@ -15820,9 +15823,6 @@ void Postprocess_Tonemap(
|
||||
{
|
||||
tonemap_push.flags |= TONEMAP_FLAG_ACES;
|
||||
}
|
||||
tonemap_push.brightness = brightness;
|
||||
tonemap_push.contrast = contrast;
|
||||
tonemap_push.saturation = saturation;
|
||||
tonemap_push.texture_input = device->GetDescriptorIndex(&input, SubresourceType::SRV);
|
||||
tonemap_push.buffer_input_luminance = device->GetDescriptorIndex((buffer_luminance == nullptr) ? &luminance_dummy : buffer_luminance, SubresourceType::SRV);
|
||||
tonemap_push.texture_input_distortion = device->GetDescriptorIndex(texture_distortion, SubresourceType::SRV);
|
||||
|
||||
@@ -4844,7 +4844,7 @@ namespace wi::scene
|
||||
{
|
||||
SoundComponent& sound = sounds[i];
|
||||
|
||||
if (!sound.soundinstance.IsValid())
|
||||
if (!sound.soundinstance.IsValid() && sound.soundResource.IsValid())
|
||||
{
|
||||
sound.soundinstance.SetLooped(sound.IsLooped());
|
||||
wi::audio::CreateSoundInstance(&sound.soundResource.GetSound(), &sound.soundinstance);
|
||||
|
||||
@@ -2078,6 +2078,7 @@ namespace wi::scene
|
||||
|
||||
// With this we will ensure that serialized entities are unique and persistent across the scene:
|
||||
EntitySerializer seri;
|
||||
seri.ctx.priority = wi::jobsystem::Priority::Low; // serialization tasks will be low priority to not block rendering if scene loading is asynchronous
|
||||
|
||||
if(archive.GetVersion() >= 84)
|
||||
{
|
||||
|
||||
@@ -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 = 455;
|
||||
const int revision = 456;
|
||||
|
||||
const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);
|
||||
|
||||
@@ -50,7 +50,7 @@ All contributors: https://github.com/turanszkij/WickedEngine/graphs/contributors
|
||||
|
||||
Patreon supporters
|
||||
---------------------------
|
||||
Nemerle, James Webb, Quifeng Jin, TheGameCreators, Joseph Goldin, Yuri, Sergey K, Yukawa Kanta, Dragon Josh, John, LurkingNinja, Bernardo Del Castillo, Invictus, Scott Hunt, Yazan Altaki, Tuan NV, Robert MacGregor, cybernescence, Alexander Dahlin, blueapples, Delhills, NI NI, Sherief, ktopoet, Justin Macklin, Cédric Fabre, TogetherTeam, Bartosz Boczula, Arne Koenig, Ivan Trajchev, nathants, Fahd Ahmed, Gabriel Jadderson, SAS_Controller, Dominik Madarász, Segfault, Mike amanfo, Dennis Brakhane, rookie, Peter Moore, therealjtgill, Nicolas Embleton, Desuuc, radino1977, Anthony Curtis, manni heck, Matthias Hölzl, Phyffer, Lucas Pinheiro, Tapkaara, gpman, Anthony Python, Gnowos, Klaus, slaughternaut, Paul Brain, Connor Greaves, Alexandr, Lee Bamber, MCAlarm MC2, Titoutan, Willow, Aldo, lokimx, K. Osterman, Nomad, ykl, Alex Krokos, Timmy, Avaflow
|
||||
Nemerle, James Webb, Quifeng Jin, TheGameCreators, Joseph Goldin, Yuri, Sergey K, Yukawa Kanta, Dragon Josh, John, LurkingNinja, Bernardo Del Castillo, Invictus, Scott Hunt, Yazan Altaki, Tuan NV, Robert MacGregor, cybernescence, Alexander Dahlin, blueapples, Delhills, NI NI, Sherief, ktopoet, Justin Macklin, Cédric Fabre, TogetherTeam, Bartosz Boczula, Arne Koenig, Ivan Trajchev, nathants, Fahd Ahmed, Gabriel Jadderson, SAS_Controller, Dominik Madarász, Segfault, Mike amanfo, Dennis Brakhane, rookie, Peter Moore, therealjtgill, Nicolas Embleton, Desuuc, radino1977, Anthony Curtis, manni heck, Matthias Hölzl, Phyffer, Lucas Pinheiro, Tapkaara, gpman, Anthony Python, Gnowos, Klaus, slaughternaut, Paul Brain, Connor Greaves, Alexandr, Lee Bamber, MCAlarm MC2, Titoutan, Willow, Aldo, lokimx, K. Osterman, Nomad, ykl, Alex Krokos, Timmy, Avaflow, mat, Hexegonel Samael Michael, Joe Spataro, soru
|
||||
)";
|
||||
|
||||
return credits;
|
||||
|
||||
Reference in New Issue
Block a user