Skip to content

Commit

Permalink
#5878: RenderableSemiCircle uses Matrix4 for axis substitution
Browse files Browse the repository at this point in the history
Instead of using a RemapPolicy struct passed via a template parameter
(which results in a separate copy of this non-trivial constructor being
generated for each axis), pass in a simple Matrix4 which is used to
substitute the axes.
  • Loading branch information
Matthew Mott committed Apr 26, 2022
1 parent 10ebd73 commit fa260f0
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 15 deletions.
32 changes: 24 additions & 8 deletions radiantcore/selection/manipulators/Renderables.h
Expand Up @@ -171,20 +171,36 @@ class RenderableLineStrip :
};

/// Line strip in the shape of a semicircle
template<typename RemapPolicy>
class RenderableSemiCircle :
public RenderableLineStrip
{
public:
RenderableSemiCircle(std::size_t segments, double radius, const Matrix4& localToWorld) :
RenderableLineStrip((segments << 2) + 1, localToWorld)

/**
* @brief Construct a new RenderableSemiCircle object
*
* @param segments
* Number of linear segments to divide the semicircle into.
*
* @param radius
* Radius of the semicircle in world units.
*
* @param localToWorld
* Local space transformation matrix.
*
* @param axisRemap
* Optional matrix to reassign axes, used to orient the semicircle in 3D space.
*/
RenderableSemiCircle(std::size_t segments, double radius, const Matrix4& localToWorld,
const Matrix4& axisRemap)
: RenderableLineStrip((segments << 2) + 1, localToWorld)
{
const double increment = math::PI / double(segments << 2);

std::size_t count = 0;
double x = radius;
double y = 0;
RemapPolicy::set(_rawPoints[segments << 2], -radius, 0, 0);
_rawPoints[segments << 2] = axisRemap * Vertex3(-radius, 0, 0);

while (count < segments) {
auto& i = _rawPoints[count];
Expand All @@ -193,17 +209,17 @@ class RenderableSemiCircle :
auto& k = _rawPoints[count + (segments << 1)];
auto& l = _rawPoints[(segments << 1) - (count + 1) + (segments << 1)];

RemapPolicy::set(i, x, -y, 0);
RemapPolicy::set(k, -y, -x, 0);
i = axisRemap * Vertex3(x, -y, 0);
k = axisRemap * Vertex3(-y, -x, 0);

++count;

const double theta = increment * count;
x = radius * cos(theta);
y = radius * sin(theta);

RemapPolicy::set(j, y, -x, 0);
RemapPolicy::set(l, -x, -y, 0);
j = axisRemap * Vertex3(y, -x, 0);
l = axisRemap * Vertex3(-x, -y, 0);
}
}
};
Expand Down
21 changes: 17 additions & 4 deletions radiantcore/selection/manipulators/RotateManipulator.cpp
Expand Up @@ -14,6 +14,19 @@ namespace
constexpr static auto CircleSegments = 8;
constexpr static auto CircleRadius = 64.0;
const Vector4 AngleTextColour(0.75, 0, 0, 1);

static const Matrix4 REMAP_YZX = Matrix4::byRows(
0, 0, 1, 0,
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 0, 1
);
static const Matrix4 REMAP_ZXY = Matrix4::byRows(
0, 1, 0, 0,
0, 0, 1, 0,
1, 0, 0, 0,
0, 0, 0, 1
);
}

RotateManipulator::RotateManipulator(ManipulationPivot& pivot, std::size_t segments, float radius) :
Expand All @@ -23,9 +36,9 @@ RotateManipulator::RotateManipulator(ManipulationPivot& pivot, std::size_t segme
_rotateAxis(*this),
_translatePivot(_pivotTranslatable),
_localPivotPoint(0,0,0),
_circleX(CircleSegments, CircleRadius, _local2worldX),
_circleY(CircleSegments, CircleRadius, _local2worldY),
_circleZ(CircleSegments, CircleRadius, _local2worldZ),
_circleX(CircleSegments, CircleRadius, _local2worldX, REMAP_YZX),
_circleY(CircleSegments, CircleRadius, _local2worldY, REMAP_ZXY),
_circleZ(CircleSegments, CircleRadius, _local2worldZ, Matrix4::getIdentity()),
_circleScreen(CircleSegments, CircleRadius * 1.15, _pivot2World._viewpointSpace),
_circleSphere(CircleSegments, CircleRadius, _pivot2World._viewpointSpace),
_pivotPoint(_localPivotPoint, _pivot2World._worldSpace),
Expand Down Expand Up @@ -116,7 +129,7 @@ void RotateManipulator::onPreRender(const RenderSystemPtr& renderSystem, const V
}

_pivot2World.update(_pivot.getMatrix4(), volume.GetModelview(), volume.GetProjection(), volume.GetViewport());

updateCircleTransforms();
updateColours();
updateAngleText();
Expand Down
6 changes: 3 additions & 3 deletions radiantcore/selection/manipulators/RotateManipulator.h
Expand Up @@ -34,9 +34,9 @@ class RotateManipulator :
Vector3 _axisScreen;
Vertex3 _localPivotPoint;

RenderableSemiCircle<RemapYZX> _circleX;
RenderableSemiCircle<RemapZXY> _circleY;
RenderableSemiCircle<RemapXYZ> _circleZ;
RenderableSemiCircle _circleX;
RenderableSemiCircle _circleY;
RenderableSemiCircle _circleZ;
RenderableCircle _circleScreen;
RenderableCircle _circleSphere;
RenderablePoint _pivotPoint;
Expand Down

0 comments on commit fa260f0

Please sign in to comment.