paint tool: axis locking, brush shape, brush rotation
This commit is contained in:
+1
-2
@@ -452,9 +452,8 @@ void EditorComponent::Load()
|
||||
ss += wi::version::GetVersionString();
|
||||
ss += "\nCreated by Turánszki János";
|
||||
ss += "\n\nWebsite: https://wickedengine.net/";
|
||||
ss += "\nGithub page: https://github.com/turanszkij/WickedEngine";
|
||||
ss += "\nSource code: https://github.com/turanszkij/WickedEngine";
|
||||
ss += "\nDiscord chat: https://discord.gg/CFjRYmE";
|
||||
ss += "\nYou can support the project on Patreon: https://www.patreon.com/wickedengine";
|
||||
ss += "\n\nControls\n";
|
||||
ss += "------------\n";
|
||||
ss += "Move camera: WASD, or Contoller left stick or D-pad\n";
|
||||
|
||||
@@ -36,3 +36,10 @@
|
||||
#define ICON_ROTATE ICON_FA_ROTATE_RIGHT
|
||||
#define ICON_TRANSLATE ICON_FA_UP_DOWN_LEFT_RIGHT
|
||||
#define ICON_CHECK ICON_FA_CHECK
|
||||
#define ICON_DISABLED ICON_FA_BAN
|
||||
|
||||
#define ICON_LEFT_RIGHT ICON_FA_LEFT_RIGHT
|
||||
#define ICON_UP_DOWN ICON_FA_UP_DOWN
|
||||
#define ICON_UPRIGHT_DOWNLEFT ICON_FA_UP_RIGHT_AND_DOWN_LEFT_FROM_CENTER
|
||||
#define ICON_CIRCLE ICON_FA_CIRCLE
|
||||
#define ICON_SQUARE ICON_FA_SQUARE_FULL
|
||||
|
||||
@@ -96,7 +96,7 @@ void OptionsWindow::Create(EditorComponent* _editor)
|
||||
AddWidget(&fpsCheckBox);
|
||||
fpsCheckBox.SetCheck(editor->main->infoDisplay.fpsinfo);
|
||||
|
||||
otherinfoCheckBox.Create("Advanced: ");
|
||||
otherinfoCheckBox.Create("Info: ");
|
||||
otherinfoCheckBox.SetTooltip("Toggle advanced data in the info display text in top left corner.");
|
||||
otherinfoCheckBox.OnClick([&](wi::gui::EventArgs args) {
|
||||
editor->main->infoDisplay.heap_allocation_counter = args.bValue;
|
||||
|
||||
+139
-15
@@ -14,7 +14,7 @@ void PaintToolWindow::Create(EditorComponent* _editor)
|
||||
editor = _editor;
|
||||
|
||||
wi::gui::Window::Create("Paint Tool", wi::gui::Window::WindowControls::COLLAPSE);
|
||||
SetSize(XMFLOAT2(360, 560));
|
||||
SetSize(XMFLOAT2(360, 600));
|
||||
|
||||
float x = 105;
|
||||
float y = 0;
|
||||
@@ -29,17 +29,17 @@ void PaintToolWindow::Create(EditorComponent* _editor)
|
||||
modeComboBox.SetTooltip("Choose paint tool mode");
|
||||
modeComboBox.SetPos(XMFLOAT2(x, y));
|
||||
modeComboBox.SetSize(XMFLOAT2(wid, hei));
|
||||
modeComboBox.AddItem("Disabled");
|
||||
modeComboBox.AddItem("Texture");
|
||||
modeComboBox.AddItem("Vertexcolor");
|
||||
modeComboBox.AddItem("Sculpting - Add");
|
||||
modeComboBox.AddItem("Sculpting - Subtract");
|
||||
modeComboBox.AddItem("Softbody - Pinning");
|
||||
modeComboBox.AddItem("Softbody - Physics");
|
||||
modeComboBox.AddItem("Hairparticle - Add Triangle");
|
||||
modeComboBox.AddItem("Hairparticle - Remove Triangle");
|
||||
modeComboBox.AddItem("Hairparticle - Length (Alpha)");
|
||||
modeComboBox.AddItem("Wind weight (Alpha)");
|
||||
modeComboBox.AddItem(ICON_DISABLED " Disabled");
|
||||
modeComboBox.AddItem(ICON_MATERIAL " Texture");
|
||||
modeComboBox.AddItem(ICON_MESH " Vertexcolor");
|
||||
modeComboBox.AddItem(ICON_MESH " Sculpting - Add");
|
||||
modeComboBox.AddItem(ICON_MESH " Sculpting - Subtract");
|
||||
modeComboBox.AddItem(ICON_SOFTBODY " Softbody - Pinning");
|
||||
modeComboBox.AddItem(ICON_SOFTBODY " Softbody - Physics");
|
||||
modeComboBox.AddItem(ICON_HAIR " Hairparticle - Add Triangle");
|
||||
modeComboBox.AddItem(ICON_HAIR " Hairparticle - Remove Triangle");
|
||||
modeComboBox.AddItem(ICON_HAIR " Hairparticle - Length (Alpha)");
|
||||
modeComboBox.AddItem(ICON_MESH " Wind weight (Alpha)");
|
||||
modeComboBox.SetSelected(0);
|
||||
modeComboBox.OnSelect([&](wi::gui::EventArgs args) {
|
||||
switch (args.iValue)
|
||||
@@ -115,6 +115,12 @@ void PaintToolWindow::Create(EditorComponent* _editor)
|
||||
spacingSlider.SetPos(XMFLOAT2(x, y += step));
|
||||
AddWidget(&spacingSlider);
|
||||
|
||||
rotationSlider.Create(0, 1, 0, 10000, "Brush Rotation: ");
|
||||
rotationSlider.SetTooltip("Brush rotation randomness. This will affect the splat mode brush texture.");
|
||||
rotationSlider.SetSize(XMFLOAT2(wid, hei));
|
||||
rotationSlider.SetPos(XMFLOAT2(x, y += step));
|
||||
AddWidget(&rotationSlider);
|
||||
|
||||
backfaceCheckBox.Create("Backfaces: ");
|
||||
backfaceCheckBox.SetTooltip("Set whether to paint on backfaces of geometry or not");
|
||||
backfaceCheckBox.SetSize(XMFLOAT2(hei, hei));
|
||||
@@ -135,6 +141,16 @@ void PaintToolWindow::Create(EditorComponent* _editor)
|
||||
pressureCheckBox.SetCheck(false);
|
||||
AddWidget(&pressureCheckBox);
|
||||
|
||||
axisCombo.Create("Axis Lock: ");
|
||||
axisCombo.SetTooltip("You can lock modification to an axis here.");
|
||||
axisCombo.SetPos(XMFLOAT2(x, y));
|
||||
axisCombo.SetSize(XMFLOAT2(wid, hei));
|
||||
axisCombo.AddItem(ICON_DISABLED, (uint64_t)AxisLock::Disabled);
|
||||
axisCombo.AddItem("X " ICON_LEFT_RIGHT, (uint64_t)AxisLock::X);
|
||||
axisCombo.AddItem("Y " ICON_UP_DOWN, (uint64_t)AxisLock::Y);
|
||||
axisCombo.AddItem("Z " ICON_UPRIGHT_DOWNLEFT, (uint64_t)AxisLock::Z);
|
||||
AddWidget(&axisCombo);
|
||||
|
||||
colorPicker.SetPos(XMFLOAT2(5, y += step));
|
||||
AddWidget(&colorPicker);
|
||||
|
||||
@@ -159,6 +175,15 @@ void PaintToolWindow::Create(EditorComponent* _editor)
|
||||
textureSlotComboBox.SetSelected(0);
|
||||
AddWidget(&textureSlotComboBox);
|
||||
|
||||
brushShapeComboBox.Create("Brush Shape: ");
|
||||
brushShapeComboBox.SetTooltip("Choose shape for brush masking effect");
|
||||
brushShapeComboBox.SetPos(XMFLOAT2(x, y += step));
|
||||
brushShapeComboBox.SetSize(XMFLOAT2(wid, hei));
|
||||
brushShapeComboBox.AddItem(ICON_CIRCLE);
|
||||
brushShapeComboBox.AddItem(ICON_SQUARE);
|
||||
brushShapeComboBox.SetSelected(0);
|
||||
AddWidget(&brushShapeComboBox);
|
||||
|
||||
saveTextureButton.Create("Save Texture");
|
||||
saveTextureButton.SetTooltip("Save edited texture.");
|
||||
saveTextureButton.SetSize(XMFLOAT2(wid, hei));
|
||||
@@ -268,19 +293,32 @@ void PaintToolWindow::Update(float dt)
|
||||
|
||||
if (GetMode() == MODE_TEXTURE)
|
||||
{
|
||||
rotationSlider.SetVisible(true);
|
||||
textureSlotComboBox.SetVisible(true);
|
||||
brushShapeComboBox.SetVisible(true);
|
||||
saveTextureButton.SetVisible(true);
|
||||
brushTextureButton.SetVisible(true);
|
||||
revealTextureButton.SetVisible(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
rotationSlider.SetVisible(false);
|
||||
textureSlotComboBox.SetVisible(false);
|
||||
brushShapeComboBox.SetVisible(false);
|
||||
saveTextureButton.SetVisible(false);
|
||||
brushTextureButton.SetVisible(false);
|
||||
revealTextureButton.SetVisible(false);
|
||||
}
|
||||
|
||||
if (GetMode() == MODE_SCULPTING_ADD || GetMode() == MODE_SCULPTING_SUBTRACT)
|
||||
{
|
||||
axisCombo.SetVisible(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
axisCombo.SetVisible(false);
|
||||
}
|
||||
|
||||
rot -= dt;
|
||||
// by default, paint tool is on center of screen, this makes it easy to tweak radius with GUI:
|
||||
XMFLOAT2 posNew;
|
||||
@@ -333,6 +371,7 @@ void PaintToolWindow::Update(float dt)
|
||||
const XMVECTOR ADD = XMVectorSet(0.5f, 0.5f, 0, 0);
|
||||
const XMVECTOR SCREEN = XMVectorSet((float)editor->GetLogicalWidth(), (float)editor->GetLogicalHeight(), 1, 1);
|
||||
const XMVECTOR F = camera.GetAt();
|
||||
const float brush_rotation = wi::random::GetRandom(0.0f, rotationSlider.GetValue() * XM_2PI);
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
@@ -406,10 +445,16 @@ void PaintToolWindow::Update(float dt)
|
||||
PaintTextureCB cb;
|
||||
cb.xPaintBrushCenter = center;
|
||||
cb.xPaintBrushRadius = (uint32_t)pressure_radius;
|
||||
if (brushShapeComboBox.GetSelected() == 1)
|
||||
{
|
||||
cb.xPaintBrushRadius = (uint)std::ceil((float(cb.xPaintBrushRadius) * 2 / std::sqrt(2.0f))); // square shape, diagonal dispatch size
|
||||
}
|
||||
cb.xPaintBrushAmount = amount;
|
||||
cb.xPaintBrushFalloff = falloff;
|
||||
cb.xPaintBrushColor = color.rgba;
|
||||
cb.xPaintReveal = revealTex.IsValid() ? 1 : 0;
|
||||
cb.xPaintBrushRotation = brush_rotation;
|
||||
cb.xPaintBrushShape = (uint)brushShapeComboBox.GetSelected();
|
||||
device->PushConstants(&cb, sizeof(cb), cmd);
|
||||
|
||||
const uint diameter = cb.xPaintBrushRadius * 2;
|
||||
@@ -435,6 +480,8 @@ void PaintToolWindow::Update(float dt)
|
||||
paintrad.uvset = uvset;
|
||||
paintrad.dimensions.x = desc.width;
|
||||
paintrad.dimensions.y = desc.height;
|
||||
paintrad.rotation = brush_rotation;
|
||||
paintrad.shape = (uint)brushShapeComboBox.GetSelected();
|
||||
wi::renderer::DrawPaintRadius(paintrad);
|
||||
}
|
||||
break;
|
||||
@@ -641,11 +688,32 @@ void PaintToolWindow::Update(float dt)
|
||||
|
||||
const XMMATRIX W = XMLoadFloat4x4(&transform->world);
|
||||
|
||||
if (sculpting_normal.x < FLT_EPSILON && sculpting_normal.y < FLT_EPSILON && sculpting_normal.z < FLT_EPSILON)
|
||||
XMVECTOR sculptDir;
|
||||
AxisLock axis_lock = (AxisLock)axisCombo.GetItemUserData(axisCombo.GetSelected());
|
||||
switch (axis_lock)
|
||||
{
|
||||
sculpting_normal = editor->hovered.normal;
|
||||
default:
|
||||
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;
|
||||
}
|
||||
sculptDir = XMVector3TransformNormal(XMVector3Normalize(XMLoadFloat3(&sculpting_normal)), XMMatrixInverse(nullptr, W));
|
||||
break;
|
||||
case PaintToolWindow::AxisLock::X:
|
||||
sculpting_normal = XMFLOAT3(1, 0, 0);
|
||||
sculptDir = XMLoadFloat3(&sculpting_normal);
|
||||
break;
|
||||
case PaintToolWindow::AxisLock::Y:
|
||||
sculpting_normal = XMFLOAT3(0, 1, 0);
|
||||
sculptDir = XMLoadFloat3(&sculpting_normal);
|
||||
break;
|
||||
case PaintToolWindow::AxisLock::Z:
|
||||
sculpting_normal = XMFLOAT3(0, 0, 1);
|
||||
sculptDir = XMLoadFloat3(&sculpting_normal);
|
||||
break;
|
||||
}
|
||||
XMVECTOR sculptDir = XMVector3TransformNormal(XMVector3Normalize(XMLoadFloat3(&sculpting_normal)), XMMatrixInverse(nullptr, W));
|
||||
|
||||
|
||||
bool rebuild = false;
|
||||
if (painting)
|
||||
@@ -1462,3 +1530,59 @@ void PaintToolWindow::ReplaceEditTextureSlot(wi::scene::MaterialComponent& mater
|
||||
material.textures[sel].resource.SetTexture(texture);
|
||||
material.SetDirty();
|
||||
}
|
||||
|
||||
void PaintToolWindow::ResizeLayout()
|
||||
{
|
||||
wi::gui::Window::ResizeLayout();
|
||||
const float padding = 4;
|
||||
const float width = GetWidgetAreaSize().x;
|
||||
float y = padding;
|
||||
|
||||
auto add = [&](wi::gui::Widget& widget) {
|
||||
if (!widget.IsVisible())
|
||||
return;
|
||||
const float margin_left = 110;
|
||||
const float margin_right = 30;
|
||||
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_right = [&](wi::gui::Widget& widget) {
|
||||
if (!widget.IsVisible())
|
||||
return;
|
||||
const float margin_right = 30;
|
||||
widget.SetPos(XMFLOAT2(width - margin_right - widget.GetSize().x, y));
|
||||
y += widget.GetSize().y;
|
||||
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;
|
||||
};
|
||||
|
||||
add(modeComboBox);
|
||||
add_fullwidth(infoLabel);
|
||||
add(radiusSlider);
|
||||
add(amountSlider);
|
||||
add(falloffSlider);
|
||||
add(spacingSlider);
|
||||
add(rotationSlider);
|
||||
add_right(backfaceCheckBox);
|
||||
add_right(wireCheckBox);
|
||||
add_right(pressureCheckBox);
|
||||
add(textureSlotComboBox);
|
||||
add(brushShapeComboBox);
|
||||
add(axisCombo);
|
||||
add(saveTextureButton);
|
||||
add_right(brushTextureButton);
|
||||
add_right(revealTextureButton);
|
||||
|
||||
colorPicker.SetPos(XMFLOAT2(padding, y));
|
||||
}
|
||||
|
||||
@@ -38,14 +38,17 @@ public:
|
||||
wi::gui::Slider amountSlider;
|
||||
wi::gui::Slider falloffSlider;
|
||||
wi::gui::Slider spacingSlider;
|
||||
wi::gui::Slider rotationSlider;
|
||||
wi::gui::CheckBox backfaceCheckBox;
|
||||
wi::gui::CheckBox wireCheckBox;
|
||||
wi::gui::CheckBox pressureCheckBox;
|
||||
wi::gui::ColorPicker colorPicker;
|
||||
wi::gui::ComboBox textureSlotComboBox;
|
||||
wi::gui::ComboBox brushShapeComboBox;
|
||||
wi::gui::Button saveTextureButton;
|
||||
wi::gui::Button brushTextureButton;
|
||||
wi::gui::Button revealTextureButton;
|
||||
wi::gui::ComboBox axisCombo;
|
||||
|
||||
void Update(float dt);
|
||||
void DrawBrush(const wi::Canvas& canvas, wi::graphics::CommandList cmd) const;
|
||||
@@ -69,7 +72,17 @@ public:
|
||||
MODE GetMode() const;
|
||||
void SetEntity(wi::ecs::Entity value, int subsetindex = -1);
|
||||
|
||||
enum class AxisLock
|
||||
{
|
||||
Disabled,
|
||||
X,
|
||||
Y,
|
||||
Z
|
||||
};
|
||||
|
||||
wi::Archive* currentHistory = nullptr;
|
||||
void RecordHistory(bool start, wi::graphics::CommandList cmd = wi::graphics::CommandList());
|
||||
void ConsumeHistoryOperation(wi::Archive& archive, bool undo);
|
||||
|
||||
void ResizeLayout() override;
|
||||
};
|
||||
|
||||
@@ -870,16 +870,23 @@ struct PaintTextureCB
|
||||
float xPaintBrushFalloff;
|
||||
uint xPaintBrushColor;
|
||||
uint xPaintReveal;
|
||||
float xPaintBrushRotation;
|
||||
|
||||
uint xPaintBrushShape;
|
||||
uint padding0;
|
||||
uint padding1;
|
||||
uint padding2;
|
||||
};
|
||||
|
||||
CBUFFER(PaintRadiusCB, CBSLOT_RENDERER_MISC)
|
||||
{
|
||||
uint2 xPaintRadResolution;
|
||||
uint2 xPaintRadCenter;
|
||||
|
||||
uint xPaintRadUVSET;
|
||||
float xPaintRadRadius;
|
||||
uint2 pad;
|
||||
float xPaintRadBrushRotation;
|
||||
uint xPaintRadBrushShape;
|
||||
};
|
||||
|
||||
struct SkinningPushConstants
|
||||
|
||||
@@ -7,10 +7,28 @@
|
||||
float4 main(PixelInput PSIn) : SV_TARGET
|
||||
{
|
||||
const float2 pixel = (xPaintRadUVSET == 0 ? PSIn.uvsets.xy : PSIn.uvsets.zw) * xPaintRadResolution;
|
||||
const float dist = distance(pixel, xPaintRadCenter);
|
||||
float circle = dist - xPaintRadRadius;
|
||||
float3 color = circle < 0 ? float3(0, 0, 0) : float3(1, 1, 1);
|
||||
float alpha = 1 - saturate(abs(circle) * 0.25f);
|
||||
|
||||
const float2x2 rot = float2x2(
|
||||
cos(xPaintRadBrushRotation), -sin(xPaintRadBrushRotation),
|
||||
sin(xPaintRadBrushRotation), cos(xPaintRadBrushRotation)
|
||||
);
|
||||
const float2 diff = mul(xPaintRadCenter - pixel, rot);
|
||||
|
||||
float dist = 0;
|
||||
switch (xPaintRadBrushShape)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
dist = length(diff);
|
||||
break;
|
||||
case 1:
|
||||
dist = max(abs(diff.x), abs(diff.y));
|
||||
break;
|
||||
}
|
||||
|
||||
float shape = dist - xPaintRadRadius;
|
||||
float3 color = shape < 0 ? float3(0, 0, 0) : float3(1, 1, 1);
|
||||
float alpha = 1 - saturate(abs(shape) * 0.25f);
|
||||
|
||||
return float4(color, alpha);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,27 @@ void main( uint3 DTid : SV_DispatchThreadID )
|
||||
{
|
||||
const uint2 pixel = push.xPaintBrushCenter + DTid.xy - push.xPaintBrushRadius.xx;
|
||||
|
||||
const float2 brush_uv = (DTid.xy + 0.5) / (push.xPaintBrushRadius.xx * 2);
|
||||
const float2x2 rot = float2x2(
|
||||
cos(push.xPaintBrushRotation), -sin(push.xPaintBrushRotation),
|
||||
sin(push.xPaintBrushRotation), cos(push.xPaintBrushRotation)
|
||||
);
|
||||
const float2 diff = mul((float2)push.xPaintBrushCenter - (float2)pixel, rot);
|
||||
|
||||
float dist = 0;
|
||||
float radius = (float)push.xPaintBrushRadius;
|
||||
switch (push.xPaintBrushShape)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
dist = length(diff);
|
||||
break;
|
||||
case 1:
|
||||
dist = max(abs(diff.x), abs(diff.y));
|
||||
radius /= SQRT2;
|
||||
break;
|
||||
}
|
||||
|
||||
const float2 brush_uv = (diff / radius) * 0.5 + 0.5;
|
||||
const float2 brush_uv_quad_x = QuadReadAcrossX(brush_uv);
|
||||
const float2 brush_uv_quad_y = QuadReadAcrossY(brush_uv);
|
||||
const float2 brush_uv_dx = brush_uv - brush_uv_quad_x;
|
||||
@@ -29,9 +49,8 @@ void main( uint3 DTid : SV_DispatchThreadID )
|
||||
const float2 reveal_uv_dy = reveal_uv - reveal_uv_quad_y;
|
||||
float4 reveal_color = texture_reveal.SampleGrad(sampler_linear_clamp, reveal_uv, reveal_uv_dx, reveal_uv_dy);
|
||||
|
||||
const float dist = distance((float2)pixel, (float2)push.xPaintBrushCenter);
|
||||
const float affection = push.xPaintBrushAmount * pow(1 - saturate(dist / (float)push.xPaintBrushRadius), push.xPaintBrushFalloff);
|
||||
if (affection > 0 && dist < (float)push.xPaintBrushRadius)
|
||||
const float affection = push.xPaintBrushAmount * pow(1 - saturate(dist / radius), push.xPaintBrushFalloff);
|
||||
if (affection > 0 && dist < radius)
|
||||
{
|
||||
if (push.xPaintReveal)
|
||||
{
|
||||
@@ -39,4 +58,8 @@ void main( uint3 DTid : SV_DispatchThreadID )
|
||||
}
|
||||
output[pixel] = lerp(output[pixel], brush_color, affection);
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// output[pixel] = float4(1,0,0,1);
|
||||
//}
|
||||
}
|
||||
|
||||
@@ -5984,6 +5984,8 @@ void DrawDebugWorld(
|
||||
cb.xPaintRadCenter = x.center;
|
||||
cb.xPaintRadRadius = x.radius;
|
||||
cb.xPaintRadUVSET = x.uvset;
|
||||
cb.xPaintRadBrushRotation = x.rotation;
|
||||
cb.xPaintRadBrushShape = x.shape;
|
||||
device->BindDynamicConstantBuffer(cb, CB_GETBINDSLOT(PaintRadiusCB), cmd);
|
||||
|
||||
ObjectPushConstants push;
|
||||
|
||||
@@ -920,8 +920,10 @@ namespace wi::renderer
|
||||
int subset = -1;
|
||||
uint32_t uvset = 0;
|
||||
float radius = 0;
|
||||
XMUINT2 center;
|
||||
XMUINT2 dimensions;
|
||||
XMUINT2 center = {};
|
||||
XMUINT2 dimensions = {};
|
||||
float rotation = 0;
|
||||
uint shape = 0; // 0: circle, 1 : square
|
||||
};
|
||||
void DrawPaintRadius(const PaintRadius& paintrad);
|
||||
|
||||
|
||||
@@ -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 = 2;
|
||||
const int revision = 3;
|
||||
|
||||
const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user