Skip to content

Commit

Permalink
Minor changes to texture locking.
Browse files Browse the repository at this point in the history
Add test case for texture locking.

Signed-off-by: Kristian Duske <[email protected]>
  • Loading branch information
kduske committed Jul 31, 2014
1 parent d344259 commit e8ca991
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 23 deletions.
2 changes: 1 addition & 1 deletion common/src/Model/BrushFace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@ namespace TrenchBroom {
void BrushFace::transform(const Mat4x4& transform, const bool lockTexture) {
using std::swap;

m_texCoordSystem->transform(m_boundary, transform, m_attribs, lockTexture);
m_texCoordSystem->transform(m_boundary, transform, m_attribs, lockTexture, center());

m_boundary.transform(transform);
for (size_t i = 0; i < 3; ++i)
Expand Down
11 changes: 5 additions & 6 deletions common/src/Model/ParallelTexCoordSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,22 +85,21 @@ namespace TrenchBroom {
m_yAxis = rot * m_yAxis;
}

void ParallelTexCoordSystem::doTransform(const Plane3& oldBoundary, const Mat4x4& transformation, BrushFaceAttribs& attribs, bool lockTexture) {
void ParallelTexCoordSystem::doTransform(const Plane3& oldBoundary, const Mat4x4& transformation, BrushFaceAttribs& attribs, bool lockTexture, const Vec3& oldInvariant) {
// calculate the current texture coordinates of the face's center
const Vec3 oldAnchor = oldBoundary.anchor();
const Vec2f oldAnchorTechCoords = computeTexCoords(oldAnchor, attribs.scale()) + attribs.offset();
const Vec2f oldInvariantTechCoords = computeTexCoords(oldInvariant, attribs.scale()) + attribs.offset();

const Vec3 offset = transformation * Vec3::Null;
m_xAxis = transformation * m_xAxis - offset;
m_yAxis = transformation * m_yAxis - offset;

// determine the new texture coordinates of the transformed center of the face, sans offsets
const Vec3 newAnchor = transformation * oldAnchor;
const Vec2f newAnchorTexCoords = computeTexCoords(newAnchor, attribs.scale());
const Vec3 newInvariant = transformation * oldInvariant;
const Vec2f newInvariantTexCoords = computeTexCoords(newInvariant, attribs.scale());

// since the center should be invariant, the offsets are determined by the difference of the current and
// the original texture coordinates of the center
const Vec2f newOffset = attribs.modOffset(oldAnchorTechCoords - newAnchorTexCoords).corrected(4);
const Vec2f newOffset = attribs.modOffset(oldInvariantTechCoords - newInvariantTexCoords).corrected(4);
attribs.setOffset(newOffset);
}

Expand Down
2 changes: 1 addition & 1 deletion common/src/Model/ParallelTexCoordSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ namespace TrenchBroom {
Vec2f doGetTexCoords(const Vec3& point, const BrushFaceAttribs& attribs) const;

void doSetRotation(const Vec3& normal, float oldAngle, float newAngle);
void doTransform(const Plane3& oldBoundary, const Mat4x4& transformation, BrushFaceAttribs& attribs, bool lockTexture);
void doTransform(const Plane3& oldBoundary, const Mat4x4& transformation, BrushFaceAttribs& attribs, bool lockTexture, const Vec3& invariant);
void doShearTexture(const Vec3& normal, const Vec2f& factors);

float doMeasureAngle(float currentAngle, const Vec2f& center, const Vec2f& point) const;
Expand Down
23 changes: 13 additions & 10 deletions common/src/Model/ParaxialTexCoordSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ namespace TrenchBroom {
setRotation(normal, 0.0f, 0.0f);
}

ParaxialTexCoordSystem::ParaxialTexCoordSystem(const Vec3& normal) {
setRotation(normal, 0.0f, 0.0f);
}

size_t ParaxialTexCoordSystem::planeNormalIndex(const Vec3& normal) {
size_t bestIndex = 0;
FloatType bestDot = static_cast<FloatType>(0.0);
Expand Down Expand Up @@ -112,35 +116,34 @@ namespace TrenchBroom {
rotateAxes(m_xAxis, m_yAxis, Math::radians(newAngle), m_index);
}

void ParaxialTexCoordSystem::doTransform(const Plane3& oldBoundary, const Mat4x4& transformation, BrushFaceAttribs& attribs, bool lockTexture) {
void ParaxialTexCoordSystem::doTransform(const Plane3& oldBoundary, const Mat4x4& transformation, BrushFaceAttribs& attribs, bool lockTexture, const Vec3& oldInvariant) {

const Vec3 offset = transformation * Vec3::Null;
const Vec3& oldNormal = oldBoundary.normal;
Vec3 newNormal = transformation * oldNormal - offset;
// fix some rounding errors - if the old and new texture axes are almost the same, use the old axis
if (newNormal.equals(oldNormal, 0.01))
newNormal = oldNormal;
assert(Math::eq(newNormal.length(), 1.0));

if (!lockTexture || attribs.xScale() == 0.0f || attribs.yScale() == 0.0f) {
setRotation(newNormal, attribs.rotation(), attribs.rotation());
return;
}

// calculate the current texture coordinates of the origin
const Vec3 oldAnchor = oldBoundary.anchor();
const Vec2f oldAnchorTexCoords = computeTexCoords(oldAnchor, attribs.scale()) + attribs.offset();
const Vec2f oldInvariantTexCoords = computeTexCoords(oldInvariant, attribs.scale()) + attribs.offset();

// compute the parameters of the transformed texture coordinate system
const Vec3 newAnchor = transformation * oldAnchor;
const Vec3 newInvariant = transformation * oldInvariant;

const Mat4x4 toBoundary = planeProjectionMatrix(0.0, oldNormal, crossed(m_xAxis, m_yAxis).normalized());
const Mat4x4 toBoundary = planeProjectionMatrix(0.0, oldNormal, getZAxis());
const Mat4x4 fromBoundary = invertedMatrix(toBoundary);
const Mat4x4 projectToBoundary = fromBoundary * Mat4x4::ZerZ * toBoundary;

// compensate the translational part of the transformation for the directional vectors
const Vec3 newXAxisOnBoundary = transformation * projectToBoundary * (m_xAxis * attribs.xScale()) - offset;
const Vec3 newYAxisOnBoundary = transformation * projectToBoundary * (m_yAxis * attribs.yScale()) - offset;
assert(Math::eq(newNormal.length(), 1.0));
const Vec3 newXAxisOnBoundary = transformation * projectToBoundary * safeScaleAxis(m_xAxis, attribs.xScale()) - offset;
const Vec3 newYAxisOnBoundary = transformation * projectToBoundary * safeScaleAxis(m_yAxis, attribs.yScale()) - offset;

// obtain the new texture plane norm and the new base texture axes
Vec3 newBaseXAxis, newBaseYAxis, newProjectionAxis;
Expand Down Expand Up @@ -205,11 +208,11 @@ namespace TrenchBroom {
doSetRotation(newNormal, attribs.rotation(), newRotation);

// determine the new texture coordinates of the transformed center of the face, sans offsets
const Vec2f newAnchorTexCoords = computeTexCoords(newAnchor, newScale);
const Vec2f newInvariantTexCoords = computeTexCoords(newInvariant, newScale);

// since the center should be invariant, the offsets are determined by the difference of the current and
// the original texture coordinates of the center
const Vec2f newOffset = attribs.modOffset(oldAnchorTexCoords - newAnchorTexCoords).corrected(4);
const Vec2f newOffset = attribs.modOffset(oldInvariantTexCoords - newInvariantTexCoords).corrected(4);

assert(!newOffset.nan());
assert(!newScale.nan());
Expand Down
3 changes: 2 additions & 1 deletion common/src/Model/ParaxialTexCoordSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ namespace TrenchBroom {
Vec3 m_yAxis;
public:
ParaxialTexCoordSystem(const Vec3& point0, const Vec3& point1, const Vec3& point2);
ParaxialTexCoordSystem(const Vec3& normal);

static size_t planeNormalIndex(const Vec3& normal);
static void axes(size_t index, Vec3& xAxis, Vec3& yAxis);
Expand All @@ -53,7 +54,7 @@ namespace TrenchBroom {
Vec2f doGetTexCoords(const Vec3& point, const BrushFaceAttribs& attribs) const;

void doSetRotation(const Vec3& normal, float oldAngle, float newAngle);
void doTransform(const Plane3& oldBoundary, const Mat4x4& transformation, BrushFaceAttribs& attribs, bool lockTexture);
void doTransform(const Plane3& oldBoundary, const Mat4x4& transformation, BrushFaceAttribs& attribs, bool lockTexture, const Vec3& invariant);
void doShearTexture(const Vec3& normal, const Vec2f& factors);

float doMeasureAngle(float currentAngle, const Vec2f& center, const Vec2f& point) const;
Expand Down
4 changes: 2 additions & 2 deletions common/src/Model/TexCoordSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ namespace TrenchBroom {
doSetRotation(normal, oldAngle, newAngle);
}

void TexCoordSystem::transform(const Plane3& oldBoundary, const Mat4x4& transformation, BrushFaceAttribs& attribs, bool lockTexture) {
doTransform(oldBoundary, transformation, attribs, lockTexture);
void TexCoordSystem::transform(const Plane3& oldBoundary, const Mat4x4& transformation, BrushFaceAttribs& attribs, bool lockTexture, const Vec3& invariant) {
doTransform(oldBoundary, transformation, attribs, lockTexture, invariant);
}

void TexCoordSystem::moveTexture(const Vec3& normal, const Vec3& up, const Vec3& right, const Vec2f& offset, BrushFaceAttribs& attribs) const {
Expand Down
4 changes: 2 additions & 2 deletions common/src/Model/TexCoordSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ namespace TrenchBroom {
Vec2f getTexCoords(const Vec3& point, const BrushFaceAttribs& attribs) const;

void setRotation(const Vec3& normal, float oldAngle, float newAngle);
void transform(const Plane3& oldBoundary, const Mat4x4& transformation, BrushFaceAttribs& attribs, bool lockTexture);
void transform(const Plane3& oldBoundary, const Mat4x4& transformation, BrushFaceAttribs& attribs, bool lockTexture, const Vec3& invariant);

void moveTexture(const Vec3& normal, const Vec3& up, const Vec3& right, const Vec2f& offset, BrushFaceAttribs& attribs) const;
void rotateTexture(const Vec3& normal, float angle, BrushFaceAttribs& attribs) const;
Expand All @@ -73,7 +73,7 @@ namespace TrenchBroom {
virtual Vec2f doGetTexCoords(const Vec3& point, const BrushFaceAttribs& attribs) const = 0;

virtual void doSetRotation(const Vec3& normal, float oldAngle, float newAngle) = 0;
virtual void doTransform(const Plane3& oldBoundary, const Mat4x4& transformation, BrushFaceAttribs& attribs, bool lockTexture) = 0;
virtual void doTransform(const Plane3& oldBoundary, const Mat4x4& transformation, BrushFaceAttribs& attribs, bool lockTexture, const Vec3& invariant) = 0;
virtual void doShearTexture(const Vec3& normal, const Vec2f& factors) = 0;

virtual float doMeasureAngle(float currentAngle, const Vec2f& center, const Vec2f& point) const = 0;
Expand Down
50 changes: 50 additions & 0 deletions test/src/Model/ParaxialTexCoordSystemTest.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
Copyright (C) 2010-2014 Kristian Duske
This file is part of TrenchBroom.
TrenchBroom is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
TrenchBroom is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with TrenchBroom. If not, see <http://www.gnu.org/licenses/>.
*/

#include <gtest/gtest.h>

#include "TestUtils.h"

#include "TrenchBroom.h"
#include "VecMath.h"
#include "Model/BrushFace.h"
#include "Model/ParaxialTexCoordSystem.h"

namespace TrenchBroom {
namespace Model {
TEST(ParaxialTexCoordSystemTest, transform) {
const FloatType oldDistance(-583.10490580282567);
const Vec3 oldNormal(0.62449286425754114, -0.63673782238023802, -0.45229814065711621);
const Plane3 oldBoundary(oldDistance, oldNormal);
ParaxialTexCoordSystem coordSystem(oldNormal);

BrushFaceAttribs attribs("texture");
const Vec3 center(16.0, 32.0, -12.0);
const Mat4x4 transform = translationMatrix(center) * rotationMatrix(Vec3::PosZ, Math::radians(15.0)) * translationMatrix(-center);
const Vec3 invariant(-184.65096673000929, 632.60193647633696, 143.68866328257172);
const Vec2f oldTexCoords = coordSystem.getTexCoords(invariant, attribs);

coordSystem.transform(oldBoundary, transform, attribs, true, invariant);
const Vec2f newTexCoords = coordSystem.getTexCoords(transform * invariant, attribs);

ASSERT_VEC_EQ(oldTexCoords, newTexCoords);
ASSERT_VEC_EQ(Vec2f::One, attribs.scale());
}
}
}

0 comments on commit e8ca991

Please sign in to comment.