Skip to content

Commit

Permalink
Aspect-preserving texture fitting now working
Browse files Browse the repository at this point in the history
Abandoned the original plan to calculate the required scale factors in
TextureProjection::fitTexture(); this turned out to be non-trivial as it would
require a calculation involving the effective aspect ratio of the selected face
in texture space.

Instead, this is done very simply at the GUI level by propagating the
calculated scale factor from the fitted axis to the non-fitted axis, in the
same way a user might achieve this effect manually by copy-pasting scale values
between the respective numeric entry fields.
  • Loading branch information
Matthew Mott committed Jul 27, 2021
1 parent b099c7d commit 58a3efa
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 11 deletions.
24 changes: 19 additions & 5 deletions radiant/ui/surfaceinspector/SurfaceInspector.cpp
Expand Up @@ -627,17 +627,31 @@ void SurfaceInspector::fitTexture(Axis axis)

if (repeatX > 0.0 && repeatY > 0.0)
{
// User-specified fit values must always be >0, but we use -1 internally
// to signal not to fit on a particular axis.
GlobalCommandSystem().executeCommand("FitTexture",
(axis == Axis::Y ? -1 : repeatX),
(axis == Axis::X ? -1 : repeatY));
GlobalCommandSystem().executeCommand("FitTexture", repeatX, repeatY);
}
else
{
// Invalid repeatX && repeatY values
wxutil::Messagebox::ShowError(_("Both fit values must be > 0."));
return;
}

// If only fitting on a single axis, propagate the scale factor for the
// fitted axis to the non-fitted axis, which should preserve the texture
// aspect ratio.
if (axis != Axis::BOTH)
{
GlobalSelectionSystem().foreachFace(
[&](IFace& face) {
ShiftScaleRotation texdef = face.getShiftScaleRotation();
if (axis == Axis::X)
texdef.scale[1] = texdef.scale[0];
else
texdef.scale[0] = texdef.scale[1];
face.setShiftScaleRotation(texdef);
}
);
}
}

void SurfaceInspector::onFit(Axis axis)
Expand Down
8 changes: 2 additions & 6 deletions radiantcore/brush/TextureProjection.cpp
Expand Up @@ -201,12 +201,8 @@ void TextureProjection::fitTexture(std::size_t width, std::size_t height,
bounds.extents.z() = 1;

// the bounds of a perfectly fitted texture transform
AABB perfect(Vector3(s_repeat > 0 ? s_repeat * 0.5 : bounds.origin.x(),
t_repeat > 0 ? t_repeat * 0.5 : bounds.origin.y(),
0),
Vector3(s_repeat > 0 ? s_repeat * 0.5 : bounds.extents.x(),
t_repeat > 0 ? t_repeat * 0.5 : bounds.extents.y(),
1));
AABB perfect(Vector3(s_repeat * 0.5, t_repeat * 0.5, 0),
Vector3(s_repeat * 0.5, t_repeat * 0.5, 1));

// the difference between the current texture transform and the perfectly fitted transform
Matrix4 diffMatrix = Matrix4::getTranslation(bounds.origin - perfect.origin);
Expand Down

0 comments on commit 58a3efa

Please sign in to comment.