Core/Dependencies: Update G3D to version 8.01

This commit is contained in:
Nay
2012-09-03 15:39:07 +01:00
parent 5f6e190a96
commit 0db5573d4d
18 changed files with 216 additions and 857 deletions

View File

@@ -10,7 +10,7 @@ bzip2 (a freely available, patent free, high-quality data compressor)
G3D (a commercial-grade C++ 3D engine available as Open Source (BSD License)
http://g3d.sourceforge.net/
Version: 8.0-Release
Version: 8.01-Release
jemalloc (a general-purpose scalable concurrent malloc-implementation)
http://www.canonware.com/jemalloc/

View File

@@ -20,6 +20,7 @@
#include "G3D/debug.h"
#include "G3D/Array.h"
#include "G3D/Plane.h"
#include "G3D/Sphere.h"
namespace G3D {
@@ -259,6 +260,8 @@ public:
void getBounds(AABox& out) const {
out = *this;
}
void getBounds(Sphere& out) const;
};
}

View File

@@ -17,7 +17,9 @@
#include "G3D/platform.h"
#include "G3D/Table.h"
#include "G3D/Array.h"
#include "G3D/Set.h"
#include "G3D/AtomicInt32.h"
#include "G3D/stringutils.h"
#include <string>
// needed for Token
@@ -448,7 +450,6 @@ public:
*/
std::string resolveStringAsFilename() const;
/** If this is named ARRAY or TABLE, returns the name. */
const std::string& name() const;
@@ -518,7 +519,7 @@ public:
// Needed to prevent the operator[](int) overload from catching
// string literals
inline const Any& operator[](const char* key) const {
const Any& operator[](const char* key) const {
return operator[](std::string(key));
}
@@ -548,7 +549,7 @@ public:
Any& operator[](const std::string& key);
/** \copydoc Any::operator[](const std::string&) */
inline Any& operator[](const char* key) {
Any& operator[](const char* key) {
return operator[](std::string(key));
}
@@ -636,6 +637,124 @@ private:
}; // class Any
/**
Convenient iteration over the keys of a Any::TABLE, usually
for implementing construction of an object from an Any.
Getting an element using either iteration or explicit requests
consumes that element from the iterator (but not from the Any!)
It is an error to consume the same element more than once from
the same iterator.
<pre>
AnyKeyIterator r(a);
r.getIfPresent("enabled", enabled);
r.getIfPresent("showSamples", showSamples);
r.getIfPresent("showTiles", showTiles);
r.verifyDone();
</pre>
\beta
*/
class AnyTableReader {
private:
Any m_any;
Set<std::string> m_alreadyRead;
public:
/** Verifies that \a is a TABLE with the given \a name. */
AnyTableReader(const std::string& name, const Any& a) : m_any(a) {
try {
m_any.verifyType(Any::TABLE);
m_any.verifyName(name);
} catch (const ParseError& e) {
// If an exception is thrown, the destructors will not be
// invoked automatically.
m_any.~Any();
m_alreadyRead.~Set();
throw e;
}
}
/** Verifies that \a is a TABLE. */
AnyTableReader(const Any& a) : m_any(a) {
try {
m_any.verifyType(Any::TABLE);
} catch (const ParseError& e) {
// If an exception is thrown, the destructors will not be
// invoked automatically.
m_any.~Any();
m_alreadyRead.~Set();
throw e;
}
}
bool hasMore() const {
return m_any.size() > m_alreadyRead.size();
}
/** Verifies that all keys have been read. */
void verifyDone() const {
if (hasMore()) {
// Generate all keys
// Remove the ones we've read
// Assert the rest
// any.verify("");
}
}
#if 0
/** Returns the current key */
const std::string& key() const;
/** Returns the current value */
const Any& value() const;
AnyKeyIterator& operator++();
#endif
/** If key \s appears in the any, reads its value into \a v and
removes that key from the ones available to iterate over.
If key \s does not appear in the any, throws a G3D::ParseError.
Assumes that if key \s appears in the any it has not already been extracted
by this iterator. If it has been read before, an assertion will fail in debug mode.
*/
template<class ValueType>
void get(const std::string& s, ValueType& v) {
v = m_any[s];
m_alreadyRead.insert(toLower(s));
}
/** Get the value associated with a key only if the key is actually present.
If key \s appears in the any, reads its value into \a v and
removes that key from the ones available to iterate over.
If key \s does not appear in the any, does nothing.
Assumes that if key \s appears in the any it has not already been extracted
by this iterator. If it has been read before, an assertion will fail in debug mode.
\return True if the value was read.
*/
template<class ValueType>
bool getIfPresent(const std::string& s, ValueType& v) {
if (m_any.containsKey(s)) {
debugAssertM(! m_alreadyRead.contains(toLower(s)), "read twice");
get(s, v);
return true;
} else {
return false;
}
}
};
} // namespace G3D
#endif

View File

@@ -360,7 +360,7 @@ public:
m_arrayIndex(0), m_epoch(0) {}
Iterator(const ThisType* grid) :
m_isEnd(false),
m_isEnd(grid->size() == 0),
m_grid(grid),
m_tableIterator( grid->m_data.begin() ),
m_arrayIndex(0),
@@ -387,6 +387,10 @@ public:
}
}
bool hasMore() const {
return ! m_isEnd;
}
bool operator==(const Iterator& other) const {
return !(*this != other);
}

View File

@@ -1,36 +0,0 @@
/**
Quat.inl
@cite Quaternion implementation based on Watt & Watt page 363.
Thanks to Max McGuire for slerp optimizations.
@maintainer Morgan McGuire, matrix@graphics3d.com
@created 2002-01-23
@edited 2004-03-04
*/
namespace G3D {
inline float& Quat::operator[] (int i) {
debugAssert(i >= 0);
debugAssert(i < 4);
return ((float*)this)[i];
}
inline const float& Quat::operator[] (int i) const {
debugAssert(i >= 0);
debugAssert(i < 4);
return ((float*)this)[i];
}
inline Quat Quat::operator-(const Quat& other) const {
return Quat(x - other.x, y - other.y, z - other.z, w - other.w);
}
inline Quat Quat::operator+(const Quat& other) const {
return Quat(x + other.x, y + other.y, z + other.z, w + other.w);
}
}

View File

@@ -15,7 +15,6 @@
#include "G3D/platform.h"
#include "G3D/Vector3.h"
#include "G3D/Array.h"
#include "G3D/Sphere.h"
namespace G3D {

View File

@@ -86,12 +86,11 @@ namespace G3D {
<PRE>
template<> struct HashTrait<MyEnum> {
static size_t equals(const MyEnum& key) const { return reinterpret_cast<size_t>( key ); }
static size_t hashCode(const MyEnum& key) const { return reinterpret_cast<size_t>( key ); }
};
</PRE>
And rely on the default enum operator==.
and rely on the default enum operator==.
Periodically check that debugGetLoad() is low (> 0.1). When it gets near
1.0 your hash function is badly designed and maps too many inputs to

View File

@@ -1,18 +0,0 @@
/**
@file Vector2.inl
@maintainer Morgan McGuire, matrix@graphics3d.com
@cite Portions by Laura Wollstadt, graphics3d.com
@cite Portions based on Dave Eberly'x Magic Software Library
at http://www.magic-software.com
@created 2001-06-02
@edited 2006-01-14
Copyright 2000-2006, Morgan McGuire.
All rights reserved.
*/
}

View File

@@ -1,249 +0,0 @@
/**
@file Vector3.inl
@maintainer Morgan McGuire, matrix@graphics3d.com
@cite Portions based on Dave Eberly's Magic Software Library at http://www.magic-software.com
@created 2001-06-02
@edited 2004-05-21
Copyright 2000-2004, Morgan McGuire.
All rights reserved.
*/
//----------------------------------------------------------------------------
#ifdef SSE
// If you receive an error on this line, it is because you do not have the file
// xmmintrin.h needed for MMX & SSE extensions. Download and install
//
// http://download.microsoft.com/download/vstudio60ent/SP5/Wideband-Full/WIN98Me/EN-US/vs6sp5.exe
// and
// http://download.microsoft.com/download/vb60ent/Update/6/W9X2KXP/EN-US/vcpp5.exe
//
// to get this file.
# include <xmmintrin.h>
#endif
inline unsigned int hashCode(const G3D::Vector3& v) {
return v.hashCode();
}
namespace G3D {
//----------------------------------------------------------------------------
inline Vector3::Vector3() : x(0.0f), y(0.0f), z(0.0f) {
}
//----------------------------------------------------------------------------
inline Vector3::Vector3 (float fX, float fY, float fZ) : x(fX), y(fY), z(fZ) {
}
//----------------------------------------------------------------------------
inline Vector3::Vector3 (float V[3]) : x(V[0]), y(V[1]), z(V[2]){
}
//----------------------------------------------------------------------------
inline Vector3::Vector3 (double V[3]) : x((float)V[0]), y((float)V[1]), z((float)V[2]){
}
//----------------------------------------------------------------------------
inline Vector3::Vector3 (const Vector3& V) : x(V.x), y(V.y), z(V.z) {
}
//----------------------------------------------------------------------------
//inline Vector3::Vector3 (const __m128& m) {
// Cast from SSE packed floats
// *this = *(Vector3*)&m;
//}
//----------------------------------------------------------------------------
inline const float& Vector3::operator[] (int i) const {
return ((float*)this)[i];
}
inline float& Vector3::operator[] (int i) {
return ((float*)this)[i];
}
//----------------------------------------------------------------------------
inline Vector3& Vector3::operator= (const Vector3& rkVector) {
x = rkVector.x;
y = rkVector.y;
z = rkVector.z;
return *this;
}
//----------------------------------------------------------------------------
inline bool Vector3::fuzzyEq(const Vector3& other) const {
return G3D::fuzzyEq((*this - other).squaredMagnitude(), 0);
}
//----------------------------------------------------------------------------
inline bool Vector3::fuzzyNe(const Vector3& other) const {
return G3D::fuzzyNe((*this - other).squaredMagnitude(), 0);
}
//----------------------------------------------------------------------------
inline bool Vector3::isFinite() const {
return G3D::isFinite(x) && G3D::isFinite(y) && G3D::isFinite(z);
}
//----------------------------------------------------------------------------
inline bool Vector3::operator== (const Vector3& rkVector) const {
return ( x == rkVector.x && y == rkVector.y && z == rkVector.z );
}
//----------------------------------------------------------------------------
inline bool Vector3::operator!= (const Vector3& rkVector) const {
return ( x != rkVector.x || y != rkVector.y || z != rkVector.z );
}
//----------------------------------------------------------------------------
inline Vector3 Vector3::operator+ (const Vector3& rkVector) const {
return Vector3(x + rkVector.x, y + rkVector.y, z + rkVector.z);
}
//----------------------------------------------------------------------------
inline Vector3 Vector3::operator- (const Vector3& rkVector) const {
return Vector3(x - rkVector.x, y - rkVector.y, z - rkVector.z);
}
//----------------------------------------------------------------------------
inline Vector3 Vector3::operator* (const Vector3& rkVector) const {
return Vector3(x * rkVector.x, y * rkVector.y, z * rkVector.z);
}
inline Vector3 Vector3::operator*(float f) const {
return Vector3(x * f, y * f, z * f);
}
//----------------------------------------------------------------------------
inline Vector3 Vector3::operator/ (const Vector3& rkVector) const {
return Vector3(x / rkVector.x, y / rkVector.y, z / rkVector.z);
}
//----------------------------------------------------------------------------
inline Vector3 Vector3::operator- () const {
return Vector3(-x, -y, -z);
}
//----------------------------------------------------------------------------
inline Vector3& Vector3::operator+= (const Vector3& rkVector) {
x += rkVector.x;
y += rkVector.y;
z += rkVector.z;
return *this;
}
//----------------------------------------------------------------------------
inline Vector3& Vector3::operator-= (const Vector3& rkVector) {
x -= rkVector.x;
y -= rkVector.y;
z -= rkVector.z;
return *this;
}
//----------------------------------------------------------------------------
inline Vector3& Vector3::operator*= (float fScalar) {
x *= fScalar;
y *= fScalar;
z *= fScalar;
return *this;
}
//----------------------------------------------------------------------------
inline Vector3& Vector3::operator*= (const Vector3& rkVector) {
x *= rkVector.x;
y *= rkVector.y;
z *= rkVector.z;
return *this;
}
//----------------------------------------------------------------------------
inline Vector3& Vector3::operator/= (const Vector3& rkVector) {
x /= rkVector.x;
y /= rkVector.y;
z /= rkVector.z;
return *this;
}
//----------------------------------------------------------------------------
inline float Vector3::squaredMagnitude () const {
return x*x + y*y + z*z;
}
//----------------------------------------------------------------------------
inline float Vector3::squaredLength () const {
return squaredMagnitude();
}
//----------------------------------------------------------------------------
inline float Vector3::magnitude() const {
return sqrtf(x*x + y*y + z*z);
}
//----------------------------------------------------------------------------
inline float Vector3::length() const {
return magnitude();
}
//----------------------------------------------------------------------------
inline Vector3 Vector3::direction () const {
float lenSquared = squaredMagnitude();
float invSqrt = 1.0f / sqrtf(lenSquared);
return Vector3(x * invSqrt, y * invSqrt, z * invSqrt);
}
//----------------------------------------------------------------------------
inline Vector3 Vector3::fastDirection () const {
float lenSquared = x * x + y * y + z * z;
float invSqrt = rsq(lenSquared);
return Vector3(x * invSqrt, y * invSqrt, z * invSqrt);
}
//----------------------------------------------------------------------------
inline float Vector3::dot (const Vector3& rkVector) const {
return x*rkVector.x + y*rkVector.y + z*rkVector.z;
}
//----------------------------------------------------------------------------
inline Vector3 Vector3::cross (const Vector3& rkVector) const {
return Vector3(y*rkVector.z - z*rkVector.y, z*rkVector.x - x*rkVector.z,
x*rkVector.y - y*rkVector.x);
}
//----------------------------------------------------------------------------
inline Vector3 Vector3::unitCross (const Vector3& rkVector) const {
Vector3 kCross(y*rkVector.z - z*rkVector.y, z*rkVector.x - x*rkVector.z,
x*rkVector.y - y*rkVector.x);
kCross.unitize();
return kCross;
}
//----------------------------------------------------------------------------
inline Vector3 Vector3::min(const Vector3 &v) const {
return Vector3(G3D::min(v.x, x), G3D::min(v.y, y), G3D::min(v.z, z));
}
//----------------------------------------------------------------------------
inline Vector3 Vector3::max(const Vector3 &v) const {
return Vector3(G3D::max(v.x, x), G3D::max(v.y, y), G3D::max(v.z, z));
}
//----------------------------------------------------------------------------
inline bool Vector3::isZero() const {
return G3D::fuzzyEq(squaredMagnitude(), 0.0f);
}
//----------------------------------------------------------------------------
inline bool Vector3::isUnit() const {
return G3D::fuzzyEq(squaredMagnitude(), 1.0f);
}
} // namespace

View File

@@ -1,191 +0,0 @@
/**
@file Vector4.inl
@maintainer Morgan McGuire, matrix@graphics3d.com
@created 2002-07-09
@edited 2003-02-10
*/
//----------------------------------------------------------------------------
inline unsigned int hashCode(const G3D::Vector4& v) {
return v.hashCode();
}
namespace G3D {
//----------------------------------------------------------------------------
inline Vector4::Vector4() {
x = y = z = w = 0;
}
//----------------------------------------------------------------------------
inline Vector4::Vector4 (float fX, float fY, float fZ, float fW) {
x = fX;
y = fY;
z = fZ;
w = fW;
}
//----------------------------------------------------------------------------
inline Vector4::Vector4 (float afCoordinate[4]) {
x = afCoordinate[0];
y = afCoordinate[1];
z = afCoordinate[2];
w = afCoordinate[3];
}
//----------------------------------------------------------------------------
inline Vector4::Vector4(const Vector4& rkVector) {
x = rkVector.x;
y = rkVector.y;
z = rkVector.z;
w = rkVector.w;
}
//----------------------------------------------------------------------------
inline Vector4::Vector4(const Vector3& rkVector, float fW) {
x = rkVector.x;
y = rkVector.y;
z = rkVector.z;
w = fW;
}
//----------------------------------------------------------------------------
inline float& Vector4::operator[] (int i) {
return ((float*)this)[i];
}
//----------------------------------------------------------------------------
inline const float& Vector4::operator[] (int i) const {
return ((float*)this)[i];
}
//----------------------------------------------------------------------------
inline Vector4::operator float* () {
return (float*)this;
}
inline Vector4::operator const float* () const {
return (float*)this;
}
//----------------------------------------------------------------------------
inline Vector4& Vector4::operator= (const Vector4& rkVector) {
x = rkVector.x;
y = rkVector.y;
z = rkVector.z;
w = rkVector.w;
return *this;
}
//----------------------------------------------------------------------------
inline bool Vector4::operator== (const Vector4& rkVector) const {
return ( (x == rkVector.x) && (y == rkVector.y) && (z == rkVector.z) && (w == rkVector.w));
}
//----------------------------------------------------------------------------
inline bool Vector4::operator!= (const Vector4& rkVector) const {
return ( x != rkVector.x || y != rkVector.y || z != rkVector.z || w != rkVector.w);
}
//----------------------------------------------------------------------------
inline Vector4 Vector4::operator+ (const Vector4& rkVector) const {
return Vector4(x + rkVector.x, y + rkVector.y, z + rkVector.z, w + rkVector.w);
}
//----------------------------------------------------------------------------
inline Vector4 Vector4::operator- (const Vector4& rkVector) const {
return Vector4(x - rkVector.x, y - rkVector.y, z - rkVector.z, w - rkVector.w);
}
//----------------------------------------------------------------------------
inline Vector4 Vector4::operator* (float fScalar) const {
return Vector4(fScalar*x, fScalar*y, fScalar*z, fScalar*w);
}
//----------------------------------------------------------------------------
inline Vector4 Vector4::operator- () const {
return Vector4( -x, -y, -z, -w);
}
//----------------------------------------------------------------------------
inline Vector4& Vector4::operator+= (const Vector4& rkVector) {
x += rkVector.x;
y += rkVector.y;
z += rkVector.z;
w += rkVector.w;
return *this;
}
//----------------------------------------------------------------------------
inline Vector4& Vector4::operator-= (const Vector4& rkVector) {
x -= rkVector.x;
y -= rkVector.y;
z -= rkVector.z;
w -= rkVector.w;
return *this;
}
//----------------------------------------------------------------------------
inline Vector4 Vector4::lerp(const Vector4& v, float alpha) const {
return (*this) + (v - *this) * alpha;
}
//----------------------------------------------------------------------------
inline Vector4& Vector4::operator*= (float fScalar) {
x *= fScalar;
y *= fScalar;
z *= fScalar;
w *= fScalar;
return *this;
}
//----------------------------------------------------------------------------
inline float Vector4::dot(const Vector4& rkVector) const {
return x*rkVector.x + y*rkVector.y + z*rkVector.z + w*rkVector.w;
}
//----------------------------------------------------------------------------
inline Vector4 Vector4::min(const Vector4 &v) const {
return Vector4(G3D::min(v.x, x), G3D::min(v.y, y), G3D::min(v.z, z), G3D::min(v.w, w));
}
//----------------------------------------------------------------------------
inline Vector4 Vector4::max(const Vector4 &v) const {
return Vector4(G3D::max(v.x, x), G3D::max(v.y, y), G3D::max(v.z, z), G3D::max(v.w, w));
}
//----------------------------------------------------------------------------
inline bool Vector4::isZero() const {
return (x == 0.0f) && (y == 0.0f) && (z == 0.0f) && (w == 0.0f);
}
//----------------------------------------------------------------------------
inline bool Vector4::isFinite() const {
return G3D::isFinite(x) && G3D::isFinite(y) && G3D::isFinite(z) && G3D::isFinite(w);
}
//----------------------------------------------------------------------------
inline bool Vector4::isUnit() const {
return squaredLength() == 1.0;
}
//----------------------------------------------------------------------------
inline float Vector4::length() const {
return sqrtf(squaredLength());
}
//----------------------------------------------------------------------------
inline float Vector4::squaredLength() const {
return x * x + y * y + z * z + w * w;
}
}

View File

@@ -1,288 +0,0 @@
/**
@file g3dmath.inl
@maintainer Morgan McGuire, matrix@graphics3d.com
@created 2001-06-02
@edited 2006-01-14
*/
#include <stdlib.h>
#ifdef _MSC_VER
// Disable conditional expression is constant, which occurs incorrectly on inlined functions
# pragma warning (push)
# pragma warning( disable : 4127 )
#endif
namespace G3D {
inline bool isNaN(double x) {
bool b1 = (x < 0.0);
bool b2 = (x >= 0.0);
bool b3 = !(b1 || b2);
return b3;
}
inline bool isFinite(double x) {
return ! isNaN(x) && (x < G3D::inf()) && (x > -G3D::inf());
}
//----------------------------------------------------------------------------
inline int iAbs (int iValue) {
return ( iValue >= 0 ? iValue : -iValue );
}
//----------------------------------------------------------------------------
inline int iCeil (double fValue) {
return int(::ceil(fValue));
}
//----------------------------------------------------------------------------
inline int iClamp(int val, int low, int hi) {
debugAssert(low <= hi);
if (val <= low) {
return low;
} else if (val >= hi) {
return hi;
} else {
return val;
}
}
//----------------------------------------------------------------------------
inline double clamp(double val, double low, double hi) {
debugAssert(low <= hi);
if (val <= low) {
return low;
} else if (val >= hi) {
return hi;
} else {
return val;
}
}
inline float clamp(float val, float low, float hi) {
debugAssert(low <= hi);
if (val <= low) {
return low;
} else if (val >= hi) {
return hi;
} else {
return val;
}
}
//----------------------------------------------------------------------------
inline int iWrap(int val, int hi) {
if (val < 0) {
return ((val % hi) + hi) % hi;
} else {
return val % hi;
}
}
//----------------------------------------------------------------------------
inline int iFloor (double fValue) {
return int(::floor(fValue));
}
//----------------------------------------------------------------------------
inline int iSign (int iValue) {
return ( iValue > 0 ? + 1 : ( iValue < 0 ? -1 : 0 ) );
}
inline int iSign (double fValue) {
return ( fValue > 0.0 ? + 1 : ( fValue < 0.0 ? -1 : 0 ) );
}
//----------------------------------------------------------------------------
inline double abs (double fValue) {
return double(::fabs(fValue));
}
//----------------------------------------------------------------------------
inline double aCos (double fValue) {
if ( -1.0 < fValue ) {
if ( fValue < 1.0 )
return double(::acos(fValue));
else
return 0.0;
} else {
return G3D_PI;
}
}
//----------------------------------------------------------------------------
inline double aSin (double fValue) {
if ( -1.0 < fValue ) {
if ( fValue < 1.0 ) {
return double(::asin(fValue));
} else {
return -G3D_HALF_PI;
}
} else {
return G3D_HALF_PI;
}
}
//----------------------------------------------------------------------------
inline double aTan (double fValue) {
return double(::atan(fValue));
}
//----------------------------------------------------------------------------
inline double aTan2 (double fY, double fX) {
return double(::atan2(fY, fX));
}
//----------------------------------------------------------------------------
inline double sign (double fValue) {
if (fValue > 0.0) {
return 1.0;
}
if (fValue < 0.0) {
return -1.0;
}
return 0.0;
}
inline double G3D_DEPRECATED unitRandom () {
return double(::rand()) / double(RAND_MAX);
}
inline float uniformRandom(float low, float hi) {
return (hi - low) * float(::rand()) / float(RAND_MAX) + low;
}
//----------------------------------------------------------------------------
inline double G3D_DEPRECATED symmetricRandom () {
return 2.0 * double(::rand()) / double(RAND_MAX) - 1.0;
}
//----------------------------------------------------------------------------
inline double square(double x) {
return x * x;
}
//----------------------------------------------------------------------------
inline double sumSquares(double x, double y) {
return x*x + y*y;
}
//----------------------------------------------------------------------------
inline double sumSquares(double x, double y, double z) {
return x*x + y*y + z*z;
}
//----------------------------------------------------------------------------
inline double distance(double x, double y) {
return sqrt(sumSquares(x, y));
}
//----------------------------------------------------------------------------
inline double distance(double x, double y, double z) {
return sqrt(sumSquares(x, y, z));
}
//----------------------------------------------------------------------------
/** @deprecated use G3D::min */
inline int iMin(int x, int y) {
return (x >= y) ? y : x;
}
//----------------------------------------------------------------------------
/** @deprecated use G3D::min */
inline int iMax(int x, int y) {
return (x >= y) ? x : y;
}
//----------------------------------------------------------------------------
inline int ceilPow2(unsigned int in) {
in -= 1;
in |= in >> 16;
in |= in >> 8;
in |= in >> 4;
in |= in >> 2;
in |= in >> 1;
return in + 1;
}
inline bool isPow2(int num) {
return ((num & -num) == num);
}
inline bool isOdd(int num) {
return (num & 1) == 1;
}
inline bool isEven(int num) {
return (num & 1) == 0;
}
inline double toRadians(double deg) {
return deg * G3D_PI / 180.0;
}
inline double toDegrees(double rad) {
return rad * 180.0 / G3D_PI;
}
/**
Computes an appropriate epsilon for comparing a and b.
*/
inline double eps(double a, double b) {
// For a and b to be nearly equal, they must have nearly
// the same magnitude. This means that we can ignore b
// since it either has the same magnitude or the comparison
// will fail anyway.
(void)b;
const double aa = abs(a) + 1;
if (aa == inf()) {
return fuzzyEpsilon;
} else {
return fuzzyEpsilon * aa;
}
}
inline bool fuzzyEq(double a, double b) {
return (a == b) || (abs(a - b) <= eps(a, b));
}
inline bool fuzzyNe(double a, double b) {
return ! fuzzyEq(a, b);
}
inline bool fuzzyGt(double a, double b) {
return a > b + eps(a, b);
}
inline bool fuzzyGe(double a, double b) {
return a > b - eps(a, b);
}
inline bool fuzzyLt(double a, double b) {
return a < b - eps(a, b);
}
inline bool fuzzyLe(double a, double b) {
return a < b + eps(a, b);
}
inline int iMod3(int x) {
return x % 3;
}
} // namespace G3D
#ifdef _MSC_VER
// Disable conditional expression is constant, which occurs incorrectly on inlined functions
# pragma warning (pop)
#endif

View File

@@ -6,7 +6,7 @@
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2003-06-09
@edited 2010-01-11
@edited 2010-08-11
*/
#ifndef G3D_platform_h
@@ -16,7 +16,7 @@
The version number of G3D in the form: MmmBB ->
version M.mm [beta BB]
*/
#define G3D_VER 80000
#define G3D_VER 80100
// fatal error for unsupported architectures
#if defined(__powerpc__)

View File

@@ -282,6 +282,10 @@ bool AABox::culledBy(
return false;
}
void AABox::getBounds(Sphere& s) const {
s.center = center();
s.radius = extent().length() / 2;
}
bool AABox::intersects(const class Sphere& sphere) const {
double d = 0;

View File

@@ -23,23 +23,23 @@
namespace G3D {
void logPrintf(const char* fmt, ...) {
va_list arg_list;
va_start(arg_list, fmt);
va_list arg_list;
va_start(arg_list, fmt);
Log::common()->vprintf(fmt, arg_list);
va_end(arg_list);
}
void logLazyPrintf(const char* fmt, ...) {
va_list arg_list;
va_start(arg_list, fmt);
va_list arg_list;
va_start(arg_list, fmt);
Log::common()->lazyvprintf(fmt, arg_list);
va_end(arg_list);
}
Log* Log::commonLog = NULL;
Log::Log(const std::string& filename, int stripFromStackBottom) :
Log::Log(const std::string& filename, int stripFromStackBottom) :
stripFromStackBottom(stripFromStackBottom) {
this->filename = filename;
@@ -50,7 +50,7 @@ Log::Log(const std::string& filename, int stripFromStackBottom) :
std::string drive, base, ext;
Array<std::string> path;
parseFilename(filename, drive, path, base, ext);
std::string logName = base + ((ext != "") ? ("." + ext) : "");
std::string logName = base + ((ext != "") ? ("." + ext) : "");
// Write time is greater than 1ms. This may be a network drive.... try another file.
#ifdef G3D_WIN32
@@ -80,7 +80,7 @@ Log::Log(const std::string& filename, int stripFromStackBottom) :
Log::~Log() {
section("Shutdown");
println("Closing log file");
// Make sure we don't leave a dangling pointer
if (Log::commonLog == this) {
Log::commonLog = NULL;

View File

@@ -257,7 +257,7 @@ bool RegistryUtil::writeString(const std::string& key, const std::string& value,
// static helpers
static HKEY getRootKeyFromString(const char* str, size_t length) {
static HKEY getRootKeyFromString(const char* str, uint32 length) {
debugAssert(str);
if (str) {

View File

@@ -920,9 +920,12 @@ RealTime System::time() {
////////////////////////////////////////////////////////////////
#define REALPTR_TO_USERPTR(x) ((uint8*)(x) + sizeof (void *))
#define USERPTR_TO_REALPTR(x) ((uint8*)(x) - sizeof (void *))
#define REALBLOCK_SIZE(x) ((x) + sizeof (void *))
#define REALPTR_TO_USERPTR(x) ((uint8*)(x) + sizeof(uint32))
#define USERPTR_TO_REALPTR(x) ((uint8*)(x) - sizeof(uint32))
#define USERSIZE_TO_REALSIZE(x) ((x) + sizeof(uint32))
#define REALSIZE_FROM_USERPTR(u) (*(uint32*)USERPTR_TO_REALPTR(ptr) + sizeof(uint32))
#define USERSIZE_FROM_USERPTR(u) (*(uint32*)USERPTR_TO_REALPTR(ptr))
class BufferPool {
public:
@@ -947,13 +950,19 @@ public:
private:
/** Pointer given to the program. Unless in the tiny heap, the user size of the block is stored right in front of the pointer as a uint32.*/
typedef void* UserPtr;
/** Actual block allocated on the heap */
typedef void* RealPtr;
class MemBlock {
public:
void* ptr;
size_t bytes;
UserPtr ptr;
size_t bytes;
inline MemBlock() : ptr(NULL), bytes(0) {}
inline MemBlock(void* p, size_t b) : ptr(p), bytes(b) {}
inline MemBlock(UserPtr p, size_t b) : ptr(p), bytes(b) {}
};
MemBlock smallPool[maxSmallBuffers];
@@ -1010,13 +1019,13 @@ private:
/**
Malloc out of the tiny heap. Returns NULL if allocation failed.
*/
inline void* tinyMalloc(size_t bytes) {
inline UserPtr tinyMalloc(size_t bytes) {
// Note that we ignore the actual byte size
// and create a constant size block.
(void)bytes;
assert(tinyBufferSize >= bytes);
void* ptr = NULL;
UserPtr ptr = NULL;
if (tinyPoolSize > 0) {
--tinyPoolSize;
@@ -1040,20 +1049,20 @@ private:
}
/** Returns true if this is a pointer into the tiny heap. */
bool inTinyHeap(void* ptr) {
bool inTinyHeap(UserPtr ptr) {
return
(ptr >= tinyHeap) &&
(ptr < (uint8*)tinyHeap + maxTinyBuffers * tinyBufferSize);
}
void tinyFree(void* ptr) {
void tinyFree(UserPtr ptr) {
assert(ptr);
assert(tinyPoolSize < maxTinyBuffers);
// "Tried to free a tiny pool buffer when the tiny pool freelist is full.");
# ifdef G3D_DEBUG
if (tinyPoolSize > 0) {
void* prevOnHeap = tinyPool[tinyPoolSize - 1];
UserPtr prevOnHeap = tinyPool[tinyPoolSize - 1];
assert(prevOnHeap != ptr);
// "System::malloc heap corruption detected: "
// "the last two pointers on the freelist are identical (during tinyFree).");
@@ -1070,7 +1079,8 @@ private:
void flushPool(MemBlock* pool, int& poolSize) {
for (int i = 0; i < poolSize; ++i) {
::free(pool[i].ptr);
bytesAllocated -= USERSIZE_TO_REALSIZE(pool[i].bytes);
::free(USERPTR_TO_REALPTR(pool[i].ptr));
pool[i].ptr = NULL;
pool[i].bytes = 0;
}
@@ -1078,24 +1088,23 @@ private:
}
/** Allocate out of a specific pool-> Return NULL if no suitable
memory was found.
*/
void* malloc(MemBlock* pool, int& poolSize, size_t bytes) {
/** Allocate out of a specific pool. Return NULL if no suitable
memory was found. */
UserPtr malloc(MemBlock* pool, int& poolSize, size_t bytes) {
// OPT: find the smallest block that satisfies the request.
// See if there's something we can use in the buffer pool->
// See if there's something we can use in the buffer pool.
// Search backwards since usually we'll re-use the last one.
for (int i = (int)poolSize - 1; i >= 0; --i) {
if (pool[i].bytes >= bytes) {
// We found a suitable entry in the pool->
// We found a suitable entry in the pool.
// No need to offset the pointer; it is already offset
void* ptr = pool[i].ptr;
UserPtr ptr = pool[i].ptr;
// Remove this element from the pool
// Remove this element from the pool, replacing it with
// the one from the end (same as Array::fastRemove)
--poolSize;
pool[i] = pool[poolSize];
@@ -1159,6 +1168,8 @@ public:
~BufferPool() {
::free(tinyHeap);
flushPool(smallPool, smallPoolSize);
flushPool(medPool, medPoolSize);
#if 0 //-------------------------------- old mutex
# ifdef G3D_WIN32
DeleteCriticalSection(&mutex);
@@ -1169,7 +1180,7 @@ public:
}
void* realloc(void* ptr, size_t bytes) {
UserPtr realloc(UserPtr ptr, size_t bytes) {
if (ptr == NULL) {
return malloc(bytes);
}
@@ -1181,7 +1192,7 @@ public:
} else {
// Free the old pointer and malloc
void* newPtr = malloc(bytes);
UserPtr newPtr = malloc(bytes);
System::memcpy(newPtr, ptr, tinyBufferSize);
tinyFree(ptr);
return newPtr;
@@ -1191,28 +1202,28 @@ public:
// In one of our heaps.
// See how big the block really was
size_t realSize = *(uint32*)USERPTR_TO_REALPTR(ptr);
if (bytes <= realSize) {
size_t userSize = USERSIZE_FROM_USERPTR(ptr);
if (bytes <= userSize) {
// The old block was big enough.
return ptr;
}
// Need to reallocate
void* newPtr = malloc(bytes);
System::memcpy(newPtr, ptr, realSize);
// Need to reallocate and move
UserPtr newPtr = malloc(bytes);
System::memcpy(newPtr, ptr, userSize);
free(ptr);
return newPtr;
}
}
void* malloc(size_t bytes) {
UserPtr malloc(size_t bytes) {
lock();
++totalMallocs;
if (bytes <= tinyBufferSize) {
void* ptr = tinyMalloc(bytes);
UserPtr ptr = tinyMalloc(bytes);
if (ptr) {
++mallocsFromTinyPool;
@@ -1226,7 +1237,7 @@ public:
// through to a small buffer
if (bytes <= smallBufferSize) {
void* ptr = malloc(smallPool, smallPoolSize, bytes);
UserPtr ptr = malloc(smallPool, smallPoolSize, bytes);
if (ptr) {
++mallocsFromSmallPool;
@@ -1239,7 +1250,7 @@ public:
// through into a medium allocation because that would
// waste the medium buffer's resources.
void* ptr = malloc(medPool, medPoolSize, bytes);
UserPtr ptr = malloc(medPool, medPoolSize, bytes);
if (ptr) {
++mallocsFromMedPool;
@@ -1249,37 +1260,37 @@ public:
}
}
bytesAllocated += REALBLOCK_SIZE(bytes);
bytesAllocated += USERSIZE_TO_REALSIZE(bytes);
unlock();
// Heap allocate
// Allocate 4 extra bytes for our size header (unfortunate,
// since malloc already added its own header).
void* ptr = ::malloc(REALBLOCK_SIZE(bytes));
RealPtr ptr = ::malloc(USERSIZE_TO_REALSIZE(bytes));
if (ptr == NULL) {
// Flush memory pools to try and recover space
flushPool(smallPool, smallPoolSize);
flushPool(medPool, medPoolSize);
ptr = ::malloc(REALBLOCK_SIZE(bytes));
ptr = ::malloc(USERSIZE_TO_REALSIZE(bytes));
}
if (ptr == NULL) {
if ((System::outOfMemoryCallback() != NULL) &&
(System::outOfMemoryCallback()(REALBLOCK_SIZE(bytes), true) == true)) {
(System::outOfMemoryCallback()(USERSIZE_TO_REALSIZE(bytes), true) == true)) {
// Re-attempt the malloc
ptr = ::malloc(REALBLOCK_SIZE(bytes));
ptr = ::malloc(USERSIZE_TO_REALSIZE(bytes));
}
}
if (ptr == NULL) {
if (System::outOfMemoryCallback() != NULL) {
// Notify the application
System::outOfMemoryCallback()(REALBLOCK_SIZE(bytes), false);
System::outOfMemoryCallback()(USERSIZE_TO_REALSIZE(bytes), false);
}
# ifdef G3D_DEBUG
debugPrintf("::malloc(%d) returned NULL\n", (int)REALBLOCK_SIZE(bytes));
debugPrintf("::malloc(%d) returned NULL\n", (int)USERSIZE_TO_REALSIZE(bytes));
# endif
debugAssertM(ptr != NULL,
"::malloc returned NULL. Either the "
@@ -1294,7 +1305,7 @@ public:
}
void free(void* ptr) {
void free(UserPtr ptr) {
if (ptr == NULL) {
// Free does nothing on null pointers
return;
@@ -1309,7 +1320,7 @@ public:
return;
}
uint32 bytes = *(uint32*)USERPTR_TO_REALPTR(ptr);
uint32 bytes = USERSIZE_FROM_USERPTR(ptr);
lock();
if (bytes <= smallBufferSize) {
@@ -1327,7 +1338,7 @@ public:
return;
}
}
bytesAllocated -= REALBLOCK_SIZE(bytes);
bytesAllocated -= USERSIZE_TO_REALSIZE(bytes);
unlock();
// Free; the buffer pools are full or this is too big to store.

View File

@@ -128,32 +128,34 @@ Token TextInput::read() {
}
std::string TextInput::readUntilNewlineAsString() {
// Go to the front of the next token
Token t = read();
// Reset the position to the start of this token
std::string TextInput::readUntilNewlineAsString() {
/*
// Reset the read position back to the start of that token
currentCharOffset = t.bytePosition();
lineNumber = t.line();
charNumber = t.character();
stack.clear();
if (currentCharOffset == buffer.size()) {
// End of file
return "";
}
*/
std::string s;
// Read until newline or eof
char c = '\0';
do {
c = buffer[currentCharOffset];
if (c == '\r' || c == '\n') {
// Done
break;
} else {
s += c;
++currentCharOffset;
}
c = buffer[currentCharOffset];
if (c == '\r' || c == '\n') {
// Done
break;
} else {
s += c;
++currentCharOffset;
++charNumber;
}
} while (currentCharOffset < buffer.size());
return s;

View File

@@ -41,7 +41,7 @@ double inf() {
}
bool isNaN(float x) {
static const float n = fnan();
static const float n = nan();
return memcmp(&x, &n, sizeof(float)) == 0;
}