Skip to content

Commit

Permalink
#5773: Refactoring, privatise the TextureMatrix member in TextureProj…
Browse files Browse the repository at this point in the history
…ection. The Face class is an exception and still accesses the field directly.
  • Loading branch information
codereader committed Oct 9, 2021
1 parent 8e9b2d5 commit 8f381f0
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 62 deletions.
24 changes: 12 additions & 12 deletions radiantcore/brush/Face.cpp
Expand Up @@ -97,7 +97,7 @@ Face::Face(Brush& owner, const Plane3& plane, const Matrix4& texdef,
setupSurfaceShader();
m_plane.setPlane(plane);

_texdef.matrix = TextureMatrix(texdef);
_texdef.setTransformFromMatrix4(texdef);

planeChanged();
shaderChanged();
Expand Down Expand Up @@ -473,26 +473,26 @@ void Face::setTexdef(const TexDef& texDef)
{
TextureProjection projection;

// Construct the BPTexDef out of the TexDef by using the according constructor
projection.matrix = TextureMatrix(texDef);
// Construct the BPTexDef out of the TexDef
projection.setFromTexDef(texDef);

// The bprimitive texdef needs to be scaled using our current texture dims
auto width = static_cast<double>(_shader.getWidth());
auto height = static_cast<double>(_shader.getHeight());

projection.matrix.coords[0][0] /= width;
projection.matrix.coords[0][1] /= width;
projection.matrix.coords[0][2] /= width;
projection.matrix.coords[1][0] /= height;
projection.matrix.coords[1][1] /= height;
projection.matrix.coords[1][2] /= height;
projection._matrix.coords[0][0] /= width;
projection._matrix.coords[0][1] /= width;
projection._matrix.coords[0][2] /= width;
projection._matrix.coords[1][0] /= height;
projection._matrix.coords[1][1] /= height;
projection._matrix.coords[1][2] /= height;

SetTexdef(projection);
}

ShiftScaleRotation Face::getShiftScaleRotation() const
{
auto texdef = _texdef.matrix.getFakeTexCoords();
auto texdef = _texdef._matrix.getFakeTexCoords();
auto ssr = texdef.toShiftScaleRotation();

// These values are going to show up in the Surface Inspector, so
Expand Down Expand Up @@ -538,7 +538,7 @@ void Face::setShiftScaleRotation(const ShiftScaleRotation& ssr)

// Construct the BPTexDef out of this TexDef
TextureProjection projection;
projection.matrix = TextureMatrix(texdef);
projection.setFromTexDef(texdef);

SetTexdef(projection);
}
Expand Down Expand Up @@ -708,7 +708,7 @@ void Face::emitTextureCoordinates()

void Face::applyDefaultTextureScale()
{
_texdef.matrix.addScale(_shader.getWidth(), _shader.getHeight());
_texdef._matrix.addScale(_shader.getWidth(), _shader.getHeight());
texdefChanged();
}

Expand Down
79 changes: 33 additions & 46 deletions radiantcore/brush/TextureProjection.cpp
Expand Up @@ -10,11 +10,11 @@ TextureProjection::TextureProjection() :
{}

TextureProjection::TextureProjection(const TextureProjection& other) :
TextureProjection(other.matrix)
TextureProjection(other._matrix)
{}

TextureProjection::TextureProjection(const TextureMatrix& otherMatrix) :
matrix(otherMatrix)
_matrix(otherMatrix)
{}

TextureMatrix TextureProjection::GetDefaultProjection()
Expand All @@ -35,15 +35,15 @@ TextureMatrix TextureProjection::GetDefaultProjection()
// Assigns an <other> projection to this one
void TextureProjection::assign(const TextureProjection& other)
{
matrix = other.matrix;
_matrix = other._matrix;
}

void TextureProjection::setTransform(const Matrix3& transform)
{
// Check the matrix for validity
if ((transform.xx() != 0 || transform.yx() != 0) && (transform.xy() != 0 || transform.yy() != 0))
{
matrix = TextureMatrix(transform);
_matrix = TextureMatrix(transform);
}
else
{
Expand All @@ -56,32 +56,37 @@ void TextureProjection::setTransformFromMatrix4(const Matrix4& transform)
// Check the matrix for validity
if ((transform[0] != 0 || transform[4] != 0) && (transform[1] != 0 || transform[5] != 0))
{
matrix = TextureMatrix(transform);
_matrix = TextureMatrix(transform);
}
else
{
rError() << "invalid texture matrix" << std::endl;
}
}

Matrix4 TextureProjection::getTransform() const
void TextureProjection::setFromTexDef(const TexDef& texDef)
{
return matrix.getTransform();
_matrix = TextureMatrix(texDef);
}

Matrix4 TextureProjection::getMatrix4() const
{
return getMatrix4FromTextureMatrix(_matrix.getMatrix3());
}

Matrix3 TextureProjection::getMatrix() const
{
return matrix.getMatrix3();
return _matrix.getMatrix3();
}

void TextureProjection::shift(double s, double t)
{
matrix.shift(s, t);
_matrix.shift(s, t);
}

void TextureProjection::normalise(float width, float height)
{
matrix.normalise(width, height);
_matrix.normalise(width, height);
}

// Fits a texture to a brush face
Expand All @@ -95,7 +100,7 @@ void TextureProjection::fitTexture(std::size_t width, std::size_t height,
}

// Sanity-check the matrix, if it contains any NaNs or INFs we fall back to the default projection (#5371)
Matrix4 st2tex = matrix.isSane() ? getTransform() : GetDefaultProjection().getTransform();
Matrix4 st2tex = _matrix.isSane() ? getMatrix4() : GetDefaultProjection().getTransform();

// the current texture transform
Matrix4 local2tex = st2tex;
Expand Down Expand Up @@ -199,26 +204,16 @@ void TextureProjection::alignTexture(IFace::AlignEdge align, const Winding& wind

Matrix4 TextureProjection::getWorldToTexture(const Vector3& normal, const Matrix4& localToWorld) const
{
// Get the transformation matrix, that contains the shift, scale and rotation
// of the texture in "condensed" form (as matrix components).
Matrix4 local2tex = getTransform();

// Now combine the normal vector with the local2tex matrix
// to retrieve the final transformation that transforms vertex
// coordinates into the texture plane.
{
// we don't care if it's not normalised...
// See the emitTextureCoordinates() method for more comments on these transformation steps

// Retrieve the basis vectors of the texture plane space, they are perpendicular to <normal>
Matrix4 xyz2st = getBasisTransformForNormal(localToWorld.transformDirection(normal));
// Texture Projection
auto local2tex = getMatrix4();

// Transform the basis vectors with the according texture scale, rotate and shift operations
// These are contained in the local2tex matrix, so the matrices have to be multiplied.
local2tex.multiplyBy(xyz2st);
}
// Axs Base
auto xyz2st = getBasisTransformForNormal(localToWorld.transformDirection(normal));
local2tex.multiplyBy(xyz2st);

// Transform the texture basis vectors into the "BrushFace space"
// usually the localToWorld matrix is identity, so this doesn't do anything.
// L2W (usually an identity transform)
local2tex.multiplyBy(localToWorld);

return local2tex;
Expand All @@ -227,31 +222,23 @@ Matrix4 TextureProjection::getWorldToTexture(const Vector3& normal, const Matrix
void TextureProjection::emitTextureCoordinates(Winding& winding, const Vector3& normal, const Matrix4& localToWorld) const
{
// Quit if we have less than three points (degenerate brushes?)
if (winding.size() < 3)
{
return;
}

// Get the transformation matrix, that contains the shift, scale and rotation
// of the texture in "condensed" form (as matrix components).
Matrix4 local2tex = getTransform();

// Now combine the face normal vector with the local2tex matrix
// to retrieve the final transformation that transforms brush vertex
// coordinates into the texture plane.
if (winding.size() < 3) return;

// we don't care if it's not normalised...
// Load the 2D texture projection matrix, transforming XY coordinates to UV
auto local2tex = getMatrix4();

// Retrieve the basis vectors of the texture plane space, they are perpendicular to <normal>
Matrix4 xyz2st = getBasisTransformForNormal(localToWorld.transformDirection(normal));
// Using the face's normal we can construct a rotation transformation,
// which rotates world space such that the Z axis is aligned with the face normal.
// After this stage we only need to consider the XY part of the 3D vertices.
auto xyz2st = getBasisTransformForNormal(localToWorld.transformDirection(normal));

// Transform the basis vectors with the according texture scale, rotate and shift operations
// These are contained in the local2tex matrix, so the matrices have to be multiplied.
local2tex.multiplyBy(xyz2st);

// Calculate the tangent and bitangent vectors to allow the correct openGL transformations
Vector3 tangent(local2tex.getTransposed().xCol().getVector3().getNormalised());
Vector3 bitangent(local2tex.getTransposed().yCol().getVector3().getNormalised());
auto tangent(local2tex.getTransposed().xCol().getVector3().getNormalised());
auto bitangent(local2tex.getTransposed().yCol().getVector3().getNormalised());

// Transform the texture basis vectors into the "BrushFace space"
// usually the localToWorld matrix is identity, so this doesn't do anything.
Expand All @@ -261,7 +248,7 @@ void TextureProjection::emitTextureCoordinates(Winding& winding, const Vector3&
// onto each of them.
for (auto& vertex : winding)
{
Vector3 texcoord = local2tex.transformPoint(vertex.vertex);
auto texcoord = local2tex.transformPoint(vertex.vertex);

// Store the s,t coordinates into the winding texcoord vector
vertex.texcoord[0] = texcoord[0];
Expand Down
12 changes: 8 additions & 4 deletions radiantcore/brush/TextureProjection.h
Expand Up @@ -14,9 +14,11 @@
*/
class TextureProjection
{
public:
TextureMatrix matrix;
private:
TextureMatrix _matrix;
friend class Face;

public:
/**
* \brief
* Construct a default TextureProjection.
Expand All @@ -36,8 +38,10 @@ class TextureProjection

void assign(const TextureProjection& other);

Matrix4 getTransform() const;
void setTransform(const Matrix3& transform);
void setTransformFromMatrix4(const Matrix4& transform);
void setFromTexDef(const TexDef& texDef);

Matrix3 getMatrix() const;

// s and t are texture coordinates, not pixels
Expand All @@ -63,7 +67,7 @@ class TextureProjection
void calculateFromPoints(const Vector3 points[3], const Vector2 uvs[3], const Vector3& normal);

private:
void setTransformFromMatrix4(const Matrix4& transform);
Matrix4 getMatrix4() const;

// Normalise projection for a given texture width and height.
void normalise(float width, float height);
Expand Down

0 comments on commit 8f381f0

Please sign in to comment.