@@ -238,33 +238,89 @@ void DebugLineRender::drawBox(const Magnum::Vector3& min,
238238 Mn::Vector3 (max.x (), max.y (), max.z ()), color);
239239}
240240
241+ namespace {
242+ // Get a vector that is perpendicular to the given normalized vector
243+ Mn::Vector3 getRandomPerpVec (const Magnum::Vector3& normal) {
244+ // https://stackoverflow.com/questions/11132681/what-is-a-formula-to-get-a-vector-perpendicular-to-another-vector
245+ // account for normal == (0, 0, -1)
246+ return fabs (normal.z ()) < fabs (normal.x ())
247+ ? Mn::Vector3 (normal.y (), -normal.x (), 0 )
248+ : Mn::Vector3 (0 , -normal.z (), normal.y ());
249+ }
250+ } // namespace
251+
241252void DebugLineRender::drawCircle (const Magnum::Vector3& pos,
242253 float radius,
243254 const Magnum::Color4& color,
244255 int numSegments,
245256 const Magnum::Vector3& normal) {
246- // https://stackoverflow.com/questions/11132681/what-is-a-formula-to-get-a-vector-perpendicular-to-another-vector
247- // account for normal == (0, 0, -1)
248- auto randomPerpVec = fabs (normal.z ()) < fabs (normal.x ())
249- ? Mn::Vector3 (normal.y (), -normal.x (), 0 )
250- : Mn::Vector3 (0 , -normal.z (), normal.y ());
257+ auto randomPerpVec = getRandomPerpVec (normal);
251258
252259 pushTransform (Mn::Matrix4::lookAt (pos, pos + normal, randomPerpVec) *
253260 Mn::Matrix4::scaling (Mn::Vector3 (radius, radius, 0 .f )));
254261
255- Mn::Vector3 prevPt;
256- for (int seg = 0 ; seg <= numSegments; ++seg) {
257- Mn::Deg angle = Mn::Deg (360 .f * float (seg) / numSegments);
262+ Mn::Vector3 prevPt (1 .0f , 0 .0f , 0 .0f );
263+ float degScale = 360 .f / numSegments;
264+ for (int seg = 1 ; seg <= numSegments; ++seg) {
265+ Mn::Deg angle = Mn::Deg (degScale * float (seg));
258266 Mn::Vector3 pt (Mn::Math::cos (angle), Mn::Math::sin (angle), 0 .f );
259- if (seg > 0 ) {
260- drawTransformedLine (prevPt, pt, color);
261- }
267+ drawTransformedLine (prevPt, pt, color);
262268 prevPt = pt;
263269 }
264270
265271 popTransform ();
266272}
267273
274+ void DebugLineRender::drawCone (const Magnum::Vector3& pos,
275+ const Magnum::Vector3& apex,
276+ float radius,
277+ const Magnum::Color4& color,
278+ int numSegments,
279+ const Magnum::Vector3& normal) {
280+ auto randomPerpVec = getRandomPerpVec (normal);
281+ const Mn::Matrix4 lookAtTrans =
282+ Mn::Matrix4::lookAt (pos, pos + normal, randomPerpVec) *
283+ Mn::Matrix4::scaling (Mn::Vector3 (radius, radius, 1 .0f ));
284+ // transform the apex to be relative to transformation
285+ Mn::Vector3 lclApex = lookAtTrans.invertedRigid ().transformPoint (apex);
286+ pushTransform (lookAtTrans);
287+
288+ Mn::Vector3 prevPt (1 .0f , 0 .0f , 0 .0f );
289+ float degScale = 360 .f / numSegments;
290+ for (int seg = 1 ; seg <= numSegments; ++seg) {
291+ Mn::Deg angle = Mn::Deg (degScale * float (seg));
292+ Mn::Vector3 pt (Mn::Math::cos (angle), Mn::Math::sin (angle), 0 .0f );
293+ drawTransformedLine (pt, lclApex, color);
294+ drawTransformedLine (prevPt, pt, color);
295+ prevPt = pt;
296+ }
297+
298+ popTransform ();
299+ } // DebugLineRender::drawCone
300+
301+ void DebugLineRender::drawCoordinateAxes (const Magnum::Vector3& pos,
302+ const Magnum::Vector3& scale,
303+ float radius) {
304+ auto buildAxis = [&](const Magnum::Vector3& pos, const Magnum::Vector3& axis,
305+ const Magnum::Color4& color, float radius) {
306+ // Draw line centered at pos along given axis of specified length, with a
307+ // cone of given radius to act as a directional arrow
308+ drawTransformedLine (pos - axis, pos + axis, color);
309+ drawCone (pos + axis * 0.9 , pos + axis, radius, color, 24 ,
310+ axis.normalized ());
311+ };
312+
313+ // Red x axis and positive endpoint circle indicator
314+ buildAxis (pos, Magnum::Vector3::xAxis (scale.x ()), Magnum::Color4::red (),
315+ radius);
316+ // Green y axis and positive endpoint circle indicator
317+ buildAxis (pos, Magnum::Vector3::yAxis (scale.y ()), Magnum::Color4::green (),
318+ radius);
319+ // Blue z axis and positive endpoint circle indicator
320+ buildAxis (pos, Magnum::Vector3::zAxis (scale.z ()), Magnum::Color4::blue (),
321+ radius);
322+ } // DebugLineRender::drawCoordinateAxes
323+
268324void DebugLineRender::drawPathWithEndpointCircles (
269325 Mn::Containers::ArrayView<const Mn::Vector3> points,
270326 float radius,
0 commit comments