diff --git a/include/ipatch.h b/include/ipatch.h index 1a22309308..5821d1ad87 100644 --- a/include/ipatch.h +++ b/include/ipatch.h @@ -215,8 +215,18 @@ class IPatch // Reverts any transform that has been applied since the last time freezeTransform() was called virtual void revertTransform() = 0; + // Returns the transformable control point (not the one returned by ctrlAt) - this one is + // part of the "transformed" working set of the patch which will either be saved on freezeTransform() + // or discarded on revertTransform(). + virtual PatchControl& getTransformedCtrlAt(std::size_t row, std::size_t col) = 0; + // Promotes the current transformed state to the new base state virtual void freezeTransform() = 0; + + // Updates the patch tesselation based on the transformed set of control vertices + // Setting force to true will update the tesselation even if controlPointsChanged() + // hasn't been called in the meantime. + virtual void updateTesselation(bool force = false) = 0; }; namespace patch diff --git a/radiantcore/patch/Patch.cpp b/radiantcore/patch/Patch.cpp index a863b8cffe..ff3b280b05 100644 --- a/radiantcore/patch/Patch.cpp +++ b/radiantcore/patch/Patch.cpp @@ -406,6 +406,11 @@ const PatchControl& Patch::ctrlAt(std::size_t row, std::size_t col) const { return _ctrl[row*_width+col]; } +PatchControl& Patch::getTransformedCtrlAt(std::size_t row, std::size_t col) +{ + return _ctrlTransformed[row * _width + col]; +} + // called just before an action to save the undo state void Patch::undoSave() { @@ -518,10 +523,10 @@ bool Patch::isDegenerate() const { return true; } -void Patch::updateTesselation() +void Patch::updateTesselation(bool force) { // Only do something if the tesselation has actually changed - if (!_tesselationChanged) return; + if (!_tesselationChanged && !force) return; _tesselationChanged = false; diff --git a/radiantcore/patch/Patch.h b/radiantcore/patch/Patch.h index 8baad8b208..11191c93c5 100644 --- a/radiantcore/patch/Patch.h +++ b/radiantcore/patch/Patch.h @@ -218,6 +218,8 @@ class Patch : // The same as above just for const const PatchControl& ctrlAt(std::size_t row, std::size_t col) const override; + PatchControl& getTransformedCtrlAt(std::size_t row, std::size_t col) override; + /** greebo: Inserts two columns before and after the column with index . * Throws an GenericPatchException if an error occurs. */ @@ -359,12 +361,12 @@ class Patch : // Static signal holder, signal is emitted after any patch texture has changed static sigc::signal& signal_patchTextureChanged(); + void updateTesselation(bool force = false); + private: // This notifies the surfaceinspector/patchinspector about the texture change void textureChanged(); - void updateTesselation(); - // greebo: checks, if the shader name is valid void check_shader(); diff --git a/radiantcore/selection/textool/PatchNode.h b/radiantcore/selection/textool/PatchNode.h index 3d954fc37c..b07e9341bb 100644 --- a/radiantcore/selection/textool/PatchNode.h +++ b/radiantcore/selection/textool/PatchNode.h @@ -1,6 +1,7 @@ #pragma once #include "ipatch.h" +#include "itextstream.h" #include "NodeBase.h" namespace textool @@ -20,13 +21,15 @@ class PatchNode : void beginTransformation() override { + // We call undoSave() here for consistency, but technically it's too early - + // the undo operation hasn't started yet _patch.undoSave(); } void revertTransformation() override { _patch.revertTransform(); - _patch.controlPointsChanged(); + _patch.updateTesselation(); } void applyTransformToSelected(const Matrix3& transform) override @@ -36,11 +39,15 @@ class PatchNode : vertex.texcoord = transform * vertex.texcoord; }); - _patch.controlPointsChanged(); + // We have to force the patch to update its tesselation since + // modifying the "transformed" control point set won't trigger this + _patch.updateTesselation(true); } void commitTransformation() override { + // Patch::freezeTransform will call undoSave() before overwriting + // the control point set with the transformed ones _patch.freezeTransform(); } @@ -118,7 +125,7 @@ class PatchNode : { for (std::size_t row = 0; row < _patch.getHeight(); ++row) { - functor(_patch.ctrlAt(row, col)); + functor(_patch.getTransformedCtrlAt(row, col)); } } }