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.
vectorfields
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 */
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))),
Constants<float>::Sqrt2/Constants<float>::Sqrt3);
Constants<float>::sqrt2()/Constants<float>::sqrt3());
}
void DistanceTest::lineSegmentPoint() {
@ -51,20 +51,20 @@ void DistanceTest::lineSegmentPoint() {
QCOMPARE((Distance::lineSegmentPoint(a, b, Vector3(0.25f))), 0.0f);
/* 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 */
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 */
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 */
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 */
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)
*/
/** @brief Numeric constants */
/**
@brief Numeric constants
@internal See MathTypeTraits class for implementation notes.
*/
template<class T> struct Constants {
#ifdef DOXYGEN_GENERATING_OUTPUT
static constexpr T Pi; /**< @brief Pi */
static constexpr T Sqrt2; /**< @brief Square root of 2 */
static constexpr T Sqrt3; /**< @brief Square root of 3 */
static inline constexpr T pi(); /**< @brief Pi */
static inline constexpr T sqrt2(); /**< @brief Square root of 2 */
static inline constexpr T sqrt3(); /**< @brief Square root of 3 */
#endif
};
#ifndef DOXYGEN_GENERATING_OUTPUT
template<> struct Constants<double> {
static constexpr double Pi = 3.14159265359;
static constexpr double Sqrt2 = 1.41421356237;
static constexpr double Sqrt3 = 1.73205080757;
static inline constexpr double pi() { return 3.14159265359; }
static inline constexpr double sqrt2() { return 1.41421356237; }
static inline constexpr double sqrt3() { return 1.73205080757; }
};
template<> struct Constants<float> {
static constexpr float Pi = 3.14159265359f;
static constexpr float Sqrt2 = 1.41421356237f;
static constexpr float Sqrt3 = 1.73205080757f;
static inline constexpr float pi() { return 3.14159265359f; }
static inline constexpr float sqrt2() { return 1.41421356237f; }
static inline constexpr float sqrt3() { return 1.73205080757f; }
};
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
* 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

6
src/Math/Test/MathTest.cpp

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

2
src/Physics/Capsule.cpp

@ -24,7 +24,7 @@ namespace Magnum { namespace Physics {
void Capsule::applyTransformation(const Matrix4& transformation) {
_transformedA = (transformation*Vector4(_a)).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;
}

2
src/Physics/Sphere.cpp

@ -23,7 +23,7 @@ namespace Magnum { namespace Physics {
void Sphere::applyTransformation(const Matrix4& transformation) {
_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;
}

4
src/Physics/Test/CapsuleTest.cpp

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

4
src/Physics/Test/SphereTest.cpp

@ -37,8 +37,8 @@ void SphereTest::applyTransformation() {
QCOMPARE(sphere.transformedRadius(), 14.0f);
/* Apply average scaling to radius */
sphere.applyTransformation(Matrix4::scaling({Math::Constants<GLfloat>::Sqrt3, -Math::Constants<GLfloat>::Sqrt2, 2.0f}));
QCOMPARE(sphere.transformedRadius(), Math::Constants<GLfloat>::Sqrt3*7.0f);
sphere.applyTransformation(Matrix4::scaling({Math::Constants<GLfloat>::sqrt3(), -Math::Constants<GLfloat>::sqrt2(), 2.0f}));
QCOMPARE(sphere.transformedRadius(), Math::Constants<GLfloat>::sqrt3()*7.0f);
}
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 textureCoordsVIncrement = 1.0f/(rings*height);
GLfloat ringAngleIncrement = Math::Constants<GLfloat>::Pi/(2*rings);
GLfloat ringAngleIncrement = Math::Constants<GLfloat>::pi()/(2*rings);
/* Bottom cap vertex */
capVertex(-height/2, -1.0f, 0.0f);
/* 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 */
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) {
GLfloat segmentAngleIncrement = 2*Math::Constants<GLfloat>::Pi/segments;
GLfloat segmentAngleIncrement = 2*Math::Constants<GLfloat>::pi()/segments;
GLfloat x, y, z;
for(unsigned int i = 0; i != count; ++i) {
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", )
GLfloat textureCoordsVIncrement = 1.0f/rings;
GLfloat ringAngleIncrement = Math::Constants<GLfloat>::Pi/rings;
GLfloat ringAngleIncrement = Math::Constants<GLfloat>::pi()/rings;
/* Bottom cap vertex */
capVertex(-1.0f, -1.0f, 0.0f);
/* 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 */
capVertex(1.0f, 1.0f, 1.0f);

Loading…
Cancel
Save