Browse Source

Math::Constants are now inline functions instead of static variables.

Static variables were compiled into the library and then linked on
every use, which was not good for performance.
pull/279/head
Vladimír Vondruš 14 years ago
parent
commit
7f6f81afc7
  1. 12
      src/Math/Geometry/Test/DistanceTest.cpp
  2. 26
      src/Math/Math.h
  3. 6
      src/Math/Test/MathTest.cpp
  4. 2
      src/Physics/Capsule.cpp
  5. 2
      src/Physics/Sphere.cpp
  6. 4
      src/Physics/Test/CapsuleTest.cpp
  7. 6
      src/Physics/Test/PlaneTest.cpp
  8. 4
      src/Physics/Test/SphereTest.cpp
  9. 6
      src/Primitives/Capsule.cpp
  10. 4
      src/Primitives/UVSphere.cpp

12
src/Math/Geometry/Test/DistanceTest.cpp

@ -38,9 +38,9 @@ void DistanceTest::linePoint() {
/* The distance should be the same for all equidistant points */ /* The distance should be the same for all equidistant points */
QCOMPARE((Distance::linePoint(a, b, Vector3(1.0f, 0.0f, 1.0f))), QCOMPARE((Distance::linePoint(a, b, Vector3(1.0f, 0.0f, 1.0f))),
Constants<float>::Sqrt2/Constants<float>::Sqrt3); Constants<float>::sqrt2()/Constants<float>::sqrt3());
QCOMPARE((Distance::linePoint(a, b, Vector3(1.0f, 0.0f, 1.0f)+Vector3(100.0f))), QCOMPARE((Distance::linePoint(a, b, Vector3(1.0f, 0.0f, 1.0f)+Vector3(100.0f))),
Constants<float>::Sqrt2/Constants<float>::Sqrt3); Constants<float>::sqrt2()/Constants<float>::sqrt3());
} }
void DistanceTest::lineSegmentPoint() { void DistanceTest::lineSegmentPoint() {
@ -51,20 +51,20 @@ void DistanceTest::lineSegmentPoint() {
QCOMPARE((Distance::lineSegmentPoint(a, b, Vector3(0.25f))), 0.0f); QCOMPARE((Distance::lineSegmentPoint(a, b, Vector3(0.25f))), 0.0f);
/* Point on the line, outside the segment, closer to A */ /* Point on the line, outside the segment, closer to A */
QCOMPARE((Distance::lineSegmentPoint(a, b, Vector3(-1.0f))), +Constants<float>::Sqrt3); QCOMPARE((Distance::lineSegmentPoint(a, b, Vector3(-1.0f))), +Constants<float>::sqrt3());
/* Point on the line, outside the segment, closer to B */ /* Point on the line, outside the segment, closer to B */
QCOMPARE((Distance::lineSegmentPoint(a, b, Vector3(1.0f+1.0f/Constants<float>::Sqrt3))), 1.0f); QCOMPARE((Distance::lineSegmentPoint(a, b, Vector3(1.0f+1.0f/Constants<float>::sqrt3()))), 1.0f);
/* Point next to the line segment */ /* Point next to the line segment */
QCOMPARE((Distance::lineSegmentPoint(a, b, Vector3(1.0f, 0.0f, 1.0f))), QCOMPARE((Distance::lineSegmentPoint(a, b, Vector3(1.0f, 0.0f, 1.0f))),
Constants<float>::Sqrt2/Constants<float>::Sqrt3); Constants<float>::sqrt2()/Constants<float>::sqrt3());
/* Point outside the line segment, closer to A */ /* Point outside the line segment, closer to A */
QCOMPARE((Distance::lineSegmentPoint(a, b, Vector3(1.0f, 0.0f, 1.0f)-Vector3(1.0f))), 1.0f); QCOMPARE((Distance::lineSegmentPoint(a, b, Vector3(1.0f, 0.0f, 1.0f)-Vector3(1.0f))), 1.0f);
/* Point outside the line segment, closer to B */ /* Point outside the line segment, closer to B */
QCOMPARE((Distance::lineSegmentPoint(a, b, Vector3(1.0f, 0.0f, 1.0f)+Vector3(1.0f))), +Constants<float>::Sqrt2); QCOMPARE((Distance::lineSegmentPoint(a, b, Vector3(1.0f, 0.0f, 1.0f)+Vector3(1.0f))), +Constants<float>::sqrt2());
} }
}}}} }}}}

26
src/Math/Math.h

@ -32,25 +32,29 @@ namespace Magnum { namespace Math {
matrices) matrices)
*/ */
/** @brief Numeric constants */ /**
@brief Numeric constants
@internal See MathTypeTraits class for implementation notes.
*/
template<class T> struct Constants { template<class T> struct Constants {
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
static constexpr T Pi; /**< @brief Pi */ static inline constexpr T pi(); /**< @brief Pi */
static constexpr T Sqrt2; /**< @brief Square root of 2 */ static inline constexpr T sqrt2(); /**< @brief Square root of 2 */
static constexpr T Sqrt3; /**< @brief Square root of 3 */ static inline constexpr T sqrt3(); /**< @brief Square root of 3 */
#endif #endif
}; };
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
template<> struct Constants<double> { template<> struct Constants<double> {
static constexpr double Pi = 3.14159265359; static inline constexpr double pi() { return 3.14159265359; }
static constexpr double Sqrt2 = 1.41421356237; static inline constexpr double sqrt2() { return 1.41421356237; }
static constexpr double Sqrt3 = 1.73205080757; static inline constexpr double sqrt3() { return 1.73205080757; }
}; };
template<> struct Constants<float> { template<> struct Constants<float> {
static constexpr float Pi = 3.14159265359f; static inline constexpr float pi() { return 3.14159265359f; }
static constexpr float Sqrt2 = 1.41421356237f; static inline constexpr float sqrt2() { return 1.41421356237f; }
static constexpr float Sqrt3 = 1.73205080757f; static inline constexpr float sqrt3() { return 1.73205080757f; }
}; };
namespace Implementation { namespace Implementation {
@ -87,7 +91,7 @@ size_t MAGNUM_EXPORT log(size_t base, size_t number);
* Function to make angle entering less error-prone. Converts the value to * Function to make angle entering less error-prone. Converts the value to
* radians at compile time. For example `deg(180.0f)` is converted to `3.14f`. * radians at compile time. For example `deg(180.0f)` is converted to `3.14f`.
*/ */
template<class T> inline constexpr T deg(T value) { return value*Constants<T>::Pi/180; } template<class T> inline constexpr T deg(T value) { return value*Constants<T>::pi()/180; }
/** /**
* @brief Angle in radians * @brief Angle in radians

6
src/Math/Test/MathTest.cpp

@ -24,9 +24,9 @@ QTEST_APPLESS_MAIN(Magnum::Math::Test::MathTest)
namespace Magnum { namespace Math { namespace Test { namespace Magnum { namespace Math { namespace Test {
void MathTest::degrad() { void MathTest::degrad() {
QCOMPARE(deg(90.0), Constants<double>::Pi/2); QCOMPARE(deg(90.0), Constants<double>::pi()/2);
QCOMPARE(deg(90.0f), Constants<float>::Pi/2); QCOMPARE(deg(90.0f), Constants<float>::pi()/2);
QCOMPARE(rad(Constants<double>::Pi/2), Constants<double>::Pi/2); QCOMPARE(rad(Constants<double>::pi()/2), Constants<double>::pi()/2);
} }
void MathTest::pow() { void MathTest::pow() {

2
src/Physics/Capsule.cpp

@ -24,7 +24,7 @@ namespace Magnum { namespace Physics {
void Capsule::applyTransformation(const Matrix4& transformation) { void Capsule::applyTransformation(const Matrix4& transformation) {
_transformedA = (transformation*Vector4(_a)).xyz(); _transformedA = (transformation*Vector4(_a)).xyz();
_transformedB = (transformation*Vector4(_b)).xyz(); _transformedB = (transformation*Vector4(_b)).xyz();
float scaling = (transformation.rotationScaling()*Vector3(1/Math::Constants<float>::Sqrt3)).length(); float scaling = (transformation.rotationScaling()*Vector3(1/Math::Constants<float>::sqrt3())).length();
_transformedRadius = scaling*_radius; _transformedRadius = scaling*_radius;
} }

2
src/Physics/Sphere.cpp

@ -23,7 +23,7 @@ namespace Magnum { namespace Physics {
void Sphere::applyTransformation(const Matrix4& transformation) { void Sphere::applyTransformation(const Matrix4& transformation) {
_transformedPosition = (transformation*Vector4(_position)).xyz(); _transformedPosition = (transformation*Vector4(_position)).xyz();
float scaling = (transformation.rotationScaling()*Vector3(1/Math::Constants<float>::Sqrt3)).length(); float scaling = (transformation.rotationScaling()*Vector3(1/Math::Constants<float>::sqrt3())).length();
_transformedRadius = scaling*_radius; _transformedRadius = scaling*_radius;
} }

4
src/Physics/Test/CapsuleTest.cpp

@ -32,8 +32,8 @@ void CapsuleTest::applyTransformation() {
QCOMPARE(capsule.radius(), 7.0f); QCOMPARE(capsule.radius(), 7.0f);
/* Apply average scaling to radius */ /* Apply average scaling to radius */
capsule.applyTransformation(Matrix4::scaling({Math::Constants<GLfloat>::Sqrt3, -Math::Constants<GLfloat>::Sqrt2, 2.0f})); capsule.applyTransformation(Matrix4::scaling({Math::Constants<GLfloat>::sqrt3(), -Math::Constants<GLfloat>::sqrt2(), 2.0f}));
QCOMPARE(capsule.transformedRadius(), Math::Constants<GLfloat>::Sqrt3*7.0f); QCOMPARE(capsule.transformedRadius(), Math::Constants<GLfloat>::sqrt3()*7.0f);
} }
void CapsuleTest::collisionPoint() { void CapsuleTest::collisionPoint() {

6
src/Physics/Test/PlaneTest.cpp

@ -24,16 +24,16 @@ QTEST_APPLESS_MAIN(Magnum::Physics::Test::PlaneTest)
namespace Magnum { namespace Physics { namespace Test { namespace Magnum { namespace Physics { namespace Test {
void PlaneTest::applyTransformation() { void PlaneTest::applyTransformation() {
Physics::Plane plane({1.0f, 2.0f, 3.0f}, {Math::Constants<float>::Sqrt2, -Math::Constants<float>::Sqrt2, 0}); Physics::Plane plane({1.0f, 2.0f, 3.0f}, {Math::Constants<float>::sqrt2(), -Math::Constants<float>::sqrt2(), 0});
plane.applyTransformation(Matrix4::rotation(deg(90.0f), Vector3::xAxis())); plane.applyTransformation(Matrix4::rotation(deg(90.0f), Vector3::xAxis()));
QVERIFY(plane.transformedPosition() == Vector3(1.0f, -3.0f, 2.0f)); QVERIFY(plane.transformedPosition() == Vector3(1.0f, -3.0f, 2.0f));
QVERIFY(plane.transformedNormal() == Vector3(Math::Constants<float>::Sqrt2, 0, -Math::Constants<float>::Sqrt2)); QVERIFY(plane.transformedNormal() == Vector3(Math::Constants<float>::sqrt2(), 0, -Math::Constants<float>::sqrt2()));
/* The normal should stay normalized */ /* The normal should stay normalized */
plane.applyTransformation(Matrix4::scaling({1.5f, 2.0f, 3.0f})); plane.applyTransformation(Matrix4::scaling({1.5f, 2.0f, 3.0f}));
QVERIFY(plane.transformedPosition() == Vector3(1.5f, 4.0f, 9.0f)); QVERIFY(plane.transformedPosition() == Vector3(1.5f, 4.0f, 9.0f));
QVERIFY(plane.transformedNormal() == Vector3(Math::Constants<float>::Sqrt2, -Math::Constants<float>::Sqrt2, 0)); QVERIFY(plane.transformedNormal() == Vector3(Math::Constants<float>::sqrt2(), -Math::Constants<float>::sqrt2(), 0));
} }
void PlaneTest::collisionLine() { void PlaneTest::collisionLine() {

4
src/Physics/Test/SphereTest.cpp

@ -37,8 +37,8 @@ void SphereTest::applyTransformation() {
QCOMPARE(sphere.transformedRadius(), 14.0f); QCOMPARE(sphere.transformedRadius(), 14.0f);
/* Apply average scaling to radius */ /* Apply average scaling to radius */
sphere.applyTransformation(Matrix4::scaling({Math::Constants<GLfloat>::Sqrt3, -Math::Constants<GLfloat>::Sqrt2, 2.0f})); sphere.applyTransformation(Matrix4::scaling({Math::Constants<GLfloat>::sqrt3(), -Math::Constants<GLfloat>::sqrt2(), 2.0f}));
QCOMPARE(sphere.transformedRadius(), Math::Constants<GLfloat>::Sqrt3*7.0f); QCOMPARE(sphere.transformedRadius(), Math::Constants<GLfloat>::sqrt3()*7.0f);
} }
void SphereTest::collisionPoint() { void SphereTest::collisionPoint() {

6
src/Primitives/Capsule.cpp

@ -24,13 +24,13 @@ Capsule::Capsule(unsigned int rings, unsigned int segments, GLfloat length, Text
GLfloat height = 2.0f+length; GLfloat height = 2.0f+length;
GLfloat textureCoordsVIncrement = 1.0f/(rings*height); GLfloat textureCoordsVIncrement = 1.0f/(rings*height);
GLfloat ringAngleIncrement = Math::Constants<GLfloat>::Pi/(2*rings); GLfloat ringAngleIncrement = Math::Constants<GLfloat>::pi()/(2*rings);
/* Bottom cap vertex */ /* Bottom cap vertex */
capVertex(-height/2, -1.0f, 0.0f); capVertex(-height/2, -1.0f, 0.0f);
/* Rings of bottom hemisphere */ /* Rings of bottom hemisphere */
vertexRings(rings, -length/2, -Math::Constants<GLfloat>::Pi/2+ringAngleIncrement, ringAngleIncrement, textureCoordsVIncrement, textureCoordsVIncrement); vertexRings(rings, -length/2, -Math::Constants<GLfloat>::pi()/2+ringAngleIncrement, ringAngleIncrement, textureCoordsVIncrement, textureCoordsVIncrement);
/* Rings of top hemisphere */ /* Rings of top hemisphere */
vertexRings(rings, length/2, 0.0f, ringAngleIncrement, (1.0f + length)/height, textureCoordsVIncrement); vertexRings(rings, length/2, 0.0f, ringAngleIncrement, (1.0f + length)/height, textureCoordsVIncrement);
@ -53,7 +53,7 @@ void Capsule::capVertex(GLfloat y, GLfloat normalY, GLfloat textureCoordsV) {
} }
void Capsule::vertexRings(unsigned int count, GLfloat centerY, GLfloat startRingAngle, GLfloat ringAngleIncrement, GLfloat startTextureCoordsV, GLfloat textureCoordsVIncrement) { void Capsule::vertexRings(unsigned int count, GLfloat centerY, GLfloat startRingAngle, GLfloat ringAngleIncrement, GLfloat startTextureCoordsV, GLfloat textureCoordsVIncrement) {
GLfloat segmentAngleIncrement = 2*Math::Constants<GLfloat>::Pi/segments; GLfloat segmentAngleIncrement = 2*Math::Constants<GLfloat>::pi()/segments;
GLfloat x, y, z; GLfloat x, y, z;
for(unsigned int i = 0; i != count; ++i) { for(unsigned int i = 0; i != count; ++i) {
GLfloat ringAngle = startRingAngle + i*ringAngleIncrement; GLfloat ringAngle = startRingAngle + i*ringAngleIncrement;

4
src/Primitives/UVSphere.cpp

@ -24,13 +24,13 @@ UVSphere::UVSphere(unsigned int rings, unsigned int segments, TextureCoords text
CORRADE_ASSERT(rings >= 2 && segments >= 3, "UVSphere must have at least two rings and three segments", ) CORRADE_ASSERT(rings >= 2 && segments >= 3, "UVSphere must have at least two rings and three segments", )
GLfloat textureCoordsVIncrement = 1.0f/rings; GLfloat textureCoordsVIncrement = 1.0f/rings;
GLfloat ringAngleIncrement = Math::Constants<GLfloat>::Pi/rings; GLfloat ringAngleIncrement = Math::Constants<GLfloat>::pi()/rings;
/* Bottom cap vertex */ /* Bottom cap vertex */
capVertex(-1.0f, -1.0f, 0.0f); capVertex(-1.0f, -1.0f, 0.0f);
/* Vertex rings */ /* Vertex rings */
vertexRings(rings-1, 0.0f, -Math::Constants<GLfloat>::Pi/2+ringAngleIncrement, ringAngleIncrement, textureCoordsVIncrement, textureCoordsVIncrement); vertexRings(rings-1, 0.0f, -Math::Constants<GLfloat>::pi()/2+ringAngleIncrement, ringAngleIncrement, textureCoordsVIncrement, textureCoordsVIncrement);
/* Top cap vertex */ /* Top cap vertex */
capVertex(1.0f, 1.0f, 1.0f); capVertex(1.0f, 1.0f, 1.0f);

Loading…
Cancel
Save