Skip to content

Commit

Permalink
Two enhancement for the path deformation tool. (#185)
Browse files Browse the repository at this point in the history
  • Loading branch information
seagetch authored Feb 14, 2023
1 parent dc07284 commit a0241e3
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public:
override
void setPath(CatmullSpline path) {
auto pathTool = cast(PathDeformTool)(tools[VertexToolMode.PathDeform]);
pathTool.path = path;
pathTool.setPath(path);
}

override int peek(ImGuiIO* io, Camera camera) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,6 @@ public:
}
}
if (dirty) {
writefln("pushDeformAction: %s", target.name);
editorAction.updateNewState();
foreach (a; editorAction.action.actions) {
if (auto laction = cast(LazyBoundAction)a)
Expand Down
73 changes: 58 additions & 15 deletions source/creator/viewport/common/mesheditor/tools/pathdeform.d
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,29 @@ import bindbc.imgui;
import std.algorithm.mutation;
import std.algorithm.searching;
import std.stdio;
import std.math;

class PathDeformTool : NodeSelect {

CatmullSpline path;
uint pathDragTarget;
uint lockedPoint;

override
void setToolMode(VertexToolMode toolMode, IncMeshEditorOne impl) {
pathDragTarget = -1;
lockedPoint = -1;
super.setToolMode(toolMode, impl);
}

void setPath(CatmullSpline path) {
if (path is null || this.path != path) {
this.path = path;
pathDragTarget = -1;
lockedPoint = -1;
}
}

override bool update(ImGuiIO* io, IncMeshEditorOne impl, int action, out bool changed) {
super.update(io, impl, action, changed);

Expand All @@ -47,6 +58,8 @@ class PathDeformTool : NodeSelect {
incStatusTooltip(_("Create/Destroy"), _("Left Mouse (x2)"));
incStatusTooltip(_("Switch Mode"), _("TAB"));
}
incStatusTooltip(_("Toggle locked point"), _("Ctrl"));
incStatusTooltip(_("Move point along with the path"), _("Shift"));

impl.vtxAtMouse = null; // Do not need this in this mode

Expand Down Expand Up @@ -81,9 +94,19 @@ class PathDeformTool : NodeSelect {
if (idx != -1) path.removePoint(idx);
else path.addPoint(impl.mousePos);
pathDragTarget = -1;
lockedPoint = -1;
path.mapReference();
} else if (igIsMouseClicked(ImGuiMouseButton.Left)) {
pathDragTarget = editPath.findPoint(impl.mousePos);
auto target = editPath.findPoint(impl.mousePos);
if (io.KeyCtrl) {
if (target == lockedPoint)
lockedPoint = -1;
else
lockedPoint = target;
pathDragTarget = -1;
} else {
pathDragTarget = target;
}
}

if (incDragStartedInViewport(ImGuiMouseButton.Left) && igIsMouseDown(ImGuiMouseButton.Left) && incInputIsDragRequested(ImGuiMouseButton.Left)) {
Expand All @@ -94,17 +117,37 @@ class PathDeformTool : NodeSelect {
}

if (isDragging && pathDragTarget != -1) {
vec2 relTranslation = impl.mousePos - impl.lastMousePos;
editPath.points[pathDragTarget].position += relTranslation;
if (pathDragTarget != lockedPoint) {
if (lockedPoint != -1) {
int step = (pathDragTarget > lockedPoint)? 1: -1;
vec2 prevRelPosition = impl.lastMousePos - editPath.points[lockedPoint].position;
vec2 relPosition = impl.mousePos - editPath.points[lockedPoint].position;
float prevAngle = atan2(prevRelPosition.y, prevRelPosition.x);
float angle = atan2(relPosition.y, relPosition.x);
float relAngle = angle - prevAngle;
mat4 rotate = mat4.identity.translate(vec3(-editPath.points[lockedPoint].position, 0)).rotateZ(relAngle).translate(vec3(editPath.points[lockedPoint].position, 0));

for (int i = lockedPoint + step; 0 <= i && i < editPath.points.length; i += step) {
editPath.points[i].position = (rotate * vec4(editPath.points[i].position, 0, 1)).xy;
}
} else if (io.KeyShift) {
float off = path.findClosestPointOffset(impl.mousePos);
vec2 pos = path.eval(off);
editPath.points[pathDragTarget].position = pos;
} else {
vec2 relTranslation = impl.mousePos - impl.lastMousePos;
editPath.points[pathDragTarget].position += relTranslation;
}

editPath.update();
if (impl.deforming) {
mat4 trans = impl.updatePathTarget();
if (impl.hasAction())
impl.markActionDirty();
changed = true;
} else {
path.mapReference();
editPath.update();
if (impl.deforming) {
mat4 trans = impl.updatePathTarget();
if (impl.hasAction())
impl.markActionDirty();
changed = true;
} else {
path.mapReference();
}
}
}

Expand All @@ -117,11 +160,11 @@ class PathDeformTool : NodeSelect {
super.draw(camera, impl);

if (path && path.target && impl.deforming) {
path.draw(impl.transform, vec4(0, 0.6, 0.6, 1));
path.target.draw(impl.transform, vec4(0, 1, 0, 1));
path.draw(impl.transform, vec4(0, 0.6, 0.6, 1), lockedPoint);
path.target.draw(impl.transform, vec4(0, 1, 0, 1), lockedPoint);
} else if (path) {
if (path.target) path.target.draw(impl.transform, vec4(0, 0.6, 0, 1));
path.draw(impl.transform, vec4(0, 1, 1, 1));
if (path.target) path.target.draw(impl.transform, vec4(0, 0.6, 0, 1), lockedPoint);
path.draw(impl.transform, vec4(0, 1, 1, 1), lockedPoint);
}
}

Expand Down
7 changes: 6 additions & 1 deletion source/creator/viewport/common/spline.d
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,7 @@ public:
interpolate();
}

void draw(mat4 trans, vec4 color) {
void draw(mat4 trans, vec4 color, uint lockedPoint = -1) {
if (drawLines.length > 0) {
inDbgSetBuffer(drawLines);
inDbgDrawLines(color, trans);
Expand All @@ -453,6 +453,11 @@ public:
inDbgPointsSize(6);
inDbgDrawPoints(color, trans);
}
if (lockedPoint >= 0 && lockedPoint < drawPoints.length) {
inDbgSetBuffer([drawPoints[lockedPoint]]);
inDbgPointsSize(6);
inDbgDrawPoints(vec4(1, 0, 0, 1), trans);
}
}

void resetFloating() {
Expand Down

0 comments on commit a0241e3

Please sign in to comment.