Browse Source

DebugTools: properly implemented special cases for CapsuleRenderer.

pull/23/head
Vladimír Vondruš 13 years ago
parent
commit
b5a2cb6b11
  1. 20
      src/DebugTools/Implementation/CapsuleRendererTransformation.h
  2. 40
      src/DebugTools/Test/CapsuleRendererTest.cpp

20
src/DebugTools/Implementation/CapsuleRendererTransformation.h

@ -26,6 +26,7 @@
#include <array>
#include "Math/Functions.h"
#include "Math/Matrix3.h"
#include "Math/Matrix4.h"
#include "Magnum.h"
@ -72,10 +73,21 @@ template<> std::array<Matrix4, 3> capsuleRendererTransformation<3>(const Vector3
Vector3 capDistance;
if(length >= Math::TypeTraits<Float>::epsilon()) {
const Vector3 directionNormalized = direction/length;
rotation.up() = directionNormalized;
rotation.right() = Vector3::cross(rotation.up(), Vector3::zAxis()).normalized();
rotation.backward() = Vector3::cross(rotation.right(), rotation.up());
CORRADE_INTERNAL_ASSERT(rotation.up().isNormalized() && rotation.backward().isNormalized());
const Float dot = Vector3::dot(directionNormalized, Vector3::zAxis());
/* Direction is parallel to Z axis, special rotation case */
if(Math::abs(dot) > 1.0f - Math::TypeTraits<Float>::epsilon()) {
rotation.up() = dot*Vector3::zAxis();
rotation.right() = Vector3::xAxis();
rotation.backward() = -dot*Vector3::yAxis();
/* Common case */
} else {
rotation.up() = directionNormalized;
rotation.right() = Vector3::cross(rotation.up(), Vector3::zAxis()).normalized();
rotation.backward() = Vector3::cross(rotation.right(), rotation.up());
CORRADE_INTERNAL_ASSERT(rotation.up().isNormalized() && rotation.backward().isNormalized());
}
capDistance = directionNormalized*radius;
}

40
src/DebugTools/Test/CapsuleRendererTest.cpp

@ -36,6 +36,8 @@ class CapsuleRendererTest: public TestSuite::Tester {
void common2D();
void zeroLength3D();
void parallel3D();
void antiParallel3D();
void common3D();
};
@ -44,6 +46,8 @@ CapsuleRendererTest::CapsuleRendererTest() {
&CapsuleRendererTest::common2D,
&CapsuleRendererTest::zeroLength3D,
&CapsuleRendererTest::parallel3D,
&CapsuleRendererTest::antiParallel3D,
&CapsuleRendererTest::common3D});
}
@ -100,6 +104,42 @@ void CapsuleRendererTest::zeroLength3D() {
CORRADE_COMPARE(transformation[2].translation(), a);
}
void CapsuleRendererTest::parallel3D() {
const Vector3 a(0.5f, 3.0f, 7.0f);
const Vector3 b(0.5f, 3.0f, 11.0f);
std::array<Matrix4, 3> transformation = Implementation::capsuleRendererTransformation<3>(a, b, 3.5f);
const auto rotation = Matrix4::rotationX(Deg(90.0f));
const auto scaling = (rotation*Matrix4::scaling(Vector3(3.5f))).rotationScaling();
CORRADE_COMPARE(transformation[0].rotationScaling(), scaling);
CORRADE_COMPARE(transformation[1].rotationScaling(),
(rotation*Matrix4::scaling({3.5f, 2.0f, 3.5f})).rotationScaling());
CORRADE_COMPARE(transformation[2].rotationScaling(), scaling);
const auto capDistance = Vector3::zAxis(3.5f);
CORRADE_COMPARE(transformation[0].translation(), a+capDistance);
CORRADE_COMPARE(transformation[1].translation(), a+Vector3::zAxis(2.0f));
CORRADE_COMPARE(transformation[2].translation(), b-capDistance);
}
void CapsuleRendererTest::antiParallel3D() {
const Vector3 a(0.5f, 3.0f, 7.0f);
const Vector3 b(0.5f, 3.0f, 3.0f);
std::array<Matrix4, 3> transformation = Implementation::capsuleRendererTransformation<3>(a, b, 3.5f);
const auto rotation = Matrix4::rotationX(-Deg(90.0f));
const auto rotationScaling = (rotation*Matrix4::scaling(Vector3(3.5f))).rotationScaling();
CORRADE_COMPARE(transformation[0].rotationScaling(), rotationScaling);
CORRADE_COMPARE(transformation[1].rotationScaling(),
(rotation*Matrix4::scaling({3.5f, 2.0f, 3.5f})).rotationScaling());
CORRADE_COMPARE(transformation[2].rotationScaling(), rotationScaling);
const auto capDistance = Vector3::zAxis(-3.5f);
CORRADE_COMPARE(transformation[0].translation(), a+capDistance);
CORRADE_COMPARE(transformation[1].translation(), a+Vector3::zAxis(-2.0f));
CORRADE_COMPARE(transformation[2].translation(), b-capDistance);
}
void CapsuleRendererTest::common3D() {
const Vector3 a(0.5f, 3.0f, 7.0f);
const Vector3 b(7.5f, -1.0f, 1.5f);

Loading…
Cancel
Save