Skip to content

Commit

Permalink
Snap rotation angles to the face edges.
Browse files Browse the repository at this point in the history
Signed-off-by: Kristian Duske <[email protected]>
  • Loading branch information
kduske committed Apr 18, 2014
1 parent 977372a commit 4d0a4d9
Show file tree
Hide file tree
Showing 12 changed files with 63 additions and 22 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ Thumbs.db
/build/
/osx/wxWidgets
/xcode/
/eclipse/
/eclipse/
*.swp
2 changes: 1 addition & 1 deletion src/Model/BrushFace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,7 @@ namespace TrenchBroom {
}

float BrushFace::measureTextureAngle(const Vec2f& center, const Vec2f& point) const {
return m_texCoordSystem->measureAngle(center, point);
return m_texCoordSystem->measureAngle(m_attribs.rotation(), center, point);
}

const BrushEdgeList& BrushFace::edges() const {
Expand Down
5 changes: 3 additions & 2 deletions src/Model/ParallelTexCoordSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,9 @@ namespace TrenchBroom {
// todo
}

float ParallelTexCoordSystem::doMeasureAngle(const Vec2f& center, const Vec2f& point) const {
const Vec3 vec(point - center);
float ParallelTexCoordSystem::doMeasureAngle(const float currentAngle, const Vec2f& center, const Vec2f& point) const {
const Quat3 rot(Vec3::PosZ, -currentAngle);
const Vec3 vec = rot * (point - center);
const FloatType angleInRadians = Math::C::TwoPi - angleBetween(vec.normalized(), Vec3::PosX, Vec3::PosZ);
return static_cast<float>(Math::degrees(angleInRadians));
}
Expand Down
2 changes: 1 addition & 1 deletion src/Model/ParallelTexCoordSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ namespace TrenchBroom {
void doUpdate(const Vec3& normal, const BrushFaceAttribs& attribs);
void doCompensate(const Vec3& normal, const Vec3& center, const Mat4x4& transformation, BrushFaceAttribs& attribs);

float doMeasureAngle(const Vec2f& center, const Vec2f& point) const;
float doMeasureAngle(float currentAngle, const Vec2f& center, const Vec2f& point) const;
};
}
}
Expand Down
16 changes: 10 additions & 6 deletions src/Model/ParaxialTexCoordSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,20 +220,24 @@ namespace TrenchBroom {
attribs.setYScale(newYScale);
}

float ParaxialTexCoordSystem::doMeasureAngle(const Vec2f& center, const Vec2f& point) const {
const Vec3 vec(point - center);
float ParaxialTexCoordSystem::doMeasureAngle(const float currentAngle, const Vec2f& center, const Vec2f& point) const {
const Vec3& zAxis = m_index % 2 == 0 ? Vec3::PosZ : Vec3::NegZ;
const Quat3 rot(zAxis, -Math::radians(currentAngle));
const Vec3 vec = rot * (point - center);

const FloatType angleInRadians = Math::C::TwoPi - angleBetween(vec.normalized(), Vec3::PosX, zAxis);
return static_cast<float>(Math::degrees(angleInRadians));
const float angleInDegrees = static_cast<float>(Math::degrees(angleInRadians));

std::cout << "Current angle: " << currentAngle << " Vec: " << vec.asString() << "new radians: " << angleInRadians << " new degrees: " << angleInDegrees << std::endl;
return angleInDegrees;
}

Vec3 ParaxialTexCoordSystem::transformAxis(const Vec3& normal, const Vec3& axis, const Mat4x4& transformation) const {
return transformation * project(normal, axis);
}

void ParaxialTexCoordSystem::rotateAxes(Vec3& xAxis, Vec3& yAxis, const FloatType angle, const size_t planeNormIndex) const {
// for some reason, when the texture plane normal is the Y axis, we must rotation clockwise
const Quat3 rot(BaseAxes[(planeNormIndex / 2) * 6], planeNormIndex == 4 ? -angle : angle);
void ParaxialTexCoordSystem::rotateAxes(Vec3& xAxis, Vec3& yAxis, const FloatType angleInRadians, const size_t planeNormIndex) const {
const Quat3 rot(BaseAxes[(planeNormIndex / 2) * 6], planeNormIndex == 4 ? -angleInRadians : angleInRadians);
xAxis = rot * xAxis;
yAxis = rot * yAxis;
}
Expand Down
4 changes: 2 additions & 2 deletions src/Model/ParaxialTexCoordSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@ namespace TrenchBroom {
void doUpdate(const Vec3& normal, float rotation);
void doCompensate(const Vec3& normal, const Vec3& center, const Mat4x4& transformation, BrushFaceAttribs& attribs);

float doMeasureAngle(const Vec2f& center, const Vec2f& point) const;
float doMeasureAngle(float currentAngle, const Vec2f& center, const Vec2f& point) const;
private:
Vec3 transformAxis(const Vec3& normal, const Vec3& axis, const Mat4x4& transformation) const;
void rotateAxes(Vec3& xAxis, Vec3& yAxis, FloatType angle, size_t planeNormIndex) const;
void rotateAxes(Vec3& xAxis, Vec3& yAxis, FloatType angleInRadians, size_t planeNormIndex) const;

template <typename T1, typename T2>
Vec<T1,3> safeScaleAxis(const Vec<T1,3>& axis, const T2 factor) const {
Expand Down
4 changes: 2 additions & 2 deletions src/Model/TexCoordSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,8 @@ namespace TrenchBroom {
return coordinateSystemMatrix(xAxis, yAxis, zAxis, origin);
}

float TexCoordSystem::measureAngle(const Vec2f& center, const Vec2f& point) const {
return doMeasureAngle(center, point);
float TexCoordSystem::measureAngle(const float currentAngle, const Vec2f& center, const Vec2f& point) const {
return doMeasureAngle(currentAngle, center, point);
}

Vec3 TexCoordSystem::project(const Vec3& normal, const Vec3& vec) const {
Expand Down
4 changes: 2 additions & 2 deletions src/Model/TexCoordSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ namespace TrenchBroom {

Mat4x4 toMatrix(const Vec2f& offset, const Vec2f& scale) const;
Mat4x4 fromMatrix(const Vec2f& offset, const Vec2f& scale) const;
float measureAngle(const Vec2f& center, const Vec2f& point) const;
float measureAngle(float currentAngle, const Vec2f& center, const Vec2f& point) const;
protected:
Vec3 project(const Vec3& normal, const Vec3& vec) const;
Vec3 project(const Plane3& plane, const Vec3& vec) const;
Expand All @@ -62,7 +62,7 @@ namespace TrenchBroom {
virtual void doUpdate(const Vec3& normal, const BrushFaceAttribs& attribs) = 0;
virtual void doCompensate(const Vec3& normal, const Vec3& center, const Mat4x4& transformation, BrushFaceAttribs& attribs) = 0;

virtual float doMeasureAngle(const Vec2f& center, const Vec2f& point) const = 0;
virtual float doMeasureAngle(float currentAngle, const Vec2f& center, const Vec2f& point) const = 0;
};
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/Vec.h
Original file line number Diff line number Diff line change
Expand Up @@ -738,9 +738,9 @@ T angleBetween(const Vec<T,3> vec, const Vec<T,3>& axis, const Vec<T,3>& up) {
// computes the CCW angle between axis and vector in relation to the given up vector
// all vectors are expected to be normalized
const T cos = vec.dot(axis);
if (Math::eq(cos, static_cast<T>(1.0)))
if (cos == static_cast<T>(1.0))
return static_cast<T>(0.0);
if (Math::eq(cos, static_cast<T>(-1.0)))
if (cos ==static_cast<T>(-1.0))
return Math::Constants<T>::Pi;
const Vec<T,3> cross = crossed(axis, vec);
if (cross.dot(up) >= static_cast<T>(0.0))
Expand Down
33 changes: 33 additions & 0 deletions src/View/TexturingViewHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "Preferences.h"
#include "Hit.h"
#include "Assets/Texture.h"
#include "Model/BrushEdge.h"
#include "Model/BrushFace.h"
#include "Model/BrushVertex.h"
#include "Model/TexCoordSystemHelper.h"
Expand Down Expand Up @@ -235,6 +236,38 @@ namespace TrenchBroom {
assert(valid());
return m_face->measureTextureAngle(rotationCenterInFaceCoords(), point);
}

float TexturingViewHelper::snapRotationAngle(const float angle) const {
assert(valid());

const float angles[] = {
Math::mod(angle + 0.0f, 360.0f),
Math::mod(angle + 90.0f, 360.0f),
Math::mod(angle + 180.0f, 360.0f),
Math::mod(angle + 270.0f, 360.0f),
};
float minDelta = std::numeric_limits<float>::max();

const Model::TexCoordSystemHelper faceCoordSystem = Model::TexCoordSystemHelper::faceCoordSystem(m_face);
const Model::BrushEdgeList& edges = m_face->edges();
Model::BrushEdgeList::const_iterator it, end;
for (it = edges.begin(), end = edges.end(); it != end; ++it) {
const Model::BrushEdge* edge = *it;

const Vec3 startInFaceCoords = faceCoordSystem.worldToTex(edge->start->position);
const Vec3 endInFaceCoords = faceCoordSystem.worldToTex(edge->end->position);
const float edgeAngle = Math::mod(m_face->measureTextureAngle(startInFaceCoords, endInFaceCoords), 360.0f);

for (size_t i = 0; i < 4; ++i) {
if (std::abs(angles[i] - edgeAngle) < std::abs(minDelta))
minDelta = angles[i] - edgeAngle;
}
}

if (std::abs(minDelta) < 3.0f)
return angle - minDelta;
return angle;
}

void TexturingViewHelper::computeScaleOriginHandles(Line3& xHandle, Line3& yHandle) const {
assert(valid());
Expand Down
1 change: 1 addition & 0 deletions src/View/TexturingViewHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ namespace TrenchBroom {
Vec2f snapToPoints(const Vec2f& pointInFaceCoords, const Vec3::List& points) const;

float measureRotationAngle(const Vec2f& point) const;
float snapRotationAngle(float angle) const;

void computeScaleOriginHandles(Line3& xHandle, Line3& yHandle) const;
void computeScaleOriginHandleVertices(const Renderer::OrthographicCamera& camera, Vec3& x1, Vec3& x2, Vec3& y1, Vec3& y2) const;
Expand Down
7 changes: 4 additions & 3 deletions src/View/TexturingViewRotateTool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,10 +128,11 @@ namespace TrenchBroom {
m_helper.setRotationCenter(snappedPoint);
} else {
const Vec3 oldCenterInWorldCoords = faceCoordSystem.texToWorld(Vec3(m_helper.rotationCenterInFaceCoords()));
const float angleDelta = Math::mod(m_helper.measureRotationAngle(curPointInFaceCoords), 360.0f);
const float angle = Math::mod(face->rotation() + angleDelta, 360.0f);
const float angle = Math::mod(m_helper.measureRotationAngle(curPointInFaceCoords), 360.0f);
const float snappedAngle = m_helper.snapRotationAngle(angle);

const Model::BrushFaceList applyTo(1, face);
controller()->setFaceRotation(applyTo, angle, false);
controller()->setFaceRotation(applyTo, snappedAngle, false);

// Correct the offsets and the position of the rotation center.
const Vec2f oldCenterInFaceCoords(faceCoordSystem.worldToTex(oldCenterInWorldCoords));
Expand Down

0 comments on commit 4d0a4d9

Please sign in to comment.