Browse Source

GCC 4.4 compatibility: better solution for explicit conversion of Unit.

Having implicit conversion on Unit class causes much more harm than
doing the conversion some other way -- mainly for multiplication and
division, which is done with builtin operators and thus the result is
unitless. Also it is possible to do wrong "retyping" between degrees and
radians:

    Rad a = Constants::pi();
    Deg b(a*2);

On GCC >4.5 b is `180`, but on GCC 4.4 it is `2pi`, which is obviously
wrong and not wanted.

The conversion is done using Unit::toUnderlyingType() which is now used
everywhere instead of conversion operator. The conversion operator is
made available only for GCC 4.5, where it can be marked as explicit.
This might cause incompatibilites with `master` branch, where no
Unit::toUnderlyingType() exists, but users should have no need to
convert it to underlying type anyway as all required functions are
available through the library.

This reverts commit 36ac4de5c4 and
partially also 0db3a183ae (UnitTest.cpp).
Vladimír Vondruš 13 years ago
parent
commit
f91f464ec8
  1. 6
      src/Color.h
  2. 8
      src/Math/Angle.h
  3. 2
      src/Math/Complex.h
  4. 6
      src/Math/Functions.h
  5. 4
      src/Math/Matrix3.h
  6. 18
      src/Math/Matrix4.h
  7. 2
      src/Math/Quaternion.h
  8. 22
      src/Math/Test/AngleTest.cpp
  9. 16
      src/Math/Test/FunctionsTest.cpp
  10. 19
      src/Math/Test/UnitTest.cpp
  11. 12
      src/Math/Unit.h
  12. 8
      src/Primitives/Capsule.cpp
  13. 2
      src/Primitives/Cylinder.cpp
  14. 2
      src/Primitives/UVSphere.cpp

6
src/Color.h

@ -46,11 +46,11 @@ template<class T> inline typename std::enable_if<std::is_floating_point<T>::valu
std::tie(hue, saturation, value) = hsv; std::tie(hue, saturation, value) = hsv;
/* Remove repeats */ /* Remove repeats */
hue -= Math::Deg<T>(int(T(hue)/T(360))*T(360)); hue -= int(hue.toUnderlyingType()/T(360))*Math::Deg<T>(360);
if(hue < Math::Deg<T>(0)) hue += Math::Deg<T>(360); if(hue < Math::Deg<T>(0)) hue += Math::Deg<T>(360);
int h = int(T(hue)/T(60)) % 6; int h = int(hue.toUnderlyingType()/T(60)) % 6;
T f = T(hue)/T(60) - h; T f = hue.toUnderlyingType()/T(60) - h;
T p = value * (T(1) - saturation); T p = value * (T(1) - saturation);
T q = value * (T(1) - f*saturation); T q = value * (T(1) - f*saturation);

8
src/Math/Angle.h

@ -231,14 +231,14 @@ See operator""_degf() for more information.
inline constexpr Rad<Float> operator "" _radf(long double value) { return Rad<Float>(value); } inline constexpr Rad<Float> operator "" _radf(long double value) { return Rad<Float>(value); }
#endif #endif
template<class T> inline constexpr Deg<T>::Deg(Unit<Rad, T> value): Unit<Math::Deg, T>(T(180)*T(value)/Math::Constants<T>::pi()) {} template<class T> inline constexpr Deg<T>::Deg(Unit<Rad, T> value): Unit<Math::Deg, T>(T(180)*value.toUnderlyingType()/Math::Constants<T>::pi()) {}
template<class T> inline constexpr Rad<T>::Rad(Unit<Deg, T> value): Unit<Math::Rad, T>(T(value)*Math::Constants<T>::pi()/T(180)) {} template<class T> inline constexpr Rad<T>::Rad(Unit<Deg, T> value): Unit<Math::Rad, T>(value.toUnderlyingType()*Math::Constants<T>::pi()/T(180)) {}
/** @debugoperator{Magnum::Math::Rad} */ /** @debugoperator{Magnum::Math::Rad} */
template<class T> Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, const Unit<Rad, T>& value) { template<class T> Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, const Unit<Rad, T>& value) {
debug << "Rad("; debug << "Rad(";
debug.setFlag(Corrade::Utility::Debug::SpaceAfterEachValue, false); debug.setFlag(Corrade::Utility::Debug::SpaceAfterEachValue, false);
debug << T(value) << ")"; debug << value.toUnderlyingType() << ")";
debug.setFlag(Corrade::Utility::Debug::SpaceAfterEachValue, true); debug.setFlag(Corrade::Utility::Debug::SpaceAfterEachValue, true);
return debug; return debug;
} }
@ -247,7 +247,7 @@ template<class T> Corrade::Utility::Debug operator<<(Corrade::Utility::Debug deb
template<class T> Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, const Unit<Deg, T>& value) { template<class T> Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, const Unit<Deg, T>& value) {
debug << "Deg("; debug << "Deg(";
debug.setFlag(Corrade::Utility::Debug::SpaceAfterEachValue, false); debug.setFlag(Corrade::Utility::Debug::SpaceAfterEachValue, false);
debug << T(value) << ")"; debug << value.toUnderlyingType() << ")";
debug.setFlag(Corrade::Utility::Debug::SpaceAfterEachValue, true); debug.setFlag(Corrade::Utility::Debug::SpaceAfterEachValue, true);
return debug; return debug;
} }

2
src/Math/Complex.h

@ -93,7 +93,7 @@ template<class T> class Complex {
* @see angle(), Matrix3::rotation(), Quaternion::rotation() * @see angle(), Matrix3::rotation(), Quaternion::rotation()
*/ */
inline static Complex<T> rotation(Rad<T> angle) { inline static Complex<T> rotation(Rad<T> angle) {
return {std::cos(T(angle)), std::sin(T(angle))}; return {std::cos(angle.toUnderlyingType()), std::sin(angle.toUnderlyingType())};
} }
/** /**

6
src/Math/Functions.h

@ -86,7 +86,7 @@ UnsignedInt MAGNUM_EXPORT log(UnsignedInt base, UnsignedInt number);
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
template<class T> inline T sin(Rad<T> angle) { return std::sin(T(angle)); } template<class T> inline T sin(Rad<T> angle) { return std::sin(T(angle)); }
#else #else
template<class T> inline T sin(Unit<Rad, T> angle) { return std::sin(T(angle)); } template<class T> inline T sin(Unit<Rad, T> angle) { return std::sin(angle.toUnderlyingType()); }
template<class T> inline T sin(Unit<Deg, T> angle) { return sin(Rad<T>(angle)); } template<class T> inline T sin(Unit<Deg, T> angle) { return sin(Rad<T>(angle)); }
#endif #endif
@ -94,7 +94,7 @@ template<class T> inline T sin(Unit<Deg, T> angle) { return sin(Rad<T>(angle));
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
template<class T> inline T cos(Rad<T> angle) { return std::cos(T(angle)); } template<class T> inline T cos(Rad<T> angle) { return std::cos(T(angle)); }
#else #else
template<class T> inline T cos(Unit<Rad, T> angle) { return std::cos(T(angle)); } template<class T> inline T cos(Unit<Rad, T> angle) { return std::cos(angle.toUnderlyingType()); }
template<class T> inline T cos(Unit<Deg, T> angle) { return cos(Rad<T>(angle)); } template<class T> inline T cos(Unit<Deg, T> angle) { return cos(Rad<T>(angle)); }
#endif #endif
@ -102,7 +102,7 @@ template<class T> inline T cos(Unit<Deg, T> angle) { return cos(Rad<T>(angle));
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
template<class T> inline T tan(Rad<T> angle) { return std::tan(T(angle)); } template<class T> inline T tan(Rad<T> angle) { return std::tan(T(angle)); }
#else #else
template<class T> inline T tan(Unit<Rad, T> angle) { return std::tan(T(angle)); } template<class T> inline T tan(Unit<Rad, T> angle) { return std::tan(angle.toUnderlyingType()); }
template<class T> inline T tan(Unit<Deg, T> angle) { return tan(Rad<T>(angle)); } template<class T> inline T tan(Unit<Deg, T> angle) { return tan(Rad<T>(angle)); }
#endif #endif

4
src/Math/Matrix3.h

@ -80,8 +80,8 @@ template<class T> class Matrix3: public Matrix<3, T> {
* Matrix4::rotation(Rad, const Vector3&) * Matrix4::rotation(Rad, const Vector3&)
*/ */
static Matrix3<T> rotation(Rad<T> angle) { static Matrix3<T> rotation(Rad<T> angle) {
T sine = std::sin(T(angle)); T sine = std::sin(angle.toUnderlyingType());
T cosine = std::cos(T(angle)); T cosine = std::cos(angle.toUnderlyingType());
return {{ cosine, sine, T(0)}, return {{ cosine, sine, T(0)},
{ -sine, cosine, T(0)}, { -sine, cosine, T(0)},

18
src/Math/Matrix4.h

@ -94,8 +94,8 @@ template<class T> class Matrix4: public Matrix<4, T> {
CORRADE_ASSERT(normalizedAxis.isNormalized(), CORRADE_ASSERT(normalizedAxis.isNormalized(),
"Math::Matrix4::rotation(): axis must be normalized", {}); "Math::Matrix4::rotation(): axis must be normalized", {});
T sine = std::sin(T(angle)); T sine = std::sin(angle.toUnderlyingType());
T cosine = std::cos(T(angle)); T cosine = std::cos(angle.toUnderlyingType());
T oneMinusCosine = T(1) - cosine; T oneMinusCosine = T(1) - cosine;
T xx = normalizedAxis.x()*normalizedAxis.x(); T xx = normalizedAxis.x()*normalizedAxis.x();
@ -131,8 +131,8 @@ template<class T> class Matrix4: public Matrix<4, T> {
* rotation() const, Quaternion::rotation(), Matrix3::rotation(Rad) * rotation() const, Quaternion::rotation(), Matrix3::rotation(Rad)
*/ */
static Matrix4<T> rotationX(Rad<T> angle) { static Matrix4<T> rotationX(Rad<T> angle) {
T sine = std::sin(T(angle)); T sine = std::sin(angle.toUnderlyingType());
T cosine = std::cos(T(angle)); T cosine = std::cos(angle.toUnderlyingType());
return {{T(1), T(0), T(0), T(0)}, return {{T(1), T(0), T(0), T(0)},
{T(0), cosine, sine, T(0)}, {T(0), cosine, sine, T(0)},
@ -149,8 +149,8 @@ template<class T> class Matrix4: public Matrix<4, T> {
* rotation() const, Quaternion::rotation(), Matrix3::rotation(Rad) * rotation() const, Quaternion::rotation(), Matrix3::rotation(Rad)
*/ */
static Matrix4<T> rotationY(Rad<T> angle) { static Matrix4<T> rotationY(Rad<T> angle) {
T sine = std::sin(T(angle)); T sine = std::sin(angle.toUnderlyingType());
T cosine = std::cos(T(angle)); T cosine = std::cos(angle.toUnderlyingType());
return {{cosine, T(0), -sine, T(0)}, return {{cosine, T(0), -sine, T(0)},
{ T(0), T(1), T(0), T(0)}, { T(0), T(1), T(0), T(0)},
@ -167,8 +167,8 @@ template<class T> class Matrix4: public Matrix<4, T> {
* rotation() const, Quaternion::rotation(), Matrix3::rotation(Rad) * rotation() const, Quaternion::rotation(), Matrix3::rotation(Rad)
*/ */
static Matrix4<T> rotationZ(Rad<T> angle) { static Matrix4<T> rotationZ(Rad<T> angle) {
T sine = std::sin(T(angle)); T sine = std::sin(angle.toUnderlyingType());
T cosine = std::cos(T(angle)); T cosine = std::cos(angle.toUnderlyingType());
return {{cosine, sine, T(0), T(0)}, return {{cosine, sine, T(0), T(0)},
{ -sine, cosine, T(0), T(0)}, { -sine, cosine, T(0), T(0)},
@ -235,7 +235,7 @@ template<class T> class Matrix4: public Matrix<4, T> {
* @see orthographicProjection(), Matrix3::projection() * @see orthographicProjection(), Matrix3::projection()
*/ */
static Matrix4<T> perspectiveProjection(Rad<T> fov, T aspectRatio, T near, T far) { static Matrix4<T> perspectiveProjection(Rad<T> fov, T aspectRatio, T near, T far) {
T xyScale = 2*std::tan(T(fov)/2)*near; T xyScale = 2*std::tan(fov.toUnderlyingType()/2)*near;
return perspectiveProjection(Vector2<T>(xyScale, xyScale/aspectRatio), near, far); return perspectiveProjection(Vector2<T>(xyScale, xyScale/aspectRatio), near, far);
} }

2
src/Math/Quaternion.h

@ -170,7 +170,7 @@ template<class T> class Quaternion {
CORRADE_ASSERT(normalizedAxis.isNormalized(), CORRADE_ASSERT(normalizedAxis.isNormalized(),
"Math::Quaternion::rotation(): axis must be normalized", {}); "Math::Quaternion::rotation(): axis must be normalized", {});
return {normalizedAxis*std::sin(T(angle)/2), std::cos(T(angle)/2)}; return {normalizedAxis*std::sin(angle.toUnderlyingType()/2), std::cos(angle.toUnderlyingType()/2)};
} }
/** /**

22
src/Math/Test/AngleTest.cpp

@ -60,24 +60,24 @@ AngleTest::AngleTest() {
void AngleTest::construct() { void AngleTest::construct() {
/* Default constructor */ /* Default constructor */
constexpr Deg m; constexpr Deg m;
CORRADE_COMPARE(Float(m), 0.0f); CORRADE_COMPARE(m.toUnderlyingType(), 0.0f);
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
constexpr Degd a; constexpr Degd a;
CORRADE_COMPARE(Double(a), 0.0); CORRADE_COMPARE(a.toUnderlyingType(), 0.0);
#else #else
constexpr Deg a; constexpr Deg a;
CORRADE_COMPARE(Float(a), 0.0f); CORRADE_COMPARE(a.toUnderlyingType(), 0.0f);
#endif #endif
/* Value constructor */ /* Value constructor */
constexpr Deg b(25.0); constexpr Deg b(25.0);
CORRADE_COMPARE(Float(b), 25.0f); CORRADE_COMPARE(b.toUnderlyingType(), 25.0f);
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
constexpr Radd n(3.14); constexpr Radd n(3.14);
CORRADE_COMPARE(Double(n), 3.14); CORRADE_COMPARE(n.toUnderlyingType(), 3.14);
#else #else
constexpr Rad n(3.14); constexpr Rad n(3.14);
CORRADE_COMPARE(Float(n), 3.14f); CORRADE_COMPARE(n.toUnderlyingType(), 3.14f);
#endif #endif
/* Copy constructor */ /* Copy constructor */
@ -93,13 +93,13 @@ void AngleTest::construct() {
/* Conversion operator */ /* Conversion operator */
constexpr Rad p(n); constexpr Rad p(n);
CORRADE_COMPARE(Float(p), 3.14f); CORRADE_COMPARE(p.toUnderlyingType(), 3.14f);
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
constexpr Degd d(b); constexpr Degd d(b);
CORRADE_COMPARE(Double(d), 25.0); CORRADE_COMPARE(d.toUnderlyingType(), 25.0);
#else #else
constexpr Deg d(b); constexpr Deg d(b);
CORRADE_COMPARE(Float(d), 25.0f); CORRADE_COMPARE(d.toUnderlyingType(), 25.0f);
#endif #endif
} }
@ -130,10 +130,10 @@ void AngleTest::literals() {
void AngleTest::conversion() { void AngleTest::conversion() {
/* Implicit conversion should be allowed */ /* Implicit conversion should be allowed */
constexpr Deg a = Rad(1.57079633f); constexpr Deg a = Rad(1.57079633f);
CORRADE_COMPARE(Float(a), 90.0f); CORRADE_COMPARE(a.toUnderlyingType(), 90.0f);
constexpr Rad b = Deg(90.0f); constexpr Rad b = Deg(90.0f);
CORRADE_COMPARE(Float(b), 1.57079633f); CORRADE_COMPARE(b.toUnderlyingType(), 1.57079633f);
} }
void AngleTest::debugDeg() { void AngleTest::debugDeg() {

16
src/Math/Test/FunctionsTest.cpp

@ -300,17 +300,17 @@ void FunctionsTest::trigonometric() {
void FunctionsTest::trigonometricWithBase() { void FunctionsTest::trigonometricWithBase() {
/* Verify that the functions can be called with Unit<Deg, T> and Unit<Rad, T> */ /* Verify that the functions can be called with Unit<Deg, T> and Unit<Rad, T> */
CORRADE_VERIFY((std::is_same<decltype(Deg(15.0f)+Deg(15.0f)), Unit<Math::Deg, Float>>::value)); CORRADE_VERIFY((std::is_same<decltype(2*Deg(15.0f)), Unit<Math::Deg, Float>>::value));
CORRADE_VERIFY((std::is_same<decltype(Rad(Constants::pi()/12)+Rad(Constants::pi()/12)), Unit<Math::Rad, Float>>::value)); CORRADE_VERIFY((std::is_same<decltype(2*Rad(Constants::pi()/12)), Unit<Math::Rad, Float>>::value));
CORRADE_COMPARE(Math::sin(Deg(15.0f)+Deg(15.0f)), 0.5f); CORRADE_COMPARE(Math::sin(2*Deg(15.0f)), 0.5f);
CORRADE_COMPARE(Math::sin(Rad(Constants::pi()/12)+Rad(Constants::pi()/12)), 0.5f); CORRADE_COMPARE(Math::sin(2*Rad(Constants::pi()/12)), 0.5f);
CORRADE_COMPARE(Math::cos(Deg(30.0f)+Deg(30.0f)), 0.5f); CORRADE_COMPARE(Math::cos(2*Deg(30.0f)), 0.5f);
CORRADE_COMPARE(Math::cos(Rad(Constants::pi()/6)+Rad(Constants::pi()/6)), 0.5f); CORRADE_COMPARE(Math::cos(2*Rad(Constants::pi()/6)), 0.5f);
CORRADE_COMPARE(Math::tan(Deg(22.5f)+Deg(22.5f)), 1.0f); CORRADE_COMPARE(Math::tan(2*Deg(22.5f)), 1.0f);
CORRADE_COMPARE(Math::tan(Rad(Constants::pi()/8)+Rad(Constants::pi()/8)), 1.0f); CORRADE_COMPARE(Math::tan(2*Rad(Constants::pi()/8)), 1.0f);
} }
}}} }}}

19
src/Math/Test/UnitTest.cpp

@ -58,21 +58,16 @@ typedef Unit<Sec_, Float> Sec;
typedef Unit<Sec_, Int> Seci; typedef Unit<Sec_, Int> Seci;
inline Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, Sec value) { inline Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, Sec value) {
return debug << Float(value); return debug << value.toUnderlyingType();
} }
void UnitTest::construct() { void UnitTest::construct() {
constexpr Sec a(25.0f); constexpr Sec a(25.0f);
CORRADE_COMPARE(Float(a), 25.0f); CORRADE_COMPARE(a.toUnderlyingType(), 25.0f);
/* Implicit conversion is not allowed */ /* Implicit conversion is not allowed */
CORRADE_VERIFY(!(std::is_convertible<Float, Sec>::value)); CORRADE_VERIFY(!(std::is_convertible<Float, Sec>::value));
{ CORRADE_VERIFY(!(std::is_convertible<Sec, Float>::value));
#ifdef CORRADE_GCC44_COMPATIBILITY
CORRADE_EXPECT_FAIL("GCC 4.4 doesn't have explicit conversion operators");
#endif
CORRADE_VERIFY(!(std::is_convertible<Sec, Float>::value));
}
} }
void UnitTest::constructDefault() { void UnitTest::constructDefault() {
@ -143,17 +138,9 @@ void UnitTest::multiplyDivide() {
constexpr Sec b(-4.5f); constexpr Sec b(-4.5f);
constexpr Sec c(5.0f); constexpr Sec c(5.0f);
/* The operation returns underlying type on GCC 4.4 because of non-explicit
conversion operators and conflicts with builtin operators */
#ifndef CORRADE_GCC44_COMPATIBILITY
constexpr Sec d = a*-1.5f; constexpr Sec d = a*-1.5f;
constexpr Sec e = -1.5f*a; constexpr Sec e = -1.5f*a;
constexpr Sec f = b/-1.5f; constexpr Sec f = b/-1.5f;
#else
constexpr Sec d(a*-1.5f);
constexpr Sec e(-1.5f*a);
constexpr Sec f(b/-1.5f);
#endif
CORRADE_COMPARE(d, b); CORRADE_COMPARE(d, b);
CORRADE_COMPARE(e, b); CORRADE_COMPARE(e, b);
CORRADE_COMPARE(f, a); CORRADE_COMPARE(f, a);

12
src/Math/Unit.h

@ -53,11 +53,12 @@ template<template<class> class Derived, class T> class Unit {
/** @brief Construct from another underlying type */ /** @brief Construct from another underlying type */
template<class U> inline constexpr explicit Unit(Unit<Derived, U> value): value(value.value) {} template<class U> inline constexpr explicit Unit(Unit<Derived, U> value): value(value.value) {}
/** @brief Explicit conversion to underlying type */
inline constexpr T toUnderlyingType() const { return value; }
/** @brief Explicit conversion to underlying type */ /** @brief Explicit conversion to underlying type */
#ifndef CORRADE_GCC44_COMPATIBILITY #ifndef CORRADE_GCC44_COMPATIBILITY
inline constexpr explicit operator T() const { return value; } inline constexpr explicit operator T() const { return value; }
#else
inline constexpr operator T() const { return value; }
#endif #endif
/** @brief Equality comparison */ /** @brief Equality comparison */
@ -117,9 +118,6 @@ template<template<class> class Derived, class T> class Unit {
return Unit<Derived, T>(value - other.value); return Unit<Derived, T>(value - other.value);
} }
/* These are conflicting with builtin operators because of non-explicit
conversion to T */
#ifndef CORRADE_GCC44_COMPATIBILITY
/** @brief Multiply with number and assign */ /** @brief Multiply with number and assign */
inline Unit<Derived, T>& operator*=(T number) { inline Unit<Derived, T>& operator*=(T number) {
value *= number; value *= number;
@ -146,21 +144,17 @@ template<template<class> class Derived, class T> class Unit {
inline constexpr T operator/(Unit<Derived, T> other) const { inline constexpr T operator/(Unit<Derived, T> other) const {
return value/other.value; return value/other.value;
} }
#endif
private: private:
T value; T value;
}; };
/* This is conflicting with builtin operator because of non-explicit conversion to T */
#ifndef CORRADE_GCC44_COMPATIBILITY
/** @relates Unit /** @relates Unit
@brief Multiply number with value @brief Multiply number with value
*/ */
template<template<class> class Derived, class T> inline constexpr Unit<Derived, T> operator*(typename std::common_type<T>::type number, const Unit<Derived, T>& value) { template<template<class> class Derived, class T> inline constexpr Unit<Derived, T> operator*(typename std::common_type<T>::type number, const Unit<Derived, T>& value) {
return value*number; return value*number;
} }
#endif
}} }}

8
src/Primitives/Capsule.cpp

@ -40,7 +40,7 @@ Capsule::Capsule(UnsignedInt hemisphereRings, UnsignedInt cylinderRings, Unsigne
capVertex(-height/2, -1.0f, 0.0f); capVertex(-height/2, -1.0f, 0.0f);
/* Rings of bottom hemisphere */ /* Rings of bottom hemisphere */
hemisphereVertexRings(hemisphereRings-1, -length/2, -Rad(Constants::pi()/2)+hemisphereRingAngleIncrement, hemisphereRingAngleIncrement, hemisphereTextureCoordsVIncrement, hemisphereTextureCoordsVIncrement); hemisphereVertexRings(hemisphereRings-1, -length/2, -Rad(Constants::pi())/2+hemisphereRingAngleIncrement, hemisphereRingAngleIncrement, hemisphereTextureCoordsVIncrement, hemisphereTextureCoordsVIncrement);
/* Rings of cylinder */ /* Rings of cylinder */
cylinderVertexRings(cylinderRings+1, -length/2, length/cylinderRings, 1.0f/height, length/(cylinderRings*height)); cylinderVertexRings(cylinderRings+1, -length/2, length/cylinderRings, 1.0f/height, length/(cylinderRings*height));
@ -71,12 +71,12 @@ void Capsule::hemisphereVertexRings(UnsignedInt count, Float centerY, Rad startR
Rad segmentAngleIncrement(2*Constants::pi()/segments); Rad segmentAngleIncrement(2*Constants::pi()/segments);
Float x, y, z; Float x, y, z;
for(UnsignedInt i = 0; i != count; ++i) { for(UnsignedInt i = 0; i != count; ++i) {
Rad ringAngle = startRingAngle + Rad(i*ringAngleIncrement); Rad ringAngle = startRingAngle + i*ringAngleIncrement;
x = z = Math::cos(ringAngle); x = z = Math::cos(ringAngle);
y = Math::sin(ringAngle); y = Math::sin(ringAngle);
for(UnsignedInt j = 0; j != segments; ++j) { for(UnsignedInt j = 0; j != segments; ++j) {
Rad segmentAngle(j*segmentAngleIncrement); Rad segmentAngle = j*segmentAngleIncrement;
positions(0)->push_back({x*Math::sin(segmentAngle), centerY+y, z*Math::cos(segmentAngle)}); positions(0)->push_back({x*Math::sin(segmentAngle), centerY+y, z*Math::cos(segmentAngle)});
normals(0)->push_back({x*Math::sin(segmentAngle), y, z*Math::cos(segmentAngle)}); normals(0)->push_back({x*Math::sin(segmentAngle), y, z*Math::cos(segmentAngle)});
@ -97,7 +97,7 @@ void Capsule::cylinderVertexRings(UnsignedInt count, Float startY, Float yIncrem
Rad segmentAngleIncrement(2*Constants::pi()/segments); Rad segmentAngleIncrement(2*Constants::pi()/segments);
for(UnsignedInt i = 0; i != count; ++i) { for(UnsignedInt i = 0; i != count; ++i) {
for(UnsignedInt j = 0; j != segments; ++j) { for(UnsignedInt j = 0; j != segments; ++j) {
Rad segmentAngle(j*segmentAngleIncrement); Rad segmentAngle = j*segmentAngleIncrement;
positions(0)->push_back({Math::sin(segmentAngle), startY, Math::cos(segmentAngle)}); positions(0)->push_back({Math::sin(segmentAngle), startY, Math::cos(segmentAngle)});
normals(0)->push_back({Math::sin(segmentAngle), 0.0f, Math::cos(segmentAngle)}); normals(0)->push_back({Math::sin(segmentAngle), 0.0f, Math::cos(segmentAngle)});

2
src/Primitives/Cylinder.cpp

@ -60,7 +60,7 @@ void Cylinder::capVertexRing(Float y, Float textureCoordsV, const Vector3& norma
Rad segmentAngleIncrement(2*Constants::pi()/segments); Rad segmentAngleIncrement(2*Constants::pi()/segments);
for(UnsignedInt i = 0; i != segments; ++i) { for(UnsignedInt i = 0; i != segments; ++i) {
Rad segmentAngle(i*segmentAngleIncrement); Rad segmentAngle = i*segmentAngleIncrement;
positions(0)->push_back({Math::sin(segmentAngle), y, Math::cos(segmentAngle)}); positions(0)->push_back({Math::sin(segmentAngle), y, Math::cos(segmentAngle)});
normals(0)->push_back(normal); normals(0)->push_back(normal);

2
src/Primitives/UVSphere.cpp

@ -38,7 +38,7 @@ UVSphere::UVSphere(UnsignedInt rings, UnsignedInt segments, TextureCoords textur
capVertex(-1.0f, -1.0f, 0.0f); capVertex(-1.0f, -1.0f, 0.0f);
/* Vertex rings */ /* Vertex rings */
hemisphereVertexRings(rings-1, 0.0f, -Rad(Constants::pi()/2)+ringAngleIncrement, ringAngleIncrement, textureCoordsVIncrement, textureCoordsVIncrement); hemisphereVertexRings(rings-1, 0.0f, -Rad(Constants::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