mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2025-11-29 17:38:24 +08:00
Core/Misc: update g3dlite lib (#2904)
* Core/Misc: update g3dlite lib * update Co-authored-by: Francesco Borzì <borzifrancesco@gmail.com>
This commit is contained in:
12
deps/g3dlite/CMakeLists.txt
vendored
12
deps/g3dlite/CMakeLists.txt
vendored
@@ -11,6 +11,7 @@
|
||||
set(g3dlib_STAT_SRCS
|
||||
source/AABox.cpp
|
||||
source/Any.cpp
|
||||
source/AnyTableReader.cpp
|
||||
source/BinaryFormat.cpp
|
||||
source/BinaryInput.cpp
|
||||
source/BinaryOutput.cpp
|
||||
@@ -26,6 +27,7 @@ set(g3dlib_STAT_SRCS
|
||||
source/format.cpp
|
||||
source/g3dfnmatch.cpp
|
||||
source/g3dmath.cpp
|
||||
source/GThread.cpp
|
||||
source/Line.cpp
|
||||
source/LineSegment.cpp
|
||||
source/Log.cpp
|
||||
@@ -38,7 +40,6 @@ set(g3dlib_STAT_SRCS
|
||||
source/Quat.cpp
|
||||
source/Random.cpp
|
||||
source/Ray.cpp
|
||||
source/ReferenceCount.cpp
|
||||
source/RegistryUtil.cpp
|
||||
source/Sphere.cpp
|
||||
source/stringutils.cpp
|
||||
@@ -55,9 +56,6 @@ set(g3dlib_STAT_SRCS
|
||||
|
||||
add_library(g3dlib STATIC ${g3dlib_STAT_SRCS})
|
||||
|
||||
# Group sources
|
||||
GroupSources(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
target_include_directories(g3dlib
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||
@@ -70,6 +68,6 @@ target_link_libraries(g3dlib
|
||||
threads)
|
||||
|
||||
set_target_properties(g3dlib
|
||||
PROPERTIES
|
||||
FOLDER
|
||||
"deps")
|
||||
PROPERTIES
|
||||
FOLDER
|
||||
"deps")
|
||||
|
||||
8
deps/g3dlite/Readme.txt
vendored
8
deps/g3dlite/Readme.txt
vendored
@@ -9,3 +9,11 @@ G3D-v8.0_hotfix5.diff - 2013-02-27 - fix compilation in cygwin environments
|
||||
G3D-v8.0_hotfix6.diff - 2013-03-08 - fix compilation in mingw
|
||||
G3D-v8.0_hotfix7.diff - 2013-08-31 - fix typo in Matrix4 == operator
|
||||
G3D-v8.0_hotfix8.diff - 2013-09-01 - fix typo in Vector3int32 += operator
|
||||
G3D-v8.0_hotfix9.diff - 2014-06-01 - only VS < 10 don't ship inttypes.h
|
||||
G3D-v9.0 hotfix1.diff - 2014-08-22 - updated to G3D9, reapplied previous patches and removed unneeded changes
|
||||
G3D-v9.0 hotfix2.diff - 2014-08-23 - fix some -Wconversion warnings
|
||||
G3D-v9.0 hotfix3.diff - 2015-06-28 - fix some warnings
|
||||
G3D-v9.0 hotfix4.diff - 2015-07-02 - backport G3D10 fix
|
||||
G3D-v9.0 hotfix5.diff - 2015-07-31 - fix MSVC 2015 warning: dep/g3dlite/include/G3D/Quat.h(352): warning C4458: declaration of 'x' hides class member
|
||||
G3D-v9.0 hotfix6.diff - 2015-11-04 - fix adding std::shared_ptr, std::weak_ptr, std::dynamic_pointer_cast, std::static_pointer_cast and std::enable_shared_from_this to global namespace
|
||||
G3D-v9.0 hotfix7.diff - 2016-10-10 - fix warning on clang 3.8 backported from G3D 10
|
||||
|
||||
193
deps/g3dlite/include/G3D/AABox.h
vendored
193
deps/g3dlite/include/G3D/AABox.h
vendored
@@ -1,29 +1,31 @@
|
||||
/**
|
||||
@file AABox.h
|
||||
\file G3D/AABox.h
|
||||
|
||||
Axis-aligned box class
|
||||
|
||||
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
\maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
|
||||
@created 2004-01-10
|
||||
@edited 2009-02-10
|
||||
\created 2004-01-10
|
||||
\edited 2013-04-13
|
||||
|
||||
Copyright 2000-2009, Morgan McGuire.
|
||||
Copyright 2000-2013, Morgan McGuire.
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef G3D_AABOX_H
|
||||
#define G3D_AABOX_H
|
||||
#ifndef G3D_AABox_h
|
||||
#define G3D_AABox_h
|
||||
|
||||
#include "G3D/platform.h"
|
||||
#include "G3D/Vector3.h"
|
||||
#include "G3D/debug.h"
|
||||
#include "G3D/Array.h"
|
||||
#include "G3D/Plane.h"
|
||||
#include "G3D/Sphere.h"
|
||||
#include "G3D/Vector3.h"
|
||||
|
||||
namespace G3D {
|
||||
|
||||
class Any;
|
||||
|
||||
/**
|
||||
An axis-aligned box.
|
||||
*/
|
||||
@@ -34,66 +36,109 @@ private:
|
||||
/** Optional argument placeholder */
|
||||
static int dummy;
|
||||
|
||||
Vector3 lo;
|
||||
Vector3 hi;
|
||||
/** NaN if empty */
|
||||
Point3 lo;
|
||||
|
||||
/** NaN if empty */
|
||||
Point3 hi;
|
||||
|
||||
public:
|
||||
|
||||
/** Does not initialize the fields */
|
||||
inline AABox() {}
|
||||
/** Creates the empty bounds, i.e., an empty set of points. */
|
||||
AABox() : lo(fnan(), fnan(), fnan()), hi(fnan(), fnan(), fnan()) {}
|
||||
|
||||
/**
|
||||
Constructs a zero-area AABox at v.
|
||||
Constructs a zero-volume AABox at v.
|
||||
*/
|
||||
inline explicit AABox(const Vector3& v) {
|
||||
explicit AABox(const Point3& v) {
|
||||
lo = hi = v;
|
||||
}
|
||||
|
||||
/** Format is one of:
|
||||
- AABox(lowpoint, highpoint)
|
||||
- AABox(point)
|
||||
- AABox::empty()
|
||||
- AABox::inf()
|
||||
*/
|
||||
explicit AABox(const class Any& a);
|
||||
|
||||
Any toAny() const;
|
||||
|
||||
bool isEmpty() const {
|
||||
return lo.isNaN();
|
||||
}
|
||||
|
||||
/** Assumes that low is less than or equal to high along each dimension.
|
||||
To have this automatically enforced, use
|
||||
<code>AABox(low.min(high), low.max(high));</code>
|
||||
*/
|
||||
inline AABox(const Vector3& low, const Vector3& high) {
|
||||
AABox(const Point3& low, const Point3& high) {
|
||||
set(low, high);
|
||||
}
|
||||
|
||||
AABox operator*(float f) const {
|
||||
if (f < 0) {
|
||||
return AABox(hi * f, lo * f);
|
||||
} else {
|
||||
return AABox(lo * f, hi * f);
|
||||
}
|
||||
}
|
||||
|
||||
AABox operator/(float f) const {
|
||||
return *this * (1.0f / f);
|
||||
}
|
||||
|
||||
/** Assumes that low is less than or equal to high along each dimension.
|
||||
*/
|
||||
inline void set(const Vector3& low, const Vector3& high) {
|
||||
inline void set(const Point3& low, const Point3& high) {
|
||||
debugAssert(
|
||||
(low.x <= high.x) &&
|
||||
(low.y <= high.y) &&
|
||||
(low.z <= high.z));
|
||||
debugAssert(! low.isNaN() && ! high.isNaN());
|
||||
lo = low;
|
||||
hi = high;
|
||||
}
|
||||
|
||||
/**
|
||||
Grows to include the bounds of a
|
||||
Grows to include the bounds of \a a
|
||||
*/
|
||||
inline void merge(const AABox& a) {
|
||||
lo = lo.min(a.lo);
|
||||
hi = hi.max(a.hi);
|
||||
if (isEmpty()) {
|
||||
lo = a.lo;
|
||||
hi = a.hi;
|
||||
} else if (! a.isEmpty()) {
|
||||
lo = lo.min(a.lo);
|
||||
hi = hi.max(a.hi);
|
||||
}
|
||||
}
|
||||
|
||||
inline void merge(const Vector3& a) {
|
||||
lo = lo.min(a);
|
||||
hi = hi.max(a);
|
||||
inline void merge(const Point3& a) {
|
||||
if (isEmpty()) {
|
||||
lo = hi = a;
|
||||
} else {
|
||||
lo = lo.min(a);
|
||||
hi = hi.max(a);
|
||||
}
|
||||
}
|
||||
|
||||
void merge(const class Box& b);
|
||||
|
||||
void serialize(class BinaryOutput& b) const;
|
||||
|
||||
void deserialize(class BinaryInput& b);
|
||||
|
||||
inline bool isFinite() const {
|
||||
return lo.isFinite() && hi.isFinite();
|
||||
return isEmpty() || (lo.isFinite() && hi.isFinite());
|
||||
}
|
||||
|
||||
inline const Vector3& low() const {
|
||||
/** Returns not-a-number if empty */
|
||||
inline const Point3& low() const {
|
||||
return lo;
|
||||
}
|
||||
|
||||
inline const Vector3& high() const {
|
||||
/** Returns not-a-number if empty */
|
||||
inline const Point3& high() const {
|
||||
return hi;
|
||||
}
|
||||
|
||||
@@ -110,25 +155,33 @@ public:
|
||||
|
||||
static const AABox& zero();
|
||||
|
||||
static const AABox& empty();
|
||||
|
||||
/**
|
||||
Returns the centroid of the box.
|
||||
Returns the centroid of the box (NaN if empty)
|
||||
*/
|
||||
inline Vector3 center() const {
|
||||
inline Point3 center() const {
|
||||
return (lo + hi) * 0.5;
|
||||
}
|
||||
|
||||
Vector3 corner(int index) const;
|
||||
Point3 corner(int index) const;
|
||||
|
||||
/**
|
||||
Distance from corner(0) to the next corner along axis a.
|
||||
*/
|
||||
inline float extent(int a) const {
|
||||
if (isEmpty()) {
|
||||
return 0.0f;
|
||||
}
|
||||
debugAssert(a < 3);
|
||||
return hi[a] - lo[a];
|
||||
}
|
||||
|
||||
|
||||
inline Vector3 extent() const {
|
||||
if (isEmpty()) {
|
||||
return Vector3::zero();
|
||||
}
|
||||
return hi - lo;
|
||||
}
|
||||
|
||||
@@ -140,46 +193,46 @@ public:
|
||||
*/
|
||||
void split(const Vector3::Axis& axis, float location, AABox& low, AABox& high) const;
|
||||
|
||||
/**
|
||||
Conservative culling test for up to 32 planes.
|
||||
Returns true if there exists a <CODE>plane[p]</CODE> for
|
||||
/**
|
||||
Conservative culling test for up to 32 planes.
|
||||
Returns true if there exists a <CODE>plane[p]</CODE> for
|
||||
which the entire object is in the negative half space
|
||||
(opposite the plane normal).
|
||||
|
||||
<CODE>testMask</CODE> and <CODE>childMask</CODE>
|
||||
are used for optimizing bounding volume hierarchies.
|
||||
<CODE>testMask</CODE> and <CODE>childMask</CODE>
|
||||
are used for optimizing bounding volume hierarchies.
|
||||
The version of this method that produces childMask
|
||||
is slower than the version without; it should only
|
||||
be used for parent nodes.
|
||||
|
||||
@param cullingPlaneIndex The index of the first plane for which
|
||||
the entire object is in the negative half-space. The function
|
||||
exits early when one plane is found. -1 when the function
|
||||
returns false (i.e. when no plane culls the whole object).
|
||||
@param cullingPlaneIndex The index of the first plane for which
|
||||
the entire object is in the negative half-space. The function
|
||||
exits early when one plane is found. -1 when the function
|
||||
returns false (i.e. when no plane culls the whole object).
|
||||
|
||||
@param testMask If bit <I>p</I> is 0, the
|
||||
bounding volume automatically passes the culling test for
|
||||
<CODE>plane[p]</CODE> (i.e. it is known that the volume
|
||||
is entirely within the positive half space). The function
|
||||
@param testMask If bit <I>p</I> is 0, the
|
||||
bounding volume automatically passes the culling test for
|
||||
<CODE>plane[p]</CODE> (i.e. it is known that the volume
|
||||
is entirely within the positive half space). The function
|
||||
must return false if testMask is 0 and test all planes
|
||||
when testMask is -1 (0xFFFFFFFF).
|
||||
|
||||
@param childMask Test mask for the children of this volume.
|
||||
|
||||
*/
|
||||
bool culledBy(
|
||||
const Array<Plane>& plane,
|
||||
int32& cullingPlaneIndex,
|
||||
const uint32 testMask,
|
||||
uint32& childMask) const;
|
||||
*/
|
||||
bool culledBy
|
||||
(const Array<Plane>& plane,
|
||||
int32& cullingPlaneIndex,
|
||||
const uint32 testMask,
|
||||
uint32& childMask) const;
|
||||
|
||||
/**
|
||||
Conservative culling test that does not produce a mask for children.
|
||||
*/
|
||||
bool culledBy(
|
||||
const Array<Plane>& plane,
|
||||
int32& cullingPlaneIndex = dummy,
|
||||
const uint32 testMask = 0xFFFFFFFF) const;
|
||||
bool culledBy
|
||||
(const Array<Plane>& plane,
|
||||
int32& cullingPlaneIndex = dummy,
|
||||
const uint32 testMask = 0xFFFFFFFF) const;
|
||||
|
||||
/** less than or equal to containment */
|
||||
inline bool contains(const AABox& other) const {
|
||||
@@ -192,8 +245,7 @@ public:
|
||||
(other.lo.z >= lo.z);
|
||||
}
|
||||
|
||||
inline bool contains(
|
||||
const Vector3& point) const {
|
||||
inline bool contains(const Point3& point) const {
|
||||
return
|
||||
(point.x >= lo.x) &&
|
||||
(point.y >= lo.y) &&
|
||||
@@ -204,31 +256,42 @@ public:
|
||||
}
|
||||
|
||||
inline float area() const {
|
||||
if (isEmpty()) { return 0; }
|
||||
Vector3 diag = hi - lo;
|
||||
return 2.0f * (diag.x * diag.y + diag.y * diag.z + diag.x * diag.z);
|
||||
}
|
||||
|
||||
inline float volume() const {
|
||||
if (isEmpty()) { return 0; }
|
||||
Vector3 diag = hi - lo;
|
||||
return diag.x * diag.y * diag.z;
|
||||
}
|
||||
|
||||
Vector3 randomInteriorPoint() const;
|
||||
Point3 randomInteriorPoint() const;
|
||||
|
||||
Vector3 randomSurfacePoint() const;
|
||||
Point3 randomSurfacePoint() const;
|
||||
|
||||
/** Returns true if there is any overlap */
|
||||
bool intersects(const AABox& other) const;
|
||||
|
||||
/** Returns true if there is any overlap.
|
||||
@cite Jim Arvo's algorithm from Graphics Gems II*/
|
||||
bool intersects(const class Sphere& other) const;
|
||||
bool intersects(const Sphere& other) const;
|
||||
|
||||
/** Return the intersection of the two boxes */
|
||||
AABox intersect(const AABox& other) const {
|
||||
Vector3 H = hi.min(other.hi);
|
||||
Vector3 L = lo.max(other.lo).min(H);
|
||||
return AABox(L, H);
|
||||
if (isEmpty() || other.isEmpty()) {
|
||||
return empty();
|
||||
}
|
||||
|
||||
const Point3& H = hi.min(other.hi);
|
||||
const Point3& L = lo.max(other.lo).min(H);
|
||||
|
||||
if (H.x < L.x && H.y < L.y && H.z < L.z) {
|
||||
return empty();
|
||||
} else {
|
||||
return AABox(L, H);
|
||||
}
|
||||
}
|
||||
|
||||
inline size_t hashCode() const {
|
||||
@@ -236,11 +299,19 @@ public:
|
||||
}
|
||||
|
||||
inline bool operator==(const AABox& b) const {
|
||||
return (lo == b.lo) && (hi == b.hi);
|
||||
if (isEmpty() && b.isEmpty()) {
|
||||
return true;
|
||||
} else {
|
||||
return (lo == b.lo) && (hi == b.hi);
|
||||
}
|
||||
}
|
||||
|
||||
inline bool operator!=(const AABox& b) const {
|
||||
return !((lo == b.lo) && (hi == b.hi));
|
||||
if (isEmpty()) {
|
||||
return b.isEmpty();
|
||||
} else {
|
||||
return !((lo == b.lo) && (hi == b.hi));
|
||||
}
|
||||
}
|
||||
|
||||
inline AABox operator+(const Vector3& v) const {
|
||||
|
||||
574
deps/g3dlite/include/G3D/Any.h
vendored
574
deps/g3dlite/include/G3D/Any.h
vendored
@@ -1,13 +1,13 @@
|
||||
/**
|
||||
@file Any.h
|
||||
\file Any.h
|
||||
|
||||
@author Morgan McGuire, Shawn Yarbrough, and Corey Taylor
|
||||
@maintainer Morgan McGuire
|
||||
\author Morgan McGuire, Shawn Yarbrough, and Corey Taylor
|
||||
\maintainer Morgan McGuire
|
||||
|
||||
@created 2006-06-11
|
||||
@edited 2010-03-16
|
||||
\created 2006-06-11
|
||||
\edited 2013-03-29
|
||||
|
||||
Copyright 2000-2010, Morgan McGuire.
|
||||
Copyright 2000-2013, Morgan McGuire.
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
#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
|
||||
#include "G3D/TextInput.h"
|
||||
#include "G3D/TextOutput.h"
|
||||
|
||||
#ifdef verify
|
||||
#undef verify
|
||||
@@ -38,7 +38,8 @@ class TextOutput;
|
||||
|
||||
Any encodes typed, structured data and can serialize it to a human
|
||||
readable format that is very similar to the Python language's data
|
||||
syntax. It is well-suited for quickly creating human-readable file
|
||||
syntax, and fully supports Python's data syntax as well.
|
||||
It is well-suited for quickly creating human-readable file
|
||||
formats, especially since deserialization and serialization preserve
|
||||
comments and an Any can tell you what file and line it came from. The
|
||||
syntax allows most C++ editors to properly highlight Any files, and
|
||||
@@ -61,7 +62,7 @@ Sample File:
|
||||
position = Vector3(1.0, -1.0, 0.0),
|
||||
video = { format = "RGB8", size = (320, 200)},
|
||||
|
||||
material = #include("rocks.mat")
|
||||
material = \#include("rocks.mat")
|
||||
}
|
||||
</pre>
|
||||
|
||||
@@ -79,7 +80,8 @@ The custom serialization format was chosen to be terse, easy for
|
||||
humans to read, and easy for machines to parse. It was specifically
|
||||
chosen over formats like XML, YAML, JSON, S-expressions, and Protocol
|
||||
Buffers, although there is no reason you could not write readers and
|
||||
writers for G3D::Any that support those.
|
||||
writers for G3D::Any that support those. Any also currently supports
|
||||
the JSON format.
|
||||
|
||||
G3D::Any assumes that structures do not contain cycles; it is an
|
||||
error to create a structure like:
|
||||
@@ -91,6 +93,17 @@ x.array().append(x); // don't do this!
|
||||
|
||||
although no exception will be thrown at runtime during that append.
|
||||
|
||||
\section includes
|
||||
|
||||
When parsing an Any from a file, the syntax
|
||||
<code>\#include(<i>filename</i>)</code> allows subsitution of the contents of
|
||||
<i>filename</i> for any single expression in an Any. The filename is interpreted
|
||||
relative to the file being parsed, and inside of the included file, relative filenames
|
||||
are interpreted with respect to the included file (and so on, recursively for nested
|
||||
inclusion).
|
||||
|
||||
Filenames are resolved with System::resolve and then System::findDataFile if not found,
|
||||
so they may contain environment variables.
|
||||
|
||||
\section Parsing
|
||||
|
||||
@@ -117,24 +130,12 @@ Vector3::Vector3(const Any& any) {
|
||||
}
|
||||
</pre>
|
||||
|
||||
It is often convenient to iterate through the table portion:
|
||||
|
||||
<pre>
|
||||
for (Any::AnyTable::Iterator it = any.table().begin(); it.hasMore(); ++it) {
|
||||
const std::string& k = toLower(it->key);
|
||||
if (key == "hello") {
|
||||
...
|
||||
} else if (key == "goodbye") {
|
||||
...
|
||||
} else {
|
||||
any.verify(false, "Unsupported key: " + it->key);
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
It is often convenient to iterate through the table portion using G3D::AnyTableReader.
|
||||
|
||||
\section BNF
|
||||
Serialized format BNF:
|
||||
|
||||
\htmlonly
|
||||
<pre>
|
||||
identifier ::= (letter | "_") (letter | digit | "_")*
|
||||
identifier-op ::= "::" | "->" | "."
|
||||
@@ -145,18 +146,19 @@ comment ::= C++ single or multi-line comments
|
||||
separator ::= "," | ";"
|
||||
|
||||
number ::= <legal C printf number format>
|
||||
string ::= <legal C double-quoted string; backslashes must be escaped>
|
||||
string ::= <legal C double-quoted or unquoted string; backslashes must be escaped>
|
||||
boolean ::= "True" | "False"
|
||||
none ::= "None"
|
||||
array ::= ("(" | "[") [ value (separator value)* [separator] ] (")" | "]")
|
||||
pair ::= (identifier | string) "=" value
|
||||
table ::= "{" [ pair (separator pair)* [separator] ] "}"
|
||||
nil ::= "Nil" <not case sensitive> | "None" <case sensitive>
|
||||
array ::= ("(" | "[" | "{") [value (separator value)* [separator] ] (")" | "]" | "}")
|
||||
pair ::= (identifier | string) ("=" | ":") value
|
||||
table ::= ("(" | "[" | "{") [ pair (separator pair)* [separator] ] (")" | "]" | "}")
|
||||
named-array ::= identifier-exp array
|
||||
named-table ::= identifier-exp table
|
||||
include ::= "#" "include" "(" string ")"
|
||||
|
||||
value ::= [comment] (none | number | boolean | string | array | table | named-array | named-table | include)
|
||||
value ::= [comment] (nil | number | boolean | string | array | table | named-array | named-table | include)
|
||||
</pre>
|
||||
\endhtmlonly
|
||||
|
||||
Except for single-line comments, whitespace is not significant.
|
||||
All parsing is case-insensitive.
|
||||
@@ -167,7 +169,7 @@ can only appear in the locations where a value is expected. This means
|
||||
that it cannot yield more than one element of an array and cannot serve
|
||||
as the pair in a table.
|
||||
|
||||
The deserializer allows the substitution of [] for () when writing
|
||||
The deserializer allows the substitution of [] or {} for () when writing
|
||||
tuples and ";" for ",". These are convenient when mimicing a
|
||||
programming language, e.g., <code>"[ printf("hello world."); clearScreen();]"</code>
|
||||
parses as an array containing two named arrays within it. The
|
||||
@@ -176,11 +178,13 @@ which also convenient when commenting out the last element.
|
||||
|
||||
The serializer indents four spaces for each level of nesting.
|
||||
Tables are written with the keys in alphabetic order.
|
||||
|
||||
\sa G3D::AnyTableReader
|
||||
*/
|
||||
class Any {
|
||||
public:
|
||||
|
||||
enum Type {NONE, BOOLEAN, NUMBER, STRING, ARRAY, TABLE};
|
||||
enum Type {NIL, BOOLEAN, NUMBER, STRING, ARRAY, TABLE, EMPTY_CONTAINER};
|
||||
|
||||
static std::string toString(Type t);
|
||||
|
||||
@@ -208,7 +212,7 @@ private:
|
||||
/** Called from deserialize() */
|
||||
static void deserializeComment(TextInput& ti, Token& token, std::string& comment);
|
||||
|
||||
/** NONE, BOOLEAN, and NUMBER are stored directly in the Any */
|
||||
/** NIL, BOOLEAN, and NUMBER are stored directly in the Any */
|
||||
union SimpleValue {
|
||||
bool b;
|
||||
double n;
|
||||
@@ -218,6 +222,11 @@ private:
|
||||
inline SimpleValue(double x) : n(x) {}
|
||||
};
|
||||
|
||||
/** The three options for Data::bracket */
|
||||
static const char* PAREN;
|
||||
static const char* BRACKET;
|
||||
static const char* BRACE;
|
||||
|
||||
class Data {
|
||||
public:
|
||||
/** ARRAY, TABLE, or STRING value only. NULL otherwise. */
|
||||
@@ -240,6 +249,16 @@ private:
|
||||
|
||||
std::string name;
|
||||
|
||||
/** If this Any was created by parsing an #include expression and
|
||||
has not been modified since, this is the original comment and
|
||||
include statement, as
|
||||
it originally appeared in the file (e.g., it may contain a relative
|
||||
filename). If this is non-empty, then when serialized, this
|
||||
Any will turn into an #include expression instead of unparsing
|
||||
its contents of the any.
|
||||
*/
|
||||
std::string includeLine;
|
||||
|
||||
/** For STRING, ARRAY and TABLE types, m_value is shared between
|
||||
multiple instances. Mutation is allowed only if the reference
|
||||
count is exactly 1, otherwise the mutating instance must copy
|
||||
@@ -249,10 +268,16 @@ private:
|
||||
|
||||
Source source;
|
||||
|
||||
/** Two-character string of "{}", "[]", or "()"; to be used when unparsing. */
|
||||
const char* bracket;
|
||||
|
||||
/** ';' or ',' separator to be used when unparsing */
|
||||
char separator;
|
||||
|
||||
private:
|
||||
|
||||
/** Called by create() */
|
||||
inline Data(Type t) : type(t), referenceCount(1) {}
|
||||
inline Data(Type t, const char* b, char s) : type(t), referenceCount(1), bracket(b), separator(s) {}
|
||||
|
||||
/** Called by destroy */
|
||||
~Data();
|
||||
@@ -261,12 +286,11 @@ private:
|
||||
|
||||
/** Clones the argument */
|
||||
static Data* create(const Data* d);
|
||||
static Data* create(Type t);
|
||||
static Data* create(Type t, const char* b = NULL, char s = '\0');
|
||||
|
||||
/** Free d, invoking its destructor and freeing the memory for
|
||||
the value. */
|
||||
static void destroy(Data* d);
|
||||
|
||||
};
|
||||
|
||||
/** If not empty, this Any was created from operator[] on a table
|
||||
@@ -283,12 +307,11 @@ private:
|
||||
SimpleValue m_simpleValue;
|
||||
mutable Data* m_data;
|
||||
|
||||
/** Called before every read operation to ensure that this object
|
||||
is not a placeholder. */
|
||||
/** Called before every read operation. */
|
||||
void beforeRead() const;
|
||||
|
||||
/** Called before every write operation to wipe the placeholder
|
||||
status. */
|
||||
/** Called before every write operation to this Any. Wipes the placeholder
|
||||
status and includedFrom entry. */
|
||||
void beforeWrite();
|
||||
|
||||
/** Decrements the reference count (if there is one). If the
|
||||
@@ -316,43 +339,61 @@ private:
|
||||
/** Read the name of a named Array or Table. */
|
||||
static void deserializeName(TextInput& ti, Token& token, std::string& name);
|
||||
|
||||
/** Read until a comma is consumed or a close paren is hit, and
|
||||
/** Read until a separator is consumed or a close paren is hit, and
|
||||
return that token. Considers the passed in token to be the first
|
||||
value read. */
|
||||
static void readUntilCommaOrClose(TextInput& ti, Token& token);
|
||||
static void readUntilSeparatorOrClose(TextInput& ti, Token& token);
|
||||
|
||||
/** Construct an Any that is a proxy for a table fetch from \a data.
|
||||
This proxy can be copied exactly once on return from operator[].*/
|
||||
Any(const std::string& key, Data* data);
|
||||
|
||||
inline bool isPlaceholder() const {
|
||||
bool isPlaceholder() const {
|
||||
return ! m_placeholderName.empty();
|
||||
}
|
||||
|
||||
void _append(const Any& v0);
|
||||
void _append(const Any& v0, const Any& v1);
|
||||
void _append(const Any& v0, const Any& v1, const Any& v2);
|
||||
void _append(const Any& v0, const Any& v1, const Any& v2, const Any& v3);
|
||||
Any _get(const std::string& key, const Any& defaultVal) const;
|
||||
void _set(const std::string& key, const Any& val);
|
||||
|
||||
void _parse(const std::string& src);
|
||||
|
||||
public:
|
||||
|
||||
/** Base class for all Any exceptions.*/
|
||||
class Exception {
|
||||
public:
|
||||
virtual ~Exception() {}
|
||||
};
|
||||
|
||||
/** Thrown by operator[] when a key is not present in a const table. */
|
||||
class KeyNotFound : public ParseError {
|
||||
public:
|
||||
std::string key;
|
||||
|
||||
KeyNotFound(const Data* data) {
|
||||
if (data) {
|
||||
filename = data->source.filename;
|
||||
line = data->source.line;
|
||||
character = data->source.character;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/** Thrown by operator[] when an array index is not present. */
|
||||
class IndexOutOfBounds : public Exception {
|
||||
class IndexOutOfBounds : public ParseError {
|
||||
public:
|
||||
int index;
|
||||
int size;
|
||||
inline IndexOutOfBounds() : index(0), size(0) {}
|
||||
inline IndexOutOfBounds(int i, int s) : index(i), size(s) {}
|
||||
IndexOutOfBounds() : index(0), size(0) {}
|
||||
IndexOutOfBounds(const Data* data, int i, int s) : index(i), size(s) {
|
||||
if (data) {
|
||||
filename = data->source.filename;
|
||||
line = data->source.line;
|
||||
character = data->source.character;
|
||||
}
|
||||
message = format("Index out of bounds: index = %d, array size = %d", i, s);
|
||||
}
|
||||
};
|
||||
|
||||
/** NONE constructor */
|
||||
/** NIL constructor */
|
||||
Any();
|
||||
|
||||
/** Deserialize */
|
||||
@@ -361,108 +402,133 @@ public:
|
||||
Any(const Any& x);
|
||||
|
||||
/** NUMBER constructor */
|
||||
Any(double x);
|
||||
explicit Any(double x);
|
||||
|
||||
#ifdef G3D_32BIT
|
||||
/** NUMBER constructor */
|
||||
Any(int64 x);
|
||||
#endif // G3D_32BIT
|
||||
explicit Any(float x);
|
||||
|
||||
#if 0
|
||||
#if defined(G3D_32Bit) || defined(_MSC_VER)
|
||||
/** NUMBER constructor */
|
||||
Any(int32 x);
|
||||
#endif // 0
|
||||
explicit Any(int64 x) : m_type(NUMBER), m_simpleValue((double)x), m_data(NULL) {}
|
||||
#endif
|
||||
|
||||
/** NUMBER constructor */
|
||||
Any(long x);
|
||||
explicit Any(long x);
|
||||
|
||||
/** NUMBER constructor */
|
||||
Any(int x);
|
||||
explicit Any(int x);
|
||||
|
||||
/** NUMBER constructor */
|
||||
Any(short x);
|
||||
explicit Any(char x);
|
||||
|
||||
/** NUMBER constructor */
|
||||
explicit Any(short x);
|
||||
|
||||
/** BOOLEAN constructor */
|
||||
Any(bool x);
|
||||
explicit Any(bool x);
|
||||
|
||||
/** STRING constructor */
|
||||
Any(const std::string& x);
|
||||
explicit Any(const std::string& x);
|
||||
|
||||
/** STRING constructor */
|
||||
Any(const char* x);
|
||||
explicit Any(const char* x);
|
||||
|
||||
/** \a t must be ARRAY or TABLE
|
||||
\param brackets must be "" (defaults to {} for table, () for array), "[]", "()", or "{}"
|
||||
\param separator must be ';', ',', or '\0' (defaults to ',' for array and ';' for table)
|
||||
*/
|
||||
explicit Any(Type t, const std::string& name = "", const std::string& brackets = "", const char separator = '\0');
|
||||
|
||||
/** Extensible constructor: call the toAny() method of any class. */
|
||||
template<class T>
|
||||
explicit Any(const T& v) : m_type(NIL), m_data(NULL) {
|
||||
*this = v.toAny();
|
||||
}
|
||||
|
||||
/** \a t must be ARRAY or TABLE */
|
||||
Any(Type t, const std::string& name = "");
|
||||
|
||||
~Any();
|
||||
|
||||
/** Removes the comment and name */
|
||||
Any& operator=(const Any& x);
|
||||
|
||||
/** Removes the comment and name */
|
||||
Any& operator=(double x);
|
||||
|
||||
/** Removes the comment and name */
|
||||
Any& operator=(int x);
|
||||
|
||||
/** Removes the comment and name */
|
||||
Any& operator=(bool x);
|
||||
|
||||
/** Removes the comment and name */
|
||||
Any& operator=(const std::string& x);
|
||||
|
||||
/** Removes the comment and name */
|
||||
Any& operator=(const char* x);
|
||||
|
||||
/** \a t must be ARRAY, TABLE, or NONE. Removes the comment and name */
|
||||
/** \a t must be ARRAY, TABLE, or NIL. Removes the comment and name */
|
||||
Any& operator=(Type t);
|
||||
|
||||
/** Assigns from an array. Assumes that T can be converted to Any. Removes the comment and name */
|
||||
template<class T>
|
||||
Any& operator=(const Array<T>& array) {
|
||||
*this = Any::ARRAY;
|
||||
resize(array.size());
|
||||
for (int i = 0; i < array.size(); ++i) {
|
||||
this->operator [](i) = array[i];
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** Removes the comment and name */
|
||||
template<class T>
|
||||
Any& operator=(const T& v) {
|
||||
*this = Any(v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Type type() const;
|
||||
|
||||
/** Same as deserialize or load, but operates on a string instead
|
||||
of a stream or file.
|
||||
|
||||
\sa deserialize, load
|
||||
\sa deserialize, load, unparse
|
||||
*/
|
||||
void parse(const std::string& src);
|
||||
static Any parse(const std::string& src);
|
||||
|
||||
std::string unparse() const;
|
||||
std::string unparse(const TextOutput::Settings& s = TextOutput::Settings()) const;
|
||||
|
||||
/** \param allowCoercion If false, throws an error if the Any uses features that are not
|
||||
supported by JSON such as named arrays. Otherwise, silently coerces to JSON. */
|
||||
std::string unparseJSON(const TextOutput::Settings& s = TextOutput::Settings(), bool allowCoercion = true) const;
|
||||
|
||||
/** Comments appear before values when they are in serialized form.*/
|
||||
const std::string& comment() const;
|
||||
void setComment(const std::string& c);
|
||||
|
||||
/** True if this is the NONE value */
|
||||
bool isNone() const;
|
||||
/** True if this is the NIL value */
|
||||
bool isNil() const;
|
||||
|
||||
/** Throws a ParseError exception if this is not a number */
|
||||
double number() const;
|
||||
float floatValue() const;
|
||||
|
||||
const std::string& string() const;
|
||||
bool boolean() const;
|
||||
|
||||
/** If a valid string, takes the string value and creates a fully qualified filename.
|
||||
If not found, the returned string is empty.
|
||||
/** If a valid string, takes the string value and creates a fully
|
||||
qualified filename.
|
||||
|
||||
The file is searched for the following ways:
|
||||
|
||||
- In the directory from which the Any was loaded.
|
||||
- By calling System::findDataFile as you would with other data files.
|
||||
|
||||
Strings that begin with '<' and end with '>' are treated as
|
||||
escape sequences and are returned unmodifed.
|
||||
*/
|
||||
std::string resolveStringAsFilename() const;
|
||||
std::string resolveStringAsFilename(bool errorIfNotFound = true) const;
|
||||
|
||||
/** If this is named ARRAY or TABLE, returns the name. */
|
||||
const std::string& name() const;
|
||||
|
||||
/** If this is named ARRAY or TABLE, returns true if the name begins with \a s. The comparision is case insensitive. */
|
||||
/** If this is named ARRAY or TABLE, returns true if the name
|
||||
begins with \a s. The comparision is case insensitive. */
|
||||
bool nameBeginsWith(const std::string& s) const;
|
||||
|
||||
/** If this is named ARRAY or TABLE, returns true if the name begins with \a s. The comparision is case insensitive. */
|
||||
/** If this is named ARRAY or TABLE, returns true if the name
|
||||
begins with \a s. The comparision is case insensitive. */
|
||||
bool nameBeginsWith(const char* s) const;
|
||||
|
||||
/** If this is named ARRAY or TABLE, returns true if the name is \a s. The comparision is case insensitive. */
|
||||
/** If this is named ARRAY or TABLE, returns true if the name is
|
||||
\a s. The comparision is case insensitive. */
|
||||
bool nameEquals(const std::string& s) const;
|
||||
|
||||
/** If this is named ARRAY or TABLE, returns true if the name is\a s. The comparision is case insensitive. */
|
||||
/** If this is named ARRAY or TABLE, returns true if the name is\a
|
||||
s. The comparision is case insensitive. */
|
||||
bool nameEquals(const char* s) const;
|
||||
|
||||
/** \brief Set the name used when serializing an ARRAY or TABLE.
|
||||
@@ -504,12 +570,29 @@ public:
|
||||
|
||||
/** Directly exposes the underlying data structure for an ARRAY. */
|
||||
const Array<Any>& array() const;
|
||||
void append(const Any& v0);
|
||||
void append(const Any& v0, const Any& v1);
|
||||
void append(const Any& v0, const Any& v1, const Any& v2);
|
||||
void append(const Any& v0, const Any& v1, const Any& v2, const Any& v3);
|
||||
|
||||
/** Directly exposes the underlying data structure for table.*/
|
||||
template<class T0>
|
||||
void append(const T0& v0) {
|
||||
_append(Any(v0));
|
||||
}
|
||||
|
||||
template<class T0, class T1>
|
||||
void append(const T0& v0, const T1& v1) {
|
||||
_append(Any(v0), Any(v1));
|
||||
}
|
||||
|
||||
template<class T0, class T1, class T2>
|
||||
void append(const T0& v0, const T1& v1, const T2& v2) {
|
||||
_append(Any(v0), Any(v1), Any(v2));
|
||||
}
|
||||
|
||||
template<class T0, class T1, class T2, class T3>
|
||||
void append(const T0& v0, const T1& v1, const T2& v2, const T3& v3) {
|
||||
_append(Any(v0), Any(v1), Any(v2), Any(v3));
|
||||
}
|
||||
|
||||
/** Directly exposes the underlying data structure for table.
|
||||
\sa G3D::AnyTableReader*/
|
||||
const Table<std::string, Any>& table() const;
|
||||
|
||||
/** For a table, returns the element for \a key. Throws KeyNotFound
|
||||
@@ -549,19 +632,25 @@ public:
|
||||
Any& operator[](const std::string& key);
|
||||
|
||||
/** \copydoc Any::operator[](const std::string&) */
|
||||
Any& operator[](const char* key) {
|
||||
inline Any& operator[](const char* key) {
|
||||
return operator[](std::string(key));
|
||||
}
|
||||
|
||||
/** For a table, returns the element for key \a x and \a
|
||||
defaultVal if it does not exist. */
|
||||
const Any& get(const std::string& key, const Any& defaultVal) const;
|
||||
template<class T>
|
||||
Any get(const std::string& key, const T& defaultVal) const {
|
||||
return _get(key, Any(defaultVal));
|
||||
}
|
||||
|
||||
/** Returns true if this key is in the TABLE. Illegal to call on an object that is not a TABLE. */
|
||||
bool containsKey(const std::string& key) const;
|
||||
|
||||
/** For a table, assigns the element for key k. */
|
||||
void set(const std::string& key, const Any& val);
|
||||
template<class T>
|
||||
void set(const std::string& key, const T& val) {
|
||||
_set(key, Any(val));
|
||||
}
|
||||
|
||||
/** for an ARRAY, resizes and returns the last element */
|
||||
Any& next();
|
||||
@@ -573,14 +662,64 @@ public:
|
||||
|
||||
/** True if the Anys are exactly equal, ignoring comments. Applies deeply on arrays and tables. */
|
||||
bool operator==(const Any& x) const;
|
||||
|
||||
bool operator==(const std::string& s) const {
|
||||
return *this == Any(s);
|
||||
}
|
||||
|
||||
bool operator==(const double& v) const {
|
||||
return *this == Any(v);
|
||||
}
|
||||
|
||||
bool operator==(int v) const {
|
||||
return *this == Any(v);
|
||||
}
|
||||
|
||||
bool operator==(bool v) const {
|
||||
return *this == Any(v);
|
||||
}
|
||||
|
||||
bool operator!=(const Any& x) const;
|
||||
|
||||
bool operator!=(const std::string& s) const {
|
||||
return *this != Any(s);
|
||||
}
|
||||
|
||||
bool operator!=(const double& v) const {
|
||||
return *this != Any(v);
|
||||
}
|
||||
|
||||
bool operator!=(int v) const {
|
||||
return *this != Any(v);
|
||||
}
|
||||
|
||||
bool operator!=(bool v) const {
|
||||
return *this != Any(v);
|
||||
}
|
||||
|
||||
operator int() const;
|
||||
operator uint32() const;
|
||||
operator float() const;
|
||||
operator double() const;
|
||||
operator bool() const;
|
||||
operator std::string() const;
|
||||
|
||||
operator char() const {
|
||||
return char(int(*this));
|
||||
}
|
||||
|
||||
operator uint8() const {
|
||||
return uint8(int(*this));
|
||||
}
|
||||
|
||||
operator int16() const {
|
||||
return int16(int(*this));
|
||||
}
|
||||
|
||||
operator uint16() const {
|
||||
return uint16(int(*this));
|
||||
}
|
||||
|
||||
/** Resize to \a n elements, where new elements are NIL
|
||||
It is an error to call this method if this is not an Any::ARRAY */
|
||||
void resize(int n);
|
||||
@@ -591,33 +730,88 @@ public:
|
||||
void clear();
|
||||
|
||||
/** Parse from a file.
|
||||
\sa deserialize, parse */
|
||||
\sa deserialize, parse, fromFile, loadIfExists
|
||||
*/
|
||||
void load(const std::string& filename);
|
||||
|
||||
/** Load a new Any from \a filename. \sa load, save, loadIfExists */
|
||||
static Any fromFile(const std::string& filename);
|
||||
|
||||
/** Load \a filename file if it exists, otherwise do not modify this */
|
||||
void loadIfExists(const std::string& filename);
|
||||
|
||||
/** Uses the serialize method. */
|
||||
void save(const std::string& filename) const;
|
||||
|
||||
void serialize(TextOutput& to) const;
|
||||
void serialize(TextOutput& to, bool json = false, bool coerce = false) const;
|
||||
|
||||
void serialize(class BinaryOutput& b) const;
|
||||
|
||||
/** Parse from a stream.
|
||||
\sa load, parse */
|
||||
void deserialize(TextInput& ti);
|
||||
|
||||
void deserialize(class BinaryInput& b);
|
||||
|
||||
const Source& source() const;
|
||||
|
||||
/** Removes this key from the Any, which must be a table. */
|
||||
void remove(const std::string& key);
|
||||
|
||||
/** Removes this key from the Any, which must be an array, and
|
||||
shifts other elements down to maintain order. */
|
||||
void remove(int index);
|
||||
|
||||
/** Throws a ParseError if \a value is false. Useful for quickly
|
||||
creating parse rules in classes that deserialize from Any.
|
||||
*/
|
||||
void verify(bool value, const std::string& message = "") const;
|
||||
|
||||
|
||||
/** Verifies that the name <i>begins with</i> identifier \a n (case insensitive).
|
||||
/** Verifies that the name is identifier \a n (case sensitive).
|
||||
It may contain identifier operators after this */
|
||||
void verifyName(const std::string& n) const;
|
||||
|
||||
/** Verifies that the name <i>begins with</i> identifier \a n or \a m (case insensitive).
|
||||
/** Verifies that the name is identifier \a n or \a m (case sensitive).
|
||||
It may contain identifier operators after this */
|
||||
void verifyName(const std::string& n, const std::string& m) const;
|
||||
|
||||
/** Verifies that the name is identifier \a n or \a m or \a p (case sensitive).
|
||||
It may contain identifier operators after this */
|
||||
void verifyName(const std::string& n, const std::string& m, const std::string& p) const;
|
||||
|
||||
/** Verifies that the name is identifier \a n or \a m or \a p or \a q (case sensitive).
|
||||
It may contain identifier operators after this */
|
||||
void verifyName(const std::string& n, const std::string& m, const std::string& p, const std::string& q) const;
|
||||
|
||||
/** Verifies that the name <i>begins with</i> identifier \a n (case sensitive).
|
||||
It may contain identifier operators after this */
|
||||
void verifyNameBeginsWith(const std::string& n) const;
|
||||
|
||||
/** Verifies that the name <i>begins with</i> identifier \a n or \a m (case sensitive).
|
||||
It may contain identifier operators after this */
|
||||
void verifyNameBeginsWith(const std::string& n, const std::string& m) const;
|
||||
|
||||
/** Verifies that the name <i>begins with</i> identifier \a n or \a m or \a p (case sensitive).
|
||||
It may contain identifier operators after this */
|
||||
void verifyNameBeginsWith(const std::string& n, const std::string& m, const std::string& p) const;
|
||||
|
||||
/** Verifies that the name <i>begins with</i> identifier \a n or \a m or \a p or \a q (case sensitive).
|
||||
It may contain identifier operators after this */
|
||||
void verifyNameBeginsWith(const std::string& n, const std::string& m, const std::string& p, const std::string& q) const;
|
||||
|
||||
/** Verifies that the name <i>begins with</i> identifier \a n or \a m or \a p or \a q or \a r (case sensitive).
|
||||
It may contain identifier operators after this */
|
||||
void verifyNameBeginsWith(const std::string& n, const std::string& m, const std::string& p, const std::string& q, const std::string& r) const;
|
||||
|
||||
/** Verifies that the name <i>begins with</i> identifier \a n or \a m or \a p or \a q or \a r or \a s (case sensitive).
|
||||
It may contain identifier operators after this */
|
||||
void verifyNameBeginsWith(const std::string& n, const std::string& m, const std::string& p, const std::string& q, const std::string& r, const std::string& s) const;
|
||||
|
||||
/** Verifies that the name <i>begins with</i> identifier \a n or \a m or \a p or \a q or \a r or \a s or \a t(case sensitive).
|
||||
It may contain identifier operators after this */
|
||||
void verifyNameBeginsWith(const std::string& n, const std::string& m, const std::string& p, const std::string& q, const std::string& r, const std::string& s, const std::string& t) const;
|
||||
|
||||
/** Verifies that the type is \a t. */
|
||||
void verifyType(Type t) const;
|
||||
|
||||
@@ -630,14 +824,49 @@ public:
|
||||
/** Verifies that the size is exactly \a s */
|
||||
void verifySize(int s) const;
|
||||
|
||||
/** Assumes that Any(T) is well-defined, e.g., by T defining a
|
||||
T::toAny() method. */
|
||||
template<class T>
|
||||
explicit Any(const Array<T>& array, const std::string& name = "") : m_type(ARRAY), m_data(NULL) {
|
||||
setName(name);
|
||||
resize(array.size());
|
||||
for (int i = 0; i < array.size(); ++i) {
|
||||
(*this)[i] = Any(array[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/** Assumes that T defines T(const Any&) */
|
||||
template<class T>
|
||||
void getArray(Array<T>& array) const {
|
||||
verifyType(ARRAY);
|
||||
array.resize(size());
|
||||
for (int i = 0; i < array.size(); ++i) {
|
||||
array[i] = T((*this)[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/** Assumes that T defines T(const Any&) */
|
||||
template<class T>
|
||||
void getTable(Table<std::string, T>& table) const {
|
||||
verifyType(TABLE);
|
||||
for (Table<std::string, Any>::Iterator it = this->table().begin(); it.isValid(); ++it) {
|
||||
table.set(it.key(), T(it.value()));
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void deserializeTable(TextInput& ti);
|
||||
void deserializeArray(TextInput& ti,const std::string& term);
|
||||
|
||||
/** Turns an empty container into a table or an array */
|
||||
void become(const Type& t);
|
||||
|
||||
}; // class Any
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Convenient iteration over the keys of a Any::TABLE, usually
|
||||
for implementing construction of an object from an Any.
|
||||
@@ -647,14 +876,14 @@ private:
|
||||
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);
|
||||
\code
|
||||
AnyTableReader r(a);
|
||||
r.getIfPresent("enabled", enabled);
|
||||
r.getIfPresent("showSamples", showSamples);
|
||||
r.get("showTiles", showTiles);
|
||||
|
||||
r.verifyDone();
|
||||
</pre>
|
||||
\endcode
|
||||
|
||||
\beta
|
||||
*/
|
||||
@@ -665,44 +894,21 @@ private:
|
||||
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;
|
||||
}
|
||||
}
|
||||
AnyTableReader(const std::string& name, const Any& a);
|
||||
|
||||
/** 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;
|
||||
}
|
||||
}
|
||||
AnyTableReader(const Any& a);
|
||||
|
||||
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("");
|
||||
}
|
||||
void verifyDone() const;
|
||||
|
||||
/** Return the underlying Any. */
|
||||
const Any& any() const {
|
||||
return m_any;
|
||||
}
|
||||
|
||||
#if 0
|
||||
@@ -714,30 +920,67 @@ public:
|
||||
|
||||
AnyKeyIterator& operator++();
|
||||
#endif
|
||||
|
||||
/** \copydoc get(const std::string& s, ValueType& v) */
|
||||
void get(const std::string& s, std::string& v) {
|
||||
v = m_any[s].string();
|
||||
m_alreadyRead.insert(s);
|
||||
}
|
||||
|
||||
/** \copydoc get(const std::string& s, ValueType& v) */
|
||||
void get(const std::string& s, uint8& v) {
|
||||
v = uint8(m_any[s].number());
|
||||
m_alreadyRead.insert(s);
|
||||
}
|
||||
|
||||
/** \copydoc get(const std::string& s, ValueType& v) */
|
||||
void get(const std::string& s, uint16& v) {
|
||||
v = uint16(m_any[s].number());
|
||||
m_alreadyRead.insert(s);
|
||||
}
|
||||
|
||||
/** Read an entire array at once.*/
|
||||
template<class T>
|
||||
void get(const std::string& s, Array<T>& v) {
|
||||
m_any[s].getArray(v);
|
||||
m_alreadyRead.insert(s);
|
||||
}
|
||||
|
||||
/** If key \s appears in the any, reads its value into \a v and
|
||||
template<class T>
|
||||
void get(const std::string& s, Table<std::string, T>& v) {
|
||||
m_any[s].getTable(v);
|
||||
m_alreadyRead.insert(s);
|
||||
}
|
||||
|
||||
/** If key \a 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.
|
||||
If key \a 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
|
||||
Assumes that if key \a 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));
|
||||
v = ValueType(m_any[s]);
|
||||
m_alreadyRead.insert(s);
|
||||
}
|
||||
|
||||
/** Same as get() */
|
||||
const Any& operator[](const std::string& s) {
|
||||
m_alreadyRead.insert(s);
|
||||
return m_any[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
|
||||
If key \a 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.
|
||||
If key \a s does not appear in the any, does nothing.
|
||||
|
||||
Assumes that if key \s appears in the any it has not already been extracted
|
||||
Assumes that if key \a 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.
|
||||
@@ -745,7 +988,7 @@ public:
|
||||
template<class ValueType>
|
||||
bool getIfPresent(const std::string& s, ValueType& v) {
|
||||
if (m_any.containsKey(s)) {
|
||||
debugAssertM(! m_alreadyRead.contains(toLower(s)), "read twice");
|
||||
debugAssertM(! m_alreadyRead.contains(s), "read twice");
|
||||
|
||||
get(s, v);
|
||||
return true;
|
||||
@@ -753,8 +996,29 @@ public:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/** \return True if \a s is in the table and has not yet been read
|
||||
using get() or getIfPresent(). */
|
||||
bool containsUnread(const std::string& s) const {
|
||||
return m_any.containsKey(s) && ! m_alreadyRead.contains(s);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} // namespace G3D
|
||||
|
||||
|
||||
/**
|
||||
\def PARSE_ANY(expression)
|
||||
|
||||
\brief Create an G3D::Any from an unquoted string.
|
||||
|
||||
e.g.,
|
||||
\code
|
||||
Any x = PARSE_ANY( { a = 3.0; b = false; } );
|
||||
\endcode
|
||||
*/
|
||||
#define PARSE_ANY(x) Any::parse(#x)
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
12
deps/g3dlite/include/G3D/AreaMemoryManager.h
vendored
12
deps/g3dlite/include/G3D/AreaMemoryManager.h
vendored
@@ -1,12 +1,12 @@
|
||||
/**
|
||||
@file AreaMemoryManager.h
|
||||
\file AreaMemoryManager.h
|
||||
|
||||
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
\maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
|
||||
@created 2009-01-20
|
||||
@edited 2009-05-29
|
||||
\created 2009-01-20
|
||||
\edited 2010-10-29
|
||||
|
||||
Copyright 2000-2009, Morgan McGuire.
|
||||
Copyright 2000-2012, Morgan McGuire.
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
@@ -57,7 +57,7 @@ private:
|
||||
|
||||
public:
|
||||
|
||||
typedef ReferenceCountedPointer<AreaMemoryManager> Ref;
|
||||
typedef shared_ptr<AreaMemoryManager> Ref;
|
||||
|
||||
/**
|
||||
\param sizeHint Total amount of memory expected to be allocated.
|
||||
|
||||
382
deps/g3dlite/include/G3D/Array.h
vendored
382
deps/g3dlite/include/G3D/Array.h
vendored
@@ -1,13 +1,13 @@
|
||||
/**
|
||||
@file Array.h
|
||||
\file Array.h
|
||||
|
||||
@maintainer Morgan McGuire, graphics3d.com
|
||||
@cite Portions written by Aaron Orenstein, a@orenstein.name
|
||||
\maintainer Morgan McGuire, graphics3d.com
|
||||
\cite Portions written by Aaron Orenstein, a@orenstein.name
|
||||
|
||||
@created 2001-03-11
|
||||
@edited 2009-05-29
|
||||
\created 2001-03-11
|
||||
\edited 2013-01-28
|
||||
|
||||
Copyright 2000-2009, Morgan McGuire, http://graphics.cs.williams.edu
|
||||
Copyright 2000-2012, Morgan McGuire, http://graphics.cs.williams.edu
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
|
||||
#include "G3D/platform.h"
|
||||
#include "G3D/debug.h"
|
||||
#include "G3D/System.h"
|
||||
#include "G3D/MemoryManager.h"
|
||||
#include "G3D/System.h"
|
||||
#ifdef G3D_DEBUG
|
||||
// For formatting error messages
|
||||
# include "G3D/format.h"
|
||||
@@ -47,6 +47,8 @@ const int SORT_INCREASING = 1;
|
||||
/** Constant for Array::sort */
|
||||
const int SORT_DECREASING = -1;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
\brief Dynamic 1D array tuned for performance.
|
||||
|
||||
@@ -89,22 +91,26 @@ const int SORT_DECREASING = -1;
|
||||
|
||||
\sa G3D::SmallArray
|
||||
*/
|
||||
template <class T, int MIN_ELEMENTS = 10, size_t MIN_BYTES = 32>
|
||||
template <class T, size_t MIN_ELEMENTS = 10>
|
||||
class Array {
|
||||
|
||||
private:
|
||||
/** Once the array has been allocated, it will never deallocate the underlying
|
||||
array unless MIN_ELEMENTS is set to 0, MIN_BYTES is 0, and the array is empty. */
|
||||
static const size_t MIN_BYTES = 32;
|
||||
|
||||
/** 0...num-1 are initialized elements, num...numAllocated-1 are not */
|
||||
T* data;
|
||||
|
||||
int num;
|
||||
int numAllocated;
|
||||
size_t num;
|
||||
size_t numAllocated;
|
||||
|
||||
MemoryManager::Ref m_memoryManager;
|
||||
|
||||
/** \param n Number of elements
|
||||
*/
|
||||
void init(int n, const MemoryManager::Ref& m) {
|
||||
void init(size_t n, const MemoryManager::Ref& m) {
|
||||
m_memoryManager = m;
|
||||
debugAssert(n >= 0);
|
||||
this->num = 0;
|
||||
this->numAllocated = 0;
|
||||
data = NULL;
|
||||
@@ -117,7 +123,7 @@ private:
|
||||
|
||||
void _copy(const Array &other) {
|
||||
init(other.num, MemoryManager::create());
|
||||
for (int i = 0; i < num; i++) {
|
||||
for (size_t i = 0; i < num; ++i) {
|
||||
data[i] = other.data[i];
|
||||
}
|
||||
}
|
||||
@@ -142,7 +148,7 @@ private:
|
||||
and then copies at most oldNum elements from the old array to it. Destructors are
|
||||
called for oldNum elements of the old array.
|
||||
*/
|
||||
void realloc(int oldNum) {
|
||||
void realloc(size_t oldNum) {
|
||||
T* oldData = data;
|
||||
|
||||
// The allocation is separate from the constructor invocation because we don't want
|
||||
@@ -154,7 +160,7 @@ private:
|
||||
alwaysAssertM(data, "Memory manager returned NULL: out of memory?");
|
||||
|
||||
// Call the copy constructors
|
||||
{const int N = G3D::min(oldNum, numAllocated);
|
||||
{const size_t N = G3D::min(oldNum, numAllocated);
|
||||
const T* end = data + N;
|
||||
T* oldPtr = oldData;
|
||||
for (T* ptr = data; ptr < end; ++ptr, ++oldPtr) {
|
||||
@@ -177,6 +183,27 @@ private:
|
||||
m_memoryManager->free(oldData);
|
||||
}
|
||||
|
||||
public:
|
||||
/**
|
||||
Assignment operator. Will be private in a future release because this is slow and can be invoked by accident by novice C++ programmers.
|
||||
If you really want to copy an Array, use the explicit copy constructor.
|
||||
*/
|
||||
Array& operator=(const Array& other) {
|
||||
resize(other.num);
|
||||
for (int i = 0; i < (int)num; ++i) {
|
||||
data[i] = other[i];
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Array& operator=(const std::vector<T>& other) {
|
||||
resize(other.size());
|
||||
for (size_t i = 0; i < num; ++i) {
|
||||
data[i] = other[i];
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
@@ -211,7 +238,7 @@ public:
|
||||
return data;
|
||||
}
|
||||
/**
|
||||
C++ STL style iterator method. Returns one after the last iterator
|
||||
C++ STL style iterator method. Returns one after the last valid iterator
|
||||
element.
|
||||
*/
|
||||
ConstIterator end() const {
|
||||
@@ -224,15 +251,27 @@ public:
|
||||
|
||||
/**
|
||||
The array returned is only valid until the next append() or resize call, or
|
||||
the Array is deallocated.
|
||||
the Array is deallocated.
|
||||
*/
|
||||
T* getCArray() {
|
||||
return data;
|
||||
}
|
||||
|
||||
/** Exchanges all data between the two arrays, which are required to have a common MemoryManager.
|
||||
This is a convenient
|
||||
way to avoid large array copies when handing off data without involving reference counting
|
||||
or manual memory management. Beware that pointers or references into the arrays will
|
||||
access memory in the <i>other</i> array after the swap. */
|
||||
static void swap(Array<T, MIN_ELEMENTS>& a, Array<T, MIN_ELEMENTS>& b) {
|
||||
alwaysAssertM(a.memoryManager() == b.memoryManager(), "The arrays are required to have the same memory manager");
|
||||
std::swap(a.data, b.data);
|
||||
std::swap(a.num, b.num);
|
||||
std::swap(a.numAllocated, b.numAllocated);
|
||||
}
|
||||
|
||||
/**
|
||||
The array returned is only valid until the next append() or resize call, or
|
||||
the Array is deallocated.
|
||||
the Array is deallocated.
|
||||
*/
|
||||
const T* getCArray() const {
|
||||
return data;
|
||||
@@ -241,12 +280,11 @@ public:
|
||||
/** Creates a zero length array (no heap allocation occurs until resize). */
|
||||
Array() : num(0) {
|
||||
init(0, MemoryManager::create());
|
||||
debugAssert(num >= 0);
|
||||
}
|
||||
|
||||
|
||||
/** Creates an array containing v0. */
|
||||
Array(const T& v0) {
|
||||
explicit Array(const T& v0) {
|
||||
init(1, MemoryManager::create());
|
||||
(*this)[0] = v0;
|
||||
}
|
||||
@@ -287,11 +325,60 @@ public:
|
||||
|
||||
|
||||
/**
|
||||
Copy constructor
|
||||
Copy constructor. Copying arrays is slow...perhaps you want to pass a reference or a pointer instead?
|
||||
*/
|
||||
Array(const Array& other) : num(0) {
|
||||
//TODO: patch rest of the API to prevent returning Arrays by value, then make explicit
|
||||
Array(const Array& other) : num(0) {
|
||||
_copy(other);
|
||||
debugAssert(num >= 0);
|
||||
}
|
||||
|
||||
explicit Array(const std::vector<T>& other) : num(0), data(NULL) {
|
||||
*this = other;
|
||||
}
|
||||
|
||||
|
||||
/* Sets this to hold the same contents as other, with num = numAllocated (no unused allocated space) */
|
||||
void copyFrom(const Array<T>& other) {
|
||||
resize(0);
|
||||
append(other);
|
||||
}
|
||||
|
||||
|
||||
/** Resizes this to match the size of \a other and then copies the data from other using memcpy. This is only safe for POD types */
|
||||
void copyPOD(const Array<T>& other) {
|
||||
static_assert(std::is_pod<T>::value, "copyPOD called on non-POD type");
|
||||
if (numAllocated < other.num) {
|
||||
m_memoryManager->free(data);
|
||||
data = NULL;
|
||||
if (other.data) {
|
||||
data = (T*)m_memoryManager->alloc(sizeof(T) * other.num);
|
||||
}
|
||||
numAllocated = other.num;
|
||||
}
|
||||
|
||||
num = other.num;
|
||||
if (other.data && (num > 0)) {
|
||||
System::memcpy(data, other.data, sizeof(T) * num);
|
||||
}
|
||||
}
|
||||
|
||||
/** Resizes this to just barely match the size of \a other + itself and then copies the data to the end of the array from other using memcpy.
|
||||
This is only safe for POD types */
|
||||
void appendPOD(const Array<T>& other) {
|
||||
static_assert(std::is_pod<T>::value, "appendPOD called on non-POD type");
|
||||
const size_t oldSize = num;
|
||||
num += other.num;
|
||||
if (numAllocated < num) {
|
||||
alwaysAssertM(other.data, "non-zero array with no allocated space");
|
||||
T* old = data;
|
||||
data = (T*)m_memoryManager->alloc(sizeof(T) * num);
|
||||
System::memcpy(data, old, sizeof(T) * oldSize);
|
||||
m_memoryManager->free(old);
|
||||
numAllocated = num;
|
||||
}
|
||||
if (other.data) {
|
||||
System::memcpy((data + oldSize), other.data, sizeof(T) * other.num);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -303,14 +390,14 @@ public:
|
||||
*/
|
||||
~Array() {
|
||||
// Invoke the destructors on the elements
|
||||
for (int i = 0; i < num; i++) {
|
||||
for (size_t i = 0; i < num; ++i) {
|
||||
(data + i)->~T();
|
||||
}
|
||||
|
||||
m_memoryManager->free(data);
|
||||
// Set to 0 in case this Array is global and gets referenced during app exit
|
||||
data = NULL;
|
||||
num = 0;
|
||||
num = 0;
|
||||
numAllocated = 0;
|
||||
}
|
||||
|
||||
@@ -335,26 +422,6 @@ public:
|
||||
clear(false);
|
||||
}
|
||||
|
||||
/**
|
||||
Assignment operator.
|
||||
*/
|
||||
Array& operator=(const Array& other) {
|
||||
debugAssert(num >= 0);
|
||||
resize(other.num); for (int i = 0; i < num; ++i) {
|
||||
data[i] = other[i];
|
||||
}
|
||||
debugAssert(num >= 0);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Array& operator=(const std::vector<T>& other) {
|
||||
resize((int)other.size());
|
||||
for (int i = 0; i < num; ++i) {
|
||||
data[i] = other[i];
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline MemoryManager::Ref memoryManager() const {
|
||||
return m_memoryManager;
|
||||
}
|
||||
@@ -363,7 +430,7 @@ public:
|
||||
Number of elements in the array.
|
||||
*/
|
||||
inline int size() const {
|
||||
return num;
|
||||
return (int)num;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -379,8 +446,7 @@ public:
|
||||
shrinks the array by one.
|
||||
*/
|
||||
void fastRemove(int index, bool shrinkIfNecessary = false) {
|
||||
debugAssert(index >= 0);
|
||||
debugAssert(index < num);
|
||||
debugAssert(index < (int)num);
|
||||
data[index] = data[num - 1];
|
||||
resize(size() - 1, shrinkIfNecessary);
|
||||
}
|
||||
@@ -393,32 +459,52 @@ public:
|
||||
// Add space for the extra element
|
||||
resize(num + 1, false);
|
||||
|
||||
for (int i = num - 1; i > n; --i) {
|
||||
for (size_t i = (size_t)(num - 1); i > (size_t)n; --i) {
|
||||
data[i] = data[i - 1];
|
||||
}
|
||||
data[n] = value;
|
||||
}
|
||||
|
||||
/** Sets all elements currently in the array to \param value */
|
||||
void setAll(const T& value) {
|
||||
for (size_t i = 0; i < num; ++i) {
|
||||
data[i] = value;
|
||||
}
|
||||
}
|
||||
|
||||
/** Resize this array to consume exactly the capacity required by its size.
|
||||
\sa clear, resize, capacity, size
|
||||
*/
|
||||
void trimToSize() {
|
||||
if (size() != capacity()) {
|
||||
size_t oldNum = numAllocated;
|
||||
numAllocated = size();
|
||||
realloc(oldNum);
|
||||
}
|
||||
}
|
||||
|
||||
/** @param shrinkIfNecessary if false, memory will never be
|
||||
reallocated when the array shrinks. This makes resizing much
|
||||
faster but can waste memory.
|
||||
faster but can waste memory. Default = true.
|
||||
|
||||
\sa clear, trimToSize
|
||||
*/
|
||||
void resize(int n, bool shrinkIfNecessary = true) {
|
||||
debugAssert(n >= 0);
|
||||
void resize(size_t n, bool shrinkIfNecessary = true) {
|
||||
alwaysAssertM(n < 0xFFFFFFFF, "This implementation does not support arrays with more than 2^32 elements, although the size in memory may be larger.");
|
||||
if (num == n) {
|
||||
return;
|
||||
}
|
||||
|
||||
int oldNum = num;
|
||||
size_t oldNum = num;
|
||||
num = n;
|
||||
|
||||
// Call the destructors on newly hidden elements if there are any
|
||||
for (int i = num; i < oldNum; ++i) {
|
||||
for (size_t i = num; i < oldNum; ++i) {
|
||||
(data + i)->~T();
|
||||
}
|
||||
|
||||
// Once allocated, always maintain MIN_ELEMENTS elements or 32 bytes, whichever is higher.
|
||||
const int minSize = std::max(MIN_ELEMENTS, (int)(MIN_BYTES / sizeof(T)));
|
||||
const size_t minSize = G3D::max(MIN_ELEMENTS, (size_t)(MIN_BYTES / sizeof(T)));
|
||||
|
||||
if ((MIN_ELEMENTS == 0) && (MIN_BYTES == 0) && (n == 0) && shrinkIfNecessary) {
|
||||
// Deallocate the array completely
|
||||
@@ -450,18 +536,21 @@ public:
|
||||
//
|
||||
// These numbers are tweaked according to performance tests.
|
||||
|
||||
float growFactor = 3.0;
|
||||
double growFactor = 3.0f;
|
||||
|
||||
int oldSizeBytes = numAllocated * sizeof(T);
|
||||
if (oldSizeBytes > 400000) {
|
||||
// Avoid bloat
|
||||
growFactor = 1.5;
|
||||
size_t oldSizeBytes = numAllocated * sizeof(T);
|
||||
if (oldSizeBytes > 10000000) {
|
||||
// Conserve memory more tightly above 10 MB
|
||||
growFactor = 1.2f;
|
||||
} else if (oldSizeBytes > 400000) {
|
||||
// Avoid bloat above 400k
|
||||
growFactor = 1.5f;
|
||||
} else if (oldSizeBytes > 64000) {
|
||||
// This is what std:: uses at all times
|
||||
growFactor = 2.0;
|
||||
growFactor = 2.0f;
|
||||
}
|
||||
|
||||
numAllocated = (num - numAllocated) + (int)(numAllocated * growFactor);
|
||||
numAllocated = (num - numAllocated) + (size_t)(numAllocated * growFactor);
|
||||
|
||||
if (numAllocated < minSize) {
|
||||
numAllocated = minSize;
|
||||
@@ -476,14 +565,14 @@ public:
|
||||
|
||||
// Only copy over old elements that still remain after resizing
|
||||
// (destructors were called for others if we're shrinking)
|
||||
realloc(iMin(num, oldNum));
|
||||
realloc(min(num, oldNum));
|
||||
|
||||
}
|
||||
|
||||
// Call the constructors on newly revealed elements.
|
||||
// Do not use parens because we don't want the intializer
|
||||
// invoked for POD types.
|
||||
for (int i = oldNum; i < num; ++i) {
|
||||
for (size_t i = oldNum; i < num; ++i) {
|
||||
new (data + i) T;
|
||||
}
|
||||
}
|
||||
@@ -583,6 +672,62 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void append(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5) {
|
||||
if (inArray(&v1) || inArray(&v2) || inArray(&v3) || inArray(&v4) || inArray(&v5)) {
|
||||
T t1 = v1;
|
||||
T t2 = v2;
|
||||
T t3 = v3;
|
||||
T t4 = v4;
|
||||
T t5 = v5;
|
||||
append(t1, t2, t3, t4, t5);
|
||||
} else if (num + 4 < numAllocated) {
|
||||
// This is a simple situation; just stick it in the next free slot using
|
||||
// the copy constructor.
|
||||
new (data + num) T(v1);
|
||||
new (data + num + 1) T(v2);
|
||||
new (data + num + 2) T(v3);
|
||||
new (data + num + 3) T(v4);
|
||||
new (data + num + 4) T(v5);
|
||||
num += 5;
|
||||
} else {
|
||||
resize(num + 5, DONT_SHRINK_UNDERLYING_ARRAY);
|
||||
data[num - 5] = v1;
|
||||
data[num - 4] = v2;
|
||||
data[num - 3] = v3;
|
||||
data[num - 2] = v4;
|
||||
data[num - 1] = v5;
|
||||
}
|
||||
}
|
||||
|
||||
void append(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6) {
|
||||
if (inArray(&v1) || inArray(&v2) || inArray(&v3) || inArray(&v4) || inArray(&v5) || inArray(&v6)) {
|
||||
T t1 = v1;
|
||||
T t2 = v2;
|
||||
T t3 = v3;
|
||||
T t4 = v4;
|
||||
T t5 = v5;
|
||||
T t6 = v6;
|
||||
append(t1, t2, t3, t4, t5, t6);
|
||||
} else if (num + 5 < numAllocated) {
|
||||
// This is a simple situation; just stick it in the next free slot using
|
||||
// the copy constructor.
|
||||
new (data + num) T(v1);
|
||||
new (data + num + 1) T(v2);
|
||||
new (data + num + 2) T(v3);
|
||||
new (data + num + 3) T(v4);
|
||||
new (data + num + 4) T(v5);
|
||||
new (data + num + 5) T(v6);
|
||||
num += 6;
|
||||
} else {
|
||||
resize(num + 6, DONT_SHRINK_UNDERLYING_ARRAY);
|
||||
data[num - 6] = v1;
|
||||
data[num - 5] = v2;
|
||||
data[num - 4] = v3;
|
||||
data[num - 3] = v4;
|
||||
data[num - 2] = v5;
|
||||
data[num - 1] = v6;
|
||||
}
|
||||
}
|
||||
/**
|
||||
Returns true if the given element is in the array.
|
||||
*/
|
||||
@@ -602,12 +747,12 @@ public:
|
||||
*/
|
||||
void append(const Array<T>& array) {
|
||||
debugAssert(this != &array);
|
||||
int oldNum = num;
|
||||
int arrayLength = array.length();
|
||||
size_t oldNum = num;
|
||||
size_t arrayLength = array.length();
|
||||
|
||||
resize(num + arrayLength, false);
|
||||
|
||||
for (int i = 0; i < arrayLength; i++) {
|
||||
for (size_t i = 0; i < arrayLength; ++i) {
|
||||
data[oldNum + i] = array.data[i];
|
||||
}
|
||||
}
|
||||
@@ -648,8 +793,8 @@ public:
|
||||
sequence, a value at least as large as size()"
|
||||
For compatibility with std::vector.
|
||||
*/
|
||||
int capacity() const {
|
||||
return numAllocated;
|
||||
int capacity() const {
|
||||
return (int)numAllocated;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -723,27 +868,40 @@ public:
|
||||
Performs bounds checks in debug mode
|
||||
*/
|
||||
inline T& operator[](int n) {
|
||||
debugAssertM((n >= 0) && (n < num), format("Array index out of bounds. n = %d, size() = %d", n, num));
|
||||
debugAssertM((n >= 0) && (n < (int)num),
|
||||
format("Array index out of bounds. n = %d, size() = %d", (int)n, (int)num));
|
||||
debugAssert(data!=NULL);
|
||||
return data[n];
|
||||
}
|
||||
|
||||
inline T& operator[](unsigned int n) {
|
||||
debugAssertM(n < (unsigned int)num, format("Array index out of bounds. n = %d, size() = %d", n, num));
|
||||
return data[n];
|
||||
inline T& operator[](uint32 n) {
|
||||
debugAssertM(n < (uint32)num, format("Array index out of bounds. n = %d, size() = %d",
|
||||
(int)n, (int)num));
|
||||
return data[n];
|
||||
}
|
||||
|
||||
inline T& operator[](uint64 n) {
|
||||
debugAssertM(n < (uint64)num, format("Array index out of bounds. n = %d, size() = %d", (int)n, (int)num));
|
||||
return data[n];
|
||||
}
|
||||
|
||||
/**
|
||||
Performs bounds checks in debug mode
|
||||
*/
|
||||
inline const T& operator[](int n) const {
|
||||
debugAssert((n >= 0) && (n < num));
|
||||
debugAssert((n >= 0) && (n < (int)num));
|
||||
debugAssert(data != NULL);
|
||||
return data[n];
|
||||
}
|
||||
|
||||
inline const T& operator[](uint32 n) const {
|
||||
debugAssert((n < (uint32)num));
|
||||
debugAssert(data!=NULL);
|
||||
return data[n];
|
||||
}
|
||||
|
||||
inline const T& operator[](unsigned int n) const {
|
||||
debugAssert((n < (unsigned int)num));
|
||||
inline const T& operator[](uint64 n) const {
|
||||
debugAssert((n < (uint64)num));
|
||||
debugAssert(data!=NULL);
|
||||
return data[n];
|
||||
}
|
||||
@@ -751,7 +909,7 @@ public:
|
||||
inline T& randomElement() {
|
||||
debugAssert(num > 0);
|
||||
debugAssert(data!=NULL);
|
||||
return data[iRandom(0, num - 1)];
|
||||
return data[iRandom(0, (int)num - 1)];
|
||||
}
|
||||
|
||||
inline const T& randomElement() const {
|
||||
@@ -821,13 +979,18 @@ public:
|
||||
Calls delete on all objects[0...size-1]
|
||||
and sets the size to zero.
|
||||
*/
|
||||
void deleteAll() {
|
||||
for (int i = 0; i < num; i++) {
|
||||
void invokeDeleteOnAllElements() {
|
||||
for (size_t i = 0; i < num; ++i) {
|
||||
delete data[i];
|
||||
}
|
||||
resize(0);
|
||||
}
|
||||
|
||||
/** \deprecated */
|
||||
void G3D_DEPRECATED deleteAll() {
|
||||
invokeDeleteOnAllElements();
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the index of (the first occurance of) an index or -1 if
|
||||
not found. Searches from the right.
|
||||
@@ -846,9 +1009,9 @@ public:
|
||||
not found.
|
||||
*/
|
||||
int findIndex(const T& value) const {
|
||||
for (int i = 0; i < num; ++i) {
|
||||
for (size_t i = 0; i < num; ++i) {
|
||||
if (data[i] == value) {
|
||||
return i;
|
||||
return (int)i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
@@ -894,8 +1057,8 @@ public:
|
||||
}
|
||||
|
||||
void remove(int index, int count = 1) {
|
||||
debugAssert((index >= 0) && (index < num));
|
||||
debugAssert((count > 0) && (index + count <= num));
|
||||
debugAssert((index >= 0) && (index < (int)num));
|
||||
debugAssert((count > 0) && (index + count <= (int)num));
|
||||
|
||||
remove(begin() + index, count);
|
||||
}
|
||||
@@ -906,8 +1069,8 @@ public:
|
||||
void reverse() {
|
||||
T temp;
|
||||
|
||||
int n2 = num / 2;
|
||||
for (int i = 0; i < n2; ++i) {
|
||||
size_t n2 = num / 2;
|
||||
for (size_t i = 0; i < n2; ++i) {
|
||||
temp = data[num - 1 - i];
|
||||
data[num - 1 - i] = data[i];
|
||||
data[i] = temp;
|
||||
@@ -917,29 +1080,29 @@ public:
|
||||
/**
|
||||
Sort using a specific less-than function, e.g.:
|
||||
|
||||
<PRE>
|
||||
\code
|
||||
bool __cdecl myLT(const MyClass& elem1, const MyClass& elem2) {
|
||||
return elem1.x < elem2.x;
|
||||
}
|
||||
</PRE>
|
||||
\endcode
|
||||
|
||||
Note that for pointer arrays, the <CODE>const</CODE> must come
|
||||
<I>after</I> the class name, e.g., <CODE>Array<MyClass*></CODE> uses:
|
||||
|
||||
<PRE>
|
||||
\code
|
||||
bool __cdecl myLT(MyClass*const& elem1, MyClass*const& elem2) {
|
||||
return elem1->x < elem2->x;
|
||||
}
|
||||
</PRE>
|
||||
\endcode
|
||||
|
||||
or a functor, e.g.,
|
||||
<pre>
|
||||
\code
|
||||
bool
|
||||
less_than_functor::operator()( const double& lhs, const double& rhs ) const
|
||||
{
|
||||
return( lhs < rhs? true : false );
|
||||
}
|
||||
</pre>
|
||||
\endcode
|
||||
*/
|
||||
// void sort(bool (__cdecl *lessThan)(const T& elem1, const T& elem2)) {
|
||||
// std::sort(data, data + num, lessThan);
|
||||
@@ -955,14 +1118,14 @@ return( lhs < rhs? true : false );
|
||||
Sorts the array in increasing order using the > or < operator. To
|
||||
invoke this method on Array<T>, T must override those operator.
|
||||
You can overide these operators as follows:
|
||||
<code>
|
||||
\code
|
||||
bool T::operator>(const T& other) const {
|
||||
return ...;
|
||||
}
|
||||
bool T::operator<(const T& other) const {
|
||||
return ...;
|
||||
}
|
||||
</code>
|
||||
\endcode
|
||||
*/
|
||||
void sort(int direction = SORT_INCREASING) {
|
||||
if (direction == SORT_INCREASING) {
|
||||
@@ -1053,7 +1216,7 @@ return( lhs < rhs? true : false );
|
||||
// Form a table of buckets for lt, eq, and gt
|
||||
Array<T>* bucket[3] = {<Array, &eqArray, >Array};
|
||||
|
||||
for (int i = 0; i < num; ++i) {
|
||||
for (size_t i = 0; i < num; ++i) {
|
||||
int c = comparator(partitionElement, data[i]);
|
||||
debugAssertM(c >= -1 && c <= 1, "Comparator returned an illegal value.");
|
||||
|
||||
@@ -1236,6 +1399,8 @@ return( lhs < rhs? true : false );
|
||||
medianPartition(ltMedian, eqMedian, gtMedian, temp, DefaultComparator());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/** Redistributes the elements so that the new order is statistically independent
|
||||
of the original order. O(n) time.*/
|
||||
@@ -1252,6 +1417,35 @@ return( lhs < rhs? true : false );
|
||||
}
|
||||
|
||||
|
||||
/** Ensures that future append() calls can grow up to size \a n without allocating memory.*/
|
||||
void reserve(int n) {
|
||||
debugAssert(n >= size());
|
||||
const int oldSize = size();
|
||||
resize(n);
|
||||
resize(oldSize, false);
|
||||
}
|
||||
|
||||
/** Number of bytes used by the array object and the memory allocated for it's data pointer. Does *not*
|
||||
* include the memory of objects pointed to by objects in the data array */
|
||||
size_t sizeInMemory() const {
|
||||
return sizeof(Array<T>) + (sizeof(T) * numAllocated);
|
||||
}
|
||||
|
||||
/** Remove all NULL elements in linear time without affecting order of the other elements. */
|
||||
void removeNulls() {
|
||||
int nextNull = 0;
|
||||
for (int i = 0; i < size(); ++i) {
|
||||
if (notNull(data[i])) {
|
||||
if (i > nextNull) {
|
||||
// Move value i down to squeeze out NULLs
|
||||
data[nextNull] = data[i];
|
||||
}
|
||||
++nextNull;
|
||||
}
|
||||
}
|
||||
|
||||
resize(nextNull, false);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
68
deps/g3dlite/include/G3D/AtomicInt32.h
vendored
68
deps/g3dlite/include/G3D/AtomicInt32.h
vendored
@@ -28,7 +28,7 @@ namespace G3D {
|
||||
*/
|
||||
class AtomicInt32 {
|
||||
private:
|
||||
# if defined(G3D_WIN32)
|
||||
# if defined(G3D_WINDOWS)
|
||||
volatile long m_value;
|
||||
# elif defined(G3D_OSX)
|
||||
int32_t m_value;
|
||||
@@ -70,18 +70,22 @@ public:
|
||||
|
||||
/** Returns the old value, before the add. */
|
||||
int32 add(const int32 x) {
|
||||
# if defined(G3D_WIN32)
|
||||
# if defined(G3D_WINDOWS)
|
||||
|
||||
return InterlockedExchangeAdd(&m_value, x);
|
||||
|
||||
# elif defined(G3D_LINUX) || defined(G3D_FREEBSD)
|
||||
|
||||
int32 old;
|
||||
asm volatile ("lock; xaddl %0,%1"
|
||||
: "=r"(old), "=m"(m_value) /* outputs */
|
||||
: "0"(x), "m"(m_value) /* inputs */
|
||||
: "memory", "cc");
|
||||
return old;
|
||||
# if defined(__aarch64__)
|
||||
return __sync_fetch_and_add(&m_value, x);
|
||||
# else
|
||||
int32 old;
|
||||
asm volatile ("lock; xaddl %0,%1"
|
||||
: "=r"(old), "=m"(m_value) /* outputs */
|
||||
: "0"(x), "m"(m_value) /* inputs */
|
||||
: "memory", "cc");
|
||||
return old;
|
||||
# endif
|
||||
|
||||
# elif defined(G3D_OSX)
|
||||
|
||||
@@ -98,7 +102,7 @@ public:
|
||||
}
|
||||
|
||||
void increment() {
|
||||
# if defined(G3D_WIN32)
|
||||
# if defined(G3D_WINDOWS)
|
||||
// Note: returns the newly incremented value
|
||||
InterlockedIncrement(&m_value);
|
||||
# elif defined(G3D_LINUX) || defined(G3D_FREEBSD)
|
||||
@@ -111,18 +115,22 @@ public:
|
||||
|
||||
/** Returns zero if the result is zero after decrement, non-zero otherwise.*/
|
||||
int32 decrement() {
|
||||
# if defined(G3D_WIN32)
|
||||
# if defined(G3D_WINDOWS)
|
||||
// Note: returns the newly decremented value
|
||||
return InterlockedDecrement(&m_value);
|
||||
# elif defined(G3D_LINUX) || defined(G3D_FREEBSD)
|
||||
unsigned char nz;
|
||||
# if defined(__aarch64__)
|
||||
return __sync_sub_and_fetch(&m_value, 1);
|
||||
# else
|
||||
unsigned char nz;
|
||||
|
||||
asm volatile ("lock; decl %1;\n\t"
|
||||
"setnz %%al"
|
||||
: "=a" (nz)
|
||||
: "m" (m_value)
|
||||
: "memory", "cc");
|
||||
return nz;
|
||||
asm volatile ("lock; decl %1;\n\t"
|
||||
"setnz %%al"
|
||||
: "=a" (nz)
|
||||
: "m" (m_value)
|
||||
: "memory", "cc");
|
||||
return nz;
|
||||
# endif
|
||||
# elif defined(G3D_OSX)
|
||||
// Note: returns the newly decremented value
|
||||
return OSAtomicDecrement32(&m_value);
|
||||
@@ -140,20 +148,24 @@ public:
|
||||
Under VC6 the sign bit may be lost.
|
||||
*/
|
||||
int32 compareAndSet(const int32 comperand, const int32 exchange) {
|
||||
# if defined(G3D_WIN32)
|
||||
# if defined(G3D_WINDOWS)
|
||||
return InterlockedCompareExchange(&m_value, exchange, comperand);
|
||||
# elif defined(G3D_LINUX) || defined(G3D_FREEBSD) || defined(G3D_OSX)
|
||||
// Based on Apache Portable Runtime
|
||||
// http://koders.com/c/fid3B6631EE94542CDBAA03E822CA780CBA1B024822.aspx
|
||||
int32 ret;
|
||||
asm volatile ("lock; cmpxchgl %1, %2"
|
||||
: "=a" (ret)
|
||||
: "r" (exchange), "m" (m_value), "0"(comperand)
|
||||
: "memory", "cc");
|
||||
return ret;
|
||||
# if defined(__aarch64__)
|
||||
return __sync_val_compare_and_swap(&m_value, comperand, exchange);
|
||||
# else
|
||||
// Based on Apache Portable Runtime
|
||||
// http://koders.com/c/fid3B6631EE94542CDBAA03E822CA780CBA1B024822.aspx
|
||||
int32 ret;
|
||||
asm volatile ("lock; cmpxchgl %1, %2"
|
||||
: "=a" (ret)
|
||||
: "r" (exchange), "m" (m_value), "0"(comperand)
|
||||
: "memory", "cc");
|
||||
return ret;
|
||||
|
||||
// Note that OSAtomicCompareAndSwap32 does not return a useful value for us
|
||||
// so it can't satisfy the cmpxchgl contract.
|
||||
// Note that OSAtomicCompareAndSwap32 does not return a useful value for us
|
||||
// so it can't satisfy the cmpxchgl contract.
|
||||
# endif
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
92
deps/g3dlite/include/G3D/BIN.h
vendored
Normal file
92
deps/g3dlite/include/G3D/BIN.h
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
#ifndef G3D_BIN_h
|
||||
#define G3D_BIN_h
|
||||
|
||||
#define _BIT(N, K) (((N >> (3*K)) & 1) << K)
|
||||
|
||||
#define _OCT_CODED_BIN(N) \
|
||||
(_BIT(N, 0) | _BIT(N, 1) | _BIT(N, 2) | _BIT(N, 3) | \
|
||||
_BIT(N, 4) | _BIT(N, 5) | _BIT(N, 6) | _BIT(N, 7) | \
|
||||
_BIT(N, | _BIT(N, 9) | _BIT(N, 10))
|
||||
|
||||
/**
|
||||
\def BIN11()
|
||||
|
||||
\brief Create a binary constant up to 11 digits long at compile time.
|
||||
|
||||
\code
|
||||
int i = BIN(01100101001)
|
||||
\endcode
|
||||
|
||||
\cite By Kaz Kylheku http://www.velocityreviews.com/forums/t620780-mathew-hendrys-macro-for-binary-integer-literals.html
|
||||
\sa BIN8(), BIN11(), BIN16(), BIN32()
|
||||
*/
|
||||
#define BIN11(N) _OCT_CODED_BIN(0 ## N ## UL)
|
||||
|
||||
|
||||
|
||||
/* turn a numeric literal into a hex constant
|
||||
(avoids problems with leading zeroes)
|
||||
8-bit constants max value 0x11111111, always fits in unsigned long
|
||||
*/
|
||||
#define HEX__(n) 0x##n##LU
|
||||
|
||||
/* 8-bit conversion function */
|
||||
#define B8__(x) ((x&0x0000000FLU)?1:0) \
|
||||
+((x&0x000000F0LU)?2:0) \
|
||||
+((x&0x00000F00LU)?4:0) \
|
||||
+((x&0x0000F000LU)?8:0) \
|
||||
+((x&0x000F0000LU)?16:0) \
|
||||
+((x&0x00F00000LU)?32:0) \
|
||||
+((x&0x0F000000LU)?64:0) \
|
||||
+((x&0xF0000000LU)?128:0)
|
||||
|
||||
/**
|
||||
\def BIN8()
|
||||
\brief Generate a 16-bit constant in binary notation, in 8-bit strings.
|
||||
|
||||
The most significant byte is first.
|
||||
|
||||
\code
|
||||
unsigned int i = BIN8(01010101); // 85
|
||||
\endcode
|
||||
|
||||
\cite Tom Torfs http://groups.google.com/group/comp.arch.embedded/msg/9d430b6d3da12c8f
|
||||
\sa BIN8(), BIN11(), BIN16(), BIN32()
|
||||
*/
|
||||
#define BIN8(d) ((unsigned char)B8__(HEX__(d)))
|
||||
|
||||
/** \def BIN16()
|
||||
\brief Generate a 16-bit constant in binary notation, in 8-bit strings.
|
||||
|
||||
The most significant byte is first.
|
||||
|
||||
\code
|
||||
unsigned int i = BIN16(10101010,01010101); // 43605
|
||||
\endcode
|
||||
|
||||
\cite Tom Torfs http://groups.google.com/group/comp.arch.embedded/msg/9d430b6d3da12c8f
|
||||
\sa BIN8(), BIN11(), BIN16(), BIN32()
|
||||
*/
|
||||
#define BIN16(dmsb, dlsb) (((unsigned short)BIN8(dmsb) << 8) + BIN8(dlsb))
|
||||
|
||||
|
||||
/**
|
||||
\def BIN32()
|
||||
\brief Generate a 32-bit constant in binary notation, in 8-bit strings.
|
||||
|
||||
The most significant byte is first.
|
||||
|
||||
\code
|
||||
unsigned int = BIN32(10000000,11111111,10101010,01010101); // 2164238933
|
||||
\endcode
|
||||
|
||||
\cite Tom Torfs http://groups.google.com/group/comp.arch.embedded/msg/9d430b6d3da12c8f
|
||||
\sa BIN8(), BIN11(), BIN16(), BIN32()
|
||||
*/
|
||||
#define BIN32(dmsb,db2,db3,dlsb) \
|
||||
(((unsigned long)BIN8(dmsb) << 24) + \
|
||||
((unsigned long)BIN8(db2) << 16) + \
|
||||
((unsigned long)BIN8(db3) << 8) + \
|
||||
BIN8(dlsb))
|
||||
|
||||
#endif
|
||||
128
deps/g3dlite/include/G3D/BinaryInput.h
vendored
128
deps/g3dlite/include/G3D/BinaryInput.h
vendored
@@ -1,12 +1,12 @@
|
||||
/**
|
||||
@file BinaryInput.h
|
||||
\file G3D/BinaryInput.h
|
||||
|
||||
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
\maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
|
||||
@created 2001-08-09
|
||||
@edited 2010-03-19
|
||||
\created 2001-08-09
|
||||
\edited 2013-01-03
|
||||
|
||||
Copyright 2000-2010, Morgan McGuire.
|
||||
Copyright 2000-2012, Morgan McGuire.
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include "G3D/platform.h"
|
||||
#include "G3D/unorm8.h"
|
||||
#include "G3D/Array.h"
|
||||
#include "G3D/Color4.h"
|
||||
#include "G3D/Color3.h"
|
||||
@@ -39,7 +40,7 @@
|
||||
|
||||
namespace G3D {
|
||||
|
||||
#if defined(G3D_WIN32) || defined(G3D_LINUX)
|
||||
#if defined(G3D_WINDOWS) || defined(G3D_LINUX)
|
||||
// Allow writing of integers to non-word aligned locations.
|
||||
// This is legal on x86, but not on other platforms.
|
||||
#define G3D_ALLOW_UNALIGNED_WRITES
|
||||
@@ -69,8 +70,15 @@ class BinaryInput {
|
||||
private:
|
||||
|
||||
// The initial buffer will be no larger than this, but
|
||||
// may grow if a large memory read occurs. 50 MB
|
||||
enum {INITIAL_BUFFER_LENGTH = 50000000};
|
||||
// may grow if a large memory read occurs. 750 MB
|
||||
static const int64
|
||||
INITIAL_BUFFER_LENGTH =
|
||||
#ifdef G3D_64BIT
|
||||
5000000000L // 5 GB
|
||||
#else
|
||||
750000000 // 750 MB
|
||||
#endif
|
||||
;
|
||||
|
||||
/**
|
||||
is the file big or little endian
|
||||
@@ -94,6 +102,7 @@ private:
|
||||
|
||||
/** When operating on huge files, we cannot load the whole file into memory.
|
||||
This is the file position to which buffer[0] corresponds.
|
||||
Even 32-bit code can load 64-bit files in chunks, so this is not size_t
|
||||
*/
|
||||
int64 m_alreadyRead;
|
||||
|
||||
@@ -122,14 +131,8 @@ private:
|
||||
void loadIntoMemory(int64 startPosition, int64 minLength = 0);
|
||||
|
||||
/** Verifies that at least this number of bytes can be read.*/
|
||||
inline void prepareToRead(int64 nbytes) {
|
||||
debugAssertM(m_length > 0, m_filename + " not found or corrupt.");
|
||||
debugAssertM(m_pos + nbytes + m_alreadyRead <= m_length, "Read past end of file.");
|
||||
void prepareToRead(int64 nbytes);
|
||||
|
||||
if (m_pos + nbytes > m_bufferLength) {
|
||||
loadIntoMemory(m_pos + m_alreadyRead, nbytes);
|
||||
}
|
||||
}
|
||||
|
||||
// Not implemented on purpose, don't use
|
||||
BinaryInput(const BinaryInput&);
|
||||
@@ -165,6 +168,7 @@ public:
|
||||
|
||||
To decompress part of a file, you can follow the following paradigm:
|
||||
|
||||
\htmlonly
|
||||
<PRE>
|
||||
BinaryInput master(...);
|
||||
|
||||
@@ -176,6 +180,7 @@ public:
|
||||
|
||||
// Now read from subset (it is ok for master to go out of scope)
|
||||
</PRE>
|
||||
\endhtmlonly
|
||||
*/
|
||||
BinaryInput(
|
||||
const uint8* data,
|
||||
@@ -199,24 +204,13 @@ public:
|
||||
return m_filename;
|
||||
}
|
||||
|
||||
/**
|
||||
Returns a pointer to the internal memory buffer.
|
||||
May throw an exception for huge files.
|
||||
*/
|
||||
const uint8* getCArray() const {
|
||||
if (m_alreadyRead > 0) {
|
||||
throw "Cannot getCArray for a huge file";
|
||||
}
|
||||
return m_buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
Performs bounds checks in debug mode. [] are relative to
|
||||
the start of the file, not the current position.
|
||||
Seeks to the new position before reading (and leaves
|
||||
that as the current position)
|
||||
*/
|
||||
inline uint8 operator[](int64 n) {
|
||||
uint8 operator[](int64 n) {
|
||||
setPosition(n);
|
||||
return readUInt8();
|
||||
}
|
||||
@@ -224,11 +218,11 @@ public:
|
||||
/**
|
||||
Returns the length of the file in bytes.
|
||||
*/
|
||||
inline int64 getLength() const {
|
||||
int64 getLength() const {
|
||||
return m_length;
|
||||
}
|
||||
|
||||
inline int64 size() const {
|
||||
int64 size() const {
|
||||
return getLength();
|
||||
}
|
||||
|
||||
@@ -236,15 +230,26 @@ public:
|
||||
Returns the current byte position in the file,
|
||||
where 0 is the beginning and getLength() - 1 is the end.
|
||||
*/
|
||||
inline int64 getPosition() const {
|
||||
int64 getPosition() const {
|
||||
return m_pos + m_alreadyRead;
|
||||
}
|
||||
|
||||
/**
|
||||
Returns a pointer to the internal memory buffer.
|
||||
May throw an exception for huge files.
|
||||
*/
|
||||
const uint8* getCArray() {
|
||||
if (m_alreadyRead > 0 || m_bufferLength < m_length) {
|
||||
throw "Cannot getCArray for a huge file";
|
||||
}
|
||||
return m_buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
Sets the position. Cannot set past length.
|
||||
May throw a char* when seeking backwards more than 10 MB on a huge file.
|
||||
*/
|
||||
inline void setPosition(int64 p) {
|
||||
void setPosition(int64 p) {
|
||||
debugAssertM(p <= m_length, "Read past end of file");
|
||||
m_pos = p - m_alreadyRead;
|
||||
if ((m_pos < 0) || (m_pos > m_bufferLength)) {
|
||||
@@ -255,25 +260,31 @@ public:
|
||||
/**
|
||||
Goes back to the beginning of the file.
|
||||
*/
|
||||
inline void reset() {
|
||||
void reset() {
|
||||
setPosition(0);
|
||||
}
|
||||
|
||||
inline int8 readInt8() {
|
||||
void readBytes(void* bytes, int64 n);
|
||||
|
||||
int8 readInt8() {
|
||||
prepareToRead(1);
|
||||
return m_buffer[m_pos++];
|
||||
}
|
||||
|
||||
inline bool readBool8() {
|
||||
|
||||
bool readBool8() {
|
||||
return (readInt8() != 0);
|
||||
}
|
||||
|
||||
inline uint8 readUInt8() {
|
||||
|
||||
uint8 readUInt8() {
|
||||
prepareToRead(1);
|
||||
return ((uint8*)m_buffer)[m_pos++];
|
||||
}
|
||||
|
||||
unorm8 readUNorm8() {
|
||||
return unorm8::fromBits(readUInt8());
|
||||
}
|
||||
|
||||
uint16 inline readUInt16() {
|
||||
uint16 readUInt16() {
|
||||
prepareToRead(2);
|
||||
|
||||
m_pos += 2;
|
||||
@@ -295,12 +306,12 @@ public:
|
||||
|
||||
}
|
||||
|
||||
inline int16 readInt16() {
|
||||
int16 readInt16() {
|
||||
uint16 a = readUInt16();
|
||||
return *(int16*)&a;
|
||||
}
|
||||
|
||||
inline uint32 readUInt32() {
|
||||
uint32 readUInt32() {
|
||||
prepareToRead(4);
|
||||
|
||||
m_pos += 4;
|
||||
@@ -326,19 +337,19 @@ public:
|
||||
}
|
||||
|
||||
|
||||
inline int32 readInt32() {
|
||||
int32 readInt32() {
|
||||
uint32 a = readUInt32();
|
||||
return *(int32*)&a;
|
||||
}
|
||||
|
||||
uint64 readUInt64();
|
||||
|
||||
inline int64 readInt64() {
|
||||
int64 readInt64() {
|
||||
uint64 a = readUInt64();
|
||||
return *(int64*)&a;
|
||||
}
|
||||
|
||||
inline float32 readFloat32() {
|
||||
float32 readFloat32() {
|
||||
union {
|
||||
uint32 a;
|
||||
float32 b;
|
||||
@@ -347,7 +358,7 @@ public:
|
||||
return b;
|
||||
}
|
||||
|
||||
inline float64 readFloat64() {
|
||||
float64 readFloat64() {
|
||||
union {
|
||||
uint64 a;
|
||||
float64 b;
|
||||
@@ -356,31 +367,34 @@ public:
|
||||
return b;
|
||||
}
|
||||
|
||||
void readBytes(void* bytes, int64 n);
|
||||
|
||||
/**
|
||||
Reads an n character string. The string is not
|
||||
required to end in NULL in the file but will
|
||||
always be a proper std::string when returned.
|
||||
Always consumes \a maxLength characters. Reads a string until NULL or \a maxLength characters. Does not require NULL termination.
|
||||
*/
|
||||
std::string readString(int64 n);
|
||||
std::string readString(int64 maxLength);
|
||||
|
||||
/**
|
||||
Reads until NULL or the end of the file is encountered.
|
||||
Reads a string until NULL or end of file.
|
||||
*/
|
||||
std::string readString();
|
||||
|
||||
/** Reads until \r, \r\n, \n\r, \n or the end of the file is encountered. Consumes the newline.*/
|
||||
/** Read a string (which may contain NULLs) of exactly numBytes bytes, including the final terminator if there is one. If there is a NULL in the string before
|
||||
the end, then only the part up to the first NULL is returned although all bytes are read.*/
|
||||
std::string readFixedLengthString(int numBytes);
|
||||
|
||||
/**
|
||||
Reads a string until NULL, newline ("\r", "\n", "\r\n", "\n\r") or the end of the file is encountered. Consumes the newline.
|
||||
*/
|
||||
std::string readStringNewline();
|
||||
|
||||
/**
|
||||
Reads until NULL or the end of the file is encountered.
|
||||
If the string has odd length (including NULL), reads
|
||||
another byte.
|
||||
another byte. This is a common format for 16-bit alignment
|
||||
in files.
|
||||
*/
|
||||
std::string readStringEven();
|
||||
|
||||
|
||||
/** Reads a uint32 and then calls readString(maxLength) with that value as the length. */
|
||||
std::string readString32();
|
||||
|
||||
Vector4 readVector4();
|
||||
@@ -393,15 +407,15 @@ public:
|
||||
/**
|
||||
Skips ahead n bytes.
|
||||
*/
|
||||
inline void skip(int64 n) {
|
||||
void skip(int64 n) {
|
||||
setPosition(m_pos + m_alreadyRead + n);
|
||||
}
|
||||
|
||||
/**
|
||||
Returns true if the position is not at the end of the file
|
||||
*/
|
||||
inline bool hasMore() const {
|
||||
return m_pos + m_alreadyRead < m_length;
|
||||
bool hasMore() const {
|
||||
return m_pos + m_alreadyRead < m_length;
|
||||
}
|
||||
|
||||
/** Prepares for bit reading via readBits. Only readBits can be
|
||||
|
||||
94
deps/g3dlite/include/G3D/BinaryOutput.h
vendored
94
deps/g3dlite/include/G3D/BinaryOutput.h
vendored
@@ -1,17 +1,17 @@
|
||||
/**
|
||||
@file BinaryOutput.h
|
||||
\file G3D/BinaryOutput.h
|
||||
|
||||
@maintainer Morgan McGuire, graphics3d.com
|
||||
\maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
|
||||
@created 2001-08-09
|
||||
@edited 2008-01-24
|
||||
\created 2001-08-09
|
||||
\edited 2011-08-24
|
||||
|
||||
Copyright 2000-2006, Morgan McGuire.
|
||||
Copyright 2000-2012, Morgan McGuire.
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef G3D_BINARYOUTPUT_H
|
||||
#define G3D_BINARYOUTPUT_H
|
||||
#ifndef G3D_BinaryOutput_h
|
||||
#define G3D_BinaryOutput_h
|
||||
|
||||
#include "G3D/platform.h"
|
||||
#include <assert.h>
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include "G3D/unorm8.h"
|
||||
#include "G3D/Color4.h"
|
||||
#include "G3D/Color3.h"
|
||||
#include "G3D/Vector4.h"
|
||||
@@ -73,19 +74,19 @@ private:
|
||||
uint8* m_buffer;
|
||||
|
||||
/** Size of the elements used */
|
||||
int m_bufferLen;
|
||||
size_t m_bufferLen;
|
||||
|
||||
/** Underlying size of memory allocaded */
|
||||
int m_maxBufferLen;
|
||||
size_t m_maxBufferLen;
|
||||
|
||||
/** Next byte in file */
|
||||
int m_pos;
|
||||
int64 m_pos;
|
||||
|
||||
/** is this initialized? */
|
||||
bool m_init;
|
||||
|
||||
/** Number of bytes already written to the file.*/
|
||||
size_t m_alreadyWritten;
|
||||
/** Number of bytes already written to the file. Even on 32-bit OS, this can be 64-bits*/
|
||||
int64 m_alreadyWritten;
|
||||
|
||||
bool m_ok;
|
||||
|
||||
@@ -97,11 +98,11 @@ private:
|
||||
Make sure at least bytes can be written, resizing if
|
||||
necessary.
|
||||
*/
|
||||
inline void reserveBytes(int bytes) {
|
||||
inline void reserveBytes(size_t bytes) {
|
||||
debugAssert(bytes > 0);
|
||||
size_t oldBufferLen = (size_t)m_bufferLen;
|
||||
size_t oldBufferLen = m_bufferLen;
|
||||
|
||||
m_bufferLen = iMax(m_bufferLen, (m_pos + bytes));
|
||||
m_bufferLen = max(m_bufferLen, (size_t)(m_pos + bytes));
|
||||
if (m_bufferLen > m_maxBufferLen) {
|
||||
reallocBuffer(bytes, oldBufferLen);
|
||||
}
|
||||
@@ -138,8 +139,10 @@ public:
|
||||
|
||||
Cannot be used for huge files (ones where the data
|
||||
was already written to disk)-- will throw char*.
|
||||
|
||||
\param level Compression level. 0 = fast, low compression; 9 = slow, high compression
|
||||
*/
|
||||
void compress();
|
||||
void compress(int level = 9);
|
||||
|
||||
/** True if no errors have been encountered.*/
|
||||
bool ok() const;
|
||||
@@ -190,11 +193,11 @@ public:
|
||||
void reset();
|
||||
|
||||
|
||||
inline int length() const {
|
||||
return (int)m_bufferLen + (int)m_alreadyWritten;
|
||||
inline int64 length() const {
|
||||
return m_bufferLen + m_alreadyWritten;
|
||||
}
|
||||
|
||||
inline int size() const {
|
||||
inline int64 size() const {
|
||||
return length();
|
||||
}
|
||||
|
||||
@@ -207,18 +210,18 @@ public:
|
||||
Throws char* when resetting a huge file to be shorter
|
||||
than its current length.
|
||||
*/
|
||||
inline void setLength(int n) {
|
||||
n = n - (int)m_alreadyWritten;
|
||||
inline void setLength(int64 n) {
|
||||
n = n - m_alreadyWritten;
|
||||
|
||||
if (n < 0) {
|
||||
throw "Cannot resize huge files to be shorter.";
|
||||
}
|
||||
|
||||
if (n < m_bufferLen) {
|
||||
if (n < (int64)m_bufferLen) {
|
||||
m_pos = n;
|
||||
}
|
||||
if (n > m_bufferLen) {
|
||||
reserveBytes(n - m_bufferLen);
|
||||
if (n > (int64)m_bufferLen) {
|
||||
reserveBytes((size_t)(n - m_bufferLen));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -227,7 +230,7 @@ public:
|
||||
where 0 is the beginning and getLength() - 1 is the end.
|
||||
*/
|
||||
inline int64 position() const {
|
||||
return (int64)m_pos + (int64)m_alreadyWritten;
|
||||
return m_pos + m_alreadyWritten;
|
||||
}
|
||||
|
||||
|
||||
@@ -239,9 +242,9 @@ public:
|
||||
May throw a char* exception when seeking backwards on a huge file.
|
||||
*/
|
||||
inline void setPosition(int64 p) {
|
||||
p = p - (int64)m_alreadyWritten;
|
||||
p = p - m_alreadyWritten;
|
||||
|
||||
if (p > m_bufferLen) {
|
||||
if (p > (int64)m_bufferLen) {
|
||||
setLength((int)(p + (int64)m_alreadyWritten));
|
||||
}
|
||||
|
||||
@@ -253,9 +256,9 @@ public:
|
||||
}
|
||||
|
||||
|
||||
void writeBytes(
|
||||
const void* b,
|
||||
int count) {
|
||||
void writeBytes
|
||||
(const void* b,
|
||||
size_t count) {
|
||||
|
||||
reserveBytes(count);
|
||||
debugAssert(m_pos >= 0);
|
||||
@@ -270,7 +273,7 @@ public:
|
||||
inline void writeInt8(int8 i) {
|
||||
reserveBytes(1);
|
||||
m_buffer[m_pos] = *(uint8*)&i;
|
||||
m_pos++;
|
||||
++m_pos;
|
||||
}
|
||||
|
||||
inline void writeBool8(bool b) {
|
||||
@@ -280,7 +283,11 @@ public:
|
||||
inline void writeUInt8(uint8 i) {
|
||||
reserveBytes(1);
|
||||
m_buffer[m_pos] = i;
|
||||
m_pos++;
|
||||
++m_pos;
|
||||
}
|
||||
|
||||
inline void writeUNorm8(unorm8 i) {
|
||||
writeUInt8(i.bits());
|
||||
}
|
||||
|
||||
void writeUInt16(uint16 u);
|
||||
@@ -328,6 +335,20 @@ public:
|
||||
writeString(s.c_str());
|
||||
}
|
||||
|
||||
/** Write a string that always consumes len bytes, truncating or padding as necessary*/
|
||||
inline void writeString(const std::string& s, int len) {
|
||||
const int pad = len - ((int)s.length() + 1);
|
||||
if (pad >= 0) {
|
||||
writeString(s.c_str());
|
||||
for (int i = 0; i < pad; ++i) {
|
||||
writeUInt8(0);
|
||||
}
|
||||
} else {
|
||||
// Truncate
|
||||
writeBytes(s.c_str(), len);
|
||||
}
|
||||
}
|
||||
|
||||
void writeString(const char* s);
|
||||
|
||||
/**
|
||||
@@ -340,12 +361,11 @@ public:
|
||||
|
||||
void writeStringEven(const char* s);
|
||||
|
||||
|
||||
void writeString32(const char* s);
|
||||
|
||||
/**
|
||||
Write a string with a 32-bit length field in front
|
||||
of it.
|
||||
Write a NULL-terminated string with a 32-bit length field in front
|
||||
of it. The NULL character is included in the length count.
|
||||
*/
|
||||
void writeString32(const std::string& s) {
|
||||
writeString32(s.c_str());
|
||||
@@ -365,8 +385,8 @@ public:
|
||||
Skips ahead n bytes.
|
||||
*/
|
||||
inline void skip(int n) {
|
||||
if (m_pos + n > m_bufferLen) {
|
||||
setLength((int)m_pos + (int)m_alreadyWritten + n);
|
||||
if (m_pos + n > (int64)m_bufferLen) {
|
||||
setLength(m_pos + m_alreadyWritten + n);
|
||||
}
|
||||
m_pos += n;
|
||||
}
|
||||
|
||||
158
deps/g3dlite/include/G3D/Box.h
vendored
158
deps/g3dlite/include/G3D/Box.h
vendored
@@ -1,20 +1,20 @@
|
||||
/**
|
||||
@file Box.h
|
||||
\file G3D/Box.h
|
||||
|
||||
Box class
|
||||
|
||||
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
\maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
|
||||
@cite Portions based on Dave Eberly's Magic Software Library at <A HREF="http://www.magic-software.com">http://www.magic-software.com</A>
|
||||
@created 2001-06-02
|
||||
@edited 2007-06-05
|
||||
\cite Portions based on Dave Eberly's Magic Software Library at <A HREF="http://www.magic-software.com">http://www.magic-software.com</A>
|
||||
\created 2001-06-02
|
||||
\edited 2013-04-13
|
||||
|
||||
Copyright 2000-2006, Morgan McGuire.
|
||||
Copyright 2000-2013, Morgan McGuire.
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef G3D_BOX_H
|
||||
#define G3D_BOX_H
|
||||
#ifndef G3D_Box_h
|
||||
#define G3D_Box_h
|
||||
|
||||
#include "G3D/platform.h"
|
||||
#include "G3D/Vector3.h"
|
||||
@@ -24,13 +24,12 @@
|
||||
namespace G3D {
|
||||
|
||||
class CoordinateFrame;
|
||||
class Any;
|
||||
|
||||
/**
|
||||
An arbitrary 3D box, useful as a bounding box.
|
||||
|
||||
|
||||
To construct a box from a coordinate frame, center and extent, use the idiom:
|
||||
\brief An arbitrary (oriented) 3D box, useful as a bounding box.
|
||||
|
||||
To construct a box from a coordinate frame, center and extent, use the idiom:
|
||||
<CODE>Box box = cframe.toObjectSpace(Box(center - extent/2, center + extent/2));</CODE>
|
||||
*/
|
||||
class Box {
|
||||
@@ -41,29 +40,14 @@ private:
|
||||
friend class CoordinateFrame;
|
||||
|
||||
/**
|
||||
<PRE>
|
||||
3 2 7 6
|
||||
|
||||
0 1 4 5
|
||||
|
||||
front back (seen through front)
|
||||
</PRE>
|
||||
Axes with length equal to the 4 edges that run along each of them
|
||||
*/
|
||||
Vector3 _corner[8];
|
||||
|
||||
/**
|
||||
Unit axes.
|
||||
*/
|
||||
Vector3 _axis[3];
|
||||
Vector3 _edgeVector[3];
|
||||
|
||||
Vector3 _center;
|
||||
|
||||
/**
|
||||
Extent along each axis.
|
||||
*/
|
||||
Vector3 _extent;
|
||||
Point3 _center;
|
||||
|
||||
float _area;
|
||||
|
||||
float _volume;
|
||||
|
||||
void init(
|
||||
@@ -72,38 +56,47 @@ private:
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
Does not initialize the fields.
|
||||
*/
|
||||
Box();
|
||||
|
||||
explicit Box(const Any& a);
|
||||
|
||||
/**
|
||||
Constructs a box from two opposite corners.
|
||||
*/
|
||||
Box(
|
||||
const Vector3& min,
|
||||
Box(const Vector3& min,
|
||||
const Vector3& max);
|
||||
|
||||
static Box inf();
|
||||
Box(const Vector3& osMin,
|
||||
const Vector3& osMax,
|
||||
const CoordinateFrame& frame);
|
||||
|
||||
Box(class BinaryInput& b);
|
||||
Box(class BinaryInput& b);
|
||||
|
||||
Box(const class AABox& b);
|
||||
|
||||
void serialize(class BinaryOutput& b) const;
|
||||
void deserialize(class BinaryInput& b);
|
||||
explicit Box(const Point3& p);
|
||||
|
||||
static Box inf();
|
||||
|
||||
Any toAny() const;
|
||||
|
||||
void serialize(class BinaryOutput& b) const;
|
||||
void deserialize(class BinaryInput& b);
|
||||
|
||||
/**
|
||||
Returns the object to world transformation for
|
||||
this box. localFrame().worldToObject(...) takes
|
||||
this box, where the origin is the center of the box. localFrame().worldToObject(...) takes
|
||||
objects into the space where the box axes are
|
||||
(1,0,0), (0,1,0), (0,0,1). Note that there
|
||||
is no scaling in this transformation.
|
||||
*/
|
||||
CoordinateFrame localFrame() const;
|
||||
|
||||
/** \sa localFrame */
|
||||
void getLocalFrame(CoordinateFrame& frame) const;
|
||||
|
||||
Box operator*(float f) const;
|
||||
|
||||
/**
|
||||
Returns the centroid of the box.
|
||||
*/
|
||||
@@ -111,18 +104,39 @@ public:
|
||||
return _center;
|
||||
}
|
||||
|
||||
/**
|
||||
\htmlonly
|
||||
<PRE>
|
||||
|
||||
|
||||
inline Vector3 corner(int i) const {
|
||||
debugAssert(i < 8);
|
||||
return _corner[i];
|
||||
}
|
||||
2--------3
|
||||
/ : /|
|
||||
/ : / |
|
||||
6--------7 |
|
||||
| : | |
|
||||
| 0....|..1
|
||||
| / | /
|
||||
|/ |/
|
||||
4--------5
|
||||
|
||||
y
|
||||
^
|
||||
|
|
||||
|-->x
|
||||
z/
|
||||
|
||||
|
||||
</PRE>
|
||||
\endhtmlonly
|
||||
*/
|
||||
Vector3 corner(int i) const;
|
||||
|
||||
/**
|
||||
Unit length.
|
||||
*/
|
||||
inline Vector3 axis(int a) const {
|
||||
debugAssert(a < 3);
|
||||
return _axis[a];
|
||||
return _edgeVector[a].direction();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -131,17 +145,43 @@ public:
|
||||
*/
|
||||
inline float extent(int a) const {
|
||||
debugAssert(a < 3);
|
||||
return (float)_extent[a];
|
||||
return _edgeVector[a].length();
|
||||
}
|
||||
|
||||
inline Vector3 extent() const {
|
||||
return _extent;
|
||||
return Vector3(_edgeVector[0].length(), _edgeVector[1].length(), _edgeVector[2].length());
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the four corners of a face (0 <= f < 6).
|
||||
The corners are returned to form a counter clockwise quad facing outwards.
|
||||
*/
|
||||
The corners are returned to form a clockwise quad facing outwards.
|
||||
|
||||
|
||||
|
||||
+--------+
|
||||
/ : /|
|
||||
/ : / |
|
||||
+--------+ |
|
||||
| : | |
|
||||
| +....|..+
|
||||
| / | /
|
||||
|/ |/
|
||||
+--------+
|
||||
|
||||
y
|
||||
^
|
||||
|
|
||||
|-->x
|
||||
z/
|
||||
Faces are in the following order:
|
||||
0: -Z
|
||||
1: X
|
||||
2: Z
|
||||
3: Y
|
||||
4: -X
|
||||
5: -Y
|
||||
|
||||
*/
|
||||
void getFaceCorners(
|
||||
int f,
|
||||
Vector3& v0,
|
||||
@@ -150,24 +190,24 @@ public:
|
||||
Vector3& v3) const;
|
||||
|
||||
|
||||
/**
|
||||
/**
|
||||
See AABox::culledBy
|
||||
*/
|
||||
*/
|
||||
bool culledBy
|
||||
(
|
||||
const Array<Plane>& plane,
|
||||
int32& cullingPlaneIndex,
|
||||
const uint32 testMask,
|
||||
uint32& childMask) const;
|
||||
const Array<Plane>& plane,
|
||||
int32& cullingPlaneIndex,
|
||||
const uint32 testMask,
|
||||
uint32& childMask) const;
|
||||
|
||||
/**
|
||||
Conservative culling test that does not produce a mask for children.
|
||||
*/
|
||||
bool culledBy
|
||||
(
|
||||
const Array<Plane>& plane,
|
||||
int32& cullingPlaneIndex = dummy,
|
||||
const uint32 testMask = -1) const;
|
||||
const Array<Plane>& plane,
|
||||
int32& cullingPlaneIndex = dummy,
|
||||
const uint32 testMask = -1) const;
|
||||
|
||||
bool contains(
|
||||
const Vector3& point) const;
|
||||
|
||||
6
deps/g3dlite/include/G3D/BumpMapPreprocess.h
vendored
6
deps/g3dlite/include/G3D/BumpMapPreprocess.h
vendored
@@ -6,7 +6,7 @@
|
||||
\created 2010-01-28
|
||||
\edited 2010-01-28
|
||||
|
||||
Copyright 2000-2010, Morgan McGuire.
|
||||
Copyright 2000-2012, Morgan McGuire.
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
@@ -20,7 +20,7 @@ class Any;
|
||||
|
||||
/**
|
||||
Not in the BumpMap class to avoid a circular dependency between Texture and BumpMap.
|
||||
G3D::GImage::computeNormalMap().
|
||||
G3D::Image::computeNormalMap().
|
||||
*/
|
||||
class BumpMapPreprocess {
|
||||
public:
|
||||
@@ -46,7 +46,7 @@ public:
|
||||
|
||||
BumpMapPreprocess(const Any& any);
|
||||
|
||||
operator Any() const;
|
||||
Any toAny() const;
|
||||
|
||||
bool operator==(const BumpMapPreprocess& other) const {
|
||||
return
|
||||
|
||||
34
deps/g3dlite/include/G3D/Capsule.h
vendored
34
deps/g3dlite/include/G3D/Capsule.h
vendored
@@ -26,32 +26,32 @@ class AABox;
|
||||
*/
|
||||
class Capsule {
|
||||
private:
|
||||
Vector3 p1;
|
||||
Vector3 p2;
|
||||
Vector3 p1;
|
||||
Vector3 p2;
|
||||
|
||||
float _radius;
|
||||
float _radius;
|
||||
public:
|
||||
|
||||
|
||||
/** Uninitialized */
|
||||
Capsule();
|
||||
Capsule(class BinaryInput& b);
|
||||
Capsule(const Vector3& _p1, const Vector3& _p2, float _r);
|
||||
void serialize(class BinaryOutput& b) const;
|
||||
void deserialize(class BinaryInput& b);
|
||||
|
||||
/** The line down the center of the capsule */
|
||||
Line axis() const;
|
||||
Capsule(const Vector3& _p1, const Vector3& _p2, float _r);
|
||||
void serialize(class BinaryOutput& b) const;
|
||||
void deserialize(class BinaryInput& b);
|
||||
|
||||
/** The line down the center of the capsule */
|
||||
Line axis() const;
|
||||
|
||||
inline float radius() const {
|
||||
return _radius;
|
||||
}
|
||||
inline float radius() const {
|
||||
return _radius;
|
||||
}
|
||||
|
||||
/** Argument may be 0 or 1 */
|
||||
inline Vector3 point(int i) const {
|
||||
debugAssert(i == 0 || i == 1);
|
||||
return (i == 0) ? p1 : p2;
|
||||
}
|
||||
/** Argument may be 0 or 1 */
|
||||
inline Vector3 point(int i) const {
|
||||
debugAssert(i == 0 || i == 1);
|
||||
return (i == 0) ? p1 : p2;
|
||||
}
|
||||
|
||||
/** Distance between the sphere centers. The total extent of the cylinder is
|
||||
2r + h. */
|
||||
|
||||
1294
deps/g3dlite/include/G3D/CollisionDetection.h
vendored
1294
deps/g3dlite/include/G3D/CollisionDetection.h
vendored
File diff suppressed because it is too large
Load Diff
49
deps/g3dlite/include/G3D/Color1.h
vendored
49
deps/g3dlite/include/G3D/Color1.h
vendored
@@ -1,30 +1,29 @@
|
||||
/**
|
||||
@file Color1.h
|
||||
\file G3D/Color1.h
|
||||
|
||||
Monochrome Color class
|
||||
|
||||
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
@created 2007-01-31
|
||||
@edited 2009-03-20
|
||||
\maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
\created 2007-01-31
|
||||
\edited 2011-08-20
|
||||
|
||||
Copyright 2000-2009, Morgan McGuire.
|
||||
Copyright 2000-2012, Morgan McGuire.
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef G3D_COLOR1_H
|
||||
#define G3D_COLOR1_H
|
||||
#ifndef G3D_Color1_h
|
||||
#define G3D_Color1_h
|
||||
|
||||
#include "G3D/platform.h"
|
||||
#include "G3D/g3dmath.h"
|
||||
#include "G3D/unorm8.h"
|
||||
#include "G3D/HashTrait.h"
|
||||
#include <string>
|
||||
|
||||
namespace G3D {
|
||||
|
||||
/**
|
||||
Monochrome color. This is just a float, but it has nice semantics
|
||||
because a scaling by 255 automatically occurs when switching between
|
||||
fixed point (Color1uint8) and floating point (Color1) formats.
|
||||
Monochrome color.
|
||||
*/
|
||||
class Color1 {
|
||||
private:
|
||||
@@ -46,6 +45,9 @@ public:
|
||||
|
||||
inline explicit Color1(float v) : value(v) {
|
||||
}
|
||||
|
||||
inline explicit Color1(unorm8 v) : value(v) {
|
||||
}
|
||||
|
||||
inline bool isZero() const {
|
||||
return value == 0.0f;
|
||||
@@ -62,7 +64,7 @@ public:
|
||||
/** Returns the value three times */
|
||||
class Color3 rgb() const;
|
||||
|
||||
Color1 (const class Color1uint8& other);
|
||||
explicit Color1(const class Color1unorm8& other);
|
||||
|
||||
void serialize(class BinaryOutput& bo) const;
|
||||
void deserialize(class BinaryInput& bi);
|
||||
@@ -71,6 +73,7 @@ public:
|
||||
return Color1(value + other.value);
|
||||
}
|
||||
|
||||
/** \deprecated */
|
||||
Color1 operator+ (const float other) const {
|
||||
return Color1(value + other);
|
||||
}
|
||||
@@ -89,6 +92,7 @@ public:
|
||||
return Color1(value - other.value);
|
||||
}
|
||||
|
||||
/** \deprecated */
|
||||
Color1 operator- (const float other) const {
|
||||
return Color1(value - other);
|
||||
}
|
||||
@@ -101,6 +105,26 @@ public:
|
||||
return Color1(value * other.value);
|
||||
}
|
||||
|
||||
Color1& operator*=(const Color1 other) {
|
||||
value *= other.value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Color1& operator*=(const float other) {
|
||||
value *= other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Color1& operator/=(const float other) {
|
||||
value /= other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Color1& operator/=(const Color1 other) {
|
||||
value /= other.value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Color1 operator* (const float other) const {
|
||||
return Color1(value * other);
|
||||
}
|
||||
@@ -140,5 +164,8 @@ struct HashTrait<G3D::Color1> {
|
||||
}
|
||||
};
|
||||
|
||||
inline G3D::Color1 operator*(float f, G3D::Color1 c) {
|
||||
return c * f;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
87
deps/g3dlite/include/G3D/Color3.h
vendored
87
deps/g3dlite/include/G3D/Color3.h
vendored
@@ -1,16 +1,16 @@
|
||||
/**
|
||||
@file Color3.h
|
||||
\file Color3.h
|
||||
|
||||
Color class
|
||||
|
||||
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
@cite Portions based on Dave Eberly's Magic Software Library
|
||||
\maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
\cite Portions based on Dave Eberly's Magic Software Library
|
||||
at <A HREF="http://www.magic-software.com">http://www.magic-software.com</A>
|
||||
|
||||
@created 2001-06-02
|
||||
@edited 2009-04-28
|
||||
\created 2001-06-02
|
||||
\edited 2013-03-29
|
||||
|
||||
Copyright 2000-2009, Morgan McGuire.
|
||||
Copyright 2000-2013, Morgan McGuire.
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
@@ -40,26 +40,41 @@ private:
|
||||
|
||||
public:
|
||||
/**
|
||||
Does not initialize fields.
|
||||
\brief Initializes to all zero.
|
||||
*/
|
||||
Color3();
|
||||
Color3() : r(0), g(0), b(0) {}
|
||||
|
||||
bool nonZero() const {
|
||||
return (r != 0) || (g != 0) || (b != 0);
|
||||
}
|
||||
|
||||
/** \param any Must be in one of the following forms:
|
||||
- Color3(#, #, #)
|
||||
- Color3(#)
|
||||
- Color3::fromARGB(#)
|
||||
- Color3::fromASRGB(#)
|
||||
- Color3{r = #, g = #, b = #)
|
||||
- Color3::one()
|
||||
- Color3::zero()
|
||||
|
||||
In the current implementation, G3D::Power3, G3D::Radiance3,
|
||||
and G3D::Irradiance3 are typedefs for Color3, so Color3
|
||||
accepts "Power3" and "Radiance3" as a prefixes as well, e.g.,
|
||||
Power3(1,0,0).
|
||||
*/
|
||||
Color3(const Any& any);
|
||||
explicit Color3(const Any& any);
|
||||
|
||||
Color3& operator=(const Any& a);
|
||||
|
||||
/** Converts the Color3 to an Any. */
|
||||
operator Any() const;
|
||||
Any toAny() const;
|
||||
|
||||
explicit Color3(class BinaryInput& bi);
|
||||
|
||||
Color3(float r, float g, float b);
|
||||
Color3(float v) : r(v), g(v), b(v) {}
|
||||
|
||||
/** \brief Initializes all channels to \a v */
|
||||
explicit Color3(float v) : r(v), g(v), b(v) {}
|
||||
|
||||
explicit Color3(const class Vector3& v);
|
||||
|
||||
@@ -75,7 +90,7 @@ public:
|
||||
*/
|
||||
Color3 (const Color3& other);
|
||||
|
||||
Color3 (const class Color3uint8& other);
|
||||
Color3 (const class Color3unorm8& other);
|
||||
|
||||
inline bool isZero() const {
|
||||
return (r == 0.0f) && (g == 0.0f) && (b == 0.0f);
|
||||
@@ -92,6 +107,12 @@ public:
|
||||
*/
|
||||
static Color3 fromARGB(uint32);
|
||||
|
||||
/**
|
||||
Initialize from an HTML-style color (e.g. 0xFF0000 == RED) by converting from sRGB to RGB.
|
||||
|
||||
*/
|
||||
static Color3 fromASRGB(uint32);
|
||||
|
||||
/** Returns one of the color wheel colors (e.g. RED, GREEN, CYAN).
|
||||
Does not include white, black, or gray. */
|
||||
static const Color3& wheelRandom();
|
||||
@@ -140,10 +161,15 @@ public:
|
||||
inline Color3 operator* (float s) const {
|
||||
return Color3(r * s, g * s, b * s);
|
||||
}
|
||||
inline Color3 operator/ (const Color3& rkVector) const {
|
||||
return Color3(r / rkVector.r, g / rkVector.g, b / rkVector.b);
|
||||
}
|
||||
|
||||
Color3 operator* (const Color3& rkVector) const;
|
||||
inline Color3 operator/ (float fScalar) const {
|
||||
return (*this) * (1.0f / fScalar);
|
||||
}
|
||||
|
||||
Color3 operator- () const;
|
||||
|
||||
// arithmetic updates
|
||||
@@ -161,7 +187,7 @@ public:
|
||||
Color3 direction() const;
|
||||
float squaredLength () const;
|
||||
float dot (const Color3& rkVector) const;
|
||||
float unitize (float fTolerance = 1e-06);
|
||||
float unitize (float fTolerance = 1e-06f);
|
||||
Color3 cross (const Color3& rkVector) const;
|
||||
Color3 unitCross (const Color3& rkVector) const;
|
||||
|
||||
@@ -258,11 +284,11 @@ inline G3D::Color3 operator* (const G3D::Color3& c, G3D::Color1& s) {
|
||||
return c * s.value;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
inline Color3::Color3 () {
|
||||
inline G3D::Color3 operator/ (float s, const G3D::Color3& c) {
|
||||
return c * (1.0f/s);
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
inline Color3::Color3(float fX, float fY, float fZ) {
|
||||
@@ -414,11 +440,36 @@ inline Color3 Color3::cross (const Color3& rkVector) const {
|
||||
inline Color3 Color3::unitCross (const Color3& rkVector) const {
|
||||
Color3 kCross(g*rkVector.b - b*rkVector.g, b*rkVector.r - r*rkVector.b,
|
||||
r*rkVector.g - g*rkVector.r);
|
||||
kCross.unitize();
|
||||
return kCross;
|
||||
return kCross.direction();
|
||||
}
|
||||
|
||||
|
||||
/** Radiance * measure(Solid Angle) between two points, measured at the receiver orthogonal to the axis between them; W/m^2 */
|
||||
typedef Color3 Biradiance3;
|
||||
|
||||
/** Power per (measure(SolidAngle) * measure(Area)); W / (m^2 sr) */
|
||||
typedef Color3 Radiance3;
|
||||
|
||||
/** Power per area; J / m^2 */
|
||||
typedef Color3 Radiosity3;
|
||||
|
||||
/** Force * distance; J */
|
||||
typedef Color3 Energy3;
|
||||
|
||||
/** Incident power per area; W/m^2*/
|
||||
typedef Color3 Irradiance3;
|
||||
|
||||
/** Energy per time; W*/
|
||||
typedef Color3 Power3;
|
||||
|
||||
#if 0 // Disabled to avoid taking these useful names from the namespace
|
||||
typedef float Power;
|
||||
typedef float Biradiance;
|
||||
typedef float Radiance;
|
||||
typedef float Radiosity;
|
||||
typedef float Energy;
|
||||
typedef float Irradiance;
|
||||
#endif
|
||||
} // namespace
|
||||
|
||||
|
||||
|
||||
14
deps/g3dlite/include/G3D/Color4.h
vendored
14
deps/g3dlite/include/G3D/Color4.h
vendored
@@ -48,16 +48,16 @@ public:
|
||||
Color4(const Any& any);
|
||||
|
||||
/** Converts the Color4 to an Any. */
|
||||
operator Any() const;
|
||||
Any toAny() const;
|
||||
|
||||
/**
|
||||
* Does not initialize fields.
|
||||
Initializes to all zero
|
||||
*/
|
||||
Color4 ();
|
||||
Color4() : r(0), g(0), b(0), a(0) {}
|
||||
|
||||
Color4(const Color3& c3, float a = 1.0);
|
||||
|
||||
Color4(const class Color4uint8& c);
|
||||
Color4(const class Color4unorm8& c);
|
||||
|
||||
Color4(class BinaryInput& bi);
|
||||
|
||||
@@ -191,12 +191,6 @@ inline Color4 operator*(const Color3& c3, const Color4& c4) {
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
inline Color4::Color4 () {
|
||||
// For efficiency in construction of large arrays of vectors, the
|
||||
// default constructor does not initialize the vector.
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
inline Color4::Color4(const Color3& c3, float a) {
|
||||
r = c3.r;
|
||||
|
||||
13
deps/g3dlite/include/G3D/Cone.h
vendored
13
deps/g3dlite/include/G3D/Cone.h
vendored
@@ -61,6 +61,19 @@ public:
|
||||
True if v is a point inside the cone.
|
||||
*/
|
||||
bool contains(const class Vector3& v) const;
|
||||
|
||||
|
||||
/** Returns the solid angle (in steradians) subtended by a cone with half-angle \a halfAngle */
|
||||
static float solidAngleFromHalfAngle(float halfAngle);
|
||||
static double solidAngleFromHalfAngle(double halfAngle);
|
||||
|
||||
/** Returns the half-angle (in radians) of a cone that subtends \a solidAngle (in steradians) */
|
||||
static float halfAngleFromSolidAngle(float solidAngle);
|
||||
static double halfAngleFromSolidAngle(double solidAngle);
|
||||
|
||||
|
||||
Vector3 randomDirectionInCone(Random& rng) const;
|
||||
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
2
deps/g3dlite/include/G3D/ConvexPolyhedron.h
vendored
2
deps/g3dlite/include/G3D/ConvexPolyhedron.h
vendored
@@ -34,7 +34,7 @@ private:
|
||||
|
||||
friend class ConvexPolyhedron;
|
||||
|
||||
Array<Vector3> _vertex;
|
||||
Array<Vector3> _vertex;
|
||||
|
||||
public:
|
||||
|
||||
|
||||
113
deps/g3dlite/include/G3D/CoordinateFrame.h
vendored
113
deps/g3dlite/include/G3D/CoordinateFrame.h
vendored
@@ -1,12 +1,12 @@
|
||||
/**
|
||||
@file CoordinateFrame.h
|
||||
\file G3D/CoordinateFrame.h
|
||||
|
||||
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
\maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
|
||||
@created 2001-03-04
|
||||
@edited 2009-04-29
|
||||
\created 2001-03-04
|
||||
\edited 2012-07-29
|
||||
|
||||
Copyright 2000-2009, Morgan McGuire.
|
||||
Copyright 2000-2012, Morgan McGuire.
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
@@ -33,9 +33,10 @@
|
||||
|
||||
namespace G3D {
|
||||
class Any;
|
||||
class Frustum;
|
||||
|
||||
/**
|
||||
A rigid body RT (rotation-translation) transformation.
|
||||
\brief A rigid body RT (rotation-translation) transformation.
|
||||
|
||||
CoordinateFrame abstracts a 4x4 matrix that maps object space to world space:
|
||||
|
||||
@@ -53,28 +54,28 @@ Convert to Matrix4 using CoordinateFrame::toMatrix4. You <I>can</I> construct a
|
||||
from a Matrix4 using Matrix4::approxCoordinateFrame, however, because a Matrix4 is more
|
||||
general than a CoordinateFrame, some information may be lost.
|
||||
|
||||
@sa G3D::UprightFrame, G3D::PhysicsFrame, G3D::Matrix4, G3D::Quat
|
||||
\sa G3D::UprightFrame, G3D::PhysicsFrame, G3D::Matrix4, G3D::Quat
|
||||
*/
|
||||
class CoordinateFrame {
|
||||
public:
|
||||
|
||||
/** Takes object space points to world space. */
|
||||
Matrix3 rotation;
|
||||
Matrix3 rotation;
|
||||
|
||||
/** Takes object space points to world space. */
|
||||
Vector3 translation;
|
||||
/** The origin of this coordinate frame in world space (or its parent's space, if nested). */
|
||||
Point3 translation;
|
||||
|
||||
/** \param any Must be in one of the following forms:
|
||||
- CFrame((matrix3 expr), (vector3 expr))
|
||||
- CFrame((matrix3 expr), (Point3 expr))
|
||||
- CFrame::fromXYZYPRDegrees(#, #, #, #, #, #)
|
||||
- CFrame { rotation = (matrix3 expr), translation = (vector3 expr) }
|
||||
- Vector3( ... )
|
||||
- CFrame { rotation = (Matrix3 expr), translation = (Point3 expr) }
|
||||
- Point3( ... )
|
||||
- Matrix3( ... )
|
||||
*/
|
||||
CoordinateFrame(const Any& any);
|
||||
|
||||
/** Converts the CFrame to an Any. */
|
||||
operator Any() const;
|
||||
Any toAny() const;
|
||||
|
||||
inline bool operator==(const CoordinateFrame& other) const {
|
||||
return (translation == other.translation) && (rotation == other.rotation);
|
||||
@@ -95,16 +96,16 @@ public:
|
||||
*/
|
||||
CoordinateFrame();
|
||||
|
||||
CoordinateFrame(const Vector3& _translation) :
|
||||
CoordinateFrame(const Point3& _translation) :
|
||||
rotation(Matrix3::identity()), translation(_translation) {
|
||||
}
|
||||
|
||||
CoordinateFrame(const Matrix3 &rotation, const Vector3 &translation) :
|
||||
CoordinateFrame(const Matrix3& rotation, const Point3& translation) :
|
||||
rotation(rotation), translation(translation) {
|
||||
}
|
||||
|
||||
CoordinateFrame(const Matrix3 &rotation) :
|
||||
rotation(rotation), translation(Vector3::zero()) {
|
||||
CoordinateFrame(const Matrix3& rotation) :
|
||||
rotation(rotation), translation(Point3::zero()) {
|
||||
}
|
||||
|
||||
CoordinateFrame(const class UprightFrame& f);
|
||||
@@ -187,26 +188,25 @@ public:
|
||||
/**
|
||||
Transforms the point into world space.
|
||||
*/
|
||||
inline Vector3 pointToWorldSpace(const Vector3& v) const {
|
||||
return Vector3(
|
||||
rotation[0][0] * v[0] + rotation[0][1] * v[1] + rotation[0][2] * v[2] + translation[0],
|
||||
rotation[1][0] * v[0] + rotation[1][1] * v[1] + rotation[1][2] * v[2] + translation[1],
|
||||
rotation[2][0] * v[0] + rotation[2][1] * v[1] + rotation[2][2] * v[2] + translation[2]);
|
||||
inline Point3 pointToWorldSpace(const Point3& v) const {
|
||||
return Point3
|
||||
(rotation[0][0] * v[0] + rotation[0][1] * v[1] + rotation[0][2] * v[2] + translation[0],
|
||||
rotation[1][0] * v[0] + rotation[1][1] * v[1] + rotation[1][2] * v[2] + translation[1],
|
||||
rotation[2][0] * v[0] + rotation[2][1] * v[1] + rotation[2][2] * v[2] + translation[2]);
|
||||
}
|
||||
|
||||
/**
|
||||
Transforms the point into object space. Assumes that the rotation matrix is orthonormal.
|
||||
*/
|
||||
inline Vector3 pointToObjectSpace(const Vector3& v) const {
|
||||
inline Point3 pointToObjectSpace(const Point3& v) const {
|
||||
float p[3];
|
||||
p[0] = v[0] - translation[0];
|
||||
p[1] = v[1] - translation[1];
|
||||
p[2] = v[2] - translation[2];
|
||||
debugAssert(G3D::fuzzyEq(rotation.determinant(), 1.0f));
|
||||
return Vector3(
|
||||
rotation[0][0] * p[0] + rotation[1][0] * p[1] + rotation[2][0] * p[2],
|
||||
rotation[0][1] * p[0] + rotation[1][1] * p[1] + rotation[2][1] * p[2],
|
||||
rotation[0][2] * p[0] + rotation[1][2] * p[1] + rotation[2][2] * p[2]);
|
||||
debugAssert(G3D::fuzzyEq(fabsf(rotation.determinant()), 1.0f));
|
||||
return Point3(rotation[0][0] * p[0] + rotation[1][0] * p[1] + rotation[2][0] * p[2],
|
||||
rotation[0][1] * p[0] + rotation[1][1] * p[1] + rotation[2][1] * p[2],
|
||||
rotation[0][2] * p[0] + rotation[1][2] * p[1] + rotation[2][2] * p[2]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -224,6 +224,8 @@ public:
|
||||
|
||||
Ray toWorldSpace(const Ray& r) const;
|
||||
|
||||
Frustum toWorldSpace(const Frustum& f) const;
|
||||
|
||||
/**
|
||||
Transforms the vector into object space (no translation).
|
||||
*/
|
||||
@@ -237,18 +239,20 @@ public:
|
||||
return v * rotation;
|
||||
}
|
||||
|
||||
void pointToWorldSpace(const Array<Vector3>& v, Array<Vector3>& vout) const;
|
||||
void pointToWorldSpace(const Array<Point3>& v, Array<Point3>& vout) const;
|
||||
|
||||
void normalToWorldSpace(const Array<Vector3>& v, Array<Vector3>& vout) const;
|
||||
|
||||
void vectorToWorldSpace(const Array<Vector3>& v, Array<Vector3>& vout) const;
|
||||
|
||||
void pointToObjectSpace(const Array<Vector3>& v, Array<Vector3>& vout) const;
|
||||
void pointToObjectSpace(const Array<Point3>& v, Array<Point3>& vout) const;
|
||||
|
||||
void normalToObjectSpace(const Array<Vector3>& v, Array<Vector3>& vout) const;
|
||||
|
||||
void vectorToObjectSpace(const Array<Vector3>& v, Array<Vector3>& vout) const;
|
||||
|
||||
void toWorldSpace(const class AABox& b, class AABox& result) const;
|
||||
|
||||
class Box toWorldSpace(const class AABox& b) const;
|
||||
|
||||
class Box toWorldSpace(const class Box& b) const;
|
||||
@@ -260,7 +264,7 @@ public:
|
||||
class Plane toWorldSpace(const class Plane& p) const;
|
||||
|
||||
class Sphere toWorldSpace(const class Sphere& b) const;
|
||||
|
||||
|
||||
class Triangle toWorldSpace(const class Triangle& t) const;
|
||||
|
||||
class Box toObjectSpace(const AABox& b) const;
|
||||
@@ -287,17 +291,32 @@ public:
|
||||
return CoordinateFrame(rotation, translation - v);
|
||||
}
|
||||
|
||||
void lookAt(const Vector3& target);
|
||||
|
||||
void lookAt(
|
||||
const Vector3& target,
|
||||
Vector3 up);
|
||||
/**
|
||||
Transform this coordinate frame towards \a goal, but not past it, goverened by maximum
|
||||
rotation and translations. This is a useful alternative to \a lerp, especially if the
|
||||
goal is expected to change every transformation step so that constant start and end positions will
|
||||
not be available.
|
||||
|
||||
\param goal Step from this towards goal
|
||||
\param maxTranslation Meters
|
||||
\param maxRotation Radians
|
||||
|
||||
\sa lerp
|
||||
*/
|
||||
void moveTowards(const CoordinateFrame& goal, float maxTranslation, float maxRotation);
|
||||
|
||||
void lookAt(const Point3& target);
|
||||
|
||||
void lookAt
|
||||
(const Point3& target,
|
||||
Vector3 up);
|
||||
|
||||
/** The direction this camera is looking (its negative z axis)*/
|
||||
inline Vector3 lookVector() const {
|
||||
return -rotation.column(2);
|
||||
}
|
||||
|
||||
inline Vector3 lookVector() const {
|
||||
return -rotation.column(2);
|
||||
}
|
||||
|
||||
/** Returns the ray starting at the camera origin travelling in direction CoordinateFrame::lookVector. */
|
||||
class Ray lookRay() const;
|
||||
|
||||
@@ -307,24 +326,26 @@ public:
|
||||
}
|
||||
|
||||
inline Vector3 rightVector() const {
|
||||
return rotation.column(0);
|
||||
}
|
||||
return rotation.column(0);
|
||||
}
|
||||
|
||||
/**
|
||||
If a viewer looks along the look vector, this is the viewer's "left".
|
||||
Useful for strafing motions and building alternative coordinate frames.
|
||||
*/
|
||||
inline Vector3 leftVector() const {
|
||||
return -rotation.column(0);
|
||||
return -rotation.column(0);
|
||||
}
|
||||
|
||||
/**
|
||||
Linearly interpolates between two coordinate frames, using
|
||||
Quat::slerp for the rotations.
|
||||
|
||||
\sa moveTowards
|
||||
*/
|
||||
CoordinateFrame lerp(
|
||||
const CoordinateFrame& other,
|
||||
float alpha) const;
|
||||
CoordinateFrame lerp
|
||||
(const CoordinateFrame& other,
|
||||
float alpha) const;
|
||||
|
||||
};
|
||||
|
||||
|
||||
45
deps/g3dlite/include/G3D/Crypto.h
vendored
45
deps/g3dlite/include/G3D/Crypto.h
vendored
@@ -1,18 +1,19 @@
|
||||
/**
|
||||
@file Crypto.h
|
||||
\file G3D/Crypto.h
|
||||
|
||||
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
\maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
|
||||
|
||||
@created 2006-03-29
|
||||
@edited 2006-04-06
|
||||
\created 2006-03-29
|
||||
\edited 2011-06-21
|
||||
*/
|
||||
|
||||
#ifndef G3D_CRYPTO_H
|
||||
#define G3D_CRYPTO_H
|
||||
#ifndef G3D_Crypto_h
|
||||
#define G3D_Crypto_h
|
||||
|
||||
#include "G3D/platform.h"
|
||||
#include "G3D/g3dmath.h"
|
||||
#include "G3D/System.h"
|
||||
#include <string>
|
||||
|
||||
namespace G3D {
|
||||
@@ -33,6 +34,24 @@ public:
|
||||
|
||||
explicit MD5Hash(class BinaryInput& b);
|
||||
|
||||
/** Rotates the bytes once */
|
||||
void rotateBytes() {
|
||||
uint8 temp = value[0];
|
||||
for (int i = 0; i < 15; ++i) {
|
||||
value[i] = value[i + 1];
|
||||
}
|
||||
value[15] = temp;
|
||||
}
|
||||
|
||||
/** Rotates by n bytes */
|
||||
void rotateBytes(int n) {
|
||||
uint8 temp[16];
|
||||
System::memcpy(temp, value, 16);
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
value[i] = value[(i + n) & 15];
|
||||
}
|
||||
}
|
||||
|
||||
uint8& operator[](int i) {
|
||||
return value[i];
|
||||
}
|
||||
@@ -56,6 +75,18 @@ public:
|
||||
void deserialize(class BinaryInput& b);
|
||||
|
||||
void serialize(class BinaryOutput& b) const;
|
||||
|
||||
static size_t hashCode(const MD5Hash& key) {
|
||||
size_t h = 0;
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
const int x = i * 4;
|
||||
h ^= (((uint32)key.value[x + 0]) << 24) |
|
||||
(((uint32)key.value[x + 1]) << 16) |
|
||||
(((uint32)key.value[x + 2]) << 8) |
|
||||
((uint32)key.value[x + 3]);
|
||||
}
|
||||
return h;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -79,7 +110,7 @@ public:
|
||||
|
||||
@cite Based on implementation by L. Peter Deutsch, ghost@aladdin.com
|
||||
*/
|
||||
MD5Hash md5(const void* bytes, size_t numBytes);
|
||||
static MD5Hash md5(const void* bytes, size_t numBytes);
|
||||
|
||||
/**
|
||||
Returns the nth prime less than 2000 in constant time. The first prime has index
|
||||
|
||||
18
deps/g3dlite/include/G3D/Cylinder.h
vendored
18
deps/g3dlite/include/G3D/Cylinder.h
vendored
@@ -26,22 +26,22 @@ class AABox;
|
||||
*/
|
||||
class Cylinder {
|
||||
private:
|
||||
Vector3 p1;
|
||||
Vector3 p2;
|
||||
Vector3 p1;
|
||||
Vector3 p2;
|
||||
|
||||
float mRadius;
|
||||
float mRadius;
|
||||
|
||||
public:
|
||||
|
||||
/** Uninitialized */
|
||||
Cylinder();
|
||||
Cylinder(class BinaryInput& b);
|
||||
Cylinder(const Vector3& _p1, const Vector3& _p2, float _r);
|
||||
void serialize(class BinaryOutput& b) const;
|
||||
void deserialize(class BinaryInput& b);
|
||||
|
||||
/** The line down the center of the Cylinder */
|
||||
Line axis() const;
|
||||
Cylinder(const Vector3& _p1, const Vector3& _p2, float _r);
|
||||
void serialize(class BinaryOutput& b) const;
|
||||
void deserialize(class BinaryInput& b);
|
||||
|
||||
/** The line down the center of the Cylinder */
|
||||
Line axis() const;
|
||||
|
||||
/**
|
||||
A reference frame in which the center of mass is at the origin and
|
||||
|
||||
32
deps/g3dlite/include/G3D/FileNotFound.h
vendored
Normal file
32
deps/g3dlite/include/G3D/FileNotFound.h
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
\file FileNotFound.h
|
||||
|
||||
\maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
\created 2011-12-31
|
||||
\edited 2011-12-31
|
||||
*/
|
||||
#ifndef G3D_FileNotFound_h
|
||||
#define G3D_FileNotFound_h
|
||||
|
||||
#include "G3D/platform.h"
|
||||
#include <string>
|
||||
|
||||
namespace G3D {
|
||||
|
||||
/** Thrown by various file opening routines if the file is not found.
|
||||
|
||||
\sa ParseError, System::findDataFile
|
||||
*/
|
||||
class FileNotFound {
|
||||
public:
|
||||
std::string filename;
|
||||
std::string message;
|
||||
|
||||
FileNotFound() {}
|
||||
FileNotFound(const std::string& f, const std::string& m) : filename(f), message(m) {}
|
||||
virtual ~FileNotFound(){};
|
||||
};
|
||||
|
||||
} // G3D
|
||||
|
||||
#endif
|
||||
369
deps/g3dlite/include/G3D/FileSystem.h
vendored
369
deps/g3dlite/include/G3D/FileSystem.h
vendored
@@ -1,10 +1,10 @@
|
||||
/**
|
||||
@file FileSystem.h
|
||||
\file FileSystem.h
|
||||
|
||||
@author Morgan McGuire, http://graphics.cs.williams.edu
|
||||
\author Morgan McGuire, http://graphics.cs.williams.edu
|
||||
|
||||
@author 2002-06-06
|
||||
@edited 2010-02-05
|
||||
\author 2002-06-06
|
||||
\edited 2012-03-26
|
||||
*/
|
||||
#ifndef G3D_FileSystem_h
|
||||
#define G3D_FileSystem_h
|
||||
@@ -12,6 +12,8 @@
|
||||
#include "G3D/platform.h"
|
||||
#include "G3D/Array.h"
|
||||
#include "G3D/Table.h"
|
||||
#include "G3D/Set.h"
|
||||
#include "G3D/GMutex.h"
|
||||
|
||||
namespace G3D {
|
||||
|
||||
@@ -34,11 +36,12 @@ namespace G3D {
|
||||
<li> There are no nested zipfiles
|
||||
</ul>
|
||||
|
||||
All FileSystem routines invoke FilePath::expandEnvironmentVariables if the input contains a '$'.
|
||||
|
||||
The extension requirement allows G3D to quickly identify whether a path could enter a
|
||||
zipfile without forcing it to open all parent directories for reading.
|
||||
|
||||
\sa FilePath
|
||||
TODO: make threadsafe!
|
||||
*/
|
||||
class FileSystem {
|
||||
public:
|
||||
@@ -63,7 +66,7 @@ public:
|
||||
ListSettings() :
|
||||
files(true),
|
||||
directories(true),
|
||||
# ifdef G3D_WIN32
|
||||
# ifdef G3D_WINDOWS
|
||||
caseSensitive(true),
|
||||
# else
|
||||
caseSensitive(false),
|
||||
@@ -111,8 +114,13 @@ private:
|
||||
/** When this entry was last updated */
|
||||
double lastChecked;
|
||||
|
||||
/** Case-independent comparison on Windows */
|
||||
bool contains(const std::string& child) const;
|
||||
bool contains(const std::string& child, bool caseSensitive =
|
||||
#ifdef G3D_WINDOWS
|
||||
false
|
||||
#else
|
||||
true
|
||||
#endif
|
||||
) const;
|
||||
|
||||
/** Compute the contents of nodeArray from this zipfile. */
|
||||
void computeZipListing(const std::string& zipfile, const std::string& pathInsideZipfile);
|
||||
@@ -132,116 +140,80 @@ private:
|
||||
FileSystem();
|
||||
|
||||
static FileSystem& instance();
|
||||
static GMutex mutex;
|
||||
|
||||
# ifdef G3D_WIN32
|
||||
/** On Windows, the drive letters that form the file system roots.*/
|
||||
|
||||
# ifdef G3D_WINDOWS
|
||||
/** \copydoc drives */
|
||||
const Array<std::string>& _drives();
|
||||
# endif
|
||||
|
||||
/** Returns true if some sub-path of \a path is a zipfile.
|
||||
|
||||
If the path itself is a zipfile, returns false.
|
||||
|
||||
\param zipfile The part of \a path that was the zipfile */
|
||||
/** \copydoc inZipfile */
|
||||
bool _inZipfile(const std::string& path, std::string& zipfile);
|
||||
|
||||
/** Clears old cache entries so that exists() and list() will reflect recent changes to the file system.
|
||||
\param path Clear only \a path and its subdirectories ("" means clear the entire cache) */
|
||||
/** \copydoc clearCache */
|
||||
void _clearCache(const std::string& path);
|
||||
|
||||
/** \copydoc inZipfile */
|
||||
bool _inZipfile(const std::string& path) {
|
||||
std::string ignore;
|
||||
return inZipfile(path, ignore);
|
||||
}
|
||||
|
||||
/** Set the cacheLifetime().
|
||||
\param t in seconds */
|
||||
/** \copydoc setCacheLifetime */
|
||||
void _setCacheLifetime(float t);
|
||||
|
||||
|
||||
/** A cache is used to optimize repeated calls. A cache entry is considered
|
||||
valid for this many seconds after it has been checked. */
|
||||
/** \copydoc cacheLifetime */
|
||||
float _cacheLifetime() const {
|
||||
return m_cacheLifetime;
|
||||
}
|
||||
|
||||
/** Creates the directory named, including any subdirectories
|
||||
that do not already exist.
|
||||
|
||||
The directory must not be inside a zipfile.
|
||||
|
||||
Flushes the cache.
|
||||
*/
|
||||
/** \copydoc createDirectory */
|
||||
void _createDirectory(const std::string& path);
|
||||
|
||||
/** Returns true if a node named \a f exists.
|
||||
/** \copydoc exists */
|
||||
bool _exists(const std::string& f, bool trustCache = true, bool caseSensitive =
|
||||
#ifdef G3D_WINDOWS
|
||||
false
|
||||
#else
|
||||
true
|
||||
#endif
|
||||
);
|
||||
|
||||
\param f If \a f contains wildcards, the function returns true if any file
|
||||
matches those wildcards. Wildcards may only appear in the base or ext, not the
|
||||
path.
|
||||
|
||||
\param trustCache If true, uses the cache for optimizing repeated calls
|
||||
in the same parent directory.
|
||||
*/
|
||||
bool _exists(const std::string& f, bool trustCache = true);
|
||||
|
||||
/** Known bug: does not work inside zipfiles */
|
||||
/** \copydoc isDirectory */
|
||||
bool _isDirectory(const std::string& path);
|
||||
|
||||
/** Known bug: does not work inside zipfiles */
|
||||
/** \copydoc isFile */
|
||||
bool _isFile(const std::string& path) {
|
||||
return ! isDirectory(path);
|
||||
}
|
||||
|
||||
/**
|
||||
\param srcPath Must name a file.
|
||||
\param dstPath Must not contain a zipfile.
|
||||
|
||||
Flushes the cache.
|
||||
*/
|
||||
/** \copydoc copyFile */
|
||||
void _copyFile(const std::string& srcPath, const std::string& dstPath);
|
||||
|
||||
/** Fully qualifies a filename.
|
||||
|
||||
The filename may contain wildcards, in which case the wildcards will be preserved in the returned value.
|
||||
|
||||
\param cwd The directory to treat as the "current" directory when resolving a relative path. The default
|
||||
value is the actual current directory. (G3D::Any::sourceDirectory is a common alternative)
|
||||
*/
|
||||
/** \copydoc resolve */
|
||||
std::string _resolve(const std::string& path, const std::string& cwd = currentDirectory());
|
||||
|
||||
/** Returns true if \param dst does not exist or \param src is newer than \param dst,
|
||||
according to their time stamps.
|
||||
|
||||
Known bug: does not work inside zipfiles.
|
||||
*/
|
||||
/** \copydoc isNewer */
|
||||
bool _isNewer(const std::string& src, const std::string& dst);
|
||||
|
||||
/** The current working directory (cwd). Only ends in a slash if this is the root of the file system. */
|
||||
/** \copydoc currentDirectory */
|
||||
std::string _currentDirectory();
|
||||
|
||||
/** Returns the length of the file in bytes, or -1 if the file could not be opened. */
|
||||
/** \copydoc size */
|
||||
int64 _size(const std::string& path);
|
||||
|
||||
/** Called from list() */
|
||||
void listHelper(const std::string& shortSpec, const std::string& parentPath, Array<std::string>& result, const ListSettings& settings);
|
||||
|
||||
/** Appends all nodes matching \a spec to the \a result array.
|
||||
|
||||
Wildcards can only appear to the right of the last slash in \a spec.
|
||||
|
||||
The names will not contain parent paths unless \a includePath == true.
|
||||
These may be relative to the current directory unless \a spec
|
||||
is fully qualified (can be done with resolveFilename).
|
||||
|
||||
*/
|
||||
/** \copydoc list */
|
||||
void _list(const std::string& spec, Array<std::string>& result, const ListSettings& listSettings = ListSettings());
|
||||
|
||||
/** Returns true if \a path is a file that is a zipfile. Note that G3D requires zipfiles to have
|
||||
some extension, although it is not required to be "zip" */
|
||||
/** \copydoc isZipfile */
|
||||
bool _isZipfile(const std::string& path);
|
||||
|
||||
/** list() files */
|
||||
/** \copydoc getFiles */
|
||||
void _getFiles(const std::string& spec, Array<std::string>& result, bool includeParentPath = false) {
|
||||
ListSettings set;
|
||||
set.includeParentPath = includeParentPath;
|
||||
@@ -250,7 +222,7 @@ private:
|
||||
return list(spec, result, set);
|
||||
}
|
||||
|
||||
/** list() directories */
|
||||
/** \copydoc getDirectories */
|
||||
void _getDirectories(const std::string& spec, Array<std::string>& result, bool includeParentPath = false) {
|
||||
ListSettings set;
|
||||
set.includeParentPath = includeParentPath;
|
||||
@@ -259,12 +231,13 @@ private:
|
||||
return list(spec, result, set);
|
||||
}
|
||||
|
||||
/** Same as the C standard library fopen, but updates the file cache
|
||||
to acknowledge the new file on a write operation. */
|
||||
/** \copydoc fopen */
|
||||
FILE* _fopen(const char* filename, const char* mode);
|
||||
|
||||
public:
|
||||
/** \copydoc removeFile */
|
||||
void _removeFile(const std::string& path);
|
||||
|
||||
public:
|
||||
|
||||
/** Create the common instance. */
|
||||
static void init();
|
||||
@@ -272,111 +245,267 @@ public:
|
||||
/** Destroy the common instance. */
|
||||
static void cleanup();
|
||||
|
||||
# ifdef G3D_WIN32
|
||||
/** \copydoc _drives */
|
||||
# ifdef G3D_WINDOWS
|
||||
/** On Windows, the drive letters that form the file system roots.*/
|
||||
static const Array<std::string>& drives() {
|
||||
return instance()._drives();
|
||||
mutex.lock();
|
||||
const Array<std::string>& s = instance()._drives();
|
||||
mutex.unlock();
|
||||
return s;
|
||||
}
|
||||
# endif
|
||||
|
||||
/** \copydoc _inZipfile */
|
||||
/** Returns true if some sub-path of \a path is a zipfile.
|
||||
|
||||
If the path itself is a zipfile, returns false.
|
||||
|
||||
\param zipfile The part of \a path that was the zipfile
|
||||
*/
|
||||
static bool inZipfile(const std::string& path, std::string& zipfile) {
|
||||
return instance()._inZipfile(path, zipfile);
|
||||
mutex.lock();
|
||||
bool b = instance()._inZipfile(path, zipfile);
|
||||
mutex.unlock();
|
||||
return b;
|
||||
}
|
||||
|
||||
/** \copydoc _clearCache */
|
||||
/** Clears old cache entries so that exists() and list() will reflect recent changes to the file system.
|
||||
\param path Clear only \a path and its subdirectories ("" means clear the entire cache) */
|
||||
static void clearCache(const std::string& path = "") {
|
||||
mutex.lock();
|
||||
instance()._clearCache(path);
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
/** \copydoc _fopen */
|
||||
|
||||
/** Same as the C standard library fopen, but updates the file cache
|
||||
to acknowledge the new file on a write operation. */
|
||||
static FILE* fopen(const char* filename, const char* mode) {
|
||||
return instance()._fopen(filename, mode);
|
||||
mutex.lock();
|
||||
FILE* f = instance()._fopen(filename, mode);
|
||||
mutex.unlock();
|
||||
return f;
|
||||
}
|
||||
|
||||
|
||||
static void fclose(FILE* f) {
|
||||
mutex.lock();
|
||||
::fclose(f);
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
/** Returns true if some sub-path of \a path is a zipfile.
|
||||
|
||||
If the path itself is a zipfile, returns false.
|
||||
*/
|
||||
static bool inZipfile(const std::string& path) {
|
||||
return instance()._inZipfile(path);
|
||||
mutex.lock();
|
||||
bool b = instance()._inZipfile(path);
|
||||
mutex.unlock();
|
||||
return b;
|
||||
}
|
||||
|
||||
/** \copydoc isZipfile */
|
||||
|
||||
/**
|
||||
\brief Delete this file.
|
||||
No effect if \a path does not exist.
|
||||
|
||||
\param path May contain wildcards. May not be inside a zipfile.
|
||||
*/
|
||||
static void removeFile(const std::string& path) {
|
||||
mutex.lock();
|
||||
instance()._removeFile(path);
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
|
||||
/** Returns true if \a path is a file that is a zipfile. Note that G3D requires zipfiles to have
|
||||
some extension, although it is not required to be "zip" */
|
||||
static bool isZipfile(const std::string& path) {
|
||||
return instance()._isZipfile(path);
|
||||
mutex.lock();
|
||||
bool b = instance()._isZipfile(path);
|
||||
mutex.unlock();
|
||||
return b;
|
||||
}
|
||||
|
||||
/** \copydoc _setCacheLifetime */
|
||||
|
||||
/** Set the cacheLifetime().
|
||||
\param t in seconds */
|
||||
void setCacheLifetime(float t) {
|
||||
mutex.lock();
|
||||
instance()._setCacheLifetime(t);
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
/** \copydoc _cacheLifetime */
|
||||
/** A cache is used to optimize repeated calls. A cache entry is considered
|
||||
valid for this many seconds after it has been checked. */
|
||||
static float cacheLifetime() {
|
||||
return instance()._cacheLifetime();
|
||||
mutex.lock();
|
||||
float f = instance()._cacheLifetime();
|
||||
mutex.unlock();
|
||||
return f;
|
||||
}
|
||||
|
||||
/** \copydoc _createDirectory */
|
||||
|
||||
/** Creates the directory named, including any subdirectories
|
||||
that do not already exist.
|
||||
|
||||
The directory must not be inside a zipfile.
|
||||
|
||||
Flushes the cache.
|
||||
*/
|
||||
static void createDirectory(const std::string& path) {
|
||||
mutex.lock();
|
||||
instance()._createDirectory(path);
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
/** \copydoc _currentDirectory */
|
||||
|
||||
/** The current working directory (cwd). Only ends in a slash if this is the root of the file system. */
|
||||
static std::string currentDirectory() {
|
||||
return instance()._currentDirectory();
|
||||
mutex.lock();
|
||||
const std::string& s = instance()._currentDirectory();
|
||||
mutex.unlock();
|
||||
return s;
|
||||
}
|
||||
|
||||
/** \copydoc _copyFile */
|
||||
|
||||
/**
|
||||
\param srcPath Must name a file.
|
||||
\param dstPath Must not contain a zipfile.
|
||||
|
||||
Flushes the cache.
|
||||
*/
|
||||
static void copyFile(const std::string& srcPath, const std::string& dstPath) {
|
||||
mutex.lock();
|
||||
instance()._copyFile(srcPath, dstPath);
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
/** \copydoc _exists */
|
||||
static bool exists(const std::string& f, bool trustCache = true) {
|
||||
return instance()._exists(f, trustCache);
|
||||
|
||||
|
||||
/** Returns true if a node named \a f exists.
|
||||
|
||||
\param f If \a f contains wildcards, the function returns true if any file
|
||||
matches those wildcards. Wildcards may only appear in the base or ext, not the
|
||||
path. Environment variables beginning with dollar signs (e.g., in "$G3DDATA/cubemap"),
|
||||
with optional parens ("$(G3DDATA)") are
|
||||
automatically expanded in \a f. Default share names on Windows (e.g., "\\mycomputer\c$")
|
||||
are correctly distinguished from empty environment variables.
|
||||
|
||||
\param trustCache If true, uses the cache for optimizing repeated calls
|
||||
in the same parent directory.
|
||||
|
||||
\param caseSensitive If true, the match must have exactly the same case for the base and extension. If false,
|
||||
case is ignored. The default on Windows is false and the default on other operating systems is true.
|
||||
*/
|
||||
static bool exists(const std::string& f, bool trustCache = true, bool caseSensitive =
|
||||
#ifdef G3D_WINDOWS
|
||||
false
|
||||
#else
|
||||
true
|
||||
#endif
|
||||
) {
|
||||
mutex.lock();
|
||||
bool e = instance()._exists(f, trustCache, caseSensitive);
|
||||
mutex.unlock();
|
||||
return e;
|
||||
}
|
||||
|
||||
/** \copydoc _isDirectory */
|
||||
|
||||
/** Known bug: does not work inside zipfiles */
|
||||
static bool isDirectory(const std::string& path) {
|
||||
return instance()._isDirectory(path);
|
||||
mutex.lock();
|
||||
bool b = instance()._isDirectory(path);
|
||||
mutex.unlock();
|
||||
return b;
|
||||
}
|
||||
|
||||
/** \copydoc _isFile */
|
||||
|
||||
/** Known bug: does not work inside zipfiles */
|
||||
static bool isFile(const std::string& path) {
|
||||
return instance()._isFile(path);
|
||||
mutex.lock();
|
||||
bool b = instance()._isFile(path);
|
||||
mutex.unlock();
|
||||
return b;
|
||||
}
|
||||
|
||||
/** \copydoc _resolve */
|
||||
|
||||
/** Fully qualifies a filename.
|
||||
|
||||
The filename may contain wildcards, in which case the wildcards will be preserved in the returned value.
|
||||
|
||||
\param cwd The directory to treat as the "current" directory when resolving a relative path. The default
|
||||
value is the actual current directory. (G3D::Any::sourceDirectory is a common alternative)
|
||||
*/
|
||||
static std::string resolve(const std::string& path, const std::string& cwd = currentDirectory()) {
|
||||
return instance()._resolve(path, cwd);
|
||||
mutex.lock();
|
||||
const std::string& s = instance()._resolve(path, cwd);
|
||||
mutex.unlock();
|
||||
return s;
|
||||
}
|
||||
|
||||
/** \copydoc _isNewer */
|
||||
|
||||
/** Returns true if \a dst does not exist or \a src is newer than \a dst,
|
||||
according to their time stamps.
|
||||
|
||||
Known bug: does not work inside zipfiles.
|
||||
*/
|
||||
static bool isNewer(const std::string& src, const std::string& dst) {
|
||||
return instance()._isNewer(src, dst);
|
||||
mutex.lock();
|
||||
bool b = instance()._isNewer(src, dst);
|
||||
mutex.unlock();
|
||||
return b;
|
||||
}
|
||||
|
||||
/** \copydoc _size */
|
||||
|
||||
/** Returns the length of the file in bytes, or -1 if the file could not be opened. */
|
||||
static int64 size(const std::string& path) {
|
||||
return instance()._size(path);
|
||||
mutex.lock();
|
||||
int64 i = instance()._size(path);
|
||||
mutex.unlock();
|
||||
return i;
|
||||
}
|
||||
|
||||
/** \copydoc _list */
|
||||
|
||||
/** Appends all nodes matching \a spec to the \a result array.
|
||||
|
||||
Wildcards can only appear to the right of the last slash in \a spec.
|
||||
|
||||
The names will not contain parent paths unless \a includePath == true.
|
||||
These may be relative to the current directory unless \a spec
|
||||
is fully qualified (can be done with resolveFilename).
|
||||
|
||||
*/
|
||||
static void list(const std::string& spec, Array<std::string>& result,
|
||||
const ListSettings& listSettings = ListSettings()) {
|
||||
return instance()._list(spec, result, listSettings);
|
||||
mutex.lock();
|
||||
instance()._list(spec, result, listSettings);
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
/** \copydoc _getFiles */
|
||||
|
||||
/** list() files */
|
||||
static void getFiles(const std::string& spec, Array<std::string>& result, bool includeParentPath = false) {
|
||||
return instance()._getFiles(spec, result, includeParentPath);
|
||||
mutex.lock();
|
||||
instance()._getFiles(spec, result, includeParentPath);
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
/** \copydoc getDirectories */
|
||||
|
||||
/** list() directories */
|
||||
static void getDirectories(const std::string& spec, Array<std::string>& result, bool includeParentPath = false) {
|
||||
return instance()._getDirectories(spec, result, includeParentPath);
|
||||
mutex.lock();
|
||||
instance()._getDirectories(spec, result, includeParentPath);
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
/** Adds \a filename to usedFiles(). This is called automatically by open() and all
|
||||
G3D routines that open files. */
|
||||
static void markFileUsed(const std::string& filename);
|
||||
|
||||
/** All files that have been marked by markFileUsed(). GApp automatically prints this list to log.txt. It is useful
|
||||
for finding the dependencies of your program automatically.*/
|
||||
static const Set<std::string>& usedFiles();
|
||||
};
|
||||
|
||||
|
||||
@@ -400,6 +529,11 @@ public:
|
||||
/** Appends file onto dirname, ensuring a / if needed. */
|
||||
static std::string concat(const std::string& a, const std::string& b);
|
||||
|
||||
/** Returns true if \a f specifies a path that parses as root of the filesystem.
|
||||
On OS X and other Unix-based operating systems, "/" is the only root.
|
||||
On Windows, drive letters and shares are roots, e.g., "c:\", "\\foo\".
|
||||
Does not check on Windows to see if the root is actually mounted or a legal
|
||||
drive letter--this is a purely string based test. */
|
||||
static bool isRoot(const std::string& f);
|
||||
|
||||
/** Removes the trailing slash unless \a f is a filesystem root */
|
||||
@@ -423,6 +557,11 @@ public:
|
||||
/** Convert all slashes to '/' */
|
||||
static std::string canonicalize(std::string x);
|
||||
|
||||
/** \brief Replaces <code>$VAR</code> and <code>$(VAR)</code> patterns with the corresponding environment variable.
|
||||
Throws std::string if the environment variable is not defined.
|
||||
*/
|
||||
static std::string expandEnvironmentVariables(const std::string& path);
|
||||
|
||||
/**
|
||||
Parses a filename into four useful pieces.
|
||||
|
||||
@@ -454,11 +593,13 @@ public:
|
||||
std::string& base,
|
||||
std::string& ext);
|
||||
|
||||
|
||||
/**
|
||||
Returns true if \a path matches \a pattern, with standard filesystem wildcards.
|
||||
*/
|
||||
static bool matches(const std::string& path, const std::string& pattern, bool caseSensitive = true);
|
||||
|
||||
/** Replaces characters that are illegal in a filename with legal equivalents.*/
|
||||
static std::string makeLegalFilename(const std::string& f, size_t maxLength = 100000);
|
||||
};
|
||||
|
||||
} // namespace G3D
|
||||
|
||||
57
deps/g3dlite/include/G3D/Frustum.h
vendored
Normal file
57
deps/g3dlite/include/G3D/Frustum.h
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
\file G3D/Frustum.h
|
||||
|
||||
\maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
|
||||
\created 2005-07-20
|
||||
\edited 2013-06-11
|
||||
*/
|
||||
|
||||
#ifndef G3D_Frustum_h
|
||||
#define G3D_Frustum_h
|
||||
|
||||
#include "G3D/platform.h"
|
||||
#include "G3D/g3dmath.h"
|
||||
#include "G3D/Plane.h"
|
||||
#include "G3D/SmallArray.h"
|
||||
#include "G3D/Vector4.h"
|
||||
|
||||
namespace G3D {
|
||||
|
||||
class Box;
|
||||
|
||||
/** \see Projection */
|
||||
class Frustum {
|
||||
public:
|
||||
class Face {
|
||||
public:
|
||||
/** Counter clockwise indices into vertexPos */
|
||||
int vertexIndex[4];
|
||||
|
||||
/** The plane containing the face. */
|
||||
Plane plane;
|
||||
};
|
||||
|
||||
/** The vertices, in homogeneous space. The order is that of
|
||||
the near face, starting from the (object space) +x,+y corner
|
||||
and proceeding CCW from the camera's point of view; followed
|
||||
by the far face also in CCW order.
|
||||
|
||||
If w == 0,
|
||||
a vertex is at infinity. */
|
||||
SmallArray<Vector4, 8> vertexPos;
|
||||
|
||||
/** The faces in the frustum. When the
|
||||
far plane is at infinity, there are 5 faces,
|
||||
otherwise there are 6. The faces are in the order
|
||||
N,R,L,B,T,[F].
|
||||
*/
|
||||
SmallArray<Face, 6> faceArray;
|
||||
|
||||
/** \param minObjectSpaceDepth Smallest value permitted for the near plane Z - far plane Z (e.g., to force finite bounds)*/
|
||||
Box boundingBox(float minObjectSpaceDepth = finf()) const;
|
||||
};
|
||||
|
||||
} // namespace G3D
|
||||
|
||||
#endif
|
||||
135
deps/g3dlite/include/G3D/G3D.h
vendored
135
deps/g3dlite/include/G3D/G3D.h
vendored
@@ -1,22 +1,23 @@
|
||||
/**
|
||||
@file G3D.h
|
||||
\file G3D.h
|
||||
|
||||
This header includes all of the G3D libraries in
|
||||
appropriate namespaces.
|
||||
|
||||
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
\maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
|
||||
@created 2001-08-25
|
||||
@edited 2010-03-20
|
||||
\created 2001-08-25
|
||||
\edited 2013-03-24
|
||||
|
||||
Copyright 2000-2010, Morgan McGuire.
|
||||
Copyright 2000-2013, Morgan McGuire.
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef G3D_G3D_h
|
||||
#define G3D_G3D_h
|
||||
|
||||
#define NOMINMAX 1
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX 1
|
||||
#endif
|
||||
#ifdef min
|
||||
#undef min
|
||||
#endif
|
||||
@@ -24,18 +25,30 @@
|
||||
#undef max
|
||||
#endif
|
||||
|
||||
#include "G3D/HaltonSequence.h"
|
||||
#include "G3D/platform.h"
|
||||
#include "G3D/Proxy.h"
|
||||
#include "G3D/BIN.h"
|
||||
#include "G3D/FileNotFound.h"
|
||||
#include "G3D/units.h"
|
||||
#include "G3D/ParseError.h"
|
||||
#include "G3D/Random.h"
|
||||
#include "G3D/Noise.h"
|
||||
#include "G3D/Array.h"
|
||||
#include "G3D/SmallArray.h"
|
||||
#include "G3D/Queue.h"
|
||||
#include "G3D/Crypto.h"
|
||||
#include "G3D/format.h"
|
||||
#include "G3D/Vector2.h"
|
||||
#include "G3D/Vector2int32.h"
|
||||
#include "G3D/Vector2int16.h"
|
||||
#include "G3D/Vector2unorm16.h"
|
||||
#include "G3D/Vector3.h"
|
||||
#include "G3D/Vector3int16.h"
|
||||
#include "G3D/Vector3int32.h"
|
||||
#include "G3D/Vector4.h"
|
||||
#include "G3D/Vector4int16.h"
|
||||
#include "G3D/Vector4int8.h"
|
||||
#include "G3D/Color1.h"
|
||||
#include "G3D/Color3.h"
|
||||
#include "G3D/Color4.h"
|
||||
@@ -43,6 +56,7 @@
|
||||
#include "G3D/Matrix3.h"
|
||||
#include "G3D/Matrix4.h"
|
||||
#include "G3D/CoordinateFrame.h"
|
||||
#include "G3D/Projection.h"
|
||||
#include "G3D/PhysicsFrame.h"
|
||||
#include "G3D/PhysicsFrameSpline.h"
|
||||
#include "G3D/Plane.h"
|
||||
@@ -53,6 +67,7 @@
|
||||
#include "G3D/Box2D.h"
|
||||
#include "G3D/AABox.h"
|
||||
#include "G3D/WrapMode.h"
|
||||
#include "G3D/CullFace.h"
|
||||
#include "G3D/Cone.h"
|
||||
#include "G3D/Quat.h"
|
||||
#include "G3D/stringutils.h"
|
||||
@@ -61,6 +76,7 @@
|
||||
#include "G3D/FileSystem.h"
|
||||
#include "G3D/Set.h"
|
||||
#include "G3D/GUniqueID.h"
|
||||
#include "G3D/RayGridIterator.h"
|
||||
#include "G3D/BinaryFormat.h"
|
||||
#include "G3D/BinaryInput.h"
|
||||
#include "G3D/BinaryOutput.h"
|
||||
@@ -68,6 +84,10 @@
|
||||
#include "G3D/g3dfnmatch.h"
|
||||
#include "G3D/G3DGameUnits.h"
|
||||
#include "G3D/g3dmath.h"
|
||||
#include "G3D/unorm8.h"
|
||||
#include "G3D/unorm16.h"
|
||||
#include "G3D/snorm8.h"
|
||||
#include "G3D/snorm16.h"
|
||||
#include "G3D/uint128.h"
|
||||
#include "G3D/fileutils.h"
|
||||
#include "G3D/ReferenceCount.h"
|
||||
@@ -75,14 +95,19 @@
|
||||
#include "G3D/GMutex.h"
|
||||
#include "G3D/PrecomputedRandom.h"
|
||||
#include "G3D/MemoryManager.h"
|
||||
#include "G3D/BlockPoolMemoryManager.h"
|
||||
#include "G3D/AreaMemoryManager.h"
|
||||
#include "G3D/BumpMapPreprocess.h"
|
||||
#include "G3D/CubeFace.h"
|
||||
#include "G3D/Line2D.h"
|
||||
#include "G3D/ThreadsafeQueue.h"
|
||||
#include "G3D/network.h"
|
||||
|
||||
template<class T> struct HashTrait< G3D::ReferenceCountedPointer<T> > {
|
||||
static size_t hashCode(G3D::ReferenceCountedPointer<T> key) { return reinterpret_cast<size_t>( key.pointer() ); }
|
||||
template<class T> struct HashTrait< shared_ptr<T> > {
|
||||
static size_t hashCode(shared_ptr<T> key) { return reinterpret_cast<size_t>( key.get() ); }
|
||||
};
|
||||
|
||||
#include "G3D/GImage.h"
|
||||
#include "G3D/Image.h"
|
||||
#include "G3D/CollisionDetection.h"
|
||||
#include "G3D/Intersect.h"
|
||||
#include "G3D/Log.h"
|
||||
@@ -98,18 +123,14 @@ template<class T> struct HashTrait< G3D::ReferenceCountedPointer<T> > {
|
||||
#include "G3D/Capsule.h"
|
||||
#include "G3D/Cylinder.h"
|
||||
#include "G3D/Triangle.h"
|
||||
#include "G3D/Color3uint8.h"
|
||||
#include "G3D/Color4uint8.h"
|
||||
#include "G3D/Vector2int16.h"
|
||||
#include "G3D/Vector3int16.h"
|
||||
#include "G3D/Vector3int32.h"
|
||||
#include "G3D/Vector4int8.h"
|
||||
#include "G3D/Color1unorm8.h"
|
||||
#include "G3D/Color2unorm8.h"
|
||||
#include "G3D/Color3unorm8.h"
|
||||
#include "G3D/Color4unorm8.h"
|
||||
#include "G3D/ConvexPolyhedron.h"
|
||||
#include "G3D/MeshAlg.h"
|
||||
#include "G3D/vectorMath.h"
|
||||
#include "G3D/Rect2D.h"
|
||||
#include "G3D/GCamera.h"
|
||||
#include "G3D/GLight.h"
|
||||
#include "G3D/KDTree.h"
|
||||
#include "G3D/PointKDTree.h"
|
||||
#include "G3D/TextOutput.h"
|
||||
@@ -124,40 +145,82 @@ template<class T> struct HashTrait< G3D::ReferenceCountedPointer<T> > {
|
||||
#include "G3D/PointHashGrid.h"
|
||||
#include "G3D/Map2D.h"
|
||||
#include "G3D/Image1.h"
|
||||
#include "G3D/Image1uint8.h"
|
||||
#include "G3D/Image1unorm8.h"
|
||||
#include "G3D/Image3.h"
|
||||
#include "G3D/Image3uint8.h"
|
||||
#include "G3D/Image3unorm8.h"
|
||||
#include "G3D/Image4.h"
|
||||
#include "G3D/Image4uint8.h"
|
||||
#include "G3D/Image4unorm8.h"
|
||||
#include "G3D/filter.h"
|
||||
#include "G3D/WeakCache.h"
|
||||
#include "G3D/Pointer.h"
|
||||
#include "G3D/Matrix.h"
|
||||
#include "G3D/ImageFormat.h"
|
||||
#include "G3D/PixelTransferBuffer.h"
|
||||
#include "G3D/typeutils.h"
|
||||
#include "G3D/SpeedLoad.h"
|
||||
#include "G3D/ParseMTL.h"
|
||||
#include "G3D/ParseOBJ.h"
|
||||
#include "G3D/ParsePLY.h"
|
||||
#include "G3D/Parse3DS.h"
|
||||
#include "G3D/PathDirection.h"
|
||||
#include "G3D/FastPODTable.h"
|
||||
#include "G3D/FastPointHashGrid.h"
|
||||
#include "G3D/PixelTransferBuffer.h"
|
||||
#include "G3D/CPUPixelTransferBuffer.h"
|
||||
#include "G3D/CompassDirection.h"
|
||||
#include "G3D/Access.h"
|
||||
|
||||
namespace G3D {
|
||||
|
||||
/**
|
||||
Call from main() to initialize the G3D library state and register
|
||||
shutdown memory managers. This does not initialize OpenGL.
|
||||
|
||||
If you invoke initGLG3D, then it will automatically call initG3D.
|
||||
It is safe to call this function more than once--it simply ignores
|
||||
multiple calls.
|
||||
|
||||
\see System, GLCaps, OSWindow, RenderDevice, initGLG3D.
|
||||
|
||||
*/
|
||||
void initG3D(const G3DSpecification& spec = G3DSpecification());
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma comment(lib, "zlib")
|
||||
# pragma comment(lib, "ws2_32")
|
||||
# pragma comment(lib, "winmm")
|
||||
# pragma comment(lib, "imagehlp")
|
||||
# pragma comment(lib, "ws2_32")
|
||||
# pragma comment(lib, "gdi32")
|
||||
# pragma comment(lib, "user32")
|
||||
# pragma comment(lib, "kernel32")
|
||||
# pragma comment(lib, "version")
|
||||
# pragma comment(lib, "advapi32")
|
||||
# pragma comment(lib, "png")
|
||||
# pragma comment(lib, "jpeg")
|
||||
# pragma comment(lib, "zip")
|
||||
# ifdef _DEBUG
|
||||
// Don't link against G3D when building G3D itself.
|
||||
# ifndef G3D_BUILDING_LIBRARY_DLL
|
||||
# pragma comment(lib, "G3Dd.lib")
|
||||
# endif
|
||||
# pragma comment(lib, "shell32")
|
||||
# pragma comment(lib, "version")
|
||||
# ifdef G3D_64BIT
|
||||
# pragma comment(lib, "zlib_x64")
|
||||
# pragma comment(lib, "zip_x64")
|
||||
# pragma comment(lib, "enet_x64")
|
||||
# else
|
||||
// Don't link against G3D when building G3D itself.
|
||||
# ifndef G3D_BUILDING_LIBRARY_DLL
|
||||
# pragma comment(lib, "G3D.lib")
|
||||
# endif
|
||||
# pragma comment(lib, "zlib")
|
||||
# pragma comment(lib, "zip")
|
||||
# pragma comment(lib, "enet")
|
||||
# endif
|
||||
# if defined(_DEBUG)
|
||||
# ifdef G3D_64BIT
|
||||
# pragma comment(lib, "G3D_x64d")
|
||||
# pragma comment(lib, "freeimage_x64d")
|
||||
# else
|
||||
# pragma comment(lib, "G3Dd")
|
||||
# pragma comment(lib, "freeimaged")
|
||||
# endif
|
||||
# else
|
||||
# ifdef G3D_64BIT
|
||||
# pragma comment(lib, "G3D_x64")
|
||||
# pragma comment(lib, "freeimage_x64")
|
||||
# else
|
||||
# pragma comment(lib, "G3D")
|
||||
# pragma comment(lib, "freeimage")
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
9
deps/g3dlite/include/G3D/G3DGameUnits.h
vendored
9
deps/g3dlite/include/G3D/G3DGameUnits.h
vendored
@@ -3,7 +3,7 @@
|
||||
|
||||
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
@created 2002-10-05
|
||||
@edited 2006-11-10
|
||||
@edited 2012-02-19
|
||||
*/
|
||||
|
||||
#ifndef G3D_GAMEUNITS_H
|
||||
@@ -12,14 +12,17 @@
|
||||
#include "G3D/platform.h"
|
||||
|
||||
namespace G3D {
|
||||
|
||||
/** \deprecated use SimTime */
|
||||
typedef double GameTime;
|
||||
|
||||
/**
|
||||
Time, in seconds.
|
||||
*/
|
||||
typedef double GameTime;
|
||||
typedef double SimTime;
|
||||
|
||||
/**
|
||||
Actual wall clock time in seconds.
|
||||
Actual wall clock time in seconds (Unix time).
|
||||
*/
|
||||
typedef double RealTime;
|
||||
|
||||
|
||||
25
deps/g3dlite/include/G3D/GMutex.h
vendored
25
deps/g3dlite/include/G3D/GMutex.h
vendored
@@ -1,8 +1,8 @@
|
||||
/**
|
||||
@file GMutex.h
|
||||
\file G3D/GMutex.h
|
||||
|
||||
@created 2005-09-22
|
||||
@edited 2009-03-25
|
||||
\created 2005-09-22
|
||||
\edited 2013-04-03
|
||||
*/
|
||||
|
||||
#ifndef G3D_GMutex_h
|
||||
@@ -13,10 +13,13 @@
|
||||
#include "G3D/debugAssert.h"
|
||||
#include <string>
|
||||
|
||||
#ifndef G3D_WIN32
|
||||
#ifndef G3D_WINDOWS
|
||||
# include <pthread.h>
|
||||
# include <signal.h>
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if defined(G3D_LINUX) || defined(G3D_OSX)
|
||||
# include <unistd.h> // For usleep
|
||||
#endif
|
||||
|
||||
|
||||
@@ -26,7 +29,7 @@ namespace G3D {
|
||||
\brief A mutual exclusion lock that busy-waits when locking.
|
||||
|
||||
On a machine with one (significant) thread per processor core,
|
||||
a spinlock may be substantially faster than a mutex.
|
||||
a Spinlock may be substantially faster than a mutex.
|
||||
|
||||
\sa G3D::GThread, G3D::GMutex, G3D::AtomicInt32
|
||||
*/
|
||||
@@ -41,12 +44,16 @@ public:
|
||||
|
||||
/** Busy waits until the lock is unlocked, then locks it
|
||||
exclusively. Returns true if the lock succeeded on the first
|
||||
try (indicating no contention). */
|
||||
try (indicating no contention).
|
||||
|
||||
Unlike a G3D::GMutex, a single thread cannot re-enter
|
||||
Spinlock::lock() that it already locked.
|
||||
*/
|
||||
inline bool lock() {
|
||||
bool first = true;
|
||||
while (x.compareAndSet(0, 1) == 1) {
|
||||
first = false;
|
||||
# ifdef G3D_WIN32
|
||||
# ifdef G3D_WINDOWS
|
||||
Sleep(0);
|
||||
# else
|
||||
usleep(0);
|
||||
@@ -68,7 +75,7 @@ public:
|
||||
*/
|
||||
class GMutex {
|
||||
private:
|
||||
# ifdef G3D_WIN32
|
||||
# ifdef G3D_WINDOWS
|
||||
CRITICAL_SECTION m_handle;
|
||||
# else
|
||||
pthread_mutex_t m_handle;
|
||||
|
||||
177
deps/g3dlite/include/G3D/GThread.h
vendored
177
deps/g3dlite/include/G3D/GThread.h
vendored
@@ -2,18 +2,21 @@
|
||||
@file GThread.h
|
||||
|
||||
@created 2005-09-22
|
||||
@edited 2007-01-31
|
||||
@edited 2010-09-10
|
||||
|
||||
*/
|
||||
|
||||
#ifndef G3D_GTHREAD_H
|
||||
#define G3D_GTHREAD_H
|
||||
#ifndef G3D_GThread_h
|
||||
#define G3D_GThread_h
|
||||
|
||||
#include "G3D/platform.h"
|
||||
#include "G3D/ReferenceCount.h"
|
||||
#include "G3D/ThreadSet.h"
|
||||
#include "G3D/Vector2int32.h"
|
||||
#include "G3D/SpawnBehavior.h"
|
||||
#include <string>
|
||||
|
||||
#ifndef G3D_WIN32
|
||||
#ifndef G3D_WINDOWS
|
||||
# include <pthread.h>
|
||||
# include <signal.h>
|
||||
#endif
|
||||
@@ -21,7 +24,9 @@
|
||||
|
||||
namespace G3D {
|
||||
|
||||
typedef ReferenceCountedPointer<class GThread> GThreadRef;
|
||||
typedef shared_ptr<class GThread> GThreadRef;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Platform independent thread implementation. You can either subclass and
|
||||
@@ -32,11 +37,11 @@ typedef ReferenceCountedPointer<class GThread> GThreadRef;
|
||||
dropping all pointers (and causing deallocation) of a GThread does NOT
|
||||
stop the underlying process.
|
||||
|
||||
@sa G3D::GMutex, G3D::Spinlock, G3D::AtomicInt32
|
||||
\sa G3D::GMutex, G3D::Spinlock, G3D::AtomicInt32, G3D::ThreadSet
|
||||
*/
|
||||
class GThread : public ReferenceCountedObject {
|
||||
private:
|
||||
// "Status" is a reserved work on FreeBSD
|
||||
// "Status" is a reserved word on FreeBSD
|
||||
enum GStatus {STATUS_CREATED, STATUS_STARTED, STATUS_RUNNING, STATUS_COMPLETED};
|
||||
|
||||
// Not implemented on purpose, don't use
|
||||
@@ -44,21 +49,21 @@ private:
|
||||
GThread& operator=(const GThread&);
|
||||
bool operator==(const GThread&);
|
||||
|
||||
#ifdef G3D_WIN32
|
||||
#ifdef G3D_WINDOWS
|
||||
static DWORD WINAPI internalThreadProc(LPVOID param);
|
||||
#else
|
||||
static void* internalThreadProc(void* param);
|
||||
#endif //G3D_WIN32
|
||||
#endif //G3D_WINDOWS
|
||||
|
||||
volatile GStatus m_status;
|
||||
|
||||
// Thread handle to hold HANDLE and pthread_t
|
||||
#ifdef G3D_WIN32
|
||||
#ifdef G3D_WINDOWS
|
||||
HANDLE m_handle;
|
||||
HANDLE m_event;
|
||||
#else
|
||||
pthread_t m_handle;
|
||||
#endif //G3D_WIN32
|
||||
#endif //G3D_WINDOWS
|
||||
|
||||
std::string m_name;
|
||||
|
||||
@@ -68,8 +73,11 @@ protected:
|
||||
virtual void threadMain() = 0;
|
||||
|
||||
public:
|
||||
typedef ReferenceCountedPointer<class GThread> Ref;
|
||||
enum SpawnBehavior {USE_NEW_THREAD, USE_CURRENT_THREAD};
|
||||
|
||||
/** Returns System::numCores(); put here to break a dependence on System.h */
|
||||
static int numCores();
|
||||
|
||||
typedef shared_ptr<class GThread> Ref;
|
||||
|
||||
GThread(const std::string& name);
|
||||
|
||||
@@ -110,12 +118,153 @@ public:
|
||||
void waitForCompletion();
|
||||
|
||||
/** Returns thread name */
|
||||
inline const std::string& name() {
|
||||
const std::string& name() {
|
||||
return m_name;
|
||||
}
|
||||
|
||||
/** For backwards compatibility to G3D 8.xx */
|
||||
static const SpawnBehavior USE_CURRENT_THREAD = G3D::USE_CURRENT_THREAD;
|
||||
/** For backwards compatibility to G3D 8.xx */
|
||||
static const SpawnBehavior USE_NEW_THREAD = G3D::USE_NEW_THREAD;
|
||||
|
||||
enum {
|
||||
/** Tells GThread::runConcurrently() and GThread::runConcurrently2D() to
|
||||
use System::numCores() threads.*/
|
||||
NUM_CORES = -100
|
||||
};
|
||||
|
||||
/**
|
||||
\brief Iterates over a 2D region using multiple threads and
|
||||
blocks until all threads have completed. <p> Evaluates \a
|
||||
object->\a method(\a x, \a y) for every <code>start.x <= x <
|
||||
upTo.x</code> and <code>start.y <= y < upTo.y</code>.
|
||||
Iteration is row major, so each thread can expect to see
|
||||
successive x values. </p>
|
||||
\param maxThreads
|
||||
Maximum number of threads to use. By default at most one
|
||||
thread per processor core will be used.
|
||||
|
||||
Example:
|
||||
|
||||
\code
|
||||
class RayTracer {
|
||||
public:
|
||||
void trace(const Vector2int32& pixel) {
|
||||
...
|
||||
}
|
||||
|
||||
void traceAll() {
|
||||
GThread::runConcurrently2D(Point2int32(0,0), Point2int32(w,h), this, &RayTracer::trace);
|
||||
}
|
||||
};
|
||||
\endcode
|
||||
*/
|
||||
template<class Class>
|
||||
static void runConcurrently2D
|
||||
(const Vector2int32& start,
|
||||
const Vector2int32& upTo,
|
||||
Class* object,
|
||||
void (Class::*method)(int x, int y),
|
||||
int maxThreads = NUM_CORES) {
|
||||
_internal_runConcurrently2DHelper(start, upTo, object, method, static_cast<void (Class::*)(int, int, int)>(NULL), maxThreads);
|
||||
}
|
||||
|
||||
/** Like the other version of runConcurrently2D, but tells the
|
||||
method the thread index that it is running on. That enables
|
||||
the caller to manage per-thread state.
|
||||
*/
|
||||
template<class Class>
|
||||
static void runConcurrently2D
|
||||
(const Vector2int32& start,
|
||||
const Vector2int32& upTo,
|
||||
Class* object,
|
||||
void (Class::*method)(int x, int y, int threadID),
|
||||
int maxThreads = NUM_CORES) {
|
||||
_internal_runConcurrently2DHelper(start, upTo, object, static_cast<void (Class::*)(int, int)>(NULL), method, maxThreads);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Can't use an inherited class inside of its parent on g++ 4.2.1 if it is later a template parameter
|
||||
|
||||
/** For use by runConcurrently2D. Designed for arbitrary iteration, although only used for
|
||||
interlaced rows in the current implementation. */
|
||||
template<class Class>
|
||||
class _internalGThreadWorker : public GThread {
|
||||
public:
|
||||
/** Start for this thread, which differs from the others */
|
||||
const int threadID;
|
||||
const Vector2int32 start;
|
||||
const Vector2int32 upTo;
|
||||
const Vector2int32 stride;
|
||||
Class* object;
|
||||
void (Class::*method1)(int x, int y);
|
||||
void (Class::*method2)(int x, int y, int threadID);
|
||||
|
||||
_internalGThreadWorker(int threadID,
|
||||
const Vector2int32& start,
|
||||
const Vector2int32& upTo,
|
||||
Class* object,
|
||||
void (Class::*method1)(int x, int y),
|
||||
void (Class::*method2)(int x, int y, int threadID),
|
||||
const Vector2int32& stride) :
|
||||
GThread("runConcurrently2D worker"),
|
||||
threadID(threadID),
|
||||
start(start),
|
||||
upTo(upTo),
|
||||
stride(stride),
|
||||
object(object),
|
||||
method1(method1),
|
||||
method2(method2) {}
|
||||
|
||||
virtual void threadMain() {
|
||||
for (int y = start.y; y < upTo.y; y += stride.y) {
|
||||
// Run whichever method was provided
|
||||
if (method1) {
|
||||
for (int x = start.x; x < upTo.x; x += stride.x) {
|
||||
(object->*method1)(x, y);
|
||||
}
|
||||
} else {
|
||||
for (int x = start.x; x < upTo.x; x += stride.x) {
|
||||
(object->*method2)(x, y, threadID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<class Class>
|
||||
void _internal_runConcurrently2DHelper
|
||||
(const Vector2int32& start,
|
||||
const Vector2int32& upTo,
|
||||
Class* object,
|
||||
void (Class::*method1)(int x, int y),
|
||||
void (Class::*method2)(int x, int y, int threadID),
|
||||
int maxThreads) {
|
||||
|
||||
// Create a group of threads
|
||||
if (maxThreads == GThread::NUM_CORES) {
|
||||
maxThreads = GThread::numCores();
|
||||
}
|
||||
|
||||
const int numRows = upTo.y - start.y;
|
||||
const int numThreads = min(maxThreads, numRows);
|
||||
const Vector2int32 stride(1, numThreads);
|
||||
ThreadSet threadSet;
|
||||
for (int t = 0; t < numThreads; ++t) {
|
||||
threadSet.insert(shared_ptr<_internalGThreadWorker<Class> >(new _internalGThreadWorker<Class>(t, start + Vector2int32(0, t), upTo, object, method1, method2, stride)));
|
||||
}
|
||||
|
||||
// Run the threads, reusing the current thread and blocking until
|
||||
// all complete
|
||||
threadSet.start(USE_CURRENT_THREAD);
|
||||
threadSet.waitForCompletion();
|
||||
}
|
||||
|
||||
|
||||
} // namespace G3D
|
||||
|
||||
#endif //G3D_GTHREAD_H
|
||||
|
||||
33
deps/g3dlite/include/G3D/GUniqueID.h
vendored
33
deps/g3dlite/include/G3D/GUniqueID.h
vendored
@@ -1,16 +1,18 @@
|
||||
/**
|
||||
@file GUniqueID.h
|
||||
@author Morgan McGuire, http://graphics.cs.williams.edu
|
||||
\file G3D/GUniqueID.h
|
||||
\author Morgan McGuire, http://graphics.cs.williams.edu
|
||||
*/
|
||||
#ifndef G3D_GUNIQUEID_H
|
||||
#define G3D_GUNIQUEID_H
|
||||
#ifndef G3D_GUniqueID_h
|
||||
#define G3D_GUniqueID_h
|
||||
|
||||
#include "G3D/platform.h"
|
||||
#include "G3D/g3dmath.h"
|
||||
#include "G3D/Table.h"
|
||||
|
||||
namespace G3D {
|
||||
|
||||
|
||||
class Any;
|
||||
|
||||
/** Globally unique identifiers. The probability of two different
|
||||
programs generating the same value from UniqueID::create is
|
||||
vanishingly small.
|
||||
@@ -25,8 +27,27 @@ private:
|
||||
|
||||
public:
|
||||
|
||||
/** \sa create */
|
||||
GUniqueID() : id(0) {}
|
||||
|
||||
GUniqueID& operator=(const Any& a);
|
||||
|
||||
/** \sa create */
|
||||
GUniqueID(const Any& a) {
|
||||
*this = a;
|
||||
}
|
||||
|
||||
Any toAny() const;
|
||||
|
||||
/** Returns a 16-character string equivalent to this GUniqueID's uint64 value. */
|
||||
std::string toString16() const;
|
||||
|
||||
static GUniqueID fromString16(const std::string& s);
|
||||
|
||||
/** Returns the ID that has the specified tag (so that it is not uninitialized), but
|
||||
which is a common sentinel "none" value. */
|
||||
static GUniqueID NONE(uint16 tag);
|
||||
|
||||
bool uninitialized() const {
|
||||
return id == 0;
|
||||
}
|
||||
@@ -37,7 +58,7 @@ public:
|
||||
|
||||
operator uint64() const {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
bool operator==(const GUniqueID& other) const {
|
||||
return id == other.id;
|
||||
|
||||
135
deps/g3dlite/include/G3D/HashTrait.h
vendored
135
deps/g3dlite/include/G3D/HashTrait.h
vendored
@@ -1,11 +1,11 @@
|
||||
/**
|
||||
@file HashTrait.h
|
||||
\file G3D/HashTrait.h
|
||||
|
||||
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
@created 2008-10-01
|
||||
@edited 2009-11-01
|
||||
\maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
\created 2008-10-01
|
||||
\edited 2011-06-09
|
||||
|
||||
Copyright 2000-2009, Morgan McGuire.
|
||||
Copyright 2000-2012, Morgan McGuire.
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
@@ -16,6 +16,88 @@
|
||||
#include "G3D/Crypto.h"
|
||||
#include "G3D/g3dmath.h"
|
||||
#include "G3D/uint128.h"
|
||||
#include <typeinfo>
|
||||
|
||||
#include <stdint.h>
|
||||
#undef get16bits
|
||||
#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \
|
||||
|| defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__)
|
||||
#define get16bits(d) (*((const uint16_t *) (d)))
|
||||
#endif
|
||||
|
||||
#if !defined (get16bits)
|
||||
#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)\
|
||||
+(uint32_t)(((const uint8_t *)(d))[0]) )
|
||||
#endif
|
||||
namespace G3D {
|
||||
/** \brief A hash function that is faster than CRC32 for arbitrary long strings
|
||||
\cite From http://www.azillionmonkeys.com/qed/hash.html by Paul Hsieh*/
|
||||
inline uint32_t superFastHash (const void* _data, size_t numBytes) {
|
||||
const char* data = (const char*)_data;
|
||||
uint32_t hash = (uint32_t)numBytes;
|
||||
uint32_t tmp;
|
||||
int rem;
|
||||
|
||||
if ((numBytes <= 0) || (data == NULL)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
rem = numBytes & 3;
|
||||
numBytes >>= 2;
|
||||
|
||||
/* Main loop */
|
||||
for (;numBytes > 0; --numBytes) {
|
||||
hash += get16bits (data);
|
||||
tmp = (get16bits (data+2) << 11) ^ hash;
|
||||
hash = (hash << 16) ^ tmp;
|
||||
data += 2*sizeof (uint16_t);
|
||||
hash += hash >> 11;
|
||||
}
|
||||
|
||||
/* Handle end cases */
|
||||
switch (rem) {
|
||||
case 3: hash += get16bits (data);
|
||||
hash ^= hash << 16;
|
||||
hash ^= data[sizeof (uint16_t)] << 18;
|
||||
hash += hash >> 11;
|
||||
break;
|
||||
case 2: hash += get16bits (data);
|
||||
hash ^= hash << 11;
|
||||
hash += hash >> 17;
|
||||
break;
|
||||
case 1: hash += *data;
|
||||
hash ^= hash << 10;
|
||||
hash += hash >> 1;
|
||||
}
|
||||
|
||||
/* Force "avalanching" of final 127 bits */
|
||||
hash ^= hash << 3;
|
||||
hash += hash >> 5;
|
||||
hash ^= hash << 4;
|
||||
hash += hash >> 17;
|
||||
hash ^= hash << 25;
|
||||
hash += hash >> 6;
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Thomas Wang's 64-to-32-bit mix hash based on Robert Jenkin's hash http://www.concentric.net/~ttwang/tech/inthash.htm
|
||||
|
||||
Found by Morgan to produce the best net performance for building tables from Vector4int16
|
||||
*/
|
||||
inline uint32_t wangHash6432Shift(int64 key) {
|
||||
key = (~key) + (key << 18); // key = (key << 18) - key - 1;
|
||||
key = key ^ (key >> 31);
|
||||
key = key * 21; // key = (key + (key << 2)) + (key << 4);
|
||||
key = key ^ (key >> 11);
|
||||
key = key + (key << 6);
|
||||
return uint32_t(key) ^ uint32_t(key >> 22);
|
||||
}
|
||||
|
||||
}
|
||||
#undef get16bits
|
||||
|
||||
/** Must be specialized for custom types.
|
||||
@see G3D::Table for specialization requirements.
|
||||
@@ -23,14 +105,19 @@
|
||||
template <typename T> struct HashTrait{};
|
||||
|
||||
template <typename T> struct HashTrait<T*> {
|
||||
static size_t hashCode(const void* k) { return reinterpret_cast<size_t>(k); }
|
||||
static size_t hashCode(const void* k) { return reinterpret_cast<size_t>(k) >> 1; }
|
||||
};
|
||||
|
||||
#if 0
|
||||
template <> struct HashTrait <int> {
|
||||
static size_t hashCode(int k) { return static_cast<size_t>(k); }
|
||||
/** For use with \code Table<std::type_info* const, ValueType> \endcode. */
|
||||
template <> struct HashTrait <std::type_info* const> {
|
||||
static size_t hashCode(const std::type_info* const t) {
|
||||
# ifdef _MSC_VER
|
||||
return t->hash_code();
|
||||
# else
|
||||
return reinterpret_cast<size_t>(t) >> 1;
|
||||
# endif
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
template <> struct HashTrait <G3D::int16> {
|
||||
static size_t hashCode(G3D::int16 k) { return static_cast<size_t>(k); }
|
||||
@@ -40,10 +127,6 @@ template <> struct HashTrait <G3D::uint16> {
|
||||
static size_t hashCode(G3D::uint16 k) { return static_cast<size_t>(k); }
|
||||
};
|
||||
|
||||
//template <> struct HashTrait <int> {
|
||||
// static size_t hashCode(int k) { return static_cast<size_t>(k); }
|
||||
//};
|
||||
|
||||
template <> struct HashTrait <G3D::int32> {
|
||||
static size_t hashCode(G3D::int32 k) { return static_cast<size_t>(k); }
|
||||
};
|
||||
@@ -58,21 +141,30 @@ template <> struct HashTrait <long unsigned int> {
|
||||
};
|
||||
#endif
|
||||
|
||||
template <> struct HashTrait <G3D::int64> {
|
||||
static size_t hashCode(G3D::int64 k) { return static_cast<size_t>(k); }
|
||||
};
|
||||
|
||||
template <> struct HashTrait <G3D::uint64> {
|
||||
static size_t hashCode(G3D::uint64 k) { return static_cast<size_t>(k); }
|
||||
static size_t hashCode(G3D::uint64 k) { return static_cast<size_t>(k) ^ static_cast<size_t>(k >> 32); }
|
||||
};
|
||||
|
||||
template <> struct HashTrait <G3D::int64> {
|
||||
static size_t hashCode(G3D::int64 k) { return HashTrait<G3D::uint64>::hashCode(G3D::uint64(k)); }
|
||||
};
|
||||
|
||||
|
||||
template <> struct HashTrait <std::string> {
|
||||
static size_t hashCode(const std::string& k) { return static_cast<size_t>(G3D::Crypto::crc32(k.c_str(), k.size())); }
|
||||
static size_t hashCode(const std::string& k) {
|
||||
return G3D::superFastHash(k.c_str(), k.size());
|
||||
//return static_cast<size_t>(G3D::Crypto::crc32(k.c_str(), k.size()));
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct HashTrait<G3D::uint128> {
|
||||
// Use the FNV-1 hash (http://isthe.com/chongo/tech/comp/fnv/#FNV-1).
|
||||
static size_t hashCode(G3D::uint128 key) {
|
||||
return G3D::superFastHash(&key, sizeof(key));
|
||||
//return HashTrait<G3D::uint64>::hashCode(key.hi) ^ HashTrait<G3D::uint64>::hashCode(key.lo);
|
||||
|
||||
#if 0 // Really slow under gcc
|
||||
// Use the FNV-1 hash (http://isthe.com/chongo/tech/comp/fnv/#FNV-1).
|
||||
static const G3D::uint128 FNV_PRIME_128(1 << 24, 0x159);
|
||||
static const G3D::uint128 FNV_OFFSET_128(0xCF470AAC6CB293D2ULL, 0xF52F88BF32307F8FULL);
|
||||
|
||||
@@ -83,9 +175,10 @@ template <> struct HashTrait<G3D::uint128> {
|
||||
hash ^= (mask & key);
|
||||
key >>= 8;
|
||||
}
|
||||
|
||||
|
||||
G3D::uint64 foldedHash = hash.hi ^ hash.lo;
|
||||
return static_cast<size_t>((foldedHash >> 32) ^ (foldedHash & 0xFFFFFFFF));
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
50
deps/g3dlite/include/G3D/Image1.h
vendored
50
deps/g3dlite/include/G3D/Image1.h
vendored
@@ -1,35 +1,34 @@
|
||||
/**
|
||||
@file Image1.h
|
||||
\file G3D/Image1.h
|
||||
|
||||
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
\maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
|
||||
@created 2007-01-31
|
||||
@edited 2007-01-31
|
||||
\created 2007-01-31
|
||||
\edited 2011-08-31
|
||||
*/
|
||||
|
||||
|
||||
#ifndef G3D_IMAGE1_H
|
||||
#define G3D_IMAGE1_H
|
||||
#ifndef G3D_Image1_h
|
||||
#define G3D_Image1_h
|
||||
|
||||
#include "G3D/platform.h"
|
||||
#include "G3D/Map2D.h"
|
||||
#include "G3D/Color1.h"
|
||||
#include "G3D/GImage.h"
|
||||
|
||||
namespace G3D {
|
||||
|
||||
typedef ReferenceCountedPointer<class Image1> Image1Ref;
|
||||
typedef shared_ptr<class Image1> Image1Ref;
|
||||
|
||||
/**
|
||||
Luminance image with 32-bit floating point storage.
|
||||
|
||||
See also G3D::Image1uint8, G3D::GImage.
|
||||
See also G3D::Image1unorm8, G3D::GImage.
|
||||
*/
|
||||
class Image1 : public Map2D<Color1, Color1> {
|
||||
public:
|
||||
|
||||
typedef Image1 Type;
|
||||
typedef ReferenceCountedPointer<class Image1> Ref;
|
||||
typedef shared_ptr<class Image1> Ref;
|
||||
typedef Color1 Storage;
|
||||
typedef Color1 Compute;
|
||||
|
||||
@@ -41,9 +40,9 @@ protected:
|
||||
void copyArray(const Color1* src, int w, int h);
|
||||
void copyArray(const Color3* src, int w, int h);
|
||||
void copyArray(const Color4* src, int w, int h);
|
||||
void copyArray(const Color1uint8* src, int w, int h);
|
||||
void copyArray(const Color3uint8* src, int w, int h);
|
||||
void copyArray(const Color4uint8* src, int w, int h);
|
||||
void copyArray(const Color1unorm8* src, int w, int h);
|
||||
void copyArray(const Color3unorm8* src, int w, int h);
|
||||
void copyArray(const Color4unorm8* src, int w, int h);
|
||||
|
||||
public:
|
||||
|
||||
@@ -55,25 +54,28 @@ public:
|
||||
/** Creates a 0 x 0 image. */
|
||||
static Ref createEmpty(WrapMode wrap = WrapMode::ERROR);
|
||||
|
||||
static Ref fromFile(const std::string& filename, WrapMode wrap = WrapMode::ERROR, GImage::Format fmt = GImage::AUTODETECT);
|
||||
static Ref fromFile(const std::string& filename, WrapMode wrap = WrapMode::ERROR);
|
||||
|
||||
static Ref fromArray(const class Color1uint8* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
|
||||
static Ref fromArray(const class Color3uint8* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
|
||||
static Ref fromArray(const class Color4uint8* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
|
||||
static Ref fromArray(const class Color1unorm8* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
|
||||
static Ref fromArray(const class Color3unorm8* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
|
||||
static Ref fromArray(const class Color4unorm8* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
|
||||
static Ref fromArray(const class Color1* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
|
||||
static Ref fromArray(const class Color3* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
|
||||
static Ref fromArray(const class Color4* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
|
||||
|
||||
static Ref fromImage1uint8(const ReferenceCountedPointer<class Image1uint8>& im);
|
||||
static Ref fromImage1unorm8(const shared_ptr<class Image1unorm8>& im);
|
||||
|
||||
static Ref fromGImage(const class GImage& im, WrapMode wrap = WrapMode::ERROR);
|
||||
/** Loads from any of the file formats supported by G3D::Image.
|
||||
|
||||
/** Loads from any of the file formats supported by G3D::GImage. If there is an alpha channel on the input,
|
||||
it is stripped. */
|
||||
void load(const std::string& filename, GImage::Format fmt = GImage::AUTODETECT);
|
||||
If there is an alpha channel on the input, it is stripped.
|
||||
Values are automatically scaled to the range [0, 1]. */
|
||||
void load(const std::string& filename);
|
||||
|
||||
/** Saves in any of the formats supported by G3D::GImage. */
|
||||
void save(const std::string& filename, GImage::Format fmt = GImage::AUTODETECT);
|
||||
/** Saves in any of the formats supported by G3D::Image.
|
||||
|
||||
The data values are assumed to be on the range [0, 1] and will
|
||||
be scaled appropriately for the save format.*/
|
||||
void save(const std::string& filename);
|
||||
};
|
||||
|
||||
} // G3D
|
||||
|
||||
44
deps/g3dlite/include/G3D/Image3.h
vendored
44
deps/g3dlite/include/G3D/Image3.h
vendored
@@ -1,10 +1,10 @@
|
||||
/**
|
||||
@file Image3.h
|
||||
\file G3D/Image3.h
|
||||
|
||||
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
\maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
|
||||
@created 2007-01-31
|
||||
@edited 2007-01-31
|
||||
\created 2007-01-31
|
||||
\edited 2011-08-31
|
||||
*/
|
||||
|
||||
|
||||
@@ -14,36 +14,32 @@
|
||||
#include "G3D/platform.h"
|
||||
#include "G3D/Map2D.h"
|
||||
#include "G3D/Color3.h"
|
||||
#include "G3D/GImage.h"
|
||||
|
||||
namespace G3D {
|
||||
|
||||
typedef ReferenceCountedPointer<class Image3> Image3Ref;
|
||||
typedef shared_ptr<class Image3> Image3Ref;
|
||||
|
||||
/**
|
||||
RGB image with 32-bit floating point storage for each channel.
|
||||
|
||||
See also G3D::Image3uint8, G3D::GImage.
|
||||
See also G3D::Image3unorm8, G3D::GImage.
|
||||
*/
|
||||
class Image3 : public Map2D<Color3, Color3> {
|
||||
public:
|
||||
|
||||
typedef Image3 Type;
|
||||
typedef ReferenceCountedPointer<class Image3> Ref;
|
||||
typedef Color3 Storage;
|
||||
typedef Color3 Compute;
|
||||
typedef shared_ptr<class Image3> Ref;
|
||||
|
||||
protected:
|
||||
|
||||
Image3(int w, int h, WrapMode wrap);
|
||||
|
||||
void copyGImage(const class GImage& im);
|
||||
void copyArray(const Color1* src, int w, int h);
|
||||
void copyArray(const Color3* src, int w, int h);
|
||||
void copyArray(const Color4* src, int w, int h);
|
||||
void copyArray(const Color1uint8* src, int w, int h);
|
||||
void copyArray(const Color3uint8* src, int w, int h);
|
||||
void copyArray(const Color4uint8* src, int w, int h);
|
||||
void copyArray(const Color1unorm8* src, int w, int h);
|
||||
void copyArray(const Color3unorm8* src, int w, int h);
|
||||
void copyArray(const Color4unorm8* src, int w, int h);
|
||||
|
||||
public:
|
||||
|
||||
@@ -55,25 +51,23 @@ public:
|
||||
/** Creates a 0 x 0 image. */
|
||||
static Ref createEmpty(WrapMode wrap = WrapMode::ERROR);
|
||||
|
||||
static Ref fromFile(const std::string& filename, WrapMode wrap = WrapMode::ERROR, GImage::Format fmt = GImage::AUTODETECT);
|
||||
static Ref fromFile(const std::string& filename, WrapMode wrap = WrapMode::ERROR);
|
||||
|
||||
static Ref fromArray(const class Color1uint8* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
|
||||
static Ref fromArray(const class Color3uint8* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
|
||||
static Ref fromArray(const class Color4uint8* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
|
||||
static Ref fromArray(const class Color1unorm8* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
|
||||
static Ref fromArray(const class Color3unorm8* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
|
||||
static Ref fromArray(const class Color4unorm8* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
|
||||
static Ref fromArray(const class Color1* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
|
||||
static Ref fromArray(const class Color3* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
|
||||
static Ref fromArray(const class Color4* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
|
||||
|
||||
static Ref fromImage3uint8(const ReferenceCountedPointer<class Image3uint8>& im);
|
||||
|
||||
static Ref fromGImage(const class GImage& im, WrapMode wrap = WrapMode::ERROR);
|
||||
static Ref fromImage3unorm8(const shared_ptr<class Image3unorm8>& im);
|
||||
|
||||
/** Loads from any of the file formats supported by G3D::GImage. If there is an alpha channel on the input,
|
||||
it is stripped. */
|
||||
void load(const std::string& filename, GImage::Format fmt = GImage::AUTODETECT);
|
||||
it is stripped. Converts 8-bit formats to the range (0, 1) */
|
||||
void load(const std::string& filename);
|
||||
|
||||
/** Saves in any of the formats supported by G3D::GImage. */
|
||||
void save(const std::string& filename, GImage::Format fmt = GImage::AUTODETECT);
|
||||
/** Saves in any of the formats supported by G3D::GImage. Assumes the data is on the range (0, 1) if saving to an 8-bit format.*/
|
||||
void save(const std::string& filename);
|
||||
};
|
||||
|
||||
} // G3D
|
||||
|
||||
46
deps/g3dlite/include/G3D/Image4.h
vendored
46
deps/g3dlite/include/G3D/Image4.h
vendored
@@ -1,24 +1,23 @@
|
||||
/**
|
||||
@file Image4.h
|
||||
\file G3D/Image4.h
|
||||
|
||||
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
\maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
|
||||
@created 2007-01-31
|
||||
@edited 2007-01-31
|
||||
\created 2007-01-31
|
||||
\edited 2011-08-11
|
||||
*/
|
||||
|
||||
|
||||
#ifndef G3D_IMAGE4_H
|
||||
#define G3D_IMAGE4_H
|
||||
#ifndef G3D_Image4_h
|
||||
#define G3D_Image4_h
|
||||
|
||||
#include "G3D/platform.h"
|
||||
#include "G3D/Map2D.h"
|
||||
#include "G3D/Color4.h"
|
||||
#include "G3D/GImage.h"
|
||||
|
||||
namespace G3D {
|
||||
|
||||
typedef ReferenceCountedPointer<class Image4> Image4Ref;
|
||||
typedef shared_ptr<class Image4> Image4Ref;
|
||||
|
||||
/**
|
||||
RGBA image with 32-bit floating point storage for each channel.
|
||||
@@ -26,30 +25,27 @@ typedef ReferenceCountedPointer<class Image4> Image4Ref;
|
||||
Whenever a method needs to convert from RGB to RGBA, A=1 is assumed.
|
||||
|
||||
Bilinear interpolation on Image4 is about 8x faster than on
|
||||
Image4uint8 due to the large cost of converting int->float on modern
|
||||
Image4unorm8 due to the large cost of converting int->float on modern
|
||||
machines.
|
||||
|
||||
@sa G3D::Image4uint8, G3D::GImage.
|
||||
@sa G3D::Image4unorm8, G3D::GImage.
|
||||
*/
|
||||
class Image4 : public Map2D<Color4, Color4> {
|
||||
public:
|
||||
|
||||
typedef Image4 Type;
|
||||
typedef ReferenceCountedPointer<class Image4> Ref;
|
||||
typedef Color4 Storage;
|
||||
typedef Color4 Compute;
|
||||
typedef shared_ptr<class Image4> Ref;
|
||||
|
||||
protected:
|
||||
|
||||
Image4(int w, int h, WrapMode wrap);
|
||||
|
||||
void copyGImage(const class GImage& im);
|
||||
void copyArray(const Color1* src, int w, int h);
|
||||
void copyArray(const Color3* src, int w, int h);
|
||||
void copyArray(const Color4* src, int w, int h);
|
||||
void copyArray(const Color1uint8* src, int w, int h);
|
||||
void copyArray(const Color3uint8* src, int w, int h);
|
||||
void copyArray(const Color4uint8* src, int w, int h);
|
||||
void copyArray(const Color1unorm8* src, int w, int h);
|
||||
void copyArray(const Color3unorm8* src, int w, int h);
|
||||
void copyArray(const Color4unorm8* src, int w, int h);
|
||||
|
||||
public:
|
||||
|
||||
@@ -61,24 +57,22 @@ public:
|
||||
/** Creates a 0 x 0 image. */
|
||||
static Ref createEmpty(WrapMode wrap = WrapMode::ERROR);
|
||||
|
||||
static Ref fromFile(const std::string& filename, WrapMode wrap = WrapMode::ERROR, GImage::Format fmt = GImage::AUTODETECT);
|
||||
static Ref fromFile(const std::string& filename, WrapMode wrap = WrapMode::ERROR);
|
||||
|
||||
static Ref fromArray(const class Color1uint8* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
|
||||
static Ref fromArray(const class Color3uint8* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
|
||||
static Ref fromArray(const class Color4uint8* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
|
||||
static Ref fromArray(const class Color1unorm8* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
|
||||
static Ref fromArray(const class Color3unorm8* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
|
||||
static Ref fromArray(const class Color4unorm8* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
|
||||
static Ref fromArray(const class Color1* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
|
||||
static Ref fromArray(const class Color3* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
|
||||
static Ref fromArray(const class Color4* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
|
||||
|
||||
static Ref fromImage4uint8(const ReferenceCountedPointer<class Image4uint8>& im);
|
||||
|
||||
static Ref fromGImage(const class GImage& im, WrapMode wrap = WrapMode::ERROR);
|
||||
static Ref fromImage4unorm8(const shared_ptr<class Image4unorm8>& im);
|
||||
|
||||
/** Loads from any of the file formats supported by G3D::GImage. */
|
||||
void load(const std::string& filename, GImage::Format fmt = GImage::AUTODETECT);
|
||||
void load(const std::string& filename);
|
||||
|
||||
/** Saves in any of the formats supported by G3D::GImage. */
|
||||
void save(const std::string& filename, GImage::Format fmt = GImage::AUTODETECT);
|
||||
void save(const std::string& filename);
|
||||
};
|
||||
|
||||
} // G3D
|
||||
|
||||
180
deps/g3dlite/include/G3D/ImageFormat.h
vendored
180
deps/g3dlite/include/G3D/ImageFormat.h
vendored
@@ -1,14 +1,14 @@
|
||||
/**
|
||||
@file ImageFormat.h
|
||||
\file G3D/ImageFormat.h
|
||||
|
||||
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
\maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
|
||||
@created 2003-05-23
|
||||
@edited 2010-05-01
|
||||
\created 2003-05-23
|
||||
\edited 2013-06-06
|
||||
*/
|
||||
|
||||
#ifndef GLG3D_ImageFormat_H
|
||||
#define GLG3D_ImageFormat_H
|
||||
#ifndef GLG3D_ImageFormat_h
|
||||
#define GLG3D_ImageFormat_h
|
||||
|
||||
#include "G3D/platform.h"
|
||||
#include "G3D/Table.h"
|
||||
@@ -17,16 +17,22 @@
|
||||
|
||||
namespace G3D {
|
||||
|
||||
/** Information about common image formats.
|
||||
Don't construct these; use the methods provided.
|
||||
/** Information about common image formats. Don't construct these;
|
||||
use the methods provided to access the const instances.
|
||||
|
||||
For most formats, the number indicates the number of bits per channel and a suffix of "F" indicates
|
||||
floating point. This does not hold for the YUV and DXT formats.*/
|
||||
For most formats, the number indicates the number of bits per
|
||||
channel and a suffix of "F" indicates floating point (following
|
||||
OpenGL conventions). This does not hold for the YUV and DXT
|
||||
formats.
|
||||
|
||||
\sa G3D::Image, G3D::Texture, G3D::ImageConvert
|
||||
*/
|
||||
class ImageFormat {
|
||||
public:
|
||||
|
||||
// Must update ImageFormat::name() when this enum changes.
|
||||
enum Code {
|
||||
CODE_AUTO = -2,
|
||||
CODE_NONE = -1,
|
||||
CODE_L8,
|
||||
CODE_L16,
|
||||
@@ -58,24 +64,57 @@ public:
|
||||
CODE_RGB8I,
|
||||
CODE_RGB8UI,
|
||||
|
||||
CODE_RGBA8I,
|
||||
CODE_RGBA8UI,
|
||||
|
||||
CODE_RGB8_SNORM,
|
||||
CODE_RGBA8_SNORM,
|
||||
CODE_RGB16_SNORM,
|
||||
CODE_RGBA16_SNORM,
|
||||
|
||||
CODE_ARGB8,
|
||||
CODE_BGR8,
|
||||
CODE_BGRA8,
|
||||
|
||||
CODE_R8,
|
||||
CODE_R8I,
|
||||
CODE_R8UI,
|
||||
|
||||
CODE_R16,
|
||||
CODE_R16I,
|
||||
CODE_R16UI,
|
||||
|
||||
CODE_R32I,
|
||||
CODE_R32UI,
|
||||
|
||||
CODE_RG8,
|
||||
CODE_RG8I,
|
||||
CODE_RG8UI,
|
||||
|
||||
CODE_RG16,
|
||||
CODE_RG16I,
|
||||
CODE_RG16UI,
|
||||
|
||||
CODE_R16F,
|
||||
CODE_RG16F,
|
||||
|
||||
CODE_RG32I,
|
||||
CODE_RG32UI,
|
||||
|
||||
CODE_R32F,
|
||||
CODE_RG32F,
|
||||
|
||||
CODE_RGBA8,
|
||||
CODE_RGBA16,
|
||||
CODE_RGBA16F,
|
||||
CODE_RGBA32F,
|
||||
|
||||
CODE_RGBA16I,
|
||||
CODE_RGBA16UI,
|
||||
|
||||
CODE_RGB32I,
|
||||
CODE_RGB32UI,
|
||||
CODE_RGBA32I,
|
||||
CODE_RGBA32UI,
|
||||
|
||||
CODE_BAYER_RGGB8,
|
||||
@@ -141,6 +180,14 @@ public:
|
||||
BAYER_PATTERN_BGGR
|
||||
};
|
||||
|
||||
|
||||
enum NumberFormat {
|
||||
FLOATING_POINT_FORMAT,
|
||||
INTEGER_FORMAT,
|
||||
NORMALIZED_FIXED_POINT_FORMAT,
|
||||
OTHER // e.g. DXT
|
||||
};
|
||||
|
||||
/** Number of channels (1 for a depth texture). */
|
||||
int numComponents;
|
||||
bool compressed;
|
||||
@@ -182,10 +229,6 @@ public:
|
||||
/** Amount of CPU memory per pixel when packed into an array, discounting any end-of-row padding. */
|
||||
int cpuBitsPerPixel;
|
||||
|
||||
/** Amount of CPU memory per pixel when packed into an array, discounting any end-of-row padding.
|
||||
@deprecated Use cpuBitsPerPixel*/
|
||||
int packedBitsPerTexel;
|
||||
|
||||
/**
|
||||
Amount of GPU memory per pixel on most graphics cards, for formats supported by OpenGL. This is
|
||||
only an estimate--the actual amount of memory may be different on your actual card.
|
||||
@@ -196,24 +239,38 @@ public:
|
||||
*/
|
||||
int openGLBitsPerPixel;
|
||||
|
||||
/** @deprecated Use openGLBitsPerPixel */
|
||||
int hardwareBitsPerTexel;
|
||||
|
||||
/** The OpenGL bytes (type) format of the data buffer used with this texture format, e.g., GL_UNSIGNED_BYTE */
|
||||
int openGLDataFormat;
|
||||
|
||||
/** True if there is no alpha channel for this texture. */
|
||||
bool opaque;
|
||||
|
||||
/** True if the bit depths specified are for float formats. */
|
||||
|
||||
/** True if the bit depths specified are for float formats. TODO: Remove, replace with function keying off numberFormat */
|
||||
bool floatingPoint;
|
||||
|
||||
/** Indicates whether this format treats numbers as integers, floating point, or normalized fixed point */
|
||||
NumberFormat numberFormat;
|
||||
|
||||
/** Human readable name of this format.*/
|
||||
const std::string& name() const;
|
||||
|
||||
/** True if data in otherFormat is binary compatible */
|
||||
bool canInterpretAs(const ImageFormat* otherFormat) const;
|
||||
|
||||
/** Returns ImageFormat representing the same channels as \a
|
||||
otherFormat plus an alpha channel, all with at least the same
|
||||
precision as \a otherFormat, or returns NULL if an equivalent
|
||||
format is unavailable. Will return itself if already contains
|
||||
an alpha channel. */
|
||||
static const ImageFormat* getFormatWithAlpha(const ImageFormat* otherFormat);
|
||||
|
||||
static const ImageFormat* getSRGBFormat(const ImageFormat* otherFormat);
|
||||
|
||||
/** Takes the same values that name() returns */
|
||||
static const ImageFormat* fromString(const std::string& s);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
ImageFormat
|
||||
@@ -228,11 +285,11 @@ private:
|
||||
int blueBits,
|
||||
int depthBits,
|
||||
int stencilBits,
|
||||
int hardwareBitsPerTexel,
|
||||
int packedBitsPerTexel,
|
||||
int openGLBitsPerPixel,
|
||||
int cpuBitsPerPixel,
|
||||
int glDataFormat,
|
||||
bool opaque,
|
||||
bool floatingPoint,
|
||||
NumberFormat numberFormat,
|
||||
Code code,
|
||||
ColorSpace colorSpace,
|
||||
BayerPattern bayerPattern = BAYER_PATTERN_NONE);
|
||||
@@ -267,14 +324,36 @@ public:
|
||||
|
||||
static const ImageFormat* BGR8();
|
||||
|
||||
static const ImageFormat* BGRA8();
|
||||
|
||||
static const ImageFormat* R8();
|
||||
static const ImageFormat* R8I();
|
||||
static const ImageFormat* R8UI();
|
||||
|
||||
static const ImageFormat* R16();
|
||||
static const ImageFormat* R16I();
|
||||
static const ImageFormat* R16UI();
|
||||
|
||||
static const ImageFormat* R32I();
|
||||
static const ImageFormat* R32UI();
|
||||
|
||||
static const ImageFormat* RG8();
|
||||
static const ImageFormat* RG8I();
|
||||
static const ImageFormat* RG8UI();
|
||||
|
||||
static const ImageFormat* RG16();
|
||||
static const ImageFormat* RG16I();
|
||||
static const ImageFormat* RG16UI();
|
||||
|
||||
static const ImageFormat* R16F();
|
||||
static const ImageFormat* RG16F();
|
||||
|
||||
static const ImageFormat* RG32I();
|
||||
static const ImageFormat* RG32UI();
|
||||
|
||||
static const ImageFormat* R32F();
|
||||
static const ImageFormat* RG32F();
|
||||
|
||||
static const ImageFormat* RGB5();
|
||||
|
||||
static const ImageFormat* RGB5A1();
|
||||
@@ -299,6 +378,12 @@ public:
|
||||
|
||||
static const ImageFormat* RGBA32F();
|
||||
|
||||
static const ImageFormat* RGBA16I();
|
||||
static const ImageFormat* RGBA16UI();
|
||||
|
||||
static const ImageFormat* RGB32UI();
|
||||
static const ImageFormat* RGB32I();
|
||||
static const ImageFormat* RGBA32I();
|
||||
static const ImageFormat* RGBA32UI();
|
||||
|
||||
static const ImageFormat* R11G11B10F();
|
||||
@@ -309,8 +394,15 @@ public:
|
||||
|
||||
static const ImageFormat* RGB8UI();
|
||||
|
||||
static const ImageFormat* RGBA8I();
|
||||
|
||||
static const ImageFormat* RGBA8UI();
|
||||
|
||||
|
||||
static const ImageFormat* RGB8_SNORM();
|
||||
static const ImageFormat* RGBA8_SNORM();
|
||||
static const ImageFormat* RGB16_SNORM();
|
||||
static const ImageFormat* RGBA16_SNORM();
|
||||
|
||||
static const ImageFormat* RGB_DXT1();
|
||||
|
||||
static const ImageFormat* RGBA_DXT1();
|
||||
@@ -359,7 +451,7 @@ public:
|
||||
|
||||
static const ImageFormat* YUV444();
|
||||
|
||||
/**
|
||||
/**
|
||||
NULL pointer; indicates that the G3D::Texture class should choose
|
||||
either RGBA8 or RGB8 depending on the presence of an alpha channel
|
||||
in the input.
|
||||
@@ -381,7 +473,6 @@ public:
|
||||
static const ImageFormat* fromCode(ImageFormat::Code code);
|
||||
|
||||
|
||||
|
||||
/** For use with ImageFormat::convert. */
|
||||
class BayerAlgorithm {
|
||||
public:
|
||||
@@ -418,13 +509,48 @@ public:
|
||||
YUV422 expects data in YUY2 format (Y, U, Y2, v). Most YUV formats require width and heights that are multiples of 2.
|
||||
|
||||
Returns true if a conversion was available, false if none occurred.
|
||||
|
||||
\deprecated
|
||||
\sa G3D::ImageConvert
|
||||
*/
|
||||
static bool convert(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits,
|
||||
const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits,
|
||||
bool invertY = false, BayerAlgorithm bayerAlg = BayerAlgorithm::MHC);
|
||||
const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits,
|
||||
bool invertY = false, BayerAlgorithm bayerAlg = BayerAlgorithm::MHC);
|
||||
|
||||
/* Checks if a conversion between two formats is available. */
|
||||
/**
|
||||
Checks if a conversion between two formats is available.
|
||||
\deprecated
|
||||
\sa G3D::ImageConvert
|
||||
*/
|
||||
static bool conversionAvailable(const ImageFormat* srcFormat, int srcRowPadBits, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY = false);
|
||||
|
||||
/** Does this contain exactly one unorm8 component? */
|
||||
bool representableAsColor1unorm8() const;
|
||||
|
||||
/** Does this contain exactly two unorm8 components? */
|
||||
bool representableAsColor2unorm8() const;
|
||||
|
||||
/** Does this contain exactly three unorm8 components? */
|
||||
bool representableAsColor3unorm8() const;
|
||||
|
||||
/** Does this contain exactly four unorm8 components? */
|
||||
bool representableAsColor4unorm8() const;
|
||||
|
||||
/** Returns a Color4 that masks off unused components in the format, given in RGBA
|
||||
For example, the mask for R32F is (1,0,0,0), for A32F is (0,0,0,1), for RGB32F is (1,1,1,0).
|
||||
(Note that luminance is interpreted as using only the R channel, even though RGB would make more sense
|
||||
to me...)
|
||||
*/
|
||||
Color4 channelMask() const;
|
||||
|
||||
bool isIntegerFormat() const{
|
||||
return (numberFormat == INTEGER_FORMAT);
|
||||
}
|
||||
|
||||
/** Returns true if these formats have the same components
|
||||
(possibly in different NumberFormat%s or sizes) */
|
||||
bool sameComponents(const ImageFormat* other) const;
|
||||
|
||||
};
|
||||
|
||||
typedef ImageFormat TextureFormat;
|
||||
|
||||
14
deps/g3dlite/include/G3D/Intersect.h
vendored
14
deps/g3dlite/include/G3D/Intersect.h
vendored
@@ -27,27 +27,27 @@ namespace G3D {
|
||||
class Intersect {
|
||||
public:
|
||||
|
||||
/** \brief Returns true if the intersection of the ray and the solid box is non-empty.
|
||||
/** \brief Returns true if the intersection of the ray and the solid box is non-empty.
|
||||
|
||||
\cite "Fast Ray / Axis-Aligned Bounding Box Overlap Tests using Ray Slopes"
|
||||
by Martin Eisemann, Thorsten Grosch, Stefan M<>ller and Marcus Magnor
|
||||
by Martin Eisemann, Thorsten Grosch, Stefan M<>ller and Marcus Magnor
|
||||
Computer Graphics Lab, TU Braunschweig, Germany and
|
||||
University of Koblenz-Landau, Germany
|
||||
*/
|
||||
static bool __fastcall rayAABox(const Ray& ray, const AABox& box);
|
||||
static bool __fastcall rayAABox(const Ray& ray, const AABox& box);
|
||||
|
||||
/** \brief Returns true if the intersection of the ray and the solid box is non-empty.
|
||||
|
||||
/** \brief Returns true if the intersection of the ray and the solid box is non-empty.
|
||||
|
||||
\param time If there is an intersection, set to the time to that intersection. If the ray origin is inside the box,
|
||||
this is a negative value indicating the distance backwards from the ray origin to the first intersection.
|
||||
\a time is not set if there is no intersection.
|
||||
|
||||
\cite Slope-Mul method from "Fast Ray / Axis-Aligned Bounding Box Overlap Tests using Ray Slopes"
|
||||
by Martin Eisemann, Thorsten Grosch, Stefan M<>ller and Marcus Magnor
|
||||
by Martin Eisemann, Thorsten Grosch, Stefan M<>ller and Marcus Magnor
|
||||
Computer Graphics Lab, TU Braunschweig, Germany and
|
||||
University of Koblenz-Landau, Germany
|
||||
*/
|
||||
static bool __fastcall rayAABox(const Ray& ray, const AABox& box, float& time);
|
||||
static bool __fastcall rayAABox(const Ray& ray, const AABox& box, float& time);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
185
deps/g3dlite/include/G3D/KDTree.h
vendored
185
deps/g3dlite/include/G3D/KDTree.h
vendored
@@ -10,8 +10,8 @@
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef G3D_KDTREE_H
|
||||
#define G3D_KDTREE_H
|
||||
#ifndef G3D_KDTree_h
|
||||
#define G3D_KDTree_h
|
||||
|
||||
#include "G3D/platform.h"
|
||||
#include "G3D/Array.h"
|
||||
@@ -24,11 +24,10 @@
|
||||
#include "G3D/Box.h"
|
||||
#include "G3D/Triangle.h"
|
||||
#include "G3D/Ray.h"
|
||||
#include "G3D/GCamera.h"
|
||||
#include "G3D/Frustum.h"
|
||||
#include "G3D/BinaryInput.h"
|
||||
#include "G3D/BinaryOutput.h"
|
||||
#include "G3D/CollisionDetection.h"
|
||||
#include "G3D/GCamera.h"
|
||||
#include "G3D/BoundsTrait.h"
|
||||
#include <algorithm>
|
||||
|
||||
@@ -260,11 +259,11 @@ protected:
|
||||
/** Compares centers */
|
||||
class CenterComparator {
|
||||
public:
|
||||
Vector3::Axis sortAxis;
|
||||
Vector3::Axis sortAxis;
|
||||
|
||||
CenterComparator(Vector3::Axis a) : sortAxis(a) {}
|
||||
CenterComparator(Vector3::Axis a) : sortAxis(a) {}
|
||||
|
||||
inline int operator()(Handle* A, const Handle* B) const {
|
||||
inline int operator()(Handle* A, const Handle* B) const {
|
||||
float a = A->center[sortAxis];
|
||||
float b = B->center[sortAxis];
|
||||
|
||||
@@ -275,18 +274,18 @@ protected:
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/** Compares bounds for strict >, <, or overlap*/
|
||||
class BoundsComparator {
|
||||
public:
|
||||
Vector3::Axis sortAxis;
|
||||
Vector3::Axis sortAxis;
|
||||
|
||||
BoundsComparator(Vector3::Axis a) : sortAxis(a) {}
|
||||
BoundsComparator(Vector3::Axis a) : sortAxis(a) {}
|
||||
|
||||
inline int operator()(Handle* A, const Handle* B) const {
|
||||
inline int operator()(Handle* A, const Handle* B) const {
|
||||
const AABox& a = A->bounds;
|
||||
const AABox& b = B->bounds;
|
||||
|
||||
@@ -297,34 +296,34 @@ protected:
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/** Compares bounds to the sort location */
|
||||
class Comparator {
|
||||
public:
|
||||
Vector3::Axis sortAxis;
|
||||
float sortLocation;
|
||||
Vector3::Axis sortAxis;
|
||||
float sortLocation;
|
||||
|
||||
Comparator(Vector3::Axis a, float l) : sortAxis(a), sortLocation(l) {}
|
||||
Comparator(Vector3::Axis a, float l) : sortAxis(a), sortLocation(l) {}
|
||||
|
||||
inline int operator()(Handle* ignore, const Handle* handle) const {
|
||||
inline int operator()(Handle* ignore, const Handle* handle) const {
|
||||
(void)ignore;
|
||||
const AABox& box = handle->bounds;
|
||||
debugAssert(ignore == NULL);
|
||||
|
||||
if (box.high()[sortAxis] < sortLocation) {
|
||||
if (box.high()[sortAxis] < sortLocation) {
|
||||
// Box is strictly below the sort location
|
||||
return -1;
|
||||
} else if (box.low()[sortAxis] > sortLocation) {
|
||||
} else if (box.low()[sortAxis] > sortLocation) {
|
||||
// Box is strictly above the sort location
|
||||
return 1;
|
||||
} else {
|
||||
return 1;
|
||||
} else {
|
||||
// Box overlaps the sort location
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Using System::malloc with this class provided no speed improvement.
|
||||
@@ -433,8 +432,8 @@ protected:
|
||||
}
|
||||
|
||||
void verifyNode(const Vector3& lo, const Vector3& hi) {
|
||||
// debugPrintf("Verifying: split %d @ %f [%f, %f, %f], [%f, %f, %f]\n",
|
||||
// splitAxis, splitLocation, lo.x, lo.y, lo.z, hi.x, hi.y, hi.z);
|
||||
// debugPrintf("Verifying: split %d @ %f [%f, %f, %f], [%f, %f, %f]\n",
|
||||
// splitAxis, splitLocation, lo.x, lo.y, lo.z, hi.x, hi.y, hi.z);
|
||||
|
||||
debugAssertM(lo == splitBounds.low(),
|
||||
format("lo = %s, splitBounds.lo = %s",
|
||||
@@ -444,6 +443,7 @@ protected:
|
||||
for (int i = 0; i < valueArray.length(); ++i) {
|
||||
const AABox& b = valueArray[i]->bounds;
|
||||
debugAssert(b == boundsArray[i]);
|
||||
(void)b;
|
||||
|
||||
for(int axis = 0; axis < 3; ++axis) {
|
||||
debugAssert(b.low()[axis] <= b.high()[axis]);
|
||||
@@ -714,27 +714,27 @@ protected:
|
||||
int numMeanSplits,
|
||||
Array<Handle*>& temp) {
|
||||
|
||||
Node* node = NULL;
|
||||
|
||||
if (source.size() <= valuesPerNode) {
|
||||
// Make a new leaf node
|
||||
node = new Node(source);
|
||||
|
||||
// Set the pointers in the memberTable
|
||||
for (int i = 0; i < source.size(); ++i) {
|
||||
memberTable.set(Member(source[i]), node);
|
||||
}
|
||||
Node* node = NULL;
|
||||
|
||||
if (source.size() <= valuesPerNode) {
|
||||
// Make a new leaf node
|
||||
node = new Node(source);
|
||||
|
||||
// Set the pointers in the memberTable
|
||||
for (int i = 0; i < source.size(); ++i) {
|
||||
memberTable.set(Member(source[i]), node);
|
||||
}
|
||||
source.clear();
|
||||
|
||||
|
||||
} else {
|
||||
// Make a new internal node
|
||||
node = new Node();
|
||||
|
||||
// Make a new internal node
|
||||
node = new Node();
|
||||
|
||||
const AABox& bounds = computeBounds(source, 0, source.size() - 1);
|
||||
const Vector3& extent = bounds.high() - bounds.low();
|
||||
|
||||
Vector3::Axis splitAxis = extent.primaryAxis();
|
||||
|
||||
const Vector3& extent = bounds.high() - bounds.low();
|
||||
|
||||
Vector3::Axis splitAxis = extent.primaryAxis();
|
||||
|
||||
float splitLocation;
|
||||
|
||||
// Arrays for holding the children
|
||||
@@ -829,20 +829,20 @@ protected:
|
||||
for (int i = 0; i < node->valueArray.size(); ++i) {
|
||||
Handle* v = node->valueArray[i];
|
||||
node->boundsArray[i] = v->bounds;
|
||||
memberTable.set(Member(v), node);
|
||||
memberTable.set(Member(v), node);
|
||||
}
|
||||
|
||||
if (lt.size() > 0) {
|
||||
node->child[0] = makeNode(lt, valuesPerNode, numMeanSplits - 1, temp);
|
||||
}
|
||||
|
||||
if (gt.size() > 0) {
|
||||
node->child[1] = makeNode(gt, valuesPerNode, numMeanSplits - 1, temp);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return node;
|
||||
if (lt.size() > 0) {
|
||||
node->child[0] = makeNode(lt, valuesPerNode, numMeanSplits - 1, temp);
|
||||
}
|
||||
|
||||
if (gt.size() > 0) {
|
||||
node->child[1] = makeNode(gt, valuesPerNode, numMeanSplits - 1, temp);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1211,7 +1211,7 @@ public:
|
||||
|
||||
/**
|
||||
Typically used to find all visible
|
||||
objects inside the view frustum (see also GCamera::getClipPlanes)... i.e. all objects
|
||||
objects inside the view frustum (see also Camera::getClipPlanes)... i.e. all objects
|
||||
<B>not</B> culled by frustum.
|
||||
|
||||
Example:
|
||||
@@ -1222,7 +1222,7 @@ public:
|
||||
</PRE>
|
||||
@param members The results are appended to this array.
|
||||
*/
|
||||
void getIntersectingMembers(const GCamera::Frustum& frustum, Array<T*>& members) const {
|
||||
void getIntersectingMembers(const Frustum& frustum, Array<T*>& members) const {
|
||||
Array<Plane> plane;
|
||||
|
||||
for (int i = 0; i < frustum.faceArray.size(); ++i) {
|
||||
@@ -1232,7 +1232,7 @@ public:
|
||||
getIntersectingMembers(plane, members);
|
||||
}
|
||||
|
||||
void getIntersectingMembers(const GCamera::Frustum& frustum, Array<T>& members) const {
|
||||
void getIntersectingMembers(const Frustum& frustum, Array<T>& members) const {
|
||||
Array<T*> temp;
|
||||
getIntersectingMembers(frustum, temp);
|
||||
for (int i = 0; i < temp.size(); ++i) {
|
||||
@@ -1450,49 +1450,50 @@ public:
|
||||
/**
|
||||
Invoke a callback for every member along a ray until the closest intersection is found.
|
||||
|
||||
@param callback either a function or an instance of a class with an overloaded operator() of the form:
|
||||
|
||||
<code>void callback(const Ray& ray, const T& object, float& distance)</code>. If the ray hits the object
|
||||
before travelling distance <code>distance</code>, updates <code>distance</code> with the new distance to
|
||||
the intersection, otherwise leaves it unmodified. A common example is:
|
||||
|
||||
@param intersectCallback Either a function or an instance of a class with an overloaded operator() of the form:
|
||||
<pre>
|
||||
void callback(const Ray& ray, const T& object, float& distance).
|
||||
</pre>
|
||||
If the ray hits the object before travelling distance <code>distance</code>, updates
|
||||
<code>distance</code> with the new distance to the intersection, otherwise leaves it
|
||||
unmodified. A common example is:
|
||||
\htmlonly
|
||||
<pre>
|
||||
class Entity {
|
||||
public:
|
||||
void intersect(const Ray& ray, float& maxDist, Vector3& outLocation, Vector3& outNormal) {
|
||||
float d = maxDist;
|
||||
|
||||
void intersect(const Ray& ray, float& maxDist, Vector3& outLocation, Vector3& outNormal) {
|
||||
float d = maxDist;
|
||||
// ... search for intersection distance d
|
||||
|
||||
// ... search for intersection distance d
|
||||
if ((d > 0) && (d < maxDist)) {
|
||||
// Intersection occured
|
||||
maxDist = d;
|
||||
outLocation = ...;
|
||||
outNormal = ...;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if ((d > 0) && (d < maxDist)) {
|
||||
// Intersection occured
|
||||
maxDist = d;
|
||||
outLocation = ...;
|
||||
outNormal = ...;
|
||||
}
|
||||
}
|
||||
};
|
||||
// Finds the surface normal and location of the first intersection with the scene
|
||||
class Intersection {
|
||||
public:
|
||||
Entity* closestEntity;
|
||||
Vector3 hitLocation;
|
||||
Vector3 hitNormal;
|
||||
|
||||
// Finds the surface normal and location of the first intersection with the scene
|
||||
class Intersection {
|
||||
public:
|
||||
Entity* closestEntity;
|
||||
Vector3 hitLocation;
|
||||
Vector3 hitNormal;
|
||||
void operator()(const Ray& ray, const Entity* entity, float& distance) {
|
||||
entity->intersect(ray, distance, hitLocation, hitNormal);
|
||||
}
|
||||
};
|
||||
|
||||
void operator()(const Ray& ray, const Entity* entity, float& distance) {
|
||||
entity->intersect(ray, distance, hitLocation, hitNormal);
|
||||
}
|
||||
};
|
||||
|
||||
KDTree<Entity*> scene;
|
||||
|
||||
Intersection intersection;
|
||||
float distance = finf();
|
||||
scene.intersectRay(camera.worldRay(x, y), intersection, distance);
|
||||
</pre>
|
||||
KDTree<Entity*> scene;
|
||||
|
||||
Intersection intersection;
|
||||
float distance = finf();
|
||||
scene.intersectRay(camera.worldRay(x, y), intersection, distance);
|
||||
</pre>
|
||||
\endhtmlonly
|
||||
|
||||
@param distance When the method is invoked, this is the maximum
|
||||
distance that the tree should search for an intersection. On
|
||||
|
||||
6
deps/g3dlite/include/G3D/Line.h
vendored
6
deps/g3dlite/include/G3D/Line.h
vendored
@@ -38,11 +38,11 @@ public:
|
||||
/** Undefined (provided for creating Array<Line> only) */
|
||||
inline Line() {}
|
||||
|
||||
Line(class BinaryInput& b);
|
||||
Line(class BinaryInput& b);
|
||||
|
||||
void serialize(class BinaryOutput& b) const;
|
||||
void serialize(class BinaryOutput& b) const;
|
||||
|
||||
void deserialize(class BinaryInput& b);
|
||||
void deserialize(class BinaryInput& b);
|
||||
|
||||
virtual ~Line() {}
|
||||
|
||||
|
||||
50
deps/g3dlite/include/G3D/LineSegment.h
vendored
50
deps/g3dlite/include/G3D/LineSegment.h
vendored
@@ -21,35 +21,39 @@ namespace G3D {
|
||||
class LineSegment {
|
||||
protected:
|
||||
|
||||
Vector3 _point;
|
||||
Point3 _point;
|
||||
|
||||
/** Not normalized */
|
||||
Vector3 direction;
|
||||
|
||||
LineSegment(const Vector3& __point, const Vector3& _direction) : _point(__point), direction(_direction) {
|
||||
LineSegment(const Point3& __point, const Vector3& _direction) : _point(__point), direction(_direction) {
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
inline LineSegment() : _point(Vector3::zero()), direction(Vector3::zero()) {}
|
||||
LineSegment() : _point(Point3::zero()), direction(Vector3::zero()) {}
|
||||
|
||||
LineSegment(class BinaryInput& b);
|
||||
|
||||
void serialize(class BinaryOutput& b) const;
|
||||
|
||||
void deserialize(class BinaryInput& b);
|
||||
LineSegment(class BinaryInput& b);
|
||||
|
||||
void serialize(class BinaryOutput& b) const;
|
||||
|
||||
void deserialize(class BinaryInput& b);
|
||||
|
||||
virtual ~LineSegment() {}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a line from two (not equal) points.
|
||||
*/
|
||||
static LineSegment fromTwoPoints(const Vector3 &point1, const Vector3 &point2) {
|
||||
static LineSegment fromTwoPoints(const Point3 &point1, const Point3 &point2) {
|
||||
return LineSegment(point1, point2 - point1);
|
||||
}
|
||||
|
||||
/** Call with 0 or 1 */
|
||||
Vector3 point(int i) const;
|
||||
/** Call with 0 or 1 */
|
||||
Point3 point(int i) const;
|
||||
|
||||
Point3 midpoint() const {
|
||||
return _point + direction * 0.5f;
|
||||
}
|
||||
|
||||
inline float length() const {
|
||||
return direction.magnitude();
|
||||
@@ -58,23 +62,23 @@ public:
|
||||
/**
|
||||
* Returns the closest point on the line segment to point.
|
||||
*/
|
||||
Vector3 closestPoint(const Vector3 &point) const;
|
||||
Point3 closestPoint(const Point3 &point) const;
|
||||
|
||||
/**
|
||||
Returns the distance between point and the line
|
||||
*/
|
||||
double distance(const Vector3& p) const {
|
||||
double distance(const Point3& p) const {
|
||||
return (closestPoint(p) - p).magnitude();
|
||||
}
|
||||
|
||||
double distanceSquared(const Vector3& p) const {
|
||||
double distanceSquared(const Point3& p) const {
|
||||
return (closestPoint(p) - p).squaredMagnitude();
|
||||
}
|
||||
|
||||
/** Returns true if some part of this segment is inside the sphere */
|
||||
bool intersectsSolidSphere(const class Sphere& s) const;
|
||||
|
||||
Vector3 randomPoint() const;
|
||||
Point3 randomPoint() const;
|
||||
|
||||
};
|
||||
|
||||
@@ -82,7 +86,7 @@ public:
|
||||
class LineSegment2D {
|
||||
private:
|
||||
|
||||
Vector2 m_origin;
|
||||
Point2 m_origin;
|
||||
|
||||
/** Not normalized */
|
||||
Vector2 m_direction;
|
||||
@@ -94,17 +98,17 @@ public:
|
||||
|
||||
LineSegment2D() {}
|
||||
|
||||
static LineSegment2D fromTwoPoints(const Vector2& p0, const Vector2& p1);
|
||||
static LineSegment2D fromTwoPoints(const Point2& p0, const Vector2& p1);
|
||||
|
||||
/** Returns the intersection of these segements (including
|
||||
testing endpoints), or Vector2::inf() if they do not intersect. */
|
||||
Vector2 intersection(const LineSegment2D& other) const;
|
||||
testing endpoints), or Point2::inf() if they do not intersect. */
|
||||
Point2 intersection(const LineSegment2D& other) const;
|
||||
|
||||
Vector2 point(int i) const;
|
||||
Point2 point(int i) const;
|
||||
|
||||
Vector2 closestPoint(const Vector2& Q) const;
|
||||
Point2 closestPoint(const Point2& Q) const;
|
||||
|
||||
float distance(const Vector2& p) const;
|
||||
float distance(const Point2& p) const;
|
||||
|
||||
float length() const;
|
||||
};
|
||||
|
||||
4
deps/g3dlite/include/G3D/Log.h
vendored
4
deps/g3dlite/include/G3D/Log.h
vendored
@@ -14,7 +14,7 @@
|
||||
#include <string>
|
||||
#include "G3D/platform.h"
|
||||
|
||||
#ifndef G3D_WIN32
|
||||
#ifndef G3D_WINDOWS
|
||||
#include <stdarg.h>
|
||||
#endif
|
||||
|
||||
@@ -57,9 +57,9 @@ private:
|
||||
|
||||
static Log* commonLog;
|
||||
|
||||
public:
|
||||
int stripFromStackBottom;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
@param stripFromStackBottom Number of call stacks to strip from the
|
||||
|
||||
85
deps/g3dlite/include/G3D/Map2D.h
vendored
85
deps/g3dlite/include/G3D/Map2D.h
vendored
@@ -87,7 +87,7 @@ namespace G3D {
|
||||
|
||||
G3D::GImage - Supports file formats, fast, Color3uint8 and Color4uint8 formats. No interpolation.
|
||||
|
||||
G3D::Texture::Ref - Represents image on the graphics card (not directly readable on the CPU). Supports 2D, 3D, and a variety of interpolation methods, loads file formats.
|
||||
G3D::shared_ptr<Texture> - Represents image on the graphics card (not directly readable on the CPU). Supports 2D, 3D, and a variety of interpolation methods, loads file formats.
|
||||
|
||||
G3D::Image3 - A subclass of Map2D<Color3> that supports image loading and saving and conversion to Texture.
|
||||
|
||||
@@ -181,7 +181,7 @@ public:
|
||||
typedef Storage StorageType;
|
||||
typedef Compute ComputeType;
|
||||
typedef Map2D<Storage, Compute> Type;
|
||||
typedef ReferenceCountedPointer<Map2D> Ref;
|
||||
typedef shared_ptr<Map2D> Ref;
|
||||
|
||||
protected:
|
||||
|
||||
@@ -296,7 +296,7 @@ public:
|
||||
GMutex mutex;
|
||||
|
||||
static Ref create(int w = 0, int h = 0, WrapMode wrap = WrapMode::ERROR) {
|
||||
return new Map2D(w, h, wrap);
|
||||
return Ref(new Map2D(w, h, wrap));
|
||||
}
|
||||
|
||||
/** Resizes without clearing, leaving garbage.
|
||||
@@ -372,7 +372,7 @@ public:
|
||||
// (we're returning a const reference so this is ok)
|
||||
return const_cast<Type*>(this)->slowGet(x, y, wrap);
|
||||
}
|
||||
# ifndef G3D_WIN32
|
||||
# ifndef G3D_WINDOWS
|
||||
// gcc gives a useless warning that the above code might reach the end of the function;
|
||||
// we use this line to supress the warning.
|
||||
return ZERO;
|
||||
@@ -393,7 +393,7 @@ public:
|
||||
|
||||
inline Storage& get(int x, int y, WrapMode wrap) {
|
||||
return const_cast<Storage&>(const_cast<const Type*>(this)->get(x, y, wrap));
|
||||
# ifndef G3D_WIN32
|
||||
# ifndef G3D_WINDOWS
|
||||
// gcc gives a useless warning that the above code might reach the end of the function;
|
||||
// we use this line to supress the warning.
|
||||
return ZERO;
|
||||
@@ -402,7 +402,7 @@ public:
|
||||
|
||||
inline Storage& get(int x, int y) {
|
||||
return const_cast<Storage&>(const_cast<const Type*>(this)->get(x, y));
|
||||
# ifndef G3D_WIN32
|
||||
# ifndef G3D_WINDOWS
|
||||
// gcc gives a useless warning that the above code might reach the end of the function;
|
||||
// we use this line to supress the warning.
|
||||
return ZERO;
|
||||
@@ -441,6 +441,19 @@ public:
|
||||
setChanged(true);
|
||||
}
|
||||
|
||||
/** Copy values from \a src, which must have the same size */
|
||||
template<class T>
|
||||
void set(const shared_ptr<Map2D<Storage, T> >& src) {
|
||||
debugAssert(src->width() == width());
|
||||
debugAssert(src->height() == height());
|
||||
const Array<Storage>& s = src->data;
|
||||
int N = w * h;
|
||||
for (int i = 0; i < N; ++i) {
|
||||
data[i] = s[i];
|
||||
}
|
||||
setChanged(true);
|
||||
}
|
||||
|
||||
/** flips if @a flip is true*/
|
||||
void maybeFlipVertical(bool flip) {
|
||||
if (flip) {
|
||||
@@ -448,38 +461,38 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual void flipVertical() {
|
||||
int halfHeight = h/2;
|
||||
Storage* d = data.getCArray();
|
||||
for (int y = 0; y < halfHeight; ++y) {
|
||||
int o1 = y * w;
|
||||
int o2 = (h - y - 1) * w;
|
||||
for (int x = 0; x < (int)w; ++x) {
|
||||
int i1 = o1 + x;
|
||||
int i2 = o2 + x;
|
||||
Storage temp = d[i1];
|
||||
d[i1] = d[i2];
|
||||
d[i2] = temp;
|
||||
}
|
||||
}
|
||||
virtual void flipVertical() {
|
||||
int halfHeight = h/2;
|
||||
Storage* d = data.getCArray();
|
||||
for (int y = 0; y < halfHeight; ++y) {
|
||||
int o1 = y * w;
|
||||
int o2 = (h - y - 1) * w;
|
||||
for (int x = 0; x < (int)w; ++x) {
|
||||
int i1 = o1 + x;
|
||||
int i2 = o2 + x;
|
||||
Storage temp = d[i1];
|
||||
d[i1] = d[i2];
|
||||
d[i2] = temp;
|
||||
}
|
||||
}
|
||||
setChanged(true);
|
||||
}
|
||||
|
||||
virtual void flipHorizontal() {
|
||||
int halfWidth = w / 2;
|
||||
Storage* d = data.getCArray();
|
||||
for (int x = 0; x < halfWidth; ++x) {
|
||||
for (int y = 0; y < (int)h; ++y) {
|
||||
int i1 = y * w + x;
|
||||
int i2 = y * w + (w - x - 1);
|
||||
Storage temp = d[i1];
|
||||
d[i1] = d[i2];
|
||||
d[i2] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual void flipHorizontal() {
|
||||
int halfWidth = w / 2;
|
||||
Storage* d = data.getCArray();
|
||||
for (int x = 0; x < halfWidth; ++x) {
|
||||
for (int y = 0; y < (int)h; ++y) {
|
||||
int i1 = y * w + x;
|
||||
int i2 = y * w + (w - x - 1);
|
||||
Storage temp = d[i1];
|
||||
d[i1] = d[i2];
|
||||
d[i2] = temp;
|
||||
}
|
||||
}
|
||||
setChanged(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
Crops this map so that it only contains pixels between (x, y) and (x + w - 1, y + h - 1) inclusive.
|
||||
*/
|
||||
|
||||
13
deps/g3dlite/include/G3D/Matrix.h
vendored
13
deps/g3dlite/include/G3D/Matrix.h
vendored
@@ -234,7 +234,7 @@ public:
|
||||
};
|
||||
private:
|
||||
|
||||
typedef ReferenceCountedPointer<Impl> ImplRef;
|
||||
typedef shared_ptr<Impl> ImplRef;
|
||||
|
||||
ImplRef impl;
|
||||
|
||||
@@ -501,10 +501,13 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
(A<SUP>T</SUP>A)<SUP>-1</SUP>A<SUP>T</SUP>) computed
|
||||
using SVD.
|
||||
\brief Computes the Moore-Penrose pseudo inverse, equivalent to
|
||||
(A<SUP>T</SUP>A)<SUP>-1</SUP>A<SUP>T</SUP>). The SVD method is used
|
||||
for performance when the matrix has more than four rows or columns
|
||||
|
||||
@param tolerance Use -1 for automatic tolerance.
|
||||
\cite http://en.wikipedia.org/wiki/Moore%E2%80%93Penrose_pseudoinverse
|
||||
|
||||
\param tolerance Use -1 for automatic tolerance.
|
||||
*/
|
||||
Matrix pseudoInverse(float tolerance = -1) const;
|
||||
|
||||
@@ -576,7 +579,7 @@ public:
|
||||
/** Serializes in Matlab source format */
|
||||
void serialize(TextOutput& t) const;
|
||||
|
||||
std::string toString(const std::string& name) const;
|
||||
std::string toString(const std::string& name) const;
|
||||
|
||||
std::string toString() const {
|
||||
static const std::string name = "";
|
||||
|
||||
20
deps/g3dlite/include/G3D/Matrix2.h
vendored
20
deps/g3dlite/include/G3D/Matrix2.h
vendored
@@ -9,7 +9,7 @@ namespace G3D {
|
||||
/** @beta */
|
||||
class Matrix2 {
|
||||
private:
|
||||
|
||||
// Row, column
|
||||
float data[2][2];
|
||||
|
||||
public:
|
||||
@@ -57,14 +57,22 @@ public:
|
||||
data[1][0] / f, data[1][1] / f);
|
||||
}
|
||||
|
||||
float* operator[](int i) {
|
||||
debugAssert(i >= 0 && i <= 2);
|
||||
return data[i];
|
||||
inline float* operator[] (int i) {
|
||||
debugAssert(i >= 0 && i <= 1);
|
||||
return (float*)&data[i][0];
|
||||
}
|
||||
|
||||
const float* operator[](int i) const {
|
||||
inline const float* operator[] (int i) const {
|
||||
debugAssert(i >= 0 && i <= 1);
|
||||
return data[i];
|
||||
return (const float*)&data[i][0];
|
||||
}
|
||||
|
||||
inline operator float* () {
|
||||
return (float*)&data[0][0];
|
||||
}
|
||||
|
||||
inline operator const float* () const{
|
||||
return (const float*)&data[0][0];
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
69
deps/g3dlite/include/G3D/Matrix3.h
vendored
69
deps/g3dlite/include/G3D/Matrix3.h
vendored
@@ -1,14 +1,14 @@
|
||||
/**
|
||||
@file Matrix3.h
|
||||
\file Matrix3.h
|
||||
|
||||
3x3 matrix class
|
||||
|
||||
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
\maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
|
||||
@cite Portions based on Dave Eberly's Magic Software Library at <A HREF="http://www.magic-software.com">http://www.magic-software.com</A>
|
||||
\cite Portions based on Dave Eberly's Magic Software Library at <A HREF="http://www.magic-software.com">http://www.magic-software.com</A>
|
||||
|
||||
@created 2001-06-02
|
||||
@edited 2006-04-05
|
||||
\created 2001-06-02
|
||||
\edited 2011-05-05
|
||||
*/
|
||||
|
||||
#ifndef G3D_Matrix3_h
|
||||
@@ -32,11 +32,12 @@ namespace G3D {
|
||||
class Any;
|
||||
|
||||
/**
|
||||
3x3 matrix. Do not subclass.
|
||||
A 3x3 matrix. Do not subclass. Data is unitializd when default constructed.
|
||||
*/
|
||||
class Matrix3 {
|
||||
private:
|
||||
|
||||
// Row, column
|
||||
float elt[3][3];
|
||||
|
||||
// Hidden operators
|
||||
@@ -47,13 +48,39 @@ private:
|
||||
|
||||
public:
|
||||
|
||||
/** Must be in one of the following forms:
|
||||
- Matrix3(#, #, # .... #)
|
||||
- Matrix3::fromAxisAngle(#, #)
|
||||
- Matrix3::diagonal(#, #, #)
|
||||
- Matrix3::identity()
|
||||
*/
|
||||
Matrix3(const Any& any);
|
||||
|
||||
operator Any() const;
|
||||
static Matrix3 fromColumns(const Vector3& c0, const Vector3& c1, const Vector3& c2) {
|
||||
Matrix3 m;
|
||||
for (int r = 0; r < 3; ++r) {
|
||||
m.elt[r][0] = c0[r];
|
||||
m.elt[r][1] = c1[r];
|
||||
m.elt[r][2] = c2[r];
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
/** Initial values are undefined for performance. See also
|
||||
Matrix3::zero(), Matrix3::identity(), Matrix3::fromAxisAngle, etc.*/
|
||||
inline Matrix3() {}
|
||||
static Matrix3 fromRows(const Vector3& r0, const Vector3& r1, const Vector3& r2) {
|
||||
Matrix3 m;
|
||||
for (int c = 0; c < 3; ++c) {
|
||||
m.elt[0][c] = r0[c];
|
||||
m.elt[1][c] = r1[c];
|
||||
m.elt[2][c] = r2[c];
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
Any toAny() const;
|
||||
|
||||
/** Initial values are undefined for performance.
|
||||
\sa Matrix3::zero, Matrix3::identity, Matrix3::fromAxisAngle, etc.*/
|
||||
Matrix3() {}
|
||||
|
||||
Matrix3 (class BinaryInput& b);
|
||||
Matrix3 (const float aafEntry[3][3]);
|
||||
@@ -62,13 +89,19 @@ public:
|
||||
float fEntry10, float fEntry11, float fEntry12,
|
||||
float fEntry20, float fEntry21, float fEntry22);
|
||||
|
||||
bool fuzzyEq(const Matrix3& b) const;
|
||||
bool fuzzyEq(const Matrix3& b) const;
|
||||
|
||||
/** Constructs a matrix from a quaternion.
|
||||
@cite Graphics Gems II, p. 351--354
|
||||
@cite Implementation from Watt and Watt, pg 362*/
|
||||
@cite Implementation from Watt and Watt, pg 362*/
|
||||
Matrix3(const class Quat& q);
|
||||
|
||||
static Matrix3 diagonal(float e00, float e11, float e22) {
|
||||
return Matrix3(e00, 0, 0,
|
||||
0, e11, 0,
|
||||
0, 0, e22);
|
||||
}
|
||||
|
||||
void serialize(class BinaryOutput& b) const;
|
||||
void deserialize(class BinaryInput& b);
|
||||
|
||||
@@ -83,7 +116,7 @@ public:
|
||||
float fEntry20, float fEntry21, float fEntry22);
|
||||
|
||||
/**
|
||||
* member access, allows use of construct mat[r][c]
|
||||
Member access, allows use of construct mat[r][c]
|
||||
*/
|
||||
inline float* operator[] (int iRow) {
|
||||
debugAssert(iRow >= 0);
|
||||
@@ -209,8 +242,8 @@ public:
|
||||
bool isOrthonormal() const;
|
||||
|
||||
Matrix3 transpose () const;
|
||||
bool inverse (Matrix3& rkInverse, float fTolerance = 1e-06) const;
|
||||
Matrix3 inverse (float fTolerance = 1e-06) const;
|
||||
bool inverse (Matrix3& rkInverse, float fTolerance = 1e-06f) const;
|
||||
Matrix3 inverse (float fTolerance = 1e-06f) const;
|
||||
float determinant () const;
|
||||
|
||||
/** singular value decomposition */
|
||||
@@ -267,8 +300,12 @@ public:
|
||||
0, 0, d.z);
|
||||
}
|
||||
|
||||
/** \sa fromUnitAxisAngle */
|
||||
static Matrix3 fromAxisAngle(const Vector3& rkAxis, float fRadians);
|
||||
|
||||
/** Assumes that rkAxis has unit length */
|
||||
static Matrix3 fromUnitAxisAngle(const Vector3& rkAxis, float fRadians);
|
||||
|
||||
/**
|
||||
* The matrix must be orthonormal. The decomposition is yaw*pitch*roll
|
||||
* where yaw is rotation about the Up vector, pitch is rotation about the
|
||||
@@ -312,7 +349,7 @@ public:
|
||||
// "You might be tempted to write [...] them as inline functions
|
||||
// inside their respective header files, but this is something you
|
||||
// must definitely not do. An inline function can be duplicated
|
||||
// in every file in which it appears <20><><EFBFBD><EFBFBD> and this duplication
|
||||
// in every file in which it appears and this duplication
|
||||
// includes the static object definition. Because inline functions
|
||||
// automatically default to internal linkage, this would result in
|
||||
// having multiple static objects across the various translation
|
||||
|
||||
142
deps/g3dlite/include/G3D/Matrix4.h
vendored
142
deps/g3dlite/include/G3D/Matrix4.h
vendored
@@ -5,8 +5,8 @@
|
||||
|
||||
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
|
||||
@created 2003-10-02
|
||||
@edited 2009-10-20
|
||||
\created 2003-10-02
|
||||
\edited 2012-12-25
|
||||
*/
|
||||
|
||||
#ifndef G3D_Matrix4_h
|
||||
@@ -26,11 +26,12 @@
|
||||
namespace G3D {
|
||||
|
||||
class Any;
|
||||
class Matrix2;
|
||||
|
||||
/**
|
||||
A 4x4 matrix.
|
||||
A 4x4 matrix. Do not subclass. Data is initialized to 0 when default constructed.
|
||||
|
||||
See also G3D::CoordinateFrame, G3D::Matrix3, G3D::Quat
|
||||
\sa G3D::CoordinateFrame, G3D::Matrix3, G3D::Quat
|
||||
*/
|
||||
class Matrix4 {
|
||||
private:
|
||||
@@ -50,10 +51,20 @@ private:
|
||||
bool operator>=(const Matrix4&) const;
|
||||
|
||||
public:
|
||||
/** Must be of the form: <code>Matrix4(#, #, # .... #)</code>*/
|
||||
Matrix4(const Any& any);
|
||||
|
||||
operator Any() const;
|
||||
/** Must be in one of the following forms:
|
||||
- Matrix4(#, #, # .... #)
|
||||
- Matrix4::scale(#)
|
||||
- Matrix4::scale(#, #, #)
|
||||
- Matrix4::translation(#, #, #)
|
||||
- Matrix4::identity()
|
||||
- Matrix4::rollDegrees(#)
|
||||
- Matrix4::pitchDegrees(#)
|
||||
- Matrix4::yawDegrees(#)
|
||||
*/
|
||||
explicit Matrix4(const Any& any);
|
||||
|
||||
Any toAny() const;
|
||||
|
||||
Matrix4(
|
||||
float r1c1, float r1c2, float r1c3, float r1c4,
|
||||
@@ -66,17 +77,25 @@ public:
|
||||
*/
|
||||
Matrix4(const float* init);
|
||||
|
||||
/**
|
||||
a is the upper left 3x3 submatrix and b is the upper right 3x1 submatrix. The last row of the created matrix is (0,0,0,1).
|
||||
*/
|
||||
/**
|
||||
a is the upper left 3x3 submatrix and b is the upper right 3x1 submatrix. The last row of the created matrix is (0,0,0,1).
|
||||
*/
|
||||
Matrix4(const class Matrix3& upper3x3, const class Vector3& lastCol = Vector3::zero());
|
||||
|
||||
Matrix4(const class CoordinateFrame& c);
|
||||
|
||||
Matrix4(const double* init);
|
||||
|
||||
/** Matrix4::zero() */
|
||||
Matrix4();
|
||||
|
||||
static Matrix4 diagonal(float e00, float e11, float e22, float e33) {
|
||||
return Matrix4(e00, 0, 0, 0,
|
||||
0, e11, 0, 0,
|
||||
0, 0, e22, 0,
|
||||
0, 0, 0, e33);
|
||||
}
|
||||
|
||||
/** Produces an RT transformation that nearly matches this Matrix4.
|
||||
Because a Matrix4 may not be precisely a rotation and translation,
|
||||
this may introduce error. */
|
||||
@@ -88,14 +107,19 @@ public:
|
||||
static const Matrix4& zero();
|
||||
|
||||
/** If this is a perspective projection matrix created by
|
||||
Matrix4::perspectiveProjection, extract its parameters. */
|
||||
Matrix4::perspectiveProjection, extract its parameters.
|
||||
|
||||
Uses double precision because the operations involved in
|
||||
projection involve divisions that can significantly impact
|
||||
precision.
|
||||
*/
|
||||
void getPerspectiveProjectionParameters
|
||||
(float& left,
|
||||
float& right,
|
||||
float& bottom,
|
||||
float& top,
|
||||
float& nearval,
|
||||
float& farval,
|
||||
(double& left,
|
||||
double& right,
|
||||
double& bottom,
|
||||
double& top,
|
||||
double& nearval,
|
||||
double& farval,
|
||||
float updirection = -1.0f) const;
|
||||
|
||||
inline float* operator[](int r) {
|
||||
@@ -110,6 +134,7 @@ public:
|
||||
return (const float*)&elt[r];
|
||||
}
|
||||
|
||||
/** Returns a row-major pointer. */
|
||||
inline operator float* () {
|
||||
return (float*)&elt[0][0];
|
||||
}
|
||||
@@ -131,6 +156,8 @@ public:
|
||||
|
||||
class Matrix3 upper3x3() const;
|
||||
|
||||
class Matrix2 upper2x2() const;
|
||||
|
||||
/** Homogeneous multiplication. Let k = M * [v w]^T. result = k.xyz() / k.w */
|
||||
class Vector3 homoMul(const class Vector3& v, float w) const;
|
||||
|
||||
@@ -151,7 +178,6 @@ public:
|
||||
float farval,
|
||||
float upDirection = -1.0f);
|
||||
|
||||
|
||||
/** \param upDirection Use -1.0 for 2D Y increasing downwards (the G3D 8.x default convention),
|
||||
1.0 for 2D Y increasing upwards (the G3D 7.x default and OpenGL convention)
|
||||
*/
|
||||
@@ -163,15 +189,18 @@ public:
|
||||
|
||||
/** \param upDirection Use -1.0 for 2D Y increasing downwards (the G3D 8.x default convention),
|
||||
1.0 for 2D Y increasing upwards (the G3D 7.x default and OpenGL convention)
|
||||
*/
|
||||
|
||||
Uses double precision because the operations involved in
|
||||
projection involve divisions that can significantly impact
|
||||
precision. */
|
||||
static Matrix4 perspectiveProjection(
|
||||
float left,
|
||||
float right,
|
||||
float bottom,
|
||||
float top,
|
||||
float nearval,
|
||||
float farval,
|
||||
float upDirection = -1.0f);
|
||||
double left,
|
||||
double right,
|
||||
double bottom,
|
||||
double top,
|
||||
double nearval,
|
||||
double farval,
|
||||
float upDirection = -1.0f);
|
||||
|
||||
void setRow(int r, const class Vector4& v);
|
||||
void setColumn(int c, const Vector4& v);
|
||||
@@ -248,6 +277,67 @@ public:
|
||||
};
|
||||
|
||||
|
||||
/** Double-precision 4x4 matrix */
|
||||
class Matrix4float64 {
|
||||
private:
|
||||
|
||||
double elt[4][4];
|
||||
|
||||
public:
|
||||
|
||||
explicit Matrix4float64(const Matrix4& m);
|
||||
|
||||
/** all zeros */
|
||||
Matrix4float64();
|
||||
|
||||
Matrix4float64(
|
||||
double r1c1, double r1c2, double r1c3, double r1c4,
|
||||
double r2c1, double r2c2, double r2c3, double r2c4,
|
||||
double r3c1, double r3c2, double r3c3, double r3c4,
|
||||
double r4c1, double r4c2, double r4c3, double r4c4);
|
||||
|
||||
// Special values.
|
||||
// Intentionally not inlined: see Matrix3::identity() for details.
|
||||
static const Matrix4float64& identity();
|
||||
|
||||
static const Matrix4float64& zero();
|
||||
|
||||
bool operator!=(const Matrix4float64& other) const;
|
||||
|
||||
bool operator==(const Matrix4float64& other) const;
|
||||
|
||||
Vector4 operator*(const Vector4& vector) const;
|
||||
|
||||
static Matrix4float64 perspectiveProjection(
|
||||
double left,
|
||||
double right,
|
||||
double bottom,
|
||||
double top,
|
||||
double nearval,
|
||||
double farval,
|
||||
float upDirection = -1.0f);
|
||||
|
||||
inline double* operator[](int r) {
|
||||
debugAssert(r >= 0);
|
||||
debugAssert(r < 4);
|
||||
return (double*)&elt[r];
|
||||
}
|
||||
|
||||
inline const double* operator[](int r) const {
|
||||
debugAssert(r >= 0);
|
||||
debugAssert(r < 4);
|
||||
return (const double*)&elt[r];
|
||||
}
|
||||
|
||||
inline operator double* () {
|
||||
return (double*)&elt[0][0];
|
||||
}
|
||||
|
||||
inline operator const double* () const {
|
||||
return (const double*)&elt[0][0];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
11
deps/g3dlite/include/G3D/MemoryManager.h
vendored
11
deps/g3dlite/include/G3D/MemoryManager.h
vendored
@@ -20,7 +20,7 @@ namespace G3D {
|
||||
Abstraction of memory management.
|
||||
Default implementation uses G3D::System::malloc and is threadsafe.
|
||||
|
||||
\sa CRTMemoryManager, AlignedMemoryManager, AreaMemoryManager */
|
||||
\sa LargePoolMemoryManager, CRTMemoryManager, AlignedMemoryManager, AreaMemoryManager */
|
||||
class MemoryManager : public ReferenceCountedObject {
|
||||
protected:
|
||||
|
||||
@@ -28,7 +28,7 @@ protected:
|
||||
|
||||
public:
|
||||
|
||||
typedef ReferenceCountedPointer<class MemoryManager> Ref;
|
||||
typedef shared_ptr<class MemoryManager> Ref;
|
||||
|
||||
/** Return a pointer to \a s bytes of memory that are unused by
|
||||
the rest of the program. The contents of the memory are
|
||||
@@ -59,7 +59,7 @@ protected:
|
||||
|
||||
public:
|
||||
|
||||
typedef ReferenceCountedPointer<class AlignedMemoryManager> Ref;
|
||||
typedef shared_ptr<class AlignedMemoryManager> Ref;
|
||||
|
||||
|
||||
virtual void* alloc(size_t s);
|
||||
@@ -72,13 +72,14 @@ public:
|
||||
};
|
||||
|
||||
|
||||
/** MemoryManager implemented using the C runtime. */
|
||||
/** A MemoryManager implemented using the C runtime. Not recommended
|
||||
for general use; this is largely for debugging. */
|
||||
class CRTMemoryManager : public MemoryManager {
|
||||
protected:
|
||||
CRTMemoryManager();
|
||||
|
||||
public:
|
||||
typedef ReferenceCountedPointer<class MemoryManager> Ref;
|
||||
typedef shared_ptr<class MemoryManager> Ref;
|
||||
virtual void* alloc(size_t s);
|
||||
virtual void free(void* ptr);
|
||||
virtual bool isThreadsafe() const;
|
||||
|
||||
21
deps/g3dlite/include/G3D/MeshAlg.h
vendored
21
deps/g3dlite/include/G3D/MeshAlg.h
vendored
@@ -20,9 +20,10 @@
|
||||
#include "G3D/constants.h"
|
||||
#include "G3D/Image1.h"
|
||||
|
||||
#ifdef G3D_WIN32
|
||||
#ifdef G3D_WINDOWS
|
||||
// Turn off "conditional expression is constant" warning; MSVC generates this
|
||||
// for debug assertions in inlined methods.
|
||||
#pragma warning( push )
|
||||
#pragma warning (disable : 4127)
|
||||
#endif
|
||||
|
||||
@@ -444,7 +445,7 @@ public:
|
||||
Array<Vector3>& newVertexPositions,
|
||||
Array<int>& toNew,
|
||||
Array<int>& toOld,
|
||||
double radius = fuzzyEpsilon);
|
||||
float radius = fuzzyEpsilon32);
|
||||
|
||||
/**
|
||||
Modifies the face, edge, and vertex arrays in place so that
|
||||
@@ -479,7 +480,7 @@ public:
|
||||
Array<Face>& faceArray,
|
||||
Array<Edge>& edgeArray,
|
||||
Array<Vertex>& vertexArray,
|
||||
double radius = fuzzyEpsilon);
|
||||
float radius = fuzzyEpsilon32);
|
||||
|
||||
|
||||
/**
|
||||
@@ -535,7 +536,7 @@ public:
|
||||
|
||||
/**
|
||||
Generates a unit square in the X-Z plane composed of a grid of wCells x hCells
|
||||
squares and then transforms it by xform.
|
||||
squares on the unit interval and then transforms it by xform.
|
||||
|
||||
@param vertex Output vertices
|
||||
@param texCoord Output texture coordinates
|
||||
@@ -545,8 +546,8 @@ public:
|
||||
@param twoSided If true, matching top and bottom planes are generated.
|
||||
\param elevation If non-NULL, values from this image are used as elevations. Apply an \a xform to adjust the scale
|
||||
*/
|
||||
static void generateGrid(
|
||||
Array<Vector3>& vertex,
|
||||
static void generateGrid
|
||||
(Array<Vector3>& vertex,
|
||||
Array<Vector2>& texCoord,
|
||||
Array<int>& index,
|
||||
int wCells = 10,
|
||||
@@ -555,7 +556,7 @@ public:
|
||||
bool spaceCentered = true,
|
||||
bool twoSided = true,
|
||||
const CoordinateFrame& xform = CoordinateFrame(),
|
||||
const Image1::Ref& elevation = NULL);
|
||||
const Image1::Ref& elevation = Image1::Ref());
|
||||
|
||||
/** Converts quadlist (QUADS),
|
||||
triangle fan (TRIANGLE_FAN),
|
||||
@@ -679,5 +680,11 @@ protected:
|
||||
int i0, int i1, int f, double area);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#ifdef G3D_WINDOWS
|
||||
#pragma warning( pop )
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
6
deps/g3dlite/include/G3D/MeshBuilder.h
vendored
6
deps/g3dlite/include/G3D/MeshBuilder.h
vendored
@@ -34,6 +34,8 @@ private:
|
||||
typedef Array<int> List;
|
||||
|
||||
std::string name;
|
||||
|
||||
bool scaleAndCenter;
|
||||
|
||||
/**
|
||||
All of the triangles, as a long triangle list.
|
||||
@@ -43,14 +45,14 @@ private:
|
||||
void centerTriList();
|
||||
void computeBounds(Vector3& min, Vector3& max);
|
||||
|
||||
bool _twoSided;
|
||||
bool _twoSided;
|
||||
|
||||
/** Collapse radius */
|
||||
double close;
|
||||
|
||||
public:
|
||||
|
||||
inline MeshBuilder(bool twoSided = false) : _twoSided(twoSided), close(AUTO_WELD) {}
|
||||
inline MeshBuilder(bool twoSided = false, bool scaleAndCenter = true) : scaleAndCenter(scaleAndCenter), _twoSided(twoSided), close(AUTO_WELD) {}
|
||||
|
||||
/** Writes the model to the arrays, which can then be used with
|
||||
G3D::IFSModel::save and G3D::MeshAlg */
|
||||
|
||||
36
deps/g3dlite/include/G3D/NetAddress.h
vendored
36
deps/g3dlite/include/G3D/NetAddress.h
vendored
@@ -1,3 +1,9 @@
|
||||
/**
|
||||
\file G3D/NetAddress.h
|
||||
|
||||
\created 2010-01-03
|
||||
\edited 2013-03-17
|
||||
*/
|
||||
#ifndef G3D_NetAddress_h
|
||||
#define G3D_NetAddress_h
|
||||
|
||||
@@ -24,20 +30,31 @@ private:
|
||||
SOCKADDR_IN addr;
|
||||
|
||||
public:
|
||||
|
||||
enum {
|
||||
/**
|
||||
Use the host portion of the IP address of the default adapter on this machine.
|
||||
*/
|
||||
// Must match ENET_HOST_ANY
|
||||
DEFAULT_ADAPTER_HOST = 0
|
||||
};
|
||||
|
||||
/**
|
||||
In host byte order
|
||||
In host byte order.
|
||||
|
||||
\sa DEFAULT_ADAPTER_HOST
|
||||
*/
|
||||
NetAddress(uint32 host, uint16 port = 0);
|
||||
explicit NetAddress(uint32 host, uint16 port = 0);
|
||||
|
||||
/**
|
||||
@param port Specified in host byte order (i.e., don't worry about endian issues)
|
||||
*/
|
||||
*/
|
||||
NetAddress(const std::string& hostname, uint16 port);
|
||||
|
||||
/**
|
||||
@param hostnameAndPort in the form "hostname:port" or "ip:port"
|
||||
*/
|
||||
NetAddress(const std::string& hostnameAndPort);
|
||||
explicit NetAddress(const std::string& hostnameAndPort);
|
||||
|
||||
/**
|
||||
@deprecated Use G3D::NetworkDevice::broadcastAddressArray()
|
||||
@@ -56,6 +73,8 @@ public:
|
||||
|
||||
NetAddress();
|
||||
|
||||
static void localHostAddresses(Array<NetAddress>& array);
|
||||
|
||||
void serialize(class BinaryOutput& b) const;
|
||||
void deserialize(class BinaryInput& b);
|
||||
|
||||
@@ -76,6 +95,13 @@ public:
|
||||
std::string ipString() const;
|
||||
std::string toString() const;
|
||||
|
||||
/** Name of this address, without the domain. Performs reverse DNS lookup on this address. This may make a network
|
||||
connection to a DNS server and block until that communication completes
|
||||
if the address is one that has not been recently checked.*/
|
||||
std::string hostname() const;
|
||||
|
||||
/** Name of the local machine machine, without the domain. The value is cached after the first call.*/
|
||||
static std::string localHostname();
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const NetAddress&);
|
||||
@@ -95,7 +121,7 @@ namespace G3D {
|
||||
they have different IP's.
|
||||
*/
|
||||
inline bool operator==(const NetAddress& a, const NetAddress& b) {
|
||||
return (a.ip() == b.ip()) && (a.port() == b.port());
|
||||
return (a.ip() == b.ip()) && (a.port() == b.port());
|
||||
}
|
||||
|
||||
|
||||
|
||||
36
deps/g3dlite/include/G3D/NetworkDevice.h
vendored
36
deps/g3dlite/include/G3D/NetworkDevice.h
vendored
@@ -1,6 +1,5 @@
|
||||
/**
|
||||
@file NetworkDevice.h
|
||||
|
||||
These classes abstract networking from the socket level to a
|
||||
serialized messaging style that is more appropriate for games. The
|
||||
performance has been tuned for sending many small messages. The
|
||||
@@ -54,7 +53,7 @@
|
||||
namespace G3D {
|
||||
|
||||
class TextOutput;
|
||||
|
||||
/** \deprecated */
|
||||
class Conduit : public ReferenceCountedObject {
|
||||
protected:
|
||||
friend class NetworkDevice;
|
||||
@@ -134,7 +133,7 @@ public:
|
||||
bool ok() const;
|
||||
};
|
||||
|
||||
typedef ReferenceCountedPointer<class ReliableConduit> ReliableConduitRef;
|
||||
typedef shared_ptr<class ReliableConduit> ReliableConduitRef;
|
||||
|
||||
#ifdef __GNUC__
|
||||
// Workaround for a known bug in gcc 4.x where htonl produces
|
||||
@@ -164,7 +163,7 @@ uint32 gcchtonl(uint32);
|
||||
You will need the server's G3D::NetAddress. Consider using
|
||||
G3D::Discovery::Client to find it via broadcasting.
|
||||
</OL>
|
||||
|
||||
\deprecated
|
||||
*/
|
||||
class ReliableConduit : public Conduit {
|
||||
private:
|
||||
@@ -209,7 +208,7 @@ private:
|
||||
// Reserve space for the 4 byte size header
|
||||
b.writeUInt32(0);
|
||||
|
||||
size_t L = b.length();
|
||||
size_t L = (size_t)b.length();
|
||||
m.serialize(b);
|
||||
if ((size_t)b.length() == L) {
|
||||
// No data was created by serialization.
|
||||
@@ -218,7 +217,7 @@ private:
|
||||
b.writeUInt8(0xFF);
|
||||
}
|
||||
|
||||
uint32 len = b.size() - 8;
|
||||
uint32 len = (uint32)b.size() - 8;
|
||||
|
||||
// We send the length first to tell recv how much data to read.
|
||||
// Here we abuse BinaryOutput a bit and write directly into
|
||||
@@ -353,7 +352,7 @@ public:
|
||||
};
|
||||
|
||||
|
||||
typedef ReferenceCountedPointer<class LightweightConduit> LightweightConduitRef;
|
||||
typedef shared_ptr<class LightweightConduit> LightweightConduitRef;
|
||||
|
||||
/**
|
||||
Provides fast but unreliable transfer of messages. On a LAN,
|
||||
@@ -402,6 +401,8 @@ and a pointer to an instance of the message you want to send.
|
||||
it go out of scope and the conduit cleans itself up automatically.
|
||||
|
||||
</OL>
|
||||
|
||||
\deprecated
|
||||
*/
|
||||
class LightweightConduit : public Conduit {
|
||||
private:
|
||||
@@ -458,7 +459,7 @@ private:
|
||||
format("This LightweightConduit is limited to messages of "
|
||||
"%d bytes (Ethernet hardware limit; this is the "
|
||||
"'UDP MTU')", maxMessageSize()),
|
||||
b.size() - 4, // Don't count the type header
|
||||
(int)b.size() - 4, // Don't count the type header
|
||||
maxMessageSize());
|
||||
}
|
||||
}
|
||||
@@ -512,13 +513,13 @@ public:
|
||||
bool receive(NetAddress& sender);
|
||||
|
||||
template<typename T> inline bool receive(NetAddress& sender, T& message) {
|
||||
bool r = receive(sender);
|
||||
if (r) {
|
||||
BinaryInput b((messageBuffer.getCArray() + 4),
|
||||
messageBuffer.size() - 4,
|
||||
G3D_LITTLE_ENDIAN, BinaryInput::NO_COPY);
|
||||
message.deserialize(b);
|
||||
}
|
||||
bool r = receive(sender);
|
||||
if (r) {
|
||||
BinaryInput b((messageBuffer.getCArray() + 4),
|
||||
messageBuffer.size() - 4,
|
||||
G3D_LITTLE_ENDIAN, BinaryInput::NO_COPY);
|
||||
message.deserialize(b);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -536,10 +537,12 @@ public:
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef ReferenceCountedPointer<class NetListener> NetListenerRef;
|
||||
typedef shared_ptr<class NetListener> NetListenerRef;
|
||||
|
||||
/**
|
||||
Runs on the server listening for clients trying to make reliable connections.
|
||||
|
||||
\deprecated
|
||||
*/
|
||||
class NetListener : public ReferenceCountedObject {
|
||||
private:
|
||||
@@ -600,6 +603,7 @@ public:
|
||||
values between these formats. G3D only ever exposes host byte order,
|
||||
so programmers rarely need to be aware of the distinction.
|
||||
|
||||
\deprecated
|
||||
*/
|
||||
class NetworkDevice {
|
||||
public:
|
||||
|
||||
3
deps/g3dlite/include/G3D/ParseError.h
vendored
3
deps/g3dlite/include/G3D/ParseError.h
vendored
@@ -52,6 +52,9 @@ public:
|
||||
|
||||
ParseError(const std::string& f, int64 b, const std::string& m) :
|
||||
filename (f), byte(b), line(UNKNOWN), character(UNKNOWN), message(m) {}
|
||||
|
||||
/** If information is known, ends in ": ", otherwise empty */
|
||||
std::string formatFileInfo() const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
35
deps/g3dlite/include/G3D/PhysicsFrame.h
vendored
35
deps/g3dlite/include/G3D/PhysicsFrame.h
vendored
@@ -1,14 +1,14 @@
|
||||
/**
|
||||
@file PhysicsFrame.h
|
||||
\file PhysicsFrame.h
|
||||
|
||||
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
\maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
|
||||
@created 2002-07-08
|
||||
@edited 2006-01-10
|
||||
\created 2002-07-08
|
||||
\edited 2011-05-10
|
||||
*/
|
||||
|
||||
#ifndef G3D_PHYSICSFRAME_H
|
||||
#define G3D_PHYSICSFRAME_H
|
||||
#ifndef G3D_PhysicsFrame_h
|
||||
#define G3D_PhysicsFrame_h
|
||||
|
||||
#include "G3D/platform.h"
|
||||
#include "G3D/Vector3.h"
|
||||
@@ -33,9 +33,9 @@ public:
|
||||
Quat rotation;
|
||||
|
||||
/**
|
||||
Takes object space points to world space.
|
||||
Origin of this reference frame in its parent's frame.
|
||||
*/
|
||||
Vector3 translation;
|
||||
Point3 translation;
|
||||
|
||||
/**
|
||||
Initializes to the identity frame.
|
||||
@@ -51,6 +51,13 @@ public:
|
||||
PhysicsFrame(const Matrix3& rot) : rotation(rot), translation(Vector3::zero()) {}
|
||||
PhysicsFrame(const CoordinateFrame& coordinateFrame);
|
||||
|
||||
PhysicsFrame& operator=(const PhysicsFrame& p) {
|
||||
rotation = p.rotation;
|
||||
translation = p.translation;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
- PhysicsFrame( [quat], [vec3] )
|
||||
- Vector3( ... )
|
||||
@@ -59,6 +66,8 @@ public:
|
||||
*/
|
||||
PhysicsFrame(const class Any& any);
|
||||
|
||||
Any toAny() const;
|
||||
|
||||
/** Compose: create the transformation that is <I>other</I> followed by <I>this</I>.*/
|
||||
PhysicsFrame operator*(const PhysicsFrame& other) const;
|
||||
|
||||
@@ -100,6 +109,16 @@ public:
|
||||
translation += f.translation;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const PhysicsFrame& other) const {
|
||||
return (translation == other.translation) &&
|
||||
((rotation == other.rotation) || (rotation == -other.rotation));
|
||||
}
|
||||
|
||||
bool operator!=(const PhysicsFrame& other) const {
|
||||
return ! ((*this) == other);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
typedef PhysicsFrame PFrame;
|
||||
|
||||
19
deps/g3dlite/include/G3D/PhysicsFrameSpline.h
vendored
19
deps/g3dlite/include/G3D/PhysicsFrameSpline.h
vendored
@@ -20,16 +20,31 @@ namespace G3D {
|
||||
*/
|
||||
class PhysicsFrameSpline : public Spline<PhysicsFrame> {
|
||||
public:
|
||||
|
||||
PhysicsFrameSpline();
|
||||
|
||||
/** Accepts a table of properties, or any valid PhysicsFrame specification for a single control*/
|
||||
PhysicsFrameSpline(const Any& any);
|
||||
|
||||
/** Clear and then reset all values from the any */
|
||||
PhysicsFrameSpline& operator=(const Any& any);
|
||||
bool operator==(const PhysicsFrameSpline& a) const;
|
||||
|
||||
bool operator!=(const PhysicsFrameSpline& a) const {
|
||||
return ! ((*this) == a);
|
||||
}
|
||||
|
||||
/** Mutates all underlying PhysicsFrames by scaling their translation by \param scaleFactor */
|
||||
void scaleControlPoints(float scaleFactor);
|
||||
|
||||
virtual void correct(PhysicsFrame& frame) const;
|
||||
virtual void ensureShortestPath(PhysicsFrame* A, int N) const;
|
||||
|
||||
virtual Any toAny(const std::string& myName) const override {
|
||||
return Spline<PhysicsFrame>::toAny(myName);
|
||||
}
|
||||
|
||||
Any toAny() const {
|
||||
return toAny("PFrameSpline");
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
68
deps/g3dlite/include/G3D/Plane.h
vendored
68
deps/g3dlite/include/G3D/Plane.h
vendored
@@ -1,16 +1,16 @@
|
||||
/**
|
||||
@file Plane.h
|
||||
\file Plane.h
|
||||
|
||||
Plane class
|
||||
|
||||
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
\maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
|
||||
@created 2001-06-02
|
||||
@edited 2004-07-18
|
||||
\created 2001-06-02
|
||||
\edited 2010-12-04
|
||||
*/
|
||||
|
||||
#ifndef G3D_PLANE_H
|
||||
#define G3D_PLANE_H
|
||||
#ifndef G3D_Plane_h
|
||||
#define G3D_Plane_h
|
||||
|
||||
#include "G3D/platform.h"
|
||||
#include "G3D/Vector3.h"
|
||||
@@ -26,8 +26,8 @@ class Plane {
|
||||
private:
|
||||
|
||||
/** normal.Dot(x,y,z) = distance */
|
||||
Vector3 _normal;
|
||||
float _distance;
|
||||
Vector3 _normal;
|
||||
float _distance;
|
||||
|
||||
/**
|
||||
Assumes the normal has unit length.
|
||||
@@ -40,43 +40,51 @@ public:
|
||||
Plane() : _normal(Vector3::unitY()), _distance(0) {
|
||||
}
|
||||
|
||||
/** Format is:
|
||||
- Plane(normal, point)
|
||||
*/
|
||||
explicit Plane(const class Any& a);
|
||||
|
||||
Any toAny() const;
|
||||
|
||||
/**
|
||||
Constructs a plane from three points.
|
||||
*/
|
||||
Plane(
|
||||
const Vector3& point0,
|
||||
const Vector3& point1,
|
||||
const Vector3& point2);
|
||||
Plane
|
||||
(const Point3& point0,
|
||||
const Point3& point1,
|
||||
const Point3& point2);
|
||||
|
||||
/**
|
||||
Constructs a plane from three points, where at most two are
|
||||
at infinity (w = 0, not xyz = inf).
|
||||
*/
|
||||
Plane(
|
||||
Vector4 point0,
|
||||
Vector4 point1,
|
||||
Vector4 point2);
|
||||
Vector4 point0,
|
||||
Vector4 point1,
|
||||
Vector4 point2);
|
||||
|
||||
/**
|
||||
The normal will be unitized.
|
||||
*/
|
||||
Plane(
|
||||
const Vector3& __normal,
|
||||
const Vector3& point);
|
||||
Plane
|
||||
(const Vector3& normal,
|
||||
const Point3& point);
|
||||
|
||||
static Plane fromEquation(float a, float b, float c, float d);
|
||||
|
||||
Plane(class BinaryInput& b);
|
||||
void serialize(class BinaryOutput& b) const;
|
||||
void deserialize(class BinaryInput& b);
|
||||
Plane(class BinaryInput& b);
|
||||
|
||||
void serialize(class BinaryOutput& b) const;
|
||||
void deserialize(class BinaryInput& b);
|
||||
|
||||
virtual ~Plane() {}
|
||||
|
||||
/**
|
||||
Returns true if point is on the side the normal points to or
|
||||
is in the plane.
|
||||
*/
|
||||
inline bool halfSpaceContains(Vector3 point) const {
|
||||
inline bool halfSpaceContains(Point3 point) const {
|
||||
// Clamp to a finite range for testing
|
||||
point = point.clamp(Vector3::minFinite(), Vector3::maxFinite());
|
||||
|
||||
@@ -101,7 +109,7 @@ public:
|
||||
Returns true if point is on the side the normal points to or
|
||||
is in the plane. Only call on finite points. Faster than halfSpaceContains.
|
||||
*/
|
||||
inline bool halfSpaceContainsFinite(const Vector3& point) const {
|
||||
inline bool halfSpaceContainsFinite(const Point3& point) const {
|
||||
debugAssert(point.isFinite());
|
||||
return _normal.dot(point) >= _distance;
|
||||
}
|
||||
@@ -109,13 +117,13 @@ public:
|
||||
/**
|
||||
Returns true if the point is nearly in the plane.
|
||||
*/
|
||||
inline bool fuzzyContains(const Vector3 &point) const {
|
||||
inline bool fuzzyContains(const Point3& point) const {
|
||||
return fuzzyEq(point.dot(_normal), _distance);
|
||||
}
|
||||
|
||||
inline const Vector3& normal() const {
|
||||
return _normal;
|
||||
}
|
||||
inline const Vector3& normal() const {
|
||||
return _normal;
|
||||
}
|
||||
|
||||
/**
|
||||
Returns distance from point to plane. Distance is negative if point is behind (not in plane in direction opposite normal) the plane.
|
||||
@@ -124,7 +132,7 @@ public:
|
||||
return (_normal.dot(x) - _distance);
|
||||
}
|
||||
|
||||
inline Vector3 closestPoint(const Vector3& x) const {
|
||||
inline Point3 closestPoint(const Point3& x) const {
|
||||
return x + (_normal * (-distance(x)));
|
||||
}
|
||||
|
||||
@@ -144,8 +152,8 @@ public:
|
||||
|
||||
<CODE>normal.Dot(Vector3(<I>x</I>, <I>y</I>, <I>z</I>)) + d = 0</CODE>
|
||||
*/
|
||||
void getEquation(Vector3 &normal, double& d) const;
|
||||
void getEquation(Vector3 &normal, float& d) const;
|
||||
void getEquation(Vector3& normal, double& d) const;
|
||||
void getEquation(Vector3& normal, float& d) const;
|
||||
|
||||
/**
|
||||
ax + by + cz + d = 0
|
||||
|
||||
242
deps/g3dlite/include/G3D/PointHashGrid.h
vendored
242
deps/g3dlite/include/G3D/PointHashGrid.h
vendored
@@ -1,11 +1,11 @@
|
||||
/**
|
||||
@file PointHashGrid.h
|
||||
\file PointHashGrid.h
|
||||
|
||||
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
@created 2008-07-01
|
||||
@edited 2009-05-28
|
||||
\maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
\created 2008-07-01
|
||||
\edited 2010-11-28
|
||||
|
||||
Copyright 2000-2010, Morgan McGuire.
|
||||
Copyright 2000-2012, Morgan McGuire.
|
||||
All rights reserved.
|
||||
*/
|
||||
#ifndef G3D_PointHashGrid_h
|
||||
@@ -25,23 +25,23 @@
|
||||
namespace G3D {
|
||||
|
||||
/**
|
||||
Storage of data in a sparse 3D grid of point-based data. The
|
||||
space cost for <I>n</I> elements is O(<I>n</I>). For data with
|
||||
\brief A sparse 3D grid of point-based data.
|
||||
|
||||
The space cost for <I>n</I> elements is O(<I>n</I>). For data with
|
||||
approximately uniform density (with respect to the radius hint),
|
||||
the time cost of searching for neighbors is O(1).
|
||||
|
||||
<i>Value</i> must be supported by a G3D::PositionTrait and
|
||||
G3D::EqualsTrait. Overloads are provided for
|
||||
common G3D classes like G3D::Vector3. For example:
|
||||
|
||||
<pre>
|
||||
class EqualsFunc {
|
||||
public:
|
||||
static bool equals(const Data& p, const Data& q) {
|
||||
return p == q;
|
||||
}
|
||||
};
|
||||
You can move members of the data set by first removing them and then
|
||||
adding them with a new location.
|
||||
|
||||
Template argument \a PosFunc must provide a static <code>getPosition</code> method
|
||||
and \a EqualsFunc must provide a static <code>equals</code> method, as described below.
|
||||
You can either write classes that support these yourself, provide template specializations of
|
||||
G3D::PositionTrait and
|
||||
G3D::EqualsTrait, or rely on the default template specializations, which already exist for
|
||||
common G3D classes like G3D::Point3. For example:
|
||||
|
||||
\code
|
||||
class PosFunc {
|
||||
public:
|
||||
static void getPosition(const Data& d, Vector3& pos) {
|
||||
@@ -49,14 +49,43 @@ namespace G3D {
|
||||
}
|
||||
};
|
||||
|
||||
class EqualsFunc {
|
||||
public:
|
||||
static bool equals(const Data& p, const Data& q) {
|
||||
return p == q;
|
||||
}
|
||||
};
|
||||
|
||||
PointHashGrid<Data, Data::PosFunc, Data::EqualsFunc> grid;
|
||||
</pre>
|
||||
\endcode
|
||||
|
||||
If the Value class defines operator==, the Equalsfunc is optional:
|
||||
If the \a Value class defines <code>operator==</code>, then the \a Equalsfunc is optional, so you can just write:
|
||||
|
||||
<pre>
|
||||
\code
|
||||
PointHashGrid<Data, Data::PosFunc> grid;
|
||||
</pre>
|
||||
\endcode
|
||||
|
||||
The simplest way to define these is often to make them both methods
|
||||
of the parameter class itself, e.g.,
|
||||
|
||||
\code
|
||||
|
||||
class Data {
|
||||
public:
|
||||
Point3 location;
|
||||
...
|
||||
|
||||
bool operator==(const Data& other) const {
|
||||
return (location == other.location) && ...;
|
||||
}
|
||||
|
||||
static void getPosition(const Data& p, Vector3& pos) {
|
||||
pos = p.location;
|
||||
}
|
||||
};
|
||||
|
||||
typedef PointHashGrid<Data, Data> DataGrid;
|
||||
\endcode
|
||||
|
||||
*/
|
||||
template<class Value,
|
||||
@@ -65,20 +94,20 @@ template<class Value,
|
||||
class PointHashGrid {
|
||||
private:
|
||||
|
||||
# define expectedCellSize (3)
|
||||
# define expectedCellSize (10)
|
||||
|
||||
# define ThisType PointHashGrid<Value, PosFunc, EqualsFunc>
|
||||
|
||||
/** A value annotated with precomputed position and hash code.*/
|
||||
class Entry {
|
||||
public:
|
||||
Vector3 position;
|
||||
Value value;
|
||||
Point3 position;
|
||||
Value value;
|
||||
};
|
||||
|
||||
/** One cell of the grid. */
|
||||
typedef SmallArray<Entry, expectedCellSize> Cell;
|
||||
typedef Table<Vector3int32, Cell > CellTable;
|
||||
typedef Table<Point3int32, Cell > CellTable;
|
||||
|
||||
/** The cube of +/-1 along each dimension. Initialized by initOffsetArray.*/
|
||||
Vector3int32 m_offsetArray[3*3*3];
|
||||
@@ -116,18 +145,19 @@ private:
|
||||
|
||||
/** Locate the cell and index within that cell containing v. Called by
|
||||
remove() and contains(). */
|
||||
bool find(const Value& v,
|
||||
Vector3int32& foundCellCoord,
|
||||
Cell*& foundCell,
|
||||
int& index) {
|
||||
bool find
|
||||
(const Value& v,
|
||||
Point3int32& foundCellCoord,
|
||||
Cell*& foundCell,
|
||||
int& index) {
|
||||
|
||||
Vector3 pos;
|
||||
Point3 pos;
|
||||
PosFunc::getPosition(v, pos);
|
||||
|
||||
Vector3int32 cellCoord;
|
||||
Point3int32 cellCoord;
|
||||
getCellCoord(pos, cellCoord);
|
||||
for (int i = 0; i < 27; ++i) {
|
||||
Vector3int32 c = cellCoord + m_offsetArray[i];
|
||||
Point3int32 c = cellCoord + m_offsetArray[i];
|
||||
Cell* cell = m_data.getPointer(c);
|
||||
if (cell != NULL) {
|
||||
// The cell exists
|
||||
@@ -146,18 +176,25 @@ private:
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Given a real-space position, returns the cell coord
|
||||
containing it.*/
|
||||
inline void getCellCoord(const Vector3& pos, Vector3int32& cellCoord) const {
|
||||
public:
|
||||
|
||||
/** \brief Compute the grid cell index of a real position.
|
||||
This is used extensively internally by PointHashGrid.
|
||||
It is useful to calling code to determine when an object
|
||||
is about to move between cells.
|
||||
*/
|
||||
inline void getCellCoord(const Point3& pos, Point3int32& cellCoord) const {
|
||||
for (int a = 0; a < 3; ++a) {
|
||||
cellCoord[a] = iFloor(pos[a] * m_invCellWidth);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
/** Initializes m_offsetArray. */
|
||||
void initOffsetArray() {
|
||||
int i = 0;
|
||||
Vector3int32 d;
|
||||
Point3int32 d;
|
||||
for (d.x = -1; d.x <= +1; ++d.x) {
|
||||
for (d.y = -1; d.y <= +1; ++d.y) {
|
||||
for (d.z = -1; d.z <= +1; ++d.z) {
|
||||
@@ -179,9 +216,10 @@ private:
|
||||
public:
|
||||
|
||||
/**
|
||||
@param radiusHint the radius that will typically be used with
|
||||
beginSphereIntersection and beginBoxIntersection. If two <i>Value</i>s are equal,
|
||||
their positions must be within this radius as well.
|
||||
\param radiusHint the radius that will typically be used with
|
||||
beginBallIntersection and beginBoxIntersection. If two <i>Value</i>s are equal,
|
||||
their positions must be within this radius as well. You can later change this
|
||||
value with clearAndSetRadiusHint().
|
||||
*/
|
||||
PointHashGrid(float radiusHint, const MemoryManager::Ref& m = MemoryManager::create()) : m_size(0), m_memoryManager(m) {
|
||||
initOffsetArray();
|
||||
@@ -192,23 +230,41 @@ public:
|
||||
m_invCellWidth = 1.0f / m_cellWidth;
|
||||
}
|
||||
|
||||
/** \sa clearAndSetRadiusHint() */
|
||||
float radiusHint() const {
|
||||
return m_cellWidth;
|
||||
}
|
||||
|
||||
void clear(float radiusHint) {
|
||||
debugAssertM(radiusHint > 0, "Cell radius must be positive");
|
||||
clear();
|
||||
m_cellWidth = radiusHint;
|
||||
m_invCellWidth = 1.0f / m_cellWidth;
|
||||
}
|
||||
|
||||
void clearAndSetRadiusHint(float radiusHint) {
|
||||
return clear(radiusHint);
|
||||
}
|
||||
|
||||
/**
|
||||
If radiusHint is negative, it is automatically chosen to put
|
||||
If \a radiusHint is negative, it is automatically chosen to put
|
||||
about 5 values in each grid cell (which means about 27 * 5
|
||||
values for each beginIntersection call).
|
||||
|
||||
\sa clearAndSetRadiusHint()
|
||||
*/
|
||||
PointHashGrid(const Array<Value>& init, float radiusHint = -1.0f, const MemoryManager::Ref& m = MemoryManager::create()) : m_size(0), m_memoryManager(m) {
|
||||
PointHashGrid(const Array<Value>& init, float radiusHint = -1.0f, const MemoryManager::Ref& m = MemoryManager::create()) : m_size(0), m_memoryManager(m) {
|
||||
initOffsetArray();
|
||||
m_data.clearAndSetMemoryManager(m_memoryManager);
|
||||
|
||||
Vector3 lo(Vector3::inf());
|
||||
Vector3 hi(-lo);
|
||||
Point3 lo(Vector3::inf());
|
||||
Point3 hi(-lo);
|
||||
|
||||
// Compute bounds
|
||||
Array<Entry> entry(init.size());
|
||||
for (int i = 0; i < entry.size(); ++i) {
|
||||
const Value& value = init[i];
|
||||
Vector3 pos;
|
||||
Point3 pos;
|
||||
|
||||
entry[i].value = value;
|
||||
entry[i].hashCode = m_hashFunc(value);
|
||||
@@ -241,7 +297,7 @@ public:
|
||||
}
|
||||
|
||||
/** Returns the number of elements. */
|
||||
inline int size() const {
|
||||
int size() const {
|
||||
return m_size;
|
||||
}
|
||||
|
||||
@@ -251,13 +307,19 @@ public:
|
||||
return m_bounds;
|
||||
}
|
||||
|
||||
void debugPrintStatistics() const {
|
||||
debugPrintf("Deepest bucket size = %d\n", (int)m_data.debugGetDeepestBucketSize());
|
||||
debugPrintf("Average bucket size = %g\n", m_data.debugGetAverageBucketSize());
|
||||
debugPrintf("Load factor = %g\n", m_data.debugGetLoad());
|
||||
}
|
||||
|
||||
/** Insert @a v at position @a p given by <code>getPosition(v, p)</code>.
|
||||
Multiple elements that are equal may be inserted; all copies will be
|
||||
in the data structure. */
|
||||
void insert(const Value& v) {
|
||||
Vector3 pos;
|
||||
Point3 pos;
|
||||
PosFunc::getPosition(v, pos);
|
||||
Vector3int32 cellCoord;
|
||||
Point3int32 cellCoord;
|
||||
getCellCoord(pos, cellCoord);
|
||||
|
||||
// See if the cell already exists
|
||||
@@ -316,7 +378,8 @@ public:
|
||||
|
||||
// Drop our pointer, which is about to dangle
|
||||
cell = NULL;
|
||||
bool success = m_data.remove(cellCoord);
|
||||
const bool success = m_data.remove(cellCoord);
|
||||
(void)success;
|
||||
debugAssertM(success, "Data structure corrupt: "
|
||||
"tried to remove a cell that doesn't exist.");
|
||||
}
|
||||
@@ -328,7 +391,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
/** Removes all elements of @v. */
|
||||
/** Removes all elements of \a v. */
|
||||
void remove(const Array<Value>& v, bool shrink = true) {
|
||||
for (int i = 0; i < v.size(); ++i) {
|
||||
remove(v[i], shrink);
|
||||
@@ -387,6 +450,11 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
bool isValid() const {
|
||||
return ! m_isEnd;
|
||||
}
|
||||
|
||||
/** @deprecated Use isValid */
|
||||
bool hasMore() const {
|
||||
return ! m_isEnd;
|
||||
}
|
||||
@@ -615,9 +683,14 @@ public:
|
||||
const Value* operator->() const { return &value(); }
|
||||
operator Value*() const { return &value(); }
|
||||
|
||||
/** \deprecated Use isValid */
|
||||
bool hasMore() const {
|
||||
return ! m_isEnd;
|
||||
}
|
||||
|
||||
bool isValid() const {
|
||||
return ! m_isEnd;
|
||||
}
|
||||
}; // BoxIterator
|
||||
|
||||
/**
|
||||
@@ -652,7 +725,7 @@ public:
|
||||
SphereIterator() : m_isEnd(true) {}
|
||||
|
||||
void advance() {
|
||||
if (! m_boxIterator.hasMore()) {
|
||||
if (! m_boxIterator.isValid()) {
|
||||
m_isEnd = true;
|
||||
return;
|
||||
}
|
||||
@@ -660,7 +733,7 @@ public:
|
||||
while (! m_sphere.contains(m_boxIterator.position())) {
|
||||
++m_boxIterator;
|
||||
|
||||
if (! m_boxIterator.hasMore()) {
|
||||
if (! m_boxIterator.isValid()) {
|
||||
m_isEnd = true;
|
||||
return;
|
||||
}
|
||||
@@ -677,13 +750,13 @@ public:
|
||||
m_isEnd(false),
|
||||
m_sphere(sphere),
|
||||
m_boxIterator(grid, false, getBoundingBox(sphere)) {
|
||||
|
||||
|
||||
// Find the first element that is actually in the sphere,
|
||||
// not just the box.
|
||||
advance();
|
||||
}
|
||||
|
||||
const Value& value() const {
|
||||
const Value& value() const {
|
||||
return *m_boxIterator;
|
||||
}
|
||||
|
||||
@@ -693,6 +766,7 @@ public:
|
||||
|
||||
// Intentionally unimplemented
|
||||
SphereIterator& operator=(const SphereIterator&);
|
||||
|
||||
public:
|
||||
|
||||
inline bool operator!=(const SphereIterator& other) const {
|
||||
@@ -710,8 +784,6 @@ public:
|
||||
return !(*this != other);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Preincrement */
|
||||
SphereIterator& operator++() {
|
||||
debugAssert(! m_isEnd);
|
||||
@@ -733,34 +805,55 @@ public:
|
||||
const Value* operator->() const { return &value(); }
|
||||
operator Value*() const { return &value(); }
|
||||
|
||||
bool hasMore() const {
|
||||
/** \deprecated use isValid */
|
||||
bool G3D_DEPRECATED hasMore() const {
|
||||
return ! m_isEnd;
|
||||
}
|
||||
|
||||
bool isValid() const {
|
||||
return ! m_isEnd;
|
||||
}
|
||||
}; // SphereIterator
|
||||
|
||||
/**
|
||||
Finds all values whose positions are within @a sphere. It is an error
|
||||
to mutate the HashGrid while iterating through it.
|
||||
*/
|
||||
SphereIterator beginSphereIntersection(const Sphere& sphere) const {
|
||||
/** Finds all values whose positions are within \a sphere. It is
|
||||
an error to mutate the PointHashGrid while iterating through
|
||||
it. */
|
||||
SphereIterator begin(const Sphere& sphere) const {
|
||||
return SphereIterator(this, sphere);
|
||||
}
|
||||
|
||||
|
||||
/** \deprecated \sa beginIntersection */
|
||||
SphereIterator G3D_DEPRECATED beginSphereIntersection(const Sphere& sphere) const {
|
||||
return SphereIterator(this, sphere);
|
||||
}
|
||||
|
||||
|
||||
/** \deprecated \sa SphereIterator::hasMore */
|
||||
const SphereIterator& endSphereIntersection() const {
|
||||
static const SphereIterator it;
|
||||
return it;
|
||||
}
|
||||
|
||||
|
||||
/** Appends results */
|
||||
void getIntersectingMembers(const Sphere& sphere, Array<Value>& result) const {
|
||||
for (SphereIterator it = beginSphereIntersection(sphere); it.isValid(); ++it) {
|
||||
result.append(*it);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
Dereference to access the bounds() and size() [element count] of the underlying
|
||||
cell objet.
|
||||
cell object.
|
||||
|
||||
Example:
|
||||
<pre>
|
||||
for(PointHashGrid<Vector3>::CellIterator iter = grid.beginCells(); iter != grid.endCells(); ++iter) {
|
||||
for(PointHashGrid<Vector3>::CellIterator iter = grid.beginCells(); iter != grid.endCells(); ++iter) {
|
||||
entriesFound += iter->size();
|
||||
}
|
||||
</pre>
|
||||
@@ -793,8 +886,8 @@ public:
|
||||
/** Returns the bounds on this cell */
|
||||
AABox bounds() const {
|
||||
const Vector3int32& k = m_parent->m_tableIterator->key;
|
||||
return AABox(Vector3(k) * m_parent->m_cellWidth,
|
||||
Vector3(k + Vector3int32(1, 1, 1)) * m_parent->m_cellWidth);
|
||||
return AABox(Vector3(k) * m_parent->m_grid->m_cellWidth,
|
||||
Vector3(k + Vector3int32(1, 1, 1)) * m_parent->m_grid->m_cellWidth);
|
||||
}
|
||||
|
||||
/** Number of elements inside this cell */
|
||||
@@ -823,7 +916,7 @@ public:
|
||||
m_tableIterator( grid->m_data.begin()),
|
||||
m_epoch(grid->m_epoch) {
|
||||
m_indirection.m_parent = this;
|
||||
m_isEnd = ! m_tableIterator.hasMore();
|
||||
m_isEnd = ! m_tableIterator.isValid();
|
||||
}
|
||||
|
||||
// Intentionally unimplemented
|
||||
@@ -853,7 +946,7 @@ public:
|
||||
"It is illegal to mutate the HashGrid while "
|
||||
"iterating through it.");
|
||||
++m_tableIterator;
|
||||
m_isEnd = ! m_tableIterator.hasMore();
|
||||
m_isEnd = ! m_tableIterator.isValid();
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -864,9 +957,14 @@ public:
|
||||
return old;
|
||||
}
|
||||
|
||||
/** \deprecated Use isValid */
|
||||
bool hasMore() const {
|
||||
return ! m_isEnd;
|
||||
}
|
||||
|
||||
bool isValid() const {
|
||||
return ! m_isEnd;
|
||||
}
|
||||
}; // CellIterator
|
||||
|
||||
/** Iterates through the non-empty cells. This is intended primarily for
|
||||
@@ -897,11 +995,11 @@ public:
|
||||
This is a helper to avoid requiring you to iterate through the data
|
||||
structure, removing and deleting each one. Clears the PointHashGrid at the
|
||||
end.
|
||||
|
||||
|
||||
Using objects (instead of pointers) or reference counted pointers is
|
||||
recommended over using pointers and this deleteAll method.*/
|
||||
void deleteAll() {
|
||||
for (Iterator it = begin(); it.hasMore(); ++it) {
|
||||
for (Iterator it = begin(); it.isValid(); ++it) {
|
||||
delete *it;
|
||||
}
|
||||
clear();
|
||||
@@ -924,7 +1022,7 @@ public:
|
||||
m_bounds = AABox();
|
||||
if (! shrink) {
|
||||
// Remove all data
|
||||
for (CellIterator it = beginCells(); it.hasMore(); ++it) {
|
||||
for (CellIterator it = beginCells(); it.isValid(); ++it) {
|
||||
it.cell().clear(true);
|
||||
}
|
||||
} else {
|
||||
@@ -934,7 +1032,7 @@ public:
|
||||
}
|
||||
|
||||
int debugGetDeepestBucketSize() const {
|
||||
return m_data.debugGetDeepestBucketSize();
|
||||
return (int)m_data.debugGetDeepestBucketSize();
|
||||
}
|
||||
|
||||
float debugGetAverageBucketSize() const {
|
||||
|
||||
149
deps/g3dlite/include/G3D/PointKDTree.h
vendored
149
deps/g3dlite/include/G3D/PointKDTree.h
vendored
@@ -4,15 +4,15 @@
|
||||
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
|
||||
@created 2004-01-11
|
||||
@edited 2008-11-02
|
||||
@edited 2012-07-30
|
||||
|
||||
Copyright 2000-2009, Morgan McGuire.
|
||||
Copyright 2000-2012, Morgan McGuire.
|
||||
All rights reserved.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef X_PointKDTree_H
|
||||
#define X_PointKDTree_H
|
||||
#ifndef G3D_PointKDTree_h
|
||||
#define G3D_PointKDTree_h
|
||||
|
||||
#include "G3D/platform.h"
|
||||
#include "G3D/Array.h"
|
||||
@@ -26,7 +26,7 @@
|
||||
#include "G3D/BinaryInput.h"
|
||||
#include "G3D/BinaryOutput.h"
|
||||
#include "G3D/CollisionDetection.h"
|
||||
#include "G3D/GCamera.h"
|
||||
#include "G3D/Frustum.h"
|
||||
#include "G3D/PositionTrait.h"
|
||||
#include <algorithm>
|
||||
|
||||
@@ -234,36 +234,38 @@ protected:
|
||||
}
|
||||
|
||||
|
||||
void verifyNode(const Vector3& lo, const Vector3& hi) {
|
||||
// debugPrintf("Verifying: split %d @ %f [%f, %f, %f], [%f, %f, %f]\n",
|
||||
// splitAxis, splitLocation, lo.x, lo.y, lo.z, hi.x, hi.y, hi.z);
|
||||
void verifyNode(const Vector3& lo, const Vector3& hi) {
|
||||
// debugPrintf("Verifying: split %d @ %f [%f, %f, %f], [%f, %f, %f]\n",
|
||||
// splitAxis, splitLocation, lo.x, lo.y, lo.z, hi.x, hi.y, hi.z);
|
||||
|
||||
debugAssert(lo == splitBounds.low());
|
||||
debugAssert(hi == splitBounds.high());
|
||||
|
||||
for (int i = 0; i < valueArray.length(); ++i) {
|
||||
const Vector3& b = valueArray[i].position();
|
||||
# ifdef G3D_DEBUG
|
||||
for (int i = 0; i < valueArray.length(); ++i) {
|
||||
const Vector3& b = valueArray[i].position();
|
||||
debugAssert(splitBounds.contains(b));
|
||||
}
|
||||
}
|
||||
# endif
|
||||
|
||||
if (child[0] || child[1]) {
|
||||
debugAssert(lo[splitAxis] < splitLocation);
|
||||
debugAssert(hi[splitAxis] > splitLocation);
|
||||
}
|
||||
if (child[0] || child[1]) {
|
||||
debugAssert(lo[splitAxis] < splitLocation);
|
||||
debugAssert(hi[splitAxis] > splitLocation);
|
||||
}
|
||||
|
||||
Vector3 newLo = lo;
|
||||
newLo[splitAxis] = splitLocation;
|
||||
Vector3 newHi = hi;
|
||||
newHi[splitAxis] = splitLocation;
|
||||
Vector3 newLo = lo;
|
||||
newLo[splitAxis] = splitLocation;
|
||||
Vector3 newHi = hi;
|
||||
newHi[splitAxis] = splitLocation;
|
||||
|
||||
if (child[0] != NULL) {
|
||||
child[0]->verifyNode(lo, newHi);
|
||||
}
|
||||
if (child[0] != NULL) {
|
||||
child[0]->verifyNode(lo, newHi);
|
||||
}
|
||||
|
||||
if (child[1] != NULL) {
|
||||
child[1]->verifyNode(newLo, hi);
|
||||
}
|
||||
}
|
||||
if (child[1] != NULL) {
|
||||
child[1]->verifyNode(newLo, hi);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@@ -297,6 +299,7 @@ protected:
|
||||
for (int c = 0; c < 2; ++c) {
|
||||
n->child[c] = deserializeStructure(bi);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -484,7 +487,7 @@ protected:
|
||||
// Compute the mean along the axis
|
||||
|
||||
splitLocation = (bounds.high()[splitAxis] +
|
||||
bounds.low()[splitAxis]) / 2.0;
|
||||
bounds.low()[splitAxis]) / 2.0f;
|
||||
|
||||
Handle splitHandle;
|
||||
Vector3 v;
|
||||
@@ -525,10 +528,10 @@ protected:
|
||||
for(int i = 0; i < node->valueArray.size(); ++i) {
|
||||
memberTable.set(node->valueArray[i].value, node);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return node;
|
||||
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -611,7 +614,7 @@ public:
|
||||
}
|
||||
|
||||
|
||||
int size() const {
|
||||
size_t size() const {
|
||||
return memberTable.size();
|
||||
}
|
||||
|
||||
@@ -809,7 +812,7 @@ private:
|
||||
|
||||
// Test values at this node against remaining planes
|
||||
for (int p = 0; p < plane.size(); ++p) {
|
||||
if ((parentMask >> p) & 1 != 0) {
|
||||
if (((parentMask >> p) & 1) != 0) {
|
||||
// Test against this plane
|
||||
const Plane& curPlane = plane[p];
|
||||
for (int v = node->valueArray.size() - 1; v >= 0; --v) {
|
||||
@@ -851,7 +854,7 @@ public:
|
||||
|
||||
/**
|
||||
Typically used to find all visible
|
||||
objects inside the view frustum (see also GCamera::getClipPlanes)... i.e. all objects
|
||||
objects inside the view frustum (see also Camera::getClipPlanes)... i.e. all objects
|
||||
<B>not</B> culled by frustum.
|
||||
|
||||
Example:
|
||||
@@ -862,7 +865,7 @@ public:
|
||||
</PRE>
|
||||
@param members The results are appended to this array.
|
||||
*/
|
||||
void getIntersectingMembers(const GCamera::Frustum& frustum, Array<T>& members) const {
|
||||
void getIntersectingMembers(const Frustum& frustum, Array<T>& members) const {
|
||||
Array<Plane> plane;
|
||||
|
||||
for (int i = 0; i < frustum.faceArray.size(); ++i) {
|
||||
@@ -960,51 +963,51 @@ public:
|
||||
BoxIntersectionIterator& operator++() {
|
||||
++nextValueArrayIndex;
|
||||
|
||||
bool foundIntersection = false;
|
||||
bool foundIntersection = false;
|
||||
while (! isEnd && ! foundIntersection) {
|
||||
|
||||
// Search for the next node if we've exhausted this one
|
||||
// Search for the next node if we've exhausted this one
|
||||
while ((! isEnd) && (nextValueArrayIndex >= node->valueArray.length())) {
|
||||
// If we entered this loop, then the iterator has exhausted the elements at
|
||||
// node (possibly because it just switched to a child node with no members).
|
||||
// This loop continues until it finds a node with members or reaches
|
||||
// the end of the whole intersection search.
|
||||
// If we entered this loop, then the iterator has exhausted the elements at
|
||||
// node (possibly because it just switched to a child node with no members).
|
||||
// This loop continues until it finds a node with members or reaches
|
||||
// the end of the whole intersection search.
|
||||
|
||||
// If the right child overlaps the box, push it onto the stack for
|
||||
// processing.
|
||||
if ((node->child[1] != NULL) &&
|
||||
(box.high()[node->splitAxis] > node->splitLocation)) {
|
||||
stack.push(node->child[1]);
|
||||
}
|
||||
// If the right child overlaps the box, push it onto the stack for
|
||||
// processing.
|
||||
if ((node->child[1] != NULL) &&
|
||||
(box.high()[node->splitAxis] > node->splitLocation)) {
|
||||
stack.push(node->child[1]);
|
||||
}
|
||||
|
||||
// If the left child overlaps the box, push it onto the stack for
|
||||
// processing.
|
||||
if ((node->child[0] != NULL) &&
|
||||
(box.low()[node->splitAxis] < node->splitLocation)) {
|
||||
stack.push(node->child[0]);
|
||||
}
|
||||
// If the left child overlaps the box, push it onto the stack for
|
||||
// processing.
|
||||
if ((node->child[0] != NULL) &&
|
||||
(box.low()[node->splitAxis] < node->splitLocation)) {
|
||||
stack.push(node->child[0]);
|
||||
}
|
||||
|
||||
if (stack.length() > 0) {
|
||||
// Go on to the next node (which may be either one of the ones we
|
||||
// just pushed, or one from farther back the tree).
|
||||
node = stack.pop();
|
||||
nextValueArrayIndex = 0;
|
||||
} else {
|
||||
// That was the last node; we're done iterating
|
||||
isEnd = true;
|
||||
}
|
||||
}
|
||||
if (stack.length() > 0) {
|
||||
// Go on to the next node (which may be either one of the ones we
|
||||
// just pushed, or one from farther back the tree).
|
||||
node = stack.pop();
|
||||
nextValueArrayIndex = 0;
|
||||
} else {
|
||||
// That was the last node; we're done iterating
|
||||
isEnd = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Search for the next intersection at this node until we run out of children
|
||||
while (! isEnd && ! foundIntersection && (nextValueArrayIndex < node->valueArray.length())) {
|
||||
if (box.intersects(node->valueArray[nextValueArrayIndex].bounds)) {
|
||||
foundIntersection = true;
|
||||
} else {
|
||||
++nextValueArrayIndex;
|
||||
// If we exhaust this node, we'll loop around the master loop
|
||||
// to find a new node.
|
||||
}
|
||||
}
|
||||
// Search for the next intersection at this node until we run out of children
|
||||
while (! isEnd && ! foundIntersection && (nextValueArrayIndex < node->valueArray.length())) {
|
||||
if (box.intersects(node->valueArray[nextValueArrayIndex].bounds)) {
|
||||
foundIntersection = true;
|
||||
} else {
|
||||
++nextValueArrayIndex;
|
||||
// If we exhaust this node, we'll loop around the master loop
|
||||
// to find a new node.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
|
||||
128
deps/g3dlite/include/G3D/Pointer.h
vendored
128
deps/g3dlite/include/G3D/Pointer.h
vendored
@@ -1,12 +1,12 @@
|
||||
/**
|
||||
@file Pointer.h
|
||||
\file Pointer.h
|
||||
|
||||
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
\maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
|
||||
@created 2007-05-16
|
||||
@edited 2009-03-26
|
||||
\created 2007-05-16
|
||||
\edited 2012-10-06
|
||||
|
||||
Copyright 2000-2009, Morgan McGuire.
|
||||
Copyright 2000-2012, Morgan McGuire.
|
||||
All rights reserved.
|
||||
*/
|
||||
#ifndef G3D_Pointer_h
|
||||
@@ -27,7 +27,7 @@ namespace G3D {
|
||||
Because the accessors require values to be passed by value (instead of by reference)
|
||||
this is primarily useful for objects whose memory size is small.
|
||||
|
||||
<pre>
|
||||
\code
|
||||
class Foo {
|
||||
public:
|
||||
void setEnabled(bool b);
|
||||
@@ -51,14 +51,15 @@ namespace G3D {
|
||||
|
||||
p2.setValue(p1.getValue());
|
||||
p2 = p1;
|
||||
</pre>
|
||||
\endcode
|
||||
|
||||
<i>Note:</i> Because of the way that dereference is implemented, you cannot pass <code>*p</code> through a function
|
||||
that takes varargs (...), e.g., <code>printf("%d", *p)</code> will produce a compile-time error. Instead use
|
||||
<code>printf("%d",(bool)*p)</code> or <code>printf("%d", p.getValue())</code>.
|
||||
|
||||
|
||||
\cite McGuire, GUIs for Real-time Programs, using Universal Pointers, SIGGRAPH 2008 Poster.
|
||||
*/
|
||||
template<class ValueType>
|
||||
template<typename ValueType>
|
||||
class Pointer {
|
||||
private:
|
||||
|
||||
@@ -78,9 +79,7 @@ private:
|
||||
|
||||
public:
|
||||
|
||||
Memory(ValueType* value) : value(value) {
|
||||
//debugAssert(value != NULL);
|
||||
}
|
||||
Memory(ValueType* value) : value(value) {}
|
||||
|
||||
virtual void set(ValueType v) {
|
||||
*value = v;
|
||||
@@ -99,6 +98,35 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
template<typename GetMethod, typename SetMethod>
|
||||
class FcnAccessor : public Interface {
|
||||
private:
|
||||
|
||||
GetMethod getMethod;
|
||||
SetMethod setMethod;
|
||||
|
||||
public:
|
||||
|
||||
FcnAccessor(GetMethod getMethod, SetMethod setMethod) : getMethod(getMethod), setMethod(setMethod) {
|
||||
}
|
||||
|
||||
virtual void set(ValueType v) {
|
||||
if (setMethod) {
|
||||
(*setMethod)(v);
|
||||
}
|
||||
}
|
||||
|
||||
virtual ValueType get() const {
|
||||
return (*getMethod)();
|
||||
}
|
||||
|
||||
virtual Interface* clone() const {
|
||||
return new FcnAccessor(getMethod, setMethod);
|
||||
}
|
||||
|
||||
virtual bool isNull() const { return false; }
|
||||
};
|
||||
|
||||
template<class T, typename GetMethod, typename SetMethod>
|
||||
class Accessor : public Interface {
|
||||
private:
|
||||
@@ -116,7 +144,9 @@ private:
|
||||
}
|
||||
|
||||
virtual void set(ValueType v) {
|
||||
(object->*setMethod)(v);
|
||||
if (setMethod) {
|
||||
(object->*setMethod)(v);
|
||||
}
|
||||
}
|
||||
|
||||
virtual ValueType get() const {
|
||||
@@ -134,17 +164,17 @@ private:
|
||||
|
||||
|
||||
template<class T, typename GetMethod, typename SetMethod>
|
||||
class RefAccessor : public Interface {
|
||||
class SharedAccessor : public Interface {
|
||||
private:
|
||||
|
||||
ReferenceCountedPointer<T> object;
|
||||
GetMethod getMethod;
|
||||
SetMethod setMethod;
|
||||
shared_ptr<T> object;
|
||||
GetMethod getMethod;
|
||||
SetMethod setMethod;
|
||||
|
||||
public:
|
||||
|
||||
RefAccessor(
|
||||
const ReferenceCountedPointer<T>& object,
|
||||
SharedAccessor
|
||||
(const shared_ptr<T>& object,
|
||||
GetMethod getMethod,
|
||||
SetMethod setMethod) : object(object), getMethod(getMethod), setMethod(setMethod) {
|
||||
|
||||
@@ -152,23 +182,24 @@ private:
|
||||
}
|
||||
|
||||
virtual void set(ValueType v) {
|
||||
(object.pointer()->*setMethod)(v);
|
||||
if (setMethod) {
|
||||
(object.get()->*setMethod)(v);
|
||||
}
|
||||
}
|
||||
|
||||
virtual ValueType get() const {
|
||||
return (object.pointer()->*getMethod)();
|
||||
return (object.get()->*getMethod)();
|
||||
}
|
||||
|
||||
virtual Interface* clone() const {
|
||||
return new RefAccessor(object, getMethod, setMethod);
|
||||
return new SharedAccessor(object, getMethod, setMethod);
|
||||
}
|
||||
|
||||
virtual bool isNull() const {
|
||||
return object.isNull();
|
||||
return (bool)object;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Interface* m_interface;
|
||||
|
||||
public:
|
||||
@@ -197,48 +228,69 @@ public:
|
||||
this[0] = p;
|
||||
}
|
||||
|
||||
|
||||
/** \param setMethod May be NULL */
|
||||
template<class Class>
|
||||
Pointer(const ReferenceCountedPointer<Class>& object,
|
||||
Pointer(const shared_ptr<Class>& object,
|
||||
ValueType (Class::*getMethod)() const,
|
||||
void (Class::*setMethod)(ValueType)) :
|
||||
m_interface(new RefAccessor<Class, ValueType (Class::*)() const, void (Class::*)(ValueType)>(object, getMethod, setMethod)) {}
|
||||
m_interface(new SharedAccessor<Class, ValueType (Class::*)() const, void (Class::*)(ValueType)>(object, getMethod, setMethod)) {}
|
||||
|
||||
/** \param setMethod May be NULL */
|
||||
template<class Class>
|
||||
Pointer(const ReferenceCountedPointer<Class>& object,
|
||||
Pointer(const shared_ptr<Class>& object,
|
||||
const ValueType& (Class::*getMethod)() const,
|
||||
void (Class::*setMethod)(ValueType)) :
|
||||
m_interface(new RefAccessor<Class, const ValueType& (Class::*)() const, void (Class::*)(ValueType)>(object, getMethod, setMethod)) {}
|
||||
m_interface(new SharedAccessor<Class, const ValueType& (Class::*)() const, void (Class::*)(ValueType)>(object, getMethod, setMethod)) {}
|
||||
|
||||
|
||||
/** \param setMethod May be NULL */
|
||||
Pointer(ValueType (*getMethod)(),
|
||||
void (*setMethod)(ValueType)) :
|
||||
m_interface(new FcnAccessor<ValueType (*)(), void (*)(ValueType)>(getMethod, setMethod)) {}
|
||||
|
||||
/** \param setMethod May be NULL */
|
||||
Pointer(const ValueType& (*getMethod)(),
|
||||
void (*setMethod)(ValueType)) :
|
||||
m_interface(new FcnAccessor<const ValueType& (*)(), void (*)(ValueType)>(getMethod, setMethod)) {}
|
||||
|
||||
|
||||
/** \param setMethod May be NULL */
|
||||
template<class Class>
|
||||
Pointer(const ReferenceCountedPointer<Class>& object,
|
||||
Pointer(const shared_ptr<Class>& object,
|
||||
ValueType (Class::*getMethod)() const,
|
||||
void (Class::*setMethod)(const ValueType&)) :
|
||||
m_interface(new RefAccessor<Class, ValueType (Class::*)() const, void (Class::*)(const ValueType&)>(object, getMethod, setMethod)) {}
|
||||
m_interface(new SharedAccessor<Class, ValueType (Class::*)() const, void (Class::*)(const ValueType&)>(object, getMethod, setMethod)) {}
|
||||
|
||||
/** \param setMethod May be NULL */
|
||||
template<class Class>
|
||||
Pointer(const ReferenceCountedPointer<Class>& object,
|
||||
Pointer(const shared_ptr<Class>& object,
|
||||
const ValueType& (Class::*getMethod)() const,
|
||||
void (Class::*setMethod)(const ValueType&)) :
|
||||
m_interface(new RefAccessor<Class, const ValueType& (Class::*)() const, void (Class::*)(const ValueType&)>(object, getMethod, setMethod)) {}
|
||||
m_interface(new SharedAccessor<Class, const ValueType& (Class::*)() const, void (Class::*)(const ValueType&)>(object, getMethod, setMethod)) {}
|
||||
|
||||
/** \param setMethod May be NULL */
|
||||
template<class Class>
|
||||
Pointer(Class* object,
|
||||
const ValueType& (Class::*getMethod)() const,
|
||||
void (Class::*setMethod)(const ValueType&)) :
|
||||
m_interface(new Accessor<Class, const ValueType& (Class::*)() const, void (Class::*)(const ValueType&)>(object, getMethod, setMethod)) {}
|
||||
|
||||
/** \param setMethod May be NULL */
|
||||
template<class Class>
|
||||
Pointer(Class* object,
|
||||
ValueType (Class::*getMethod)() const,
|
||||
void (Class::*setMethod)(const ValueType&)) :
|
||||
m_interface(new Accessor<Class, ValueType (Class::*)() const, void (Class::*)(const ValueType&)>(object, getMethod, setMethod)) {}
|
||||
|
||||
/** \param setMethod May be NULL */
|
||||
template<class Class>
|
||||
Pointer(Class* object,
|
||||
const ValueType& (Class::*getMethod)() const,
|
||||
void (Class::*setMethod)(ValueType)) :
|
||||
m_interface(new Accessor<Class, const ValueType& (Class::*)() const, void (Class::*)(ValueType)>(object, getMethod, setMethod)) {}
|
||||
|
||||
/** \param setMethod May be NULL */
|
||||
template<class Class>
|
||||
Pointer(Class* object,
|
||||
ValueType (Class::*getMethod)() const,
|
||||
@@ -254,6 +306,8 @@ public:
|
||||
return m_interface->get();
|
||||
}
|
||||
|
||||
/** \brief Assign a value to the referenced element.
|
||||
If this Pointer was initialized with a NULL setMethod, the call is ignored */
|
||||
inline void setValue(const ValueType& v) {
|
||||
debugAssert(m_interface != NULL);
|
||||
m_interface->set(v);
|
||||
@@ -287,6 +341,16 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template<class T>
|
||||
bool isNull(const Pointer<T>& p) {
|
||||
return p.isNull();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool notNull(const Pointer<T>& p) {
|
||||
return ! p.isNull();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
115
deps/g3dlite/include/G3D/Quat.h
vendored
115
deps/g3dlite/include/G3D/Quat.h
vendored
@@ -1,12 +1,12 @@
|
||||
/**
|
||||
@file Quat.h
|
||||
\file G3D/Quat.h
|
||||
|
||||
Quaternion
|
||||
|
||||
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
\maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
|
||||
@created 2002-01-23
|
||||
@edited 2009-05-10
|
||||
\created 2002-01-23
|
||||
\edited 2011-05-10
|
||||
*/
|
||||
|
||||
#ifndef G3D_Quat_h
|
||||
@@ -21,9 +21,9 @@
|
||||
namespace G3D {
|
||||
|
||||
/**
|
||||
Arbitrary quaternion (not necessarily unit)
|
||||
Arbitrary quaternion (not necessarily unit).
|
||||
|
||||
Unit quaternions are used in computer graphics to represent
|
||||
Unit quaternions (aka versors) are used in computer graphics to represent
|
||||
rotation about an axis. Any 3x3 rotation matrix can
|
||||
be stored as a quaternion.
|
||||
|
||||
@@ -72,6 +72,8 @@ public:
|
||||
/** Expects "Quat(x,y,z,w)" or a Matrix3 constructor. */
|
||||
Quat(const class Any& a);
|
||||
|
||||
Any toAny() const;
|
||||
|
||||
Quat(const Matrix3& rot);
|
||||
|
||||
Quat(float _x, float _y, float _z, float _w) :
|
||||
@@ -81,6 +83,12 @@ public:
|
||||
Quat(const Vector3& v, float _w = 0) : x(v.x), y(v.y), z(v.z), w(_w) {
|
||||
}
|
||||
|
||||
/** True if the components are exactly equal. Note that two quaternations may
|
||||
be unequal but map to the same rotation. */
|
||||
bool operator==(const Quat& q) const {
|
||||
return x == q.x && y == q.y && z == q.z && w == q.w;
|
||||
}
|
||||
|
||||
/**
|
||||
The real part of the quaternion.
|
||||
*/
|
||||
@@ -92,9 +100,9 @@ public:
|
||||
return w;
|
||||
}
|
||||
|
||||
Quat operator-() const {
|
||||
return Quat(-x, -y, -z, -w);
|
||||
}
|
||||
Quat operator-() const {
|
||||
return Quat(-x, -y, -z, -w);
|
||||
}
|
||||
|
||||
Quat operator-(const Quat& other) const {
|
||||
return Quat(x - other.x, y - other.y, z - other.z, w - other.w);
|
||||
@@ -148,7 +156,7 @@ public:
|
||||
}
|
||||
|
||||
|
||||
/** @cite Based on Watt & Watt, page 360 */
|
||||
/** @cite Based on Watt & Watt, page 360 */
|
||||
friend Quat operator* (float s, const Quat& q);
|
||||
|
||||
inline Quat operator/(float s) const {
|
||||
@@ -196,36 +204,69 @@ public:
|
||||
void toAxisAngleRotation(
|
||||
Vector3& axis,
|
||||
float& angle) const {
|
||||
double d;
|
||||
toAxisAngleRotation(axis, d);
|
||||
angle = (float)d;
|
||||
}
|
||||
double d;
|
||||
toAxisAngleRotation(axis, d);
|
||||
angle = (float)d;
|
||||
}
|
||||
|
||||
Matrix3 toRotationMatrix() const;
|
||||
|
||||
void toRotationMatrix(
|
||||
Matrix3& rot) const;
|
||||
|
||||
private:
|
||||
/** \param maxAngle Maximum angle of rotation allowed. If a larger rotation is required, the angle of rotation applied is clamped to maxAngle */
|
||||
Quat slerp
|
||||
(const Quat& other,
|
||||
float alpha,
|
||||
float threshold,
|
||||
float maxAngle) const;
|
||||
public:
|
||||
|
||||
/**
|
||||
Spherical linear interpolation: linear interpolation along the
|
||||
shortest (3D) great-circle route between two quaternions.
|
||||
|
||||
Assumes that both arguments are unit quaternions.
|
||||
|
||||
Note: Correct rotations are expected between 0 and PI in the right order.
|
||||
|
||||
@cite Based on Game Physics -- David Eberly pg 538-540
|
||||
@param threshold Critical angle between between rotations at which
|
||||
the algorithm switches to normalized lerp, which is more
|
||||
numerically stable in those situations. 0.0 will always slerp.
|
||||
\cite Based on Game Physics -- David Eberly pg 538-540
|
||||
|
||||
\param threshold Critical angle between between rotations (in radians) at which
|
||||
the algorithm switches to normalized lerp, which is more
|
||||
numerically stable in those situations. 0.0 will always slerp.
|
||||
|
||||
*/
|
||||
Quat slerp(
|
||||
const Quat& other,
|
||||
Quat slerp
|
||||
(const Quat& other,
|
||||
float alpha,
|
||||
float threshold = 0.05f) const;
|
||||
float threshold = 0.05f) const {
|
||||
return slerp(other, alpha, threshold, finf());
|
||||
}
|
||||
|
||||
/** Normalized linear interpolation of quaternion components. */
|
||||
Quat nlerp(const Quat& other, float alpha) const;
|
||||
/** Rotates towards \a other by at most \a maxAngle. */
|
||||
Quat movedTowards
|
||||
(const Quat& other,
|
||||
float maxAngle) const {
|
||||
return slerp(other, 1.0f, 0.05f, maxAngle);
|
||||
}
|
||||
|
||||
/** Rotates towards \a other by at most \a maxAngle. */
|
||||
void moveTowards
|
||||
(const Quat& other,
|
||||
float maxAngle) {
|
||||
*this = movedTowards(other, maxAngle);
|
||||
}
|
||||
|
||||
/** Returns the angle in radians between this and other, assuming both are unit quaternions.
|
||||
|
||||
\returns On the range [0, pif()]*/
|
||||
float angleBetween(const Quat& other) const;
|
||||
|
||||
/** Normalized linear interpolation of quaternion components. */
|
||||
Quat nlerp(const Quat& other, float alpha) const;
|
||||
|
||||
|
||||
/** Note that q<SUP>-1</SUP> = q.conj() for a unit quaternion.
|
||||
@cite Dam99 page 13 */
|
||||
@@ -274,22 +315,6 @@ public:
|
||||
return Quat(t * x, t * y, t * z, ::logf(len));
|
||||
}
|
||||
}
|
||||
/** log q = [Av, 0] where q = [sin(A) * v, cos(A)].
|
||||
Only for unit quaternions
|
||||
debugAssertM(isUnit(), "Log only defined for unit quaternions");
|
||||
// Solve for A in q = [sin(A)*v, cos(A)]
|
||||
Vector3 u(x, y, z);
|
||||
double len = u.magnitude();
|
||||
|
||||
if (len == 0.0) {
|
||||
return
|
||||
}
|
||||
double A = atan2((double)w, len);
|
||||
Vector3 v = u / len;
|
||||
|
||||
return Quat(v * A, 0);
|
||||
}
|
||||
*/
|
||||
|
||||
/** exp q = [sin(A) * v, cos(A)] where q = [Av, 0].
|
||||
Only defined for pure-vector quaternions */
|
||||
@@ -310,8 +335,8 @@ public:
|
||||
Note that q.pow(a).pow(b) == q.pow(a + b)
|
||||
@cite Dam98 pg 21
|
||||
*/
|
||||
inline Quat pow(float x) const {
|
||||
return (log() * x).exp();
|
||||
inline Quat pow(float r) const {
|
||||
return (log() * r).exp();
|
||||
}
|
||||
|
||||
/** Make unit length in place */
|
||||
@@ -324,9 +349,9 @@ public:
|
||||
the magnitude.
|
||||
*/
|
||||
Quat toUnit() const {
|
||||
Quat x = *this;
|
||||
x.unitize();
|
||||
return x;
|
||||
Quat copyOfThis = *this;
|
||||
copyOfThis.unitize();
|
||||
return copyOfThis;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -348,7 +373,7 @@ public:
|
||||
float& operator[] (int i);
|
||||
|
||||
/** Generate uniform random unit quaternion (i.e. random "direction")
|
||||
@cite From "Uniform Random Rotations", Ken Shoemake, Graphics Gems III.
|
||||
@cite From "Uniform Random Rotations", Ken Shoemake, Graphics Gems III.
|
||||
*/
|
||||
static Quat unitRandom();
|
||||
|
||||
|
||||
12
deps/g3dlite/include/G3D/Queue.h
vendored
12
deps/g3dlite/include/G3D/Queue.h
vendored
@@ -7,8 +7,8 @@
|
||||
@edited 2008-12-20
|
||||
*/
|
||||
|
||||
#ifndef G3D_QUEUE_H
|
||||
#define G3D_QUEUE_H
|
||||
#ifndef G3D_Queue_h
|
||||
#define G3D_Queue_h
|
||||
|
||||
#include "G3D/platform.h"
|
||||
#include "G3D/System.h"
|
||||
@@ -23,6 +23,8 @@ namespace G3D {
|
||||
sequence without using the modulo operator.
|
||||
|
||||
[0 ... secondEnd) [head .... firstEnd)
|
||||
|
||||
\sa ThreadsafeQueue
|
||||
*/
|
||||
#define FIND_ENDS \
|
||||
int firstEnd = head + num;\
|
||||
@@ -325,6 +327,10 @@ public:
|
||||
return (*this)[size() - 1];
|
||||
}
|
||||
|
||||
bool empty() const {
|
||||
return size() == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
Returns true if the given element is in the queue.
|
||||
*/
|
||||
@@ -346,7 +352,7 @@ public:
|
||||
FIND_ENDS;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < secondEnd; ++i) {
|
||||
for (i = 0; i < secondEnd; ++i) {
|
||||
delete data[i];
|
||||
}
|
||||
|
||||
|
||||
37
deps/g3dlite/include/G3D/Random.h
vendored
37
deps/g3dlite/include/G3D/Random.h
vendored
@@ -1,12 +1,12 @@
|
||||
/**
|
||||
@file Random.h
|
||||
\file G3D/Random.h
|
||||
|
||||
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
\maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
|
||||
@created 2009-01-02
|
||||
@edited 2009-03-20
|
||||
\created 2009-01-02
|
||||
\edited 2012-07-20
|
||||
|
||||
Copyright 2000-2009, Morgan McGuire.
|
||||
Copyright 2000-2012, Morgan McGuire.
|
||||
All rights reserved.
|
||||
*/
|
||||
#ifndef G3D_Random_h
|
||||
@@ -33,6 +33,8 @@ namespace G3D {
|
||||
|
||||
On OS X, Random is about 10x faster than drand48() (which is
|
||||
threadsafe) and 4x faster than rand() (which is not threadsafe).
|
||||
|
||||
\sa Noise
|
||||
*/
|
||||
class Random {
|
||||
protected:
|
||||
@@ -71,6 +73,23 @@ protected:
|
||||
public constructor.*/
|
||||
Random(void*);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
Random& operator=(const Random&) {
|
||||
alwaysAssertM(false,
|
||||
"There is no copy constructor or assignment operator for Random because you "
|
||||
"probably didn't actually want to copy the state--it would "
|
||||
"be slow and duplicate the state of a pseudo-random sequence. Maybe you could "
|
||||
"provide arguments to a member variable in the constructor, "
|
||||
"or pass the Random by reference?");
|
||||
return *this;
|
||||
}
|
||||
|
||||
Random(const Random& r) {
|
||||
*this = r;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/** \param threadsafe Set to false if you know that this random
|
||||
@@ -81,6 +100,8 @@ public:
|
||||
|
||||
virtual ~Random();
|
||||
|
||||
virtual void reset(uint32 seed = 0xF018A4D2, bool threadsafe = true);
|
||||
|
||||
/** Each bit is random. Subclasses can choose to override just
|
||||
this method and the other methods will all work automatically. */
|
||||
virtual uint32 bits();
|
||||
@@ -109,9 +130,13 @@ public:
|
||||
virtual float gaussian(float mean, float stdev);
|
||||
|
||||
/** Returns 3D unit vectors distributed according to
|
||||
a cosine distribution about the z-axis. */
|
||||
a cosine distribution about the positive z-axis. */
|
||||
virtual void cosHemi(float& x, float& y, float& z);
|
||||
|
||||
/** Returns 3D unit vectors distributed according to
|
||||
a cosine distribution about the z-axis. */
|
||||
virtual void cosSphere(float& x, float& y, float& z);
|
||||
|
||||
/** Returns 3D unit vectors distributed according to a cosine
|
||||
power distribution (\f$ \cos^k \theta \f$) about
|
||||
the z-axis. */
|
||||
|
||||
201
deps/g3dlite/include/G3D/Ray.h
vendored
201
deps/g3dlite/include/G3D/Ray.h
vendored
@@ -25,78 +25,85 @@ class Ray {
|
||||
private:
|
||||
friend class Intersect;
|
||||
|
||||
Vector3 m_origin;
|
||||
Point3 m_origin;
|
||||
|
||||
/** Unit length */
|
||||
Vector3 m_direction;
|
||||
/** Unit length */
|
||||
Vector3 m_direction;
|
||||
|
||||
/** 1.0 / direction */
|
||||
Vector3 m_invDirection;
|
||||
/** 1.0 / direction */
|
||||
Vector3 m_invDirection;
|
||||
|
||||
|
||||
/** The following are for the "ray slope" optimization from
|
||||
"Fast Ray / Axis-Aligned Bounding Box Overlap Tests using Ray Slopes"
|
||||
by Martin Eisemann, Thorsten Grosch, Stefan Müller and Marcus Magnor
|
||||
Computer Graphics Lab, TU Braunschweig, Germany and
|
||||
University of Koblenz-Landau, Germany */
|
||||
enum Classification {MMM, MMP, MPM, MPP, PMM, PMP, PPM, PPP, POO, MOO, OPO, OMO, OOP, OOM, OMM, OMP, OPM, OPP, MOM, MOP, POM, POP, MMO, MPO, PMO, PPO};
|
||||
|
||||
// The following are for the "ray slope" optimization from
|
||||
// "Fast Ray / Axis-Aligned Bounding Box Overlap Tests using Ray Slopes"
|
||||
// by Martin Eisemann, Thorsten Grosch, Stefan M<>ller and Marcus Magnor
|
||||
// Computer Graphics Lab, TU Braunschweig, Germany and
|
||||
// University of Koblenz-Landau, Germany*/
|
||||
enum Classification {MMM, MMP, MPM, MPP, PMM, PMP, PPM, PPP, POO, MOO, OPO, OMO, OOP, OOM, OMM, OMP, OPM, OPP, MOM, MOP, POM, POP, MMO, MPO, PMO, PPO}; Classification classification;
|
||||
// ray slope
|
||||
float ibyj, jbyi, kbyj, jbyk, ibyk, kbyi;
|
||||
// Precomputed components
|
||||
float c_xy, c_xz, c_yx, c_yz, c_zx, c_zy;
|
||||
Classification classification;
|
||||
|
||||
/** ray slope */
|
||||
float ibyj, jbyi, kbyj, jbyk, ibyk, kbyi;
|
||||
|
||||
/** Precomputed components */
|
||||
float c_xy, c_xz, c_yx, c_yz, c_zx, c_zy;
|
||||
|
||||
public:
|
||||
/** \param direction Assumed to have unit length */
|
||||
void set(const Point3& origin, const Vector3& direction);
|
||||
|
||||
void set(const Vector3& origin, const Vector3& direction);
|
||||
|
||||
inline const Vector3& origin() const {
|
||||
return m_origin;
|
||||
}
|
||||
|
||||
/** Unit direction vector. */
|
||||
inline const Vector3& direction() const {
|
||||
return m_direction;
|
||||
}
|
||||
|
||||
/** Component-wise inverse of direction vector. May have inf() components */
|
||||
inline const Vector3& invDirection() const {
|
||||
return m_invDirection;
|
||||
}
|
||||
|
||||
inline Ray() {
|
||||
set(Vector3::zero(), Vector3::unitX());
|
||||
}
|
||||
|
||||
inline Ray(const Vector3& origin, const Vector3& direction) {
|
||||
set(origin, direction);
|
||||
}
|
||||
|
||||
Ray(class BinaryInput& b);
|
||||
|
||||
void serialize(class BinaryOutput& b) const;
|
||||
void deserialize(class BinaryInput& b);
|
||||
|
||||
/**
|
||||
Creates a Ray from a origin and a (nonzero) unit direction.
|
||||
*/
|
||||
static Ray fromOriginAndDirection(const Vector3& point, const Vector3& direction) {
|
||||
return Ray(point, direction);
|
||||
const Point3& origin() const {
|
||||
return m_origin;
|
||||
}
|
||||
|
||||
/** Unit direction vector. */
|
||||
const Vector3& direction() const {
|
||||
return m_direction;
|
||||
}
|
||||
|
||||
/** Advances the origin along the direction by @a distance */
|
||||
inline Ray bump(float distance) const {
|
||||
return Ray(m_origin + m_direction * distance, m_direction);
|
||||
}
|
||||
/** Component-wise inverse of direction vector. May have inf() components */
|
||||
const Vector3& invDirection() const {
|
||||
return m_invDirection;
|
||||
}
|
||||
|
||||
Ray() {
|
||||
set(Point3::zero(), Vector3::unitX());
|
||||
}
|
||||
|
||||
/** Advances the origin along the @a bumpDirection by @a distance and returns the new ray*/
|
||||
inline Ray bump(float distance, const Vector3& bumpDirection) const {
|
||||
return Ray(m_origin + bumpDirection * distance, m_direction);
|
||||
}
|
||||
/** \param direction Assumed to have unit length */
|
||||
Ray(const Point3& origin, const Vector3& direction) {
|
||||
set(origin, direction);
|
||||
}
|
||||
|
||||
Ray(class BinaryInput& b);
|
||||
|
||||
void serialize(class BinaryOutput& b) const;
|
||||
void deserialize(class BinaryInput& b);
|
||||
|
||||
/**
|
||||
Creates a Ray from a origin and a (nonzero) unit direction.
|
||||
*/
|
||||
static Ray fromOriginAndDirection(const Point3& point, const Vector3& direction) {
|
||||
return Ray(point, direction);
|
||||
}
|
||||
|
||||
/** Returns a new ray which has the same direction but an origin
|
||||
advanced along direction by @a distance */
|
||||
Ray bumpedRay(float distance) const {
|
||||
return Ray(m_origin + m_direction * distance, m_direction);
|
||||
}
|
||||
|
||||
/** Returns a new ray which has the same direction but an origin
|
||||
advanced by \a distance * \a bumpDirection */
|
||||
Ray bumpedRay(float distance, const Vector3& bumpDirection) const {
|
||||
return Ray(m_origin + bumpDirection * distance, m_direction);
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the closest point on the Ray to point.
|
||||
*/
|
||||
Vector3 closestPoint(const Vector3& point) const {
|
||||
\brief Returns the closest point on the Ray to point.
|
||||
*/
|
||||
Point3 closestPoint(const Point3& point) const {
|
||||
float t = m_direction.dot(point - m_origin);
|
||||
if (t < 0) {
|
||||
return m_origin;
|
||||
@@ -108,7 +115,7 @@ public:
|
||||
/**
|
||||
Returns the closest distance between point and the Ray
|
||||
*/
|
||||
float distance(const Vector3& point) const {
|
||||
float distance(const Point3& point) const {
|
||||
return (closestPoint(point) - point).magnitude();
|
||||
}
|
||||
|
||||
@@ -119,7 +126,7 @@ public:
|
||||
Planes are considered one-sided, so the ray will not intersect
|
||||
a plane where the normal faces in the traveling direction.
|
||||
*/
|
||||
Vector3 intersection(const class Plane& plane) const;
|
||||
Point3 intersection(const class Plane& plane) const;
|
||||
|
||||
/**
|
||||
Returns the distance until intersection with the sphere or the (solid) ball bounded by the sphere.
|
||||
@@ -151,54 +158,56 @@ public:
|
||||
float intersectionTime(
|
||||
const Vector3& v0, const Vector3& v1, const Vector3& v2,
|
||||
const Vector3& edge01, const Vector3& edge02,
|
||||
double& w0, double& w1, double& w2) const;
|
||||
float& w0, float& w1, float& w2) const;
|
||||
|
||||
/**
|
||||
Ray-triangle intersection for a 1-sided triangle. Fastest version.
|
||||
@cite http://www.acm.org/jgt/papers/MollerTrumbore97/
|
||||
http://www.graphics.cornell.edu/pubs/1997/MT97.html
|
||||
*/
|
||||
inline float intersectionTime(
|
||||
const Vector3& vert0,
|
||||
const Vector3& vert1,
|
||||
const Vector3& vert2,
|
||||
float intersectionTime(
|
||||
const Point3& vert0,
|
||||
const Point3& vert1,
|
||||
const Point3& vert2,
|
||||
const Vector3& edge01,
|
||||
const Vector3& edge02) const;
|
||||
|
||||
|
||||
inline float intersectionTime(
|
||||
const Vector3& vert0,
|
||||
const Vector3& vert1,
|
||||
const Vector3& vert2) const {
|
||||
float intersectionTime(
|
||||
const Point3& vert0,
|
||||
const Point3& vert1,
|
||||
const Point3& vert2) const {
|
||||
|
||||
return intersectionTime(vert0, vert1, vert2, vert1 - vert0, vert2 - vert0);
|
||||
}
|
||||
|
||||
|
||||
inline float intersectionTime(
|
||||
const Vector3& vert0,
|
||||
const Vector3& vert1,
|
||||
const Vector3& vert2,
|
||||
double& w0,
|
||||
double& w1,
|
||||
double& w2) const {
|
||||
float intersectionTime(
|
||||
const Point3& vert0,
|
||||
const Point3& vert1,
|
||||
const Point3& vert2,
|
||||
float& w0,
|
||||
float& w1,
|
||||
float& w2) const {
|
||||
|
||||
return intersectionTime(vert0, vert1, vert2, vert1 - vert0, vert2 - vert0, w0, w1, w2);
|
||||
}
|
||||
|
||||
|
||||
/* One-sided triangle
|
||||
*/
|
||||
inline float intersectionTime(const Triangle& triangle) const {
|
||||
float intersectionTime(const Triangle& triangle) const {
|
||||
return intersectionTime(
|
||||
triangle.vertex(0), triangle.vertex(1), triangle.vertex(2),
|
||||
triangle.edge01(), triangle.edge02());
|
||||
}
|
||||
|
||||
inline float intersectionTime(
|
||||
const Triangle& triangle,
|
||||
double& w0,
|
||||
double& w1,
|
||||
double& w2) const {
|
||||
|
||||
float intersectionTime
|
||||
(const Triangle& triangle,
|
||||
float& w0,
|
||||
float& w1,
|
||||
float& w2) const {
|
||||
return intersectionTime(triangle.vertex(0), triangle.vertex(1), triangle.vertex(2),
|
||||
triangle.edge01(), triangle.edge02(), w0, w1, w2);
|
||||
}
|
||||
@@ -236,9 +245,9 @@ public:
|
||||
dest[2]=v1[2]-v2[2];
|
||||
|
||||
inline float Ray::intersectionTime(
|
||||
const Vector3& vert0,
|
||||
const Vector3& vert1,
|
||||
const Vector3& vert2,
|
||||
const Point3& vert0,
|
||||
const Point3& vert1,
|
||||
const Point3& vert2,
|
||||
const Vector3& edge1,
|
||||
const Vector3& edge2) const {
|
||||
|
||||
@@ -294,15 +303,15 @@ inline float Ray::intersectionTime(
|
||||
}
|
||||
|
||||
|
||||
inline float Ray::intersectionTime(
|
||||
const Vector3& vert0,
|
||||
const Vector3& vert1,
|
||||
const Vector3& vert2,
|
||||
const Vector3& edge1,
|
||||
const Vector3& edge2,
|
||||
double& w0,
|
||||
double& w1,
|
||||
double& w2) const {
|
||||
inline float Ray::intersectionTime
|
||||
(const Point3& vert0,
|
||||
const Point3& vert1,
|
||||
const Point3& vert2,
|
||||
const Vector3& edge1,
|
||||
const Vector3& edge2,
|
||||
float& w0,
|
||||
float& w1,
|
||||
float& w2) const {
|
||||
|
||||
(void)vert1;
|
||||
(void)vert2;
|
||||
|
||||
139
deps/g3dlite/include/G3D/Rect2D.h
vendored
139
deps/g3dlite/include/G3D/Rect2D.h
vendored
@@ -1,12 +1,12 @@
|
||||
/**
|
||||
@file Rect2D.h
|
||||
\file Rect2D.h
|
||||
|
||||
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
\maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
|
||||
@created 2003-11-13
|
||||
@created 2009-11-16
|
||||
\created 2003-11-13
|
||||
\created 2011-06-16
|
||||
|
||||
Copyright 2000-2009, Morgan McGuire.
|
||||
Copyright 2000-2012, Morgan McGuire.
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
@@ -39,7 +39,7 @@ class Any;
|
||||
*/
|
||||
class Rect2D {
|
||||
private:
|
||||
Vector2 min, max;
|
||||
Point2 min, max;
|
||||
|
||||
/**
|
||||
Returns true if the whole polygon is clipped.
|
||||
@@ -117,38 +117,60 @@ private:
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Uninitialized constructor */
|
||||
Rect2D(bool /*b*/) {}
|
||||
public:
|
||||
|
||||
/** \param any Must either Rect2D::xywh(#, #, #, #) or Rect2D::xyxy(#, #, #, #)*/
|
||||
Rect2D(const Any& any);
|
||||
|
||||
/** Converts the Rect2D to an Any. */
|
||||
operator Any() const;
|
||||
Any toAny() const;
|
||||
|
||||
Rect2D() : min(0, 0), max(0, 0) {}
|
||||
Rect2D(const Rect2D& r) : min(r.min), max(r.max) {}
|
||||
|
||||
/** Creates the empty set rectangle.
|
||||
*/
|
||||
Rect2D() : min(fnan(), fnan()), max(fnan(), fnan()) {}
|
||||
|
||||
static const Rect2D& empty();
|
||||
|
||||
/** Returns true if this is the empty set, which is distinct from a zero-area rectangle. */
|
||||
inline bool isEmpty() const {
|
||||
return min.isNaN() && max.isNaN();
|
||||
}
|
||||
|
||||
/** Creates a rectangle at 0,0 with the given width and height*/
|
||||
Rect2D(const Vector2& wh) : min(0, 0), max(wh.x, wh.y) {}
|
||||
|
||||
/** Computes a rectangle that contains both @a a and @a b.
|
||||
Note that even if @a or @b has zero area, its origin will be included.*/
|
||||
Rect2D(const Rect2D& a, const Rect2D& b) {
|
||||
min = a.min.min(b.min);
|
||||
max = a.max.max(b.max);
|
||||
Vector2 extent() const {
|
||||
if (isEmpty()) {
|
||||
return Vector2::zero();
|
||||
} else {
|
||||
return max - min;
|
||||
}
|
||||
}
|
||||
|
||||
/** @brief Uniformly random point on the interior */
|
||||
Vector2 randomPoint() const {
|
||||
return Vector2(uniformRandom(0, max.x - min.x) + min.x,
|
||||
Point2 randomPoint() const {
|
||||
return Point2(uniformRandom(0, max.x - min.x) + min.x,
|
||||
uniformRandom(0, max.y - min.y) + min.y);
|
||||
}
|
||||
|
||||
float width() const {
|
||||
return max.x - min.x;
|
||||
if (isEmpty()) {
|
||||
return 0;
|
||||
} else {
|
||||
return max.x - min.x;
|
||||
}
|
||||
}
|
||||
|
||||
float height() const {
|
||||
return max.y - min.y;
|
||||
if (isEmpty()) {
|
||||
return 0;
|
||||
} else {
|
||||
return max.y - min.y;
|
||||
}
|
||||
}
|
||||
|
||||
float x0() const {
|
||||
@@ -168,29 +190,33 @@ public:
|
||||
}
|
||||
|
||||
/** Min, min corner */
|
||||
Vector2 x0y0() const {
|
||||
Point2 x0y0() const {
|
||||
return min;
|
||||
}
|
||||
|
||||
Vector2 x1y0() const {
|
||||
return Vector2(max.x, min.y);
|
||||
Point2 x1y0() const {
|
||||
return Point2(max.x, min.y);
|
||||
}
|
||||
|
||||
Vector2 x0y1() const {
|
||||
return Vector2(min.x, max.y);
|
||||
Point2 x0y1() const {
|
||||
return Point2(min.x, max.y);
|
||||
}
|
||||
|
||||
/** Max,max corner */
|
||||
Vector2 x1y1() const {
|
||||
Point2 x1y1() const {
|
||||
return max;
|
||||
}
|
||||
|
||||
/** Width and height */
|
||||
Vector2 wh() const {
|
||||
return max - min;
|
||||
if (isEmpty()) {
|
||||
return Vector2::zero();
|
||||
} else {
|
||||
return max - min;
|
||||
}
|
||||
}
|
||||
|
||||
Vector2 center() const {
|
||||
Point2 center() const {
|
||||
return (max + min) * 0.5;
|
||||
}
|
||||
|
||||
@@ -203,7 +229,7 @@ public:
|
||||
}
|
||||
|
||||
Rect2D lerp(const Rect2D& other, float alpha) const {
|
||||
Rect2D out;
|
||||
Rect2D out(false);
|
||||
|
||||
out.min = min.lerp(other.min, alpha);
|
||||
out.max = max.lerp(other.max, alpha);
|
||||
@@ -212,7 +238,7 @@ public:
|
||||
}
|
||||
|
||||
static Rect2D xyxy(float x0, float y0, float x1, float y1) {
|
||||
Rect2D r;
|
||||
Rect2D r(false);
|
||||
|
||||
r.min.x = G3D::min(x0, x1);
|
||||
r.min.y = G3D::min(y0, y1);
|
||||
@@ -222,8 +248,8 @@ public:
|
||||
return r;
|
||||
}
|
||||
|
||||
static Rect2D xyxy(const Vector2& v0, const Vector2& v1) {
|
||||
Rect2D r;
|
||||
static Rect2D xyxy(const Point2& v0, const Point2& v1) {
|
||||
Rect2D r(false);
|
||||
|
||||
r.min = v0.min(v1);
|
||||
r.max = v0.max(v1);
|
||||
@@ -235,7 +261,7 @@ public:
|
||||
return xyxy(x, y, x + w, y + h);
|
||||
}
|
||||
|
||||
static Rect2D xywh(const Vector2& v, const Vector2& w) {
|
||||
static Rect2D xywh(const Point2& v, const Vector2& w) {
|
||||
return xyxy(v.x, v.y, v.x + w.x, v.y + w.y);
|
||||
}
|
||||
|
||||
@@ -246,11 +272,13 @@ public:
|
||||
return xyxy(Vector2::inf(), Vector2::inf());
|
||||
}
|
||||
|
||||
bool contains(const Vector2& v) const {
|
||||
bool contains(const Point2& v) const {
|
||||
// This will automatically return false if isEmpty()
|
||||
return (v.x >= min.x) && (v.y >= min.y) && (v.x <= max.x) && (v.y <= max.y);
|
||||
}
|
||||
|
||||
bool contains(const Rect2D& r) const {
|
||||
// This will automatically return false if isEmpty()
|
||||
return (min.x <= r.min.x) && (min.y <= r.min.y) &&
|
||||
(max.x >= r.max.x) && (max.y >= r.max.y);
|
||||
}
|
||||
@@ -259,12 +287,14 @@ public:
|
||||
Note that two rectangles that are adjacent do not intersect because there is
|
||||
zero area to the overlap, even though one of them "contains" the corners of the other.*/
|
||||
bool intersects(const Rect2D& r) const {
|
||||
// This will automatically return false if isEmpty()
|
||||
return (min.x < r.max.x) && (min.y < r.max.y) &&
|
||||
(max.x > r.min.x) && (max.y > r.min.y);
|
||||
}
|
||||
|
||||
/** Like intersection, but counts the adjacent case as touching. */
|
||||
bool intersectsOrTouches(const Rect2D& r) const {
|
||||
// This will automatically return false if isEmpty()
|
||||
return (min.x <= r.max.x) && (min.y <= r.max.y) &&
|
||||
(max.x >= r.min.x) && (max.y >= r.min.y);
|
||||
}
|
||||
@@ -273,6 +303,10 @@ public:
|
||||
return xyxy(min.x * s, min.y * s, max.x * s, max.y * s);
|
||||
}
|
||||
|
||||
Rect2D operator*(const Vector2& s) const {
|
||||
return xyxy(min * s, max * s);
|
||||
}
|
||||
|
||||
Rect2D operator/(float s) const {
|
||||
return xyxy(min / s, max / s);
|
||||
}
|
||||
@@ -297,21 +331,25 @@ public:
|
||||
return (min != other.min) || (max != other.max);
|
||||
}
|
||||
|
||||
void serialize(class BinaryOutput& b) const;
|
||||
|
||||
void deserialize(class BinaryInput& b);
|
||||
|
||||
/** Returns the corners in the order: (min,min), (max,min), (max,max), (min,max). */
|
||||
Vector2 corner(int i) const {
|
||||
Point2 corner(int i) const {
|
||||
debugAssert(i >= 0 && i < 4);
|
||||
switch (i & 3) {
|
||||
case 0:
|
||||
return Vector2(min.x, min.y);
|
||||
return Point2(min.x, min.y);
|
||||
case 1:
|
||||
return Vector2(max.x, min.y);
|
||||
return Point2(max.x, min.y);
|
||||
case 2:
|
||||
return Vector2(max.x, max.y);
|
||||
return Point2(max.x, max.y);
|
||||
case 3:
|
||||
return Vector2(min.x, max.y);
|
||||
return Point2(min.x, max.y);
|
||||
default:
|
||||
// Should never get here
|
||||
return Vector2(0, 0);
|
||||
return Point2(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -345,6 +383,22 @@ public:
|
||||
return Rect2D::xywh(newX, newY, newW, newH);
|
||||
}
|
||||
|
||||
void merge(const Rect2D& other) {
|
||||
if (isEmpty()) {
|
||||
*this = other;
|
||||
} else if (! other.isEmpty()) {
|
||||
min = min.min(other.min);
|
||||
max = max.max(other.max);
|
||||
}
|
||||
}
|
||||
|
||||
/** Computes a rectangle that contains both @a a and @a b.
|
||||
Note that even if @a or @b has zero area, its origin will be included.*/
|
||||
Rect2D(const Rect2D& a, const Rect2D& b) {
|
||||
*this = a;
|
||||
merge(b);
|
||||
}
|
||||
|
||||
/**
|
||||
Clips so that the rightmost point of the outPoly is at rect.x1 (e.g. a 800x600 window produces
|
||||
rightmost point 799, not 800). The results are suitable for pixel rendering if iRounded.
|
||||
@@ -398,15 +452,16 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the overlap region between the two rectangles. This may have zero area
|
||||
if they do not intersect. See the two-Rect2D constructor for a way to compute
|
||||
a union-like rectangle.
|
||||
Returns the overlap region between the two rectangles. This may
|
||||
have zero area if they do not intersect. See the two-Rect2D
|
||||
constructor and merge() for a way to compute a union-like
|
||||
rectangle.
|
||||
*/
|
||||
Rect2D intersect(const Rect2D& other) const {
|
||||
if (intersects(other)) {
|
||||
return Rect2D::xyxy(min.max(other.min), max.min(other.max));
|
||||
}else{
|
||||
return Rect2D::xywh(0, 0, 0, 0);
|
||||
} else {
|
||||
return empty();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
568
deps/g3dlite/include/G3D/ReferenceCount.h
vendored
568
deps/g3dlite/include/G3D/ReferenceCount.h
vendored
@@ -1,14 +1,12 @@
|
||||
/**
|
||||
@file ReferenceCount.h
|
||||
\file G3D/ReferenceCount.h
|
||||
|
||||
Reference Counting Garbage Collector for C++
|
||||
|
||||
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
@cite Adapted and extended from Justin Miller's "RGC" class that appeared in BYTE magazine.
|
||||
@cite See also http://www.jelovic.com/articles/cpp_without_memory_errors_slides.htm
|
||||
\maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
|
||||
@created 2001-10-23
|
||||
@edited 2009-04-25
|
||||
\created 2001-10-23
|
||||
\edited 2013-01-05
|
||||
*/
|
||||
#ifndef G3D_ReferenceCount_h
|
||||
#define G3D_ReferenceCount_h
|
||||
@@ -17,552 +15,40 @@
|
||||
#include "G3D/debug.h"
|
||||
#include "G3D/AtomicInt32.h"
|
||||
|
||||
#define USE_SHARED_PTR
|
||||
|
||||
#define ReferenceCountedPointer shared_ptr
|
||||
#define WeakReferenceCountedPointer weak_ptr
|
||||
namespace G3D {
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// Turn off "conditional expression is constant" warning; MSVC generates this
|
||||
// for debug assertions in inlined methods.
|
||||
# pragma warning (disable : 4127)
|
||||
#endif
|
||||
|
||||
/** Base class for WeakReferenceCountedPointer */
|
||||
class _WeakPtr {
|
||||
class ReferenceCountedObject : public enable_shared_from_this<ReferenceCountedObject> {
|
||||
public:
|
||||
inline virtual ~_WeakPtr() {}
|
||||
|
||||
protected:
|
||||
friend class ReferenceCountedObject;
|
||||
|
||||
/** Called by ReferenceCountedObject to tell a weak pointer that its underlying object was collected. */
|
||||
virtual void objectCollected() = 0;
|
||||
virtual ~ReferenceCountedObject() {};
|
||||
};
|
||||
|
||||
/** Used internally by ReferenceCountedObject */
|
||||
class _WeakPtrLinkedList {
|
||||
public:
|
||||
_WeakPtr* weakPtr;
|
||||
_WeakPtrLinkedList* next;
|
||||
} // namespace
|
||||
|
||||
inline _WeakPtrLinkedList() : weakPtr(NULL), next(NULL) {}
|
||||
namespace G3D {
|
||||
|
||||
/** Inserts this node into the head of the list that previously had n as its head. */
|
||||
inline _WeakPtrLinkedList(_WeakPtr* p, _WeakPtrLinkedList* n) : weakPtr(p), next(n) {}
|
||||
};
|
||||
|
||||
/**
|
||||
Objects that are reference counted inherit from this. Subclasses
|
||||
<B>must</B> have a public destructor (the default destructor is fine)
|
||||
and <B>publicly</B> inherit ReferenceCountedObject.
|
||||
|
||||
Multiple inheritance from a reference counted object is dangerous-- use
|
||||
at your own risk.
|
||||
|
||||
ReferenceCountedPointer and ReferenceCountedObject are threadsafe.
|
||||
You can create and drop references on multiple threads without
|
||||
violating integrity. WeakReferenceCountedPointer is <i>not</i>
|
||||
threadsafe. Introducing a weak pointer destroys all thread safety,
|
||||
even for strong pointers to the same object (this is inherent in the
|
||||
design of the class; we cannot fix it without slowing down the
|
||||
performance of reference counted objects.)
|
||||
|
||||
<B>Usage Example</B>
|
||||
|
||||
<PRE>
|
||||
|
||||
class Foo : public G3D::ReferenceCountedObject {
|
||||
public:
|
||||
int x;
|
||||
};
|
||||
|
||||
class Bar : public Foo {};
|
||||
|
||||
typedef G3D::ReferenceCountedPointer<Foo> FooRef;
|
||||
typedef G3D::WeakReferenceCountedPointer<Foo> WeakFooRef;
|
||||
typedef G3D::ReferenceCountedPointer<Bar> BarRef;
|
||||
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
WeakFooRef x;
|
||||
|
||||
{
|
||||
FooRef a = new Foo();
|
||||
|
||||
// Reference count == 1
|
||||
|
||||
x = a;
|
||||
// Weak references do not increase count
|
||||
|
||||
{
|
||||
FooRef b = a;
|
||||
// Reference count == 2
|
||||
}
|
||||
|
||||
// Reference count == 1
|
||||
}
|
||||
// No more strong references; object automatically deleted.
|
||||
// x is set to NULL automatically.
|
||||
|
||||
// Example of using dynamic cast on reference counted objects
|
||||
BarRef b = new Bar();
|
||||
|
||||
// No cast needed to go down the heirarchy.
|
||||
FooRef f = b;
|
||||
|
||||
// We can't cast the reference object because it is a class.
|
||||
// Instead we must extract the pointer and cast that:
|
||||
b = dynamic_cast<Bar*>(&*f);
|
||||
|
||||
return 0;
|
||||
template<class T>
|
||||
bool isNull(const ReferenceCountedPointer<T>& ptr) {
|
||||
return ! ptr;
|
||||
}
|
||||
</PRE>
|
||||
*/
|
||||
class ReferenceCountedObject {
|
||||
public:
|
||||
|
||||
/**
|
||||
The long name is to keep this from accidentally conflicting with
|
||||
a subclass's variable name. Do not use or explicitly manipulate
|
||||
this value--its type may change in the future and is not part
|
||||
of the supported API.
|
||||
*/
|
||||
AtomicInt32 ReferenceCountedObject_refCount;
|
||||
|
||||
/**
|
||||
Linked list of all weak pointers that reference this (some may be
|
||||
on the stack!). Do not use or explicitly manipulate this value.
|
||||
*/
|
||||
_WeakPtrLinkedList* ReferenceCountedObject_weakPointer;
|
||||
template<class T>
|
||||
bool notNull(const ReferenceCountedPointer<T>& ptr) {
|
||||
return (bool)ptr;
|
||||
}
|
||||
|
||||
protected:
|
||||
template<class T>
|
||||
bool isNull(const T* ptr) {
|
||||
return ptr == NULL;
|
||||
}
|
||||
|
||||
ReferenceCountedObject();
|
||||
|
||||
public:
|
||||
|
||||
/** Automatically called immediately before the object is deleted.
|
||||
This is not called from the destructor because it needs to be invoked
|
||||
before the subclass destructor.
|
||||
*/
|
||||
void ReferenceCountedObject_zeroWeakPointers();
|
||||
|
||||
virtual ~ReferenceCountedObject();
|
||||
|
||||
|
||||
/**
|
||||
Note: copies will initially start out with 0
|
||||
references and 0 weak references like any other object.
|
||||
*/
|
||||
ReferenceCountedObject(const ReferenceCountedObject& notUsed);
|
||||
|
||||
ReferenceCountedObject& operator=(const ReferenceCountedObject& other);
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Use ReferenceCountedPointer<T> in place of T* in your program.
|
||||
T must subclass ReferenceCountedObject.
|
||||
@deprecated To be replaced by boost::shared_ptr in 7.0
|
||||
*/
|
||||
template <class T>
|
||||
class ReferenceCountedPointer {
|
||||
private:
|
||||
|
||||
T* m_pointer;
|
||||
|
||||
public:
|
||||
typedef T element_type;
|
||||
|
||||
inline T* pointer() const {
|
||||
return m_pointer;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/** Nulls out the pointer and drops a reference. If the reference
|
||||
count hits zero. */
|
||||
void zeroPointer() {
|
||||
if (m_pointer != NULL) {
|
||||
|
||||
ReferenceCountedObject* pointer = ((ReferenceCountedObject*)m_pointer);
|
||||
debugAssert(G3D::isValidHeapPointer(m_pointer));
|
||||
debugAssertM(pointer->ReferenceCountedObject_refCount.value() > 0,
|
||||
"Dangling reference detected.");
|
||||
|
||||
// Only delete if this instance caused the count to hit
|
||||
// exactly zero. If there is a race condition, the value
|
||||
// may be zero after decrement returns, but only one of
|
||||
// the instances will get a zero return value.
|
||||
if (pointer->ReferenceCountedObject_refCount.decrement() == 0) {
|
||||
// We held the last reference, so delete the object.
|
||||
// This test is threadsafe because there is no way for
|
||||
// the reference count to increase after the last
|
||||
// reference was dropped (assuming the application does
|
||||
// not voilate the class abstraction).
|
||||
//debugPrintf(" delete 0x%x\n", m_pointer);
|
||||
|
||||
// We must zero the weak pointers *before* deletion in case there
|
||||
// are cycles of weak references.
|
||||
// Note that since there are no strong references at this point,
|
||||
// it is perfectly fair to zero the weak pointers anyway.
|
||||
pointer->ReferenceCountedObject_zeroWeakPointers();
|
||||
delete pointer;
|
||||
}
|
||||
|
||||
m_pointer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/** Non-atomic (except for the referencec increment). Can only be
|
||||
called in contexts like the copy constructor or initial
|
||||
constructor where it is known that the reference count will
|
||||
not hit zero on some other thread. */
|
||||
void setPointer(T* x) {
|
||||
if (x != m_pointer) {
|
||||
zeroPointer();
|
||||
|
||||
if (x != NULL) {
|
||||
debugAssert(G3D::isValidHeapPointer(x));
|
||||
|
||||
m_pointer = x;
|
||||
|
||||
// Note that the ref count can be zero if this is the
|
||||
// first pointer to it
|
||||
ReferenceCountedObject* pointer = (ReferenceCountedObject*)m_pointer;
|
||||
debugAssertM(pointer->ReferenceCountedObject_refCount.value() >= 0,
|
||||
"Negative reference count detected.");
|
||||
pointer->ReferenceCountedObject_refCount.increment();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
inline ReferenceCountedPointer() : m_pointer(NULL) {}
|
||||
|
||||
/**
|
||||
Allow silent cast <i>to</i> the base class.
|
||||
|
||||
<pre>
|
||||
SubRef s = new Sub();
|
||||
BaseRef b = s;
|
||||
</pre>
|
||||
|
||||
i.e., compile-time subtyping rule
|
||||
RCP<<I>T</I>> <: RCP<<I>S</I>> if <I>T</I> <: <I>S</I>
|
||||
*/
|
||||
template <class S>
|
||||
inline ReferenceCountedPointer(const ReferenceCountedPointer<S>& p) :
|
||||
m_pointer(NULL) {
|
||||
setPointer(p.pointer());
|
||||
}
|
||||
|
||||
# if (! defined(MSC_VER) || (MSC_VER >= 1300))
|
||||
/**
|
||||
Explicit cast to a subclass. Acts like dynamic cast; the result will be NULL if
|
||||
the cast cannot succeed. Not supported on VC6.
|
||||
<pre>
|
||||
SubRef s = new Sub();
|
||||
BaseRef b = s;
|
||||
s = b.downcast<Sub>(); // Note that the template argument is the object type, not the pointer type.
|
||||
</pre>
|
||||
*/
|
||||
template <class S>
|
||||
ReferenceCountedPointer<S> downcast() {
|
||||
return ReferenceCountedPointer<S>(dynamic_cast<S*>(m_pointer));
|
||||
}
|
||||
|
||||
template <class S>
|
||||
const ReferenceCountedPointer<S> downcast() const {
|
||||
return ReferenceCountedPointer<S>(dynamic_cast<const S*>(m_pointer));
|
||||
}
|
||||
# endif
|
||||
|
||||
// We need an explicit version of the copy constructor as well or
|
||||
// the default copy constructor will be used.
|
||||
inline ReferenceCountedPointer(const ReferenceCountedPointer<T>& p) : m_pointer(NULL) {
|
||||
setPointer(p.m_pointer);
|
||||
}
|
||||
|
||||
/** Allows construction from a raw pointer. That object will thereafter be
|
||||
reference counted -- do not call delete on it.
|
||||
|
||||
Use of const allows downcast on const references */
|
||||
inline ReferenceCountedPointer(const T* p) : m_pointer(NULL) {
|
||||
// only const constructor is defined to remove ambiguity using NULL
|
||||
setPointer(const_cast<T*>(p));
|
||||
}
|
||||
|
||||
|
||||
inline ~ReferenceCountedPointer() {
|
||||
zeroPointer();
|
||||
}
|
||||
|
||||
inline size_t hashCode() const {
|
||||
return reinterpret_cast<size_t>(m_pointer);;
|
||||
}
|
||||
|
||||
inline const ReferenceCountedPointer<T>& operator=(const ReferenceCountedPointer<T>& p) {
|
||||
setPointer(p.m_pointer);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline ReferenceCountedPointer<T>& operator=(T* p) {
|
||||
setPointer(p);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline bool operator==(const ReferenceCountedPointer<T>& y) const {
|
||||
return (m_pointer == y.m_pointer);
|
||||
}
|
||||
|
||||
inline bool operator!=(const ReferenceCountedPointer<T>& y) const {
|
||||
return (m_pointer != y.m_pointer);
|
||||
}
|
||||
|
||||
bool operator < (const ReferenceCountedPointer<T>& y) const {
|
||||
return (m_pointer < y.m_pointer);
|
||||
}
|
||||
|
||||
bool operator > (const ReferenceCountedPointer<T>& y) const {
|
||||
return (m_pointer > y.m_pointer);
|
||||
}
|
||||
|
||||
bool operator <= (const ReferenceCountedPointer<T>& y) const {
|
||||
return (m_pointer <= y.m_pointer);
|
||||
}
|
||||
|
||||
bool operator >= (const ReferenceCountedPointer<T>& y) const {
|
||||
return (m_pointer >= y.m_pointer);
|
||||
}
|
||||
|
||||
inline T& operator*() const {
|
||||
debugAssertM(m_pointer != NULL, "Dereferenced a NULL ReferenceCountedPointer");
|
||||
return (*m_pointer);
|
||||
}
|
||||
|
||||
inline T* operator->() const {
|
||||
debugAssertM(m_pointer != NULL, "Dereferenced a NULL ReferenceCountedPointer");
|
||||
return m_pointer;
|
||||
}
|
||||
|
||||
inline bool isNull() const {
|
||||
return (m_pointer == NULL);
|
||||
}
|
||||
|
||||
inline bool notNull() const {
|
||||
return (m_pointer != NULL);
|
||||
}
|
||||
|
||||
// TODO: distinguish between last strong and last any pointer
|
||||
/**
|
||||
Returns true if this is the last reference to an object.
|
||||
Useful for flushing memoization caches-- a cache that holds the last
|
||||
reference is unnecessarily keeping an object alive.
|
||||
|
||||
<b>Not threadsafe.</b>
|
||||
|
||||
@deprecated Use WeakReferenceCountedPointer for caches
|
||||
*/
|
||||
inline int isLastReference() const {
|
||||
return (m_pointer->ReferenceCountedObject_refCount.value() == 1);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
A weak pointer allows the object it references to be garbage collected.
|
||||
Weak pointers are commonly used in caches, where it is important to hold
|
||||
a pointer to an object without keeping that object alive solely for the
|
||||
cache's benefit (i.e., the object can be collected as soon as all
|
||||
pointers to it <B>outside</B> the cache are gone). They are also convenient
|
||||
for adding back-pointers in tree and list structures.
|
||||
|
||||
Weak pointers may become NULL at any point (when their target is collected).
|
||||
Therefore the only way to reference the target is to convert to a strong
|
||||
pointer and then check that it is not NULL.
|
||||
|
||||
@deprecated To be replaced by boost::weak_ptr in 7.0
|
||||
*/
|
||||
template <class T>
|
||||
class WeakReferenceCountedPointer : public _WeakPtr {
|
||||
private:
|
||||
|
||||
/** NULL if the object has been collected. */
|
||||
T* pointer;
|
||||
|
||||
public:
|
||||
/**
|
||||
Creates a strong pointer, which prevents the object from being
|
||||
garbage collected. The strong pointer may be NULL, which means
|
||||
that the underlying.
|
||||
*/
|
||||
// There is intentionally no way to check if the
|
||||
// WeakReferenceCountedPointer has a null reference without
|
||||
// creating a strong pointer since there is no safe way to use
|
||||
// that information-- the pointer could be collected by a
|
||||
// subsequent statement.
|
||||
ReferenceCountedPointer<T> createStrongPtr() const {
|
||||
// TODO: What if the object's destructor is called while we
|
||||
// are in this method?
|
||||
return ReferenceCountedPointer<T>(pointer);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/** Thread issues: safe because this is only called when another
|
||||
object is guaranteed to keep p alive for the duration of this
|
||||
call. */
|
||||
void setPointer(T* p) {
|
||||
// TODO: must prevent the object from being collected while in
|
||||
// this method
|
||||
|
||||
zeroPointer();
|
||||
pointer = p;
|
||||
|
||||
if (pointer != NULL) {
|
||||
// TODO: threadsafe: must update the list atomically
|
||||
|
||||
// Add myself to the head of my target's list of weak pointers
|
||||
_WeakPtrLinkedList* head =
|
||||
new _WeakPtrLinkedList
|
||||
(this,
|
||||
pointer->ReferenceCountedObject_weakPointer);
|
||||
|
||||
pointer->ReferenceCountedObject_weakPointer = head;
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Removes this from its target's list of weak pointers. Called
|
||||
when the weak pointer goes out of scope.
|
||||
|
||||
Thread issues: depends on the thread safety of createStrongPtr.
|
||||
*/
|
||||
void zeroPointer() {
|
||||
// Grab a strong reference to prevent the object from being collected while we
|
||||
// are traversing its list.
|
||||
ReferenceCountedPointer<T> strong = createStrongPtr();
|
||||
|
||||
// If the following test fails then the object was collected before we
|
||||
// reached it.
|
||||
if (strong.notNull()) {
|
||||
debugAssertM(((ReferenceCountedObject*)pointer)->ReferenceCountedObject_weakPointer != NULL,
|
||||
"Weak pointer exists without a backpointer from the object.");
|
||||
|
||||
// Remove myself from my target's list of weak pointers
|
||||
_WeakPtrLinkedList** node = &((ReferenceCountedObject*)pointer)->ReferenceCountedObject_weakPointer;
|
||||
while ((*node)->weakPtr != this) {
|
||||
node = &((*node)->next);
|
||||
debugAssertM(*node != NULL,
|
||||
"Weak pointer exists without a backpointer from the object (2).");
|
||||
}
|
||||
|
||||
// Node must now point at the node for me. Remove node and
|
||||
// close the linked list behind it.
|
||||
_WeakPtrLinkedList* temp = *node;
|
||||
*node = temp->next;
|
||||
|
||||
// Now delete the node corresponding to me
|
||||
delete temp;
|
||||
}
|
||||
|
||||
pointer = NULL;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
WeakReferenceCountedPointer() : pointer(0) {}
|
||||
|
||||
/**
|
||||
Allow compile time subtyping rule
|
||||
RCP<<I>T</I>> <: RCP<<I>S</I>> if <I>T</I> <: <I>S</I>
|
||||
*/
|
||||
template <class S>
|
||||
inline WeakReferenceCountedPointer(const WeakReferenceCountedPointer<S>& p) : pointer(0) {
|
||||
// Threadsafe: the object cannot be collected while the other pointer exists.
|
||||
setPointer(p.pointer);
|
||||
}
|
||||
|
||||
template <class S>
|
||||
inline WeakReferenceCountedPointer(const ReferenceCountedPointer<S>& p) : pointer(0) {
|
||||
// Threadsafe: the object cannot be collected while the other
|
||||
// pointer exists.
|
||||
setPointer(p.pointer());
|
||||
}
|
||||
|
||||
// Gets called a *lot* when weak pointers are on the stack
|
||||
WeakReferenceCountedPointer(
|
||||
const WeakReferenceCountedPointer<T>& weakPtr) : pointer(0) {
|
||||
setPointer(weakPtr.pointer);
|
||||
}
|
||||
|
||||
WeakReferenceCountedPointer(
|
||||
const ReferenceCountedPointer<T>& strongPtr) : pointer(0) {
|
||||
setPointer(strongPtr.pointer());
|
||||
}
|
||||
|
||||
~WeakReferenceCountedPointer() {
|
||||
zeroPointer();
|
||||
}
|
||||
|
||||
WeakReferenceCountedPointer<T>& operator=(const WeakReferenceCountedPointer<T>& other) {
|
||||
// Threadsafe: the object cannot be collected while the other pointer exists.
|
||||
|
||||
// I now point at other's target
|
||||
setPointer(other.pointer);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
WeakReferenceCountedPointer<T>& operator=(const ReferenceCountedPointer<T>& other) {
|
||||
|
||||
// Threadsafe: the object cannot be collected while the other pointer exists.
|
||||
|
||||
// I now point at other's target
|
||||
setPointer(other.pointer());
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const WeakReferenceCountedPointer<T>& other) const {
|
||||
return pointer == other.pointer;
|
||||
}
|
||||
|
||||
bool operator!=(const WeakReferenceCountedPointer<T>& other) const {
|
||||
return pointer != other.pointer;
|
||||
}
|
||||
|
||||
bool operator < (const WeakReferenceCountedPointer<T>& y) const {
|
||||
return (pointer < y.pointer);
|
||||
}
|
||||
|
||||
bool operator > (const WeakReferenceCountedPointer<T>& y) const {
|
||||
return (pointer > y.pointer);
|
||||
}
|
||||
|
||||
bool operator <= (const WeakReferenceCountedPointer<T>& y) const {
|
||||
return (pointer <= y.pointer);
|
||||
}
|
||||
|
||||
bool operator >= (const ReferenceCountedPointer<T>& y) const {
|
||||
return (pointer >= y.pointer);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
/** Invoked by the destructor on ReferenceCountedPointer. */
|
||||
void objectCollected() {
|
||||
debugAssertM(pointer != NULL,
|
||||
"Removed a weak pointer twice.");
|
||||
pointer = NULL;
|
||||
}
|
||||
|
||||
};
|
||||
template<class T>
|
||||
bool notNull(const T* ptr) {
|
||||
return ptr != NULL;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
4
deps/g3dlite/include/G3D/RegistryUtil.h
vendored
4
deps/g3dlite/include/G3D/RegistryUtil.h
vendored
@@ -15,7 +15,7 @@
|
||||
#include "G3D/g3dmath.h"
|
||||
|
||||
// This file is only used on Windows
|
||||
#ifdef G3D_WIN32
|
||||
#ifdef G3D_WINDOWS
|
||||
|
||||
#include <string>
|
||||
|
||||
@@ -92,6 +92,6 @@ public:
|
||||
|
||||
} // namespace G3D
|
||||
|
||||
#endif // G3D_WIN32
|
||||
#endif // G3D_WINDOWS
|
||||
|
||||
#endif // G3D_REGISTRYTUIL_H
|
||||
|
||||
7
deps/g3dlite/include/G3D/Set.h
vendored
7
deps/g3dlite/include/G3D/Set.h
vendored
@@ -125,8 +125,13 @@ public:
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
bool isValid() const {
|
||||
return it.isValid();
|
||||
}
|
||||
|
||||
/** @deprecated Use isValid */
|
||||
bool hasMore() const {
|
||||
return it.hasMore();
|
||||
return it.isValid();
|
||||
}
|
||||
|
||||
bool operator==(const Iterator& other) const {
|
||||
|
||||
53
deps/g3dlite/include/G3D/SmallArray.h
vendored
53
deps/g3dlite/include/G3D/SmallArray.h
vendored
@@ -1,10 +1,10 @@
|
||||
/**
|
||||
@file SmallArray.h
|
||||
\file G3D/SmallArray.h
|
||||
|
||||
@created 2009-04-26
|
||||
@edited 2010-02-26
|
||||
\created 2009-04-26
|
||||
\edited 2012-07-23
|
||||
|
||||
Copyright 2000-2010, Morgan McGuire, http://graphics.cs.williams.edu
|
||||
Copyright 2000-2012, Morgan McGuire, http://graphics.cs.williams.edu
|
||||
All rights reserved.
|
||||
*/
|
||||
#ifndef G3D_SmallArray_h
|
||||
@@ -83,6 +83,35 @@ public:
|
||||
push(v);
|
||||
}
|
||||
|
||||
inline void append(const T& v, const T& v2) {
|
||||
push(v);
|
||||
push(v2);
|
||||
}
|
||||
|
||||
inline void append(const T& v, const T& v2, const T& v3) {
|
||||
push(v);
|
||||
push(v2);
|
||||
push(v3);
|
||||
}
|
||||
|
||||
inline void append(const T& v, const T& v2, const T& v3, const T& v4) {
|
||||
push(v);
|
||||
push(v2);
|
||||
push(v3);
|
||||
push(v4);
|
||||
}
|
||||
|
||||
/** Find the index of \a v or -1 if not found */
|
||||
int findIndex(const T& v) {
|
||||
for (int i = 0; i < N; ++i) {
|
||||
if (m_embedded[i] == v) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return m_rest.findIndex(v) + N;
|
||||
}
|
||||
|
||||
void fastRemove(int i, bool shrinkIfNecessary = false) {
|
||||
debugAssert(i < m_size && i >= 0);
|
||||
if (i < N) {
|
||||
@@ -139,8 +168,8 @@ public:
|
||||
return m_rest.contains(value);
|
||||
}
|
||||
|
||||
template<int MIN_ELEMENTS, int MIN_BYTES>
|
||||
SmallArray<T, N>& operator=(const Array<T, MIN_ELEMENTS, MIN_BYTES>& src) {
|
||||
template<int MIN_ELEMENTS>
|
||||
SmallArray<T, N>& operator=(const Array<T, MIN_ELEMENTS>& src) {
|
||||
resize(src.size());
|
||||
for (int i = 0; i < src.size(); ++i) {
|
||||
(*this)[i] = src[i];
|
||||
@@ -148,13 +177,13 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline const T& last() const {
|
||||
return (*this)[size() - 1];
|
||||
}
|
||||
inline const T& last() const {
|
||||
return (*this)[size() - 1];
|
||||
}
|
||||
|
||||
inline T& last() {
|
||||
return (*this)[size() - 1];
|
||||
}
|
||||
inline T& last() {
|
||||
return (*this)[size() - 1];
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
6
deps/g3dlite/include/G3D/SpawnBehavior.h
vendored
Normal file
6
deps/g3dlite/include/G3D/SpawnBehavior.h
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
#ifndef SpawnBehavior_h
|
||||
#define SpawnBehavior_h
|
||||
namespace G3D {
|
||||
enum SpawnBehavior {USE_NEW_THREAD, USE_CURRENT_THREAD};
|
||||
}
|
||||
#endif
|
||||
58
deps/g3dlite/include/G3D/Sphere.h
vendored
58
deps/g3dlite/include/G3D/Sphere.h
vendored
@@ -1,16 +1,16 @@
|
||||
/**
|
||||
@file Sphere.h
|
||||
\file G3D/Sphere.h
|
||||
|
||||
Sphere class
|
||||
|
||||
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
\maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
|
||||
@created 2001-06-02
|
||||
@edited 2008-10-07
|
||||
\created 2001-06-02
|
||||
\edited 2011-02-07
|
||||
*/
|
||||
|
||||
#ifndef G3D_SPHERE_H
|
||||
#define G3D_SPHERE_H
|
||||
#ifndef G3D_Sphere_h
|
||||
#define G3D_Sphere_h
|
||||
|
||||
#include "G3D/platform.h"
|
||||
#include "G3D/Vector3.h"
|
||||
@@ -27,28 +27,36 @@ private:
|
||||
static int32 dummy;
|
||||
|
||||
public:
|
||||
Vector3 center;
|
||||
Point3 center;
|
||||
float radius;
|
||||
|
||||
Sphere() {
|
||||
center = Vector3::zero();
|
||||
radius = 0;
|
||||
Sphere() : center(Point3::zero()), radius(0) {
|
||||
}
|
||||
|
||||
explicit Sphere(float radius) : radius(radius) {}
|
||||
|
||||
Sphere(class BinaryInput& b);
|
||||
void serialize(class BinaryOutput& b) const;
|
||||
void deserialize(class BinaryInput& b);
|
||||
|
||||
Sphere(
|
||||
const Vector3& center,
|
||||
float radius) {
|
||||
/** Format is one of:
|
||||
- Sphere(point, radius)
|
||||
- Sphere(radius)
|
||||
*/
|
||||
explicit Sphere(const class Any& a);
|
||||
|
||||
this->center = center;
|
||||
this->radius = radius;
|
||||
Any toAny() const;
|
||||
|
||||
Sphere
|
||||
(const Point3& center,
|
||||
float radius) : center(center), radius(radius) {
|
||||
}
|
||||
|
||||
virtual ~Sphere() {}
|
||||
|
||||
/** Returns the infinite sphere. */
|
||||
static const Sphere& inf();
|
||||
|
||||
bool operator==(const Sphere& other) const {
|
||||
return (center == other.center) && (radius == other.radius);
|
||||
}
|
||||
@@ -61,7 +69,7 @@ public:
|
||||
Returns true if point is less than or equal to radius away from
|
||||
the center.
|
||||
*/
|
||||
bool contains(const Vector3& point) const;
|
||||
bool contains(const Point3& point) const;
|
||||
|
||||
bool contains(const Sphere& other) const;
|
||||
|
||||
@@ -71,7 +79,7 @@ public:
|
||||
bool culledBy(
|
||||
const class Plane* plane,
|
||||
int numPlanes,
|
||||
int32& cullingPlaneIndex,
|
||||
int32& cullingPlaneIndex,
|
||||
const uint32 testMask,
|
||||
uint32& childMask) const;
|
||||
|
||||
@@ -88,18 +96,18 @@ public:
|
||||
See AABox::culledBy
|
||||
*/
|
||||
bool culledBy(
|
||||
const Array<Plane>& plane,
|
||||
int32& cullingPlaneIndex,
|
||||
const uint32 testMask,
|
||||
const Array<Plane>& plane,
|
||||
int32& cullingPlaneIndex,
|
||||
const uint32 testMask,
|
||||
uint32& childMask) const;
|
||||
|
||||
/**
|
||||
Conservative culling test that does not produce a mask for children.
|
||||
*/
|
||||
bool culledBy(
|
||||
const Array<Plane>& plane,
|
||||
int32& cullingPlaneIndex = dummy,
|
||||
const uint32 testMask = 0xFFFFFFFF) const;
|
||||
const Array<Plane>& plane,
|
||||
int32& cullingPlaneIndex = dummy,
|
||||
const uint32 testMask = 0xFFFFFFFF) const;
|
||||
|
||||
virtual std::string toString() const;
|
||||
|
||||
@@ -110,12 +118,12 @@ public:
|
||||
/**
|
||||
Uniformly distributed on the surface.
|
||||
*/
|
||||
Vector3 randomSurfacePoint() const;
|
||||
Point3 randomSurfacePoint() const;
|
||||
|
||||
/**
|
||||
Uniformly distributed on the interior (includes surface)
|
||||
*/
|
||||
Vector3 randomInteriorPoint() const;
|
||||
Point3 randomInteriorPoint() const;
|
||||
|
||||
void getBounds(class AABox& out) const;
|
||||
|
||||
|
||||
124
deps/g3dlite/include/G3D/Spline.h
vendored
124
deps/g3dlite/include/G3D/Spline.h
vendored
@@ -1,17 +1,19 @@
|
||||
/**
|
||||
@file Spline.h
|
||||
\file G3D/Spline.h
|
||||
|
||||
@author Morgan McGuire, http://graphics.cs.williams.edu
|
||||
\author Morgan McGuire, http://graphics.cs.williams.edu
|
||||
*/
|
||||
|
||||
#ifndef G3D_SPLINE_H
|
||||
#define G3D_SPLINE_H
|
||||
#ifndef G3D_Spline_h
|
||||
#define G3D_Spline_h
|
||||
|
||||
#include "G3D/platform.h"
|
||||
#include "G3D/Array.h"
|
||||
#include "G3D/g3dmath.h"
|
||||
#include "G3D/Matrix4.h"
|
||||
#include "G3D/Vector4.h"
|
||||
#include "G3D/Any.h"
|
||||
#include "G3D/SplineExtrapolationMode.h"
|
||||
|
||||
namespace G3D {
|
||||
|
||||
@@ -23,10 +25,12 @@ public:
|
||||
number of elements as Spline::control. */
|
||||
Array<float> time;
|
||||
|
||||
/** If cyclic, then the control points will be assumed to wrap around.
|
||||
If not cyclic, then the tangents at the ends of the spline
|
||||
point to the final control points.*/
|
||||
bool cyclic;
|
||||
/** If CYCLIC, then the control points will be assumed to wrap around.
|
||||
If LINEAR, then the tangents at the ends of the spline
|
||||
point to the final control points. If CONSTANT, the end control
|
||||
points will be treated as multiple contol points (so the value remains constant at the ends)
|
||||
*/
|
||||
SplineExtrapolationMode extrapolationMode;
|
||||
|
||||
/** For a cyclic spline, this is the time elapsed between the last
|
||||
control point and the first. If less than or equal to zero this is
|
||||
@@ -36,8 +40,13 @@ public:
|
||||
time[time.size() - 1] - time[time.size() - 2]) / 2.
|
||||
*/
|
||||
float finalInterval;
|
||||
|
||||
SplineInterpolationMode interpolationMode;
|
||||
|
||||
SplineBase() : cyclic(true), finalInterval(-1) {}
|
||||
SplineBase() :
|
||||
extrapolationMode(SplineExtrapolationMode::CYCLIC),
|
||||
finalInterval(-1),
|
||||
interpolationMode(SplineInterpolationMode::CUBIC) {}
|
||||
|
||||
virtual ~SplineBase() {}
|
||||
|
||||
@@ -144,11 +153,7 @@ public:
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (time[0] == 0) {
|
||||
append(1, c);
|
||||
} else {
|
||||
append(time[0], c);
|
||||
}
|
||||
append(time[0] + 1, c);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -192,7 +197,7 @@ public:
|
||||
if (N == 0) {
|
||||
c = zero;
|
||||
t = 0;
|
||||
} else if (cyclic) {
|
||||
} else if (extrapolationMode == SplineExtrapolationMode::CYCLIC) {
|
||||
c = control[iWrap(i, N)];
|
||||
|
||||
if (i < 0) {
|
||||
@@ -222,9 +227,16 @@ public:
|
||||
// Step away from control point 0
|
||||
float dt = time[1] - time[0];
|
||||
|
||||
// Extrapolate (note; i is negative)
|
||||
c = control[1] * float(i) + control[0] * float(1 - i);
|
||||
correct(c);
|
||||
if (extrapolationMode == SplineExtrapolationMode::LINEAR) {
|
||||
// Extrapolate (note; i is negative)
|
||||
c = control[1] * float(i) + control[0] * float(1 - i);
|
||||
correct(c);
|
||||
} else if (extrapolationMode == SplineExtrapolationMode::CLAMP){
|
||||
// Return the first, clamping
|
||||
c = control[0];
|
||||
} else {
|
||||
alwaysAssertM(false, "Invalid extrapolation mode");
|
||||
}
|
||||
t = dt * i + time[0];
|
||||
|
||||
} else {
|
||||
@@ -239,9 +251,17 @@ public:
|
||||
if (N >= 2) {
|
||||
float dt = time[N - 1] - time[N - 2];
|
||||
|
||||
if (extrapolationMode == SplineExtrapolationMode::LINEAR) {
|
||||
// Extrapolate (note; i is negative)
|
||||
c = control[N - 1] * float(i - N + 2) + control[N - 2] * -float(i - N + 1);
|
||||
correct(c);
|
||||
} else if (extrapolationMode == SplineExtrapolationMode::CLAMP){
|
||||
// Return the last, clamping
|
||||
c = control.last();
|
||||
} else {
|
||||
alwaysAssertM(false, "Invalid extrapolation mode");
|
||||
}
|
||||
// Extrapolate
|
||||
c = control[N - 1] * float(i - N + 2) + control[N - 2] * -float(i - N + 1);
|
||||
correct(c);
|
||||
t = time[N - 1] + dt * (i - N + 1);
|
||||
|
||||
} else {
|
||||
@@ -279,8 +299,47 @@ protected:
|
||||
/** Normalize or otherwise adjust this interpolated Control. */
|
||||
virtual void correct(Control& A) const { (void)A; }
|
||||
|
||||
/** Does not invoke verifyDone() on the propertyTable because subclasses may have more properties */
|
||||
virtual void init(AnyTableReader& propertyTable) {
|
||||
propertyTable.getIfPresent("extrapolationMode", extrapolationMode);
|
||||
propertyTable.getIfPresent("interpolationMode", interpolationMode);
|
||||
propertyTable.getIfPresent("finalInterval", finalInterval);
|
||||
|
||||
const bool hasTime = propertyTable.getIfPresent("time", time);
|
||||
|
||||
if (propertyTable.getIfPresent("control", control)) {
|
||||
if (! hasTime) {
|
||||
// Assign unit times
|
||||
time.resize(control.size());
|
||||
for (int i = 0; i < time.size(); ++i) {
|
||||
time[i] = float(i);
|
||||
}
|
||||
} // if has time
|
||||
} // if has control
|
||||
} // init
|
||||
|
||||
public:
|
||||
|
||||
|
||||
/** Accepts a table of properties, or any valid PhysicsFrame specification for a single control*/
|
||||
explicit Spline(const Any& any) {
|
||||
AnyTableReader propertyTable(any);
|
||||
init(propertyTable);
|
||||
propertyTable.verifyDone();
|
||||
}
|
||||
|
||||
/** Note that invoking classes can call setName on the returned value instead of passing a name in. */
|
||||
virtual Any toAny(const std::string& myName) const {
|
||||
Any a(Any::TABLE, myName);
|
||||
|
||||
a["extrapolationMode"] = extrapolationMode;
|
||||
a["interpolationMode"] = interpolationMode;
|
||||
a["control"] = Any(control);
|
||||
a["time"] = Any(time);
|
||||
a["finalInterval"] = finalInterval;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Return the position at time s. The spline is defined outside
|
||||
@@ -313,6 +372,22 @@ public:
|
||||
Control p[4];
|
||||
float t[4];
|
||||
getControls(i - 1, t, p, 4);
|
||||
|
||||
const Control& p0 = p[0];
|
||||
const Control& p1 = p[1];
|
||||
const Control& p2 = p[2];
|
||||
const Control& p3 = p[3];
|
||||
|
||||
// Compute the weighted sum of the neighboring control points.
|
||||
Control sum;
|
||||
|
||||
if (interpolationMode == SplineInterpolationMode::LINEAR) {
|
||||
const float a = (s - t[1]) / (t[2] - t[1]);
|
||||
sum = p1 * (1.0f - a) + p2 * a;
|
||||
correct(sum);
|
||||
return sum;
|
||||
}
|
||||
|
||||
float dt0 = t[1] - t[0];
|
||||
float dt1 = t[2] - t[1];
|
||||
float dt2 = t[3] - t[2];
|
||||
@@ -325,13 +400,6 @@ public:
|
||||
// Compute the weights on each of the control points.
|
||||
const Vector4& weights = uvec * basis;
|
||||
|
||||
// Compute the weighted sum of the neighboring control points.
|
||||
Control sum;
|
||||
|
||||
const Control& p0 = p[0];
|
||||
const Control& p1 = p[1];
|
||||
const Control& p2 = p[2];
|
||||
const Control& p3 = p[3];
|
||||
|
||||
// The factor of 1/2 from averaging two time intervals is
|
||||
// already factored into the basis
|
||||
|
||||
94
deps/g3dlite/include/G3D/SplineExtrapolationMode.h
vendored
Normal file
94
deps/g3dlite/include/G3D/SplineExtrapolationMode.h
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
/**
|
||||
\file G3D/SplineExtrapolationMode.h
|
||||
|
||||
\maintainer Michael Mara, http://graphics.cs.williams.edu
|
||||
|
||||
\created 2013-01-24
|
||||
\edited 2013-01-24
|
||||
|
||||
Copyright 2000-2013, Morgan McGuire.
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef G3D_SplineExtrapolationMode_h
|
||||
#define G3D_SplineExtrapolationMode_h
|
||||
|
||||
#include "G3D/platform.h"
|
||||
#include "G3D/enumclass.h"
|
||||
|
||||
|
||||
namespace G3D {
|
||||
|
||||
/**
|
||||
Describes the behavior of G3D::Spline, etc. when accessing a time outside of the control point range.
|
||||
|
||||
Refer to these as scoped enums, e.g., <code>SplineExtrapolationMode m = SplineExtrapolationMode::CLAMP;</code>.
|
||||
|
||||
Uses the "Intelligent Enum" design pattern
|
||||
http://www.codeguru.com/cpp/cpp/cpp_mfc/article.php/c4001/
|
||||
*/
|
||||
class SplineExtrapolationMode {
|
||||
public:
|
||||
/** Don't use this enum; use SplineExtrapolationMode instances instead. */
|
||||
enum Value {
|
||||
CYCLIC,
|
||||
LINEAR,
|
||||
CLAMP
|
||||
};
|
||||
Value value;
|
||||
private:
|
||||
|
||||
static const char* toString(int i, Value& v) {
|
||||
static const char* str[] = {"CYCLIC", "LINEAR", "CLAMP", NULL};
|
||||
static const Value val[] = {CYCLIC, LINEAR, CLAMP};
|
||||
const char* s = str[i];
|
||||
if (s) {
|
||||
v = val[i];
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
G3D_DECLARE_ENUM_CLASS_METHODS(SplineExtrapolationMode);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Describes the behavior of G3D::Spline
|
||||
*/
|
||||
class SplineInterpolationMode {
|
||||
public:
|
||||
/** Don't use this enum; use SplineExtrapolationMode instances instead. */
|
||||
enum Value {
|
||||
LINEAR,
|
||||
CUBIC
|
||||
};
|
||||
Value value;
|
||||
private:
|
||||
|
||||
static const char* toString(int i, Value& v) {
|
||||
static const char* str[] = {"LINEAR", "CUBIC", NULL};
|
||||
static const Value val[] = {LINEAR, CUBIC};
|
||||
const char* s = str[i];
|
||||
if (s) {
|
||||
v = val[i];
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
G3D_DECLARE_ENUM_CLASS_METHODS(SplineInterpolationMode);
|
||||
|
||||
};
|
||||
|
||||
|
||||
} // namespace G3D
|
||||
|
||||
G3D_DECLARE_ENUM_CLASS_HASHCODE(G3D::SplineExtrapolationMode);
|
||||
G3D_DECLARE_ENUM_CLASS_HASHCODE(G3D::SplineInterpolationMode);
|
||||
|
||||
#endif
|
||||
17
deps/g3dlite/include/G3D/Stopwatch.h
vendored
17
deps/g3dlite/include/G3D/Stopwatch.h
vendored
@@ -46,6 +46,9 @@ class Stopwatch {
|
||||
private:
|
||||
|
||||
std::string myName;
|
||||
|
||||
bool m_enabled;
|
||||
|
||||
double startTime;
|
||||
std::string prevMark;
|
||||
double prevTime;
|
||||
@@ -85,6 +88,15 @@ public:
|
||||
|
||||
Stopwatch(const std::string& name = "Stopwatch");
|
||||
|
||||
void setEnabled(bool e) {
|
||||
m_enabled = e;
|
||||
}
|
||||
|
||||
/** A stopwatch only prints output when enabled */
|
||||
bool enabled() const {
|
||||
return m_enabled;
|
||||
}
|
||||
|
||||
/** Returns the number of times that tick was called per wall-clock second;
|
||||
e.g. frames-per-second. */
|
||||
double FPS() const {
|
||||
@@ -130,7 +142,10 @@ public:
|
||||
void reset();
|
||||
|
||||
/** Call after an operation has completed, with the name of the operation, to
|
||||
print a debug message listing the time since the previous after() call. */
|
||||
print a debug message listing the time since the previous after() call.
|
||||
|
||||
Does nothing if the stopwatch is disabled.
|
||||
*/
|
||||
void after(const std::string& s = "");
|
||||
|
||||
};
|
||||
|
||||
219
deps/g3dlite/include/G3D/System.h
vendored
219
deps/g3dlite/include/G3D/System.h
vendored
@@ -1,14 +1,14 @@
|
||||
/**
|
||||
@file System.h
|
||||
\file System.h
|
||||
|
||||
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
\maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
|
||||
@cite Rob Wyatt http://www.gamasutra.com/features/wyatts_world/19990709/processor_detection_01.htm
|
||||
@cite Benjamin Jurke http://www.flipcode.com/cgi-bin/msg.cgi?showThread=COTD-ProcessorDetectionClass&forum=cotd&id=-1
|
||||
@cite Michael Herf http://www.stereopsis.com/memcpy.html
|
||||
\cite Rob Wyatt http://www.gamasutra.com/features/wyatts_world/19990709/processor_detection_01.htm
|
||||
\cite Benjamin Jurke http://www.flipcode.com/cgi-bin/msg.cgi?showThread=COTD-ProcessorDetectionClass&forum=cotd&id=-1
|
||||
\cite Michael Herf http://www.stereopsis.com/memcpy.html
|
||||
|
||||
@created 2003-01-25
|
||||
@edited 2008-10-14
|
||||
\created 2003-01-25
|
||||
\edited 2012-10-02
|
||||
*/
|
||||
|
||||
#ifndef G3D_System_h
|
||||
@@ -18,28 +18,20 @@
|
||||
#include "G3D/g3dmath.h"
|
||||
#include "G3D/G3DGameUnits.h"
|
||||
#include "G3D/BinaryFormat.h"
|
||||
#include "G3D/FileNotFound.h"
|
||||
#include <string>
|
||||
#ifdef G3D_LINUX
|
||||
# include <sys/socket.h>
|
||||
|
||||
#if defined(__aarch64__)
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#ifdef G3D_OSX
|
||||
#define Zone OSX_Zone
|
||||
# include <CoreServices/CoreServices.h>
|
||||
#endif
|
||||
|
||||
namespace G3D {
|
||||
|
||||
/**
|
||||
Routine used by the demos to find the data. Searches in
|
||||
../data, ../../data, etc. up to 5 levels back. Checks
|
||||
common locations like \verbatim c:\libraries\g3d-<version>\data \endverbatim
|
||||
and some hard-coded paths on the Brown University file
|
||||
system.
|
||||
|
||||
@deprecated
|
||||
*/
|
||||
std::string demoFindData(bool errorIfNotFound = true);
|
||||
|
||||
|
||||
/** G3D, SDL, and IJG libraries require license documentation
|
||||
to be distributed with your program. This generates the
|
||||
string that must appear in your documentation.
|
||||
@@ -118,7 +110,7 @@ private:
|
||||
std::string m_cpuArch;
|
||||
std::string m_operatingSystem;
|
||||
|
||||
# ifdef G3D_WIN32
|
||||
# ifdef G3D_WINDOWS
|
||||
/** Used by getTick() for timing */
|
||||
LARGE_INTEGER m_start;
|
||||
LARGE_INTEGER m_counterFrequency;
|
||||
@@ -167,7 +159,6 @@ private:
|
||||
*/
|
||||
static void cpuid(CPUIDFunction func, uint32& areg, uint32& breg, uint32& creg, uint32& dreg);
|
||||
|
||||
void init();
|
||||
|
||||
/** Called from init() */
|
||||
void getStandardProcessorExtensions();
|
||||
@@ -175,7 +166,12 @@ private:
|
||||
/** Called from init() */
|
||||
void initTime();
|
||||
|
||||
void init();
|
||||
|
||||
public:
|
||||
|
||||
/** atexit handling code invoked from G3DCleanupHook. */
|
||||
static void cleanup();
|
||||
|
||||
/** Returns the speed of processor 0 in MHz.
|
||||
Always returns 0 on linux.*/
|
||||
@@ -243,16 +239,13 @@ public:
|
||||
*/
|
||||
static std::string currentDateString();
|
||||
|
||||
/**
|
||||
Guarantees that the start of the array is aligned to the
|
||||
specified number of bytes.
|
||||
*/
|
||||
static void* alignedMalloc(size_t bytes, size_t alignment);
|
||||
|
||||
/** Returns the current 24-hour local time as a string in the form HH:MM:SS */
|
||||
static std::string currentTimeString();
|
||||
|
||||
/**
|
||||
Uses pooled storage to optimize small allocations (1 byte to 5
|
||||
kilobytes). Can be 10x to 100x faster than calling ::malloc or
|
||||
new.
|
||||
kilobytes). Can be 10x to 100x faster than calling \c malloc or
|
||||
\c new.
|
||||
|
||||
The result must be freed with free.
|
||||
|
||||
@@ -288,6 +281,12 @@ public:
|
||||
*/
|
||||
static void free(void* p);
|
||||
|
||||
/**
|
||||
Guarantees that the start of the array is aligned to the
|
||||
specified number of bytes.
|
||||
*/
|
||||
static void* alignedMalloc(size_t bytes, size_t alignment);
|
||||
|
||||
/**
|
||||
Frees memory allocated with alignedMalloc.
|
||||
*/
|
||||
@@ -370,6 +369,7 @@ public:
|
||||
/**
|
||||
To count the number of cycles a given operation takes:
|
||||
|
||||
\htmlonly
|
||||
<PRE>
|
||||
unsigned long count;
|
||||
System::beginCycleCount(count);
|
||||
@@ -377,11 +377,12 @@ public:
|
||||
System::endCycleCount(count);
|
||||
// count now contains the cycle count for the intervening operation.
|
||||
</PRE>
|
||||
\endhtmlonly
|
||||
*/
|
||||
/* static void beginCycleCount(uint64& cycleCount);
|
||||
static void beginCycleCount(uint64& cycleCount);
|
||||
static void endCycleCount(uint64& cycleCount);
|
||||
|
||||
static uint64 getCycleCount(); */
|
||||
static uint64 getCycleCount();
|
||||
|
||||
inline static void setOutOfMemoryCallback(OutOfMemoryCallback c) {
|
||||
instance().m_outOfMemoryCallback = c;
|
||||
@@ -404,7 +405,7 @@ public:
|
||||
|
||||
/** Set an environment variable for the current process */
|
||||
static void setEnv(const std::string& name, const std::string& value);
|
||||
|
||||
|
||||
/** Get an environment variable for the current process. Returns NULL if the variable doesn't exist. */
|
||||
static const char* getEnv(const std::string& name);
|
||||
|
||||
@@ -412,25 +413,53 @@ public:
|
||||
Prints a human-readable description of this machine
|
||||
to the text output stream. Either argument may be NULL.
|
||||
*/
|
||||
static void describeSystem(
|
||||
class TextOutput& t);
|
||||
static void describeSystem
|
||||
(class TextOutput& t);
|
||||
|
||||
static void describeSystem(
|
||||
std::string& s);
|
||||
|
||||
/** On Win32, returns the clipboard text contents. Does nothing on other
|
||||
platforms (yet) */
|
||||
static std::string getClipboardText();
|
||||
|
||||
/** Copies the text to the clipboard on Win32. */
|
||||
static void setClipboardText(const std::string& s);
|
||||
static void describeSystem
|
||||
(std::string& s);
|
||||
|
||||
/**
|
||||
Tries to locate the resource by looking in related directories.
|
||||
If found, returns the full path to the resource, otherwise
|
||||
returns the empty string.
|
||||
|
||||
Looks in:
|
||||
|
||||
- Literal interpretation of full (i.e., if it contains a fully-qualified name)
|
||||
- Last directory in which a file was found
|
||||
- Current directory
|
||||
- System::appDataDir (which is usually GApp::Settings.dataDir, which defaults to the directory containing the program binary)
|
||||
- $G3D9DATA directory
|
||||
- System::appDataDir() + "data/" (note that this may be a zipfile named "data" with no extension)
|
||||
- System::appDataDir() + "data.zip/"
|
||||
- ../data-files/ (windows)
|
||||
- ../../data-files/ (windows)
|
||||
- ../../../data-files/ (windows)
|
||||
|
||||
Plus the following subdirectories of those:
|
||||
|
||||
- cubemap
|
||||
- gui
|
||||
- font
|
||||
- icon
|
||||
- models
|
||||
- image
|
||||
- sky
|
||||
- md2
|
||||
- md3
|
||||
- ifs
|
||||
- 3ds
|
||||
|
||||
\param exceptionIfNotFound If true and the file is not found, throws G3D::FileNotFound.
|
||||
*/
|
||||
static std::string findDataFile(const std::string& full, bool errorIfNotFound = true);
|
||||
static std::string findDataFile(const std::string& full, bool exceptionIfNotFound = true, bool caseSensitive =
|
||||
#ifdef G3D_WINDOWS
|
||||
false
|
||||
#else
|
||||
true
|
||||
#endif
|
||||
);
|
||||
|
||||
/**
|
||||
Sets the path that the application is using as its data directory.
|
||||
@@ -441,47 +470,80 @@ public:
|
||||
|
||||
};
|
||||
|
||||
/* don't need that for Moongose, not portable to Win64...
|
||||
|
||||
#ifdef _MSC_VER
|
||||
inline uint64 System::getCycleCount() {
|
||||
uint32 timehi, timelo;
|
||||
# ifdef _M_IX86
|
||||
// 32-bit
|
||||
inline uint64 System::getCycleCount() {
|
||||
uint32 timehi, timelo;
|
||||
|
||||
// Use the assembly instruction rdtsc, which gets the current
|
||||
// cycle count (since the process started) and puts it in edx:eax.
|
||||
__asm
|
||||
{
|
||||
rdtsc;
|
||||
mov timehi, edx;
|
||||
mov timelo, eax;
|
||||
}
|
||||
// Use the assembly instruction rdtsc, which gets the current
|
||||
// cycle count (since the process started) and puts it in edx:eax.
|
||||
__asm
|
||||
{
|
||||
rdtsc;
|
||||
mov timehi, edx;
|
||||
mov timelo, eax;
|
||||
}
|
||||
|
||||
return ((uint64)timehi << 32) + (uint64)timelo;
|
||||
}
|
||||
return ((uint64)timehi << 32) + (uint64)timelo;
|
||||
}
|
||||
# else
|
||||
// 64-bit
|
||||
inline uint64 System::getCycleCount() {
|
||||
LARGE_INTEGER now;
|
||||
QueryPerformanceCounter(&now);
|
||||
return now.QuadPart;
|
||||
}
|
||||
|
||||
# endif
|
||||
|
||||
#elif defined(G3D_LINUX)
|
||||
|
||||
inline uint64 System::getCycleCount() {
|
||||
uint32 timehi, timelo;
|
||||
# if defined(__aarch64__)
|
||||
# if (__ARM_ARCH >= 6) // V6 is the earliest arch that has a standard cyclecount
|
||||
uint32_t pmccntr;
|
||||
uint32_t pmuseren;
|
||||
uint32_t pmcntenset;
|
||||
// Read the user mode perf monitor counter access permissions.
|
||||
__asm__ __volatile__("mrc p15, 0, %w0, c9, c14, 0" : "=r"(pmuseren));
|
||||
if (pmuseren & 1) { // Allows reading perfmon counters for user mode code.
|
||||
__asm__ __volatile__("mrc p15, 0, %w0, c9, c12, 1" : "=r"(pmcntenset));
|
||||
if (pmcntenset & 0x80000000ul) { // Is it counting?
|
||||
__asm__ __volatile__("mrc p15, 0, %w0, c9, c13, 0" : "=r"(pmccntr));
|
||||
// The counter is set up to count every 64th cycle
|
||||
return static_cast<uint64>(pmccntr) * 64; // Should optimize to << 6
|
||||
}
|
||||
}
|
||||
# endif
|
||||
|
||||
__asm__ __volatile__ (
|
||||
"rdtsc "
|
||||
: "=a" (timelo),
|
||||
"=d" (timehi)
|
||||
: );
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, nullptr);
|
||||
return static_cast<uint64>(tv.tv_sec) * 1000000 + tv.tv_usec;
|
||||
# else
|
||||
uint32 timehi, timelo;
|
||||
|
||||
return ((uint64)timehi << 32) + (uint64)timelo;
|
||||
__asm__ __volatile__ (
|
||||
"rdtsc "
|
||||
: "=a" (timelo),
|
||||
"=d" (timehi)
|
||||
: );
|
||||
|
||||
return ((uint64)timehi << 32) + (uint64)timelo;
|
||||
# endif
|
||||
}
|
||||
|
||||
#elif defined(G3D_OSX)
|
||||
|
||||
inline uint64 System::getCycleCount() {
|
||||
//Note: To put off extra processing until the end, this does not
|
||||
//return the actual clock cycle count. It is a bus cycle count.
|
||||
//When endCycleCount() is called, it converts the two into a difference
|
||||
//of clock cycles
|
||||
|
||||
//Note: To put off extra processing until the end, this does not
|
||||
//return the actual clock cycle count. It is a bus cycle count.
|
||||
//When endCycleCount() is called, it converts the two into a difference
|
||||
//of clock cycles
|
||||
|
||||
return (uint64) UnsignedWideToUInt64(UpTime());
|
||||
//return (uint64) mach_absolute_time();
|
||||
//return (uint64) mach_absolute_time();
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -496,15 +558,20 @@ inline void System::endCycleCount(uint64& cycleCount) {
|
||||
cycleCount = getCycleCount() - cycleCount;
|
||||
#else
|
||||
AbsoluteTime end = UpTime();
|
||||
Nanoseconds diffNS =
|
||||
Nanoseconds diffNS =
|
||||
AbsoluteDeltaToNanoseconds(end, UInt64ToUnsignedWide(cycleCount));
|
||||
cycleCount =
|
||||
(uint64) ((double) (instance().m_OSXCPUSpeed) *
|
||||
cycleCount =
|
||||
(uint64) ((double) (instance().m_OSXCPUSpeed) *
|
||||
(double) UnsignedWideToUInt64(diffNS) * instance().m_secondsPerNS);
|
||||
#endif
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
#ifdef G3D_OSX
|
||||
#undef Zone
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
189
deps/g3dlite/include/G3D/Table.h
vendored
189
deps/g3dlite/include/G3D/Table.h
vendored
@@ -5,8 +5,8 @@
|
||||
|
||||
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
@created 2001-04-22
|
||||
@edited 2010-01-28
|
||||
Copyright 2000-2010, Morgan McGuire.
|
||||
@edited 2013-01-22
|
||||
Copyright 2000-2013, Morgan McGuire.
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
@@ -90,7 +90,8 @@ namespace G3D {
|
||||
};
|
||||
</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
|
||||
@@ -132,10 +133,12 @@ private:
|
||||
// Private to require use of the allocator
|
||||
Node(const Key& k, const Value& v, size_t h, Node* n)
|
||||
: entry(k, v), hashCode(h), next(n) {
|
||||
debugAssert((next == NULL) || isValidHeapPointer(next));
|
||||
}
|
||||
|
||||
Node(const Key& k, size_t h, Node* n)
|
||||
: entry(k), hashCode(h), next(n) {
|
||||
debugAssert((next == NULL) || isValidHeapPointer(next));
|
||||
}
|
||||
|
||||
public:
|
||||
@@ -213,9 +216,9 @@ private:
|
||||
|
||||
// Allocate a new m_bucket array with the new size
|
||||
m_bucket = (Node**)alloc(sizeof(Node*) * newSize);
|
||||
alwaysAssertM(m_bucket != NULL, "MemoryManager::alloc returned NULL. Out of memory.");
|
||||
// Set all pointers to NULL
|
||||
System::memset(m_bucket, 0, newSize * sizeof(Node*));
|
||||
debugAssertM(m_bucket != NULL, "MemoryManager::alloc returned NULL. Out of memory.");
|
||||
// Move each node to its new hash location
|
||||
for (size_t b = 0; b < m_numBuckets; ++b) {
|
||||
Node* node = oldBucket[b];
|
||||
@@ -274,7 +277,7 @@ private:
|
||||
void freeMemory() {
|
||||
checkIntegrity();
|
||||
|
||||
for (size_t b = 0; b < m_numBuckets; b++) {
|
||||
for (size_t b = 0; b < m_numBuckets; ++b) {
|
||||
Node* node = m_bucket[b];
|
||||
while (node != NULL) {
|
||||
Node* next = node->next;
|
||||
@@ -357,7 +360,7 @@ public:
|
||||
size_t debugGetDeepestBucketSize() const {
|
||||
size_t deepest = 0;
|
||||
|
||||
for (size_t b = 0; b < m_numBuckets; b++) {
|
||||
for (size_t b = 0; b < m_numBuckets; ++b) {
|
||||
size_t count = 0;
|
||||
Node* node = m_bucket[b];
|
||||
while (node != NULL) {
|
||||
@@ -377,21 +380,16 @@ public:
|
||||
Returns the average size of non-empty buckets.
|
||||
*/
|
||||
float debugGetAverageBucketSize() const {
|
||||
size_t num = 0;
|
||||
size_t count = 0;
|
||||
uint64 num = 0;
|
||||
|
||||
for (size_t b = 0; b < m_numBuckets; b++) {
|
||||
for (size_t b = 0; b < m_numBuckets; ++b) {
|
||||
Node* node = m_bucket[b];
|
||||
if (node != NULL) {
|
||||
++num;
|
||||
while (node != NULL) {
|
||||
node = node->next;
|
||||
++count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (float)((double)count / num);
|
||||
return (float)((double)size() / num);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -402,7 +400,7 @@ public:
|
||||
many keys to the same code.
|
||||
*/
|
||||
double debugGetLoad() const {
|
||||
return debugGetDeepestBucketSize() / (double)size();
|
||||
return (double)size() / m_numBuckets;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -428,7 +426,7 @@ public:
|
||||
Linked list node.
|
||||
*/
|
||||
Node* node;
|
||||
ThisType* table;
|
||||
|
||||
size_t m_numBuckets;
|
||||
Node** m_bucket;
|
||||
bool isDone;
|
||||
@@ -436,13 +434,14 @@ public:
|
||||
/**
|
||||
Creates the end iterator.
|
||||
*/
|
||||
Iterator(const ThisType* table) : table(const_cast<ThisType*>(table)) {
|
||||
Iterator() : index(0), node(NULL), m_bucket(NULL) {
|
||||
isDone = true;
|
||||
}
|
||||
|
||||
Iterator(const ThisType* table, size_t m_numBuckets, Node** m_bucket) :
|
||||
table(const_cast<ThisType*>(table)),
|
||||
m_numBuckets(m_numBuckets),
|
||||
Iterator(size_t numBuckets, Node** m_bucket) :
|
||||
index(0),
|
||||
node(NULL),
|
||||
m_numBuckets(numBuckets),
|
||||
m_bucket(m_bucket) {
|
||||
|
||||
if (m_numBuckets == 0) {
|
||||
@@ -451,26 +450,38 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
# ifdef G3D_DEBUG
|
||||
for (unsigned int i = 0; i < m_numBuckets; ++i) {
|
||||
debugAssert((m_bucket[i] == NULL) || isValidHeapPointer(m_bucket[i]));
|
||||
}
|
||||
# endif
|
||||
|
||||
index = 0;
|
||||
node = m_bucket[index];
|
||||
debugAssert((node == NULL) || isValidHeapPointer(node));
|
||||
isDone = false;
|
||||
findNext();
|
||||
debugAssert((node == NULL) || isValidHeapPointer(node));
|
||||
}
|
||||
|
||||
/**
|
||||
Finds the next element, setting isDone if one can't be found.
|
||||
Looks at the current element first.
|
||||
If node is NULL, then finds the next element by searching through the bucket array.
|
||||
Sets isDone if no more nodes are available.
|
||||
*/
|
||||
void findNext() {
|
||||
while (node == NULL) {
|
||||
index++;
|
||||
++index;
|
||||
if (index >= m_numBuckets) {
|
||||
m_bucket = NULL;
|
||||
index = 0;
|
||||
isDone = true;
|
||||
break;
|
||||
return;
|
||||
} else {
|
||||
node = m_bucket[index];
|
||||
debugAssert((node == NULL) || isValidHeapPointer(node));
|
||||
}
|
||||
}
|
||||
debugAssert(isValidHeapPointer(node));
|
||||
}
|
||||
|
||||
public:
|
||||
@@ -481,12 +492,9 @@ public:
|
||||
bool operator==(const Iterator& other) const {
|
||||
if (other.isDone || isDone) {
|
||||
// Common case; check against isDone.
|
||||
return (isDone == other.isDone) && (other.table == table);
|
||||
return (isDone == other.isDone);
|
||||
} else {
|
||||
return
|
||||
(table == other.table) &&
|
||||
(node == other.node) &&
|
||||
(index == other.index);
|
||||
return (node == other.node) && (index == other.index);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -494,8 +502,13 @@ public:
|
||||
Pre increment.
|
||||
*/
|
||||
Iterator& operator++() {
|
||||
debugAssert(! isDone);
|
||||
debugAssert(node != NULL);
|
||||
debugAssert(isValidHeapPointer(node));
|
||||
debugAssert((node->next == NULL) || isValidHeapPointer(node->next));
|
||||
node = node->next;
|
||||
findNext();
|
||||
debugAssert(isDone || isValidHeapPointer(node));
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -512,17 +525,32 @@ public:
|
||||
return node->entry;
|
||||
}
|
||||
|
||||
const Value& value() const {
|
||||
return node->entry.value;
|
||||
}
|
||||
|
||||
const Key& key() const {
|
||||
return node->entry.key;
|
||||
}
|
||||
|
||||
Entry* operator->() const {
|
||||
debugAssert(isValidHeapPointer(node));
|
||||
return &(node->entry);
|
||||
}
|
||||
|
||||
operator Entry*() const {
|
||||
debugAssert(isValidHeapPointer(node));
|
||||
return &(node->entry);
|
||||
}
|
||||
|
||||
bool hasMore() const {
|
||||
return ! isDone;
|
||||
}
|
||||
bool isValid() const {
|
||||
return ! isDone;
|
||||
}
|
||||
|
||||
/** @deprecated Use isValid */
|
||||
bool hasMore() const {
|
||||
return ! isDone;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -532,7 +560,7 @@ public:
|
||||
the next element. Do not modify the table while iterating.
|
||||
*/
|
||||
Iterator begin() const {
|
||||
return Iterator(this, m_numBuckets, m_bucket);
|
||||
return Iterator(m_numBuckets, m_bucket);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -540,11 +568,12 @@ public:
|
||||
element.
|
||||
*/
|
||||
const Iterator end() const {
|
||||
return Iterator(this);
|
||||
return Iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
Removes all elements
|
||||
Removes all elements. Guaranteed to free all memory associated with
|
||||
the table.
|
||||
*/
|
||||
void clear() {
|
||||
freeMemory();
|
||||
@@ -578,20 +607,21 @@ private:
|
||||
if (m_numBuckets == 0) {
|
||||
return false;
|
||||
}
|
||||
size_t code = HashFunc::hashCode(key);
|
||||
size_t b = code % m_numBuckets;
|
||||
|
||||
const size_t code = HashFunc::hashCode(key);
|
||||
const size_t b = code % m_numBuckets;
|
||||
|
||||
// Go to the m_bucket
|
||||
Node* n = m_bucket[b];
|
||||
// Go to the m_bucket
|
||||
Node* n = m_bucket[b];
|
||||
|
||||
if (n == NULL) {
|
||||
return false;
|
||||
}
|
||||
if (n == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Node* previous = NULL;
|
||||
Node* previous = NULL;
|
||||
|
||||
// Try to find the node
|
||||
do {
|
||||
// Try to find the node
|
||||
do {
|
||||
if ((code == n->hashCode) && EqualsFunc::equals(n->entry.key, key)) {
|
||||
// This is the node; remove it
|
||||
|
||||
@@ -609,6 +639,8 @@ private:
|
||||
// Delete the node
|
||||
Node::destroy(n, m_memoryManager);
|
||||
--m_size;
|
||||
|
||||
//checkIntegrity();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -616,8 +648,8 @@ private:
|
||||
n = n->next;
|
||||
} while (n != NULL);
|
||||
|
||||
//checkIntegrity();
|
||||
return false;
|
||||
//alwaysAssertM(false, "Tried to remove a key that was not in the table.");
|
||||
}
|
||||
|
||||
public:
|
||||
@@ -658,7 +690,7 @@ private:
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
public:
|
||||
@@ -733,7 +765,6 @@ public:
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Called by getCreate() and set()
|
||||
|
||||
\param created Set to true if the entry was created by this method.
|
||||
@@ -756,6 +787,7 @@ public:
|
||||
m_bucket[b] = Node::create(key, code, NULL, m_memoryManager);
|
||||
++m_size;
|
||||
created = true;
|
||||
//checkIntegrity();
|
||||
return m_bucket[b]->entry;
|
||||
}
|
||||
|
||||
@@ -772,6 +804,7 @@ public:
|
||||
|
||||
if ((code == n->hashCode) && EqualsFunc::equals(n->entry.key, key)) {
|
||||
// This is the a pre-existing node
|
||||
//checkIntegrity();
|
||||
return n->entry;
|
||||
}
|
||||
|
||||
@@ -779,12 +812,18 @@ public:
|
||||
++bucketLength;
|
||||
} while (n != NULL);
|
||||
|
||||
// Allow the load factor to rise as the table gets huge
|
||||
const int bucketsPerElement =
|
||||
(m_size > 50000) ? 3 :
|
||||
((m_size > 10000) ? 5 :
|
||||
((m_size > 5000) ? 10 : 15));
|
||||
|
||||
const size_t maxBucketLength = 3;
|
||||
// (Don't bother changing the size of the table if all entries
|
||||
// have the same hashcode--they'll still collide)
|
||||
if ((bucketLength > maxBucketLength) &&
|
||||
! allSameCode &&
|
||||
(m_numBuckets < m_size * 15)) {
|
||||
(m_numBuckets < m_size * bucketsPerElement)) {
|
||||
|
||||
// This m_bucket was really large; rehash if all elements
|
||||
// don't have the same hashcode the number of buckets is
|
||||
@@ -807,8 +846,10 @@ public:
|
||||
m_bucket[b] = Node::create(key, code, m_bucket[b], m_memoryManager);
|
||||
++m_size;
|
||||
created = true;
|
||||
|
||||
//checkIntegrity();
|
||||
return m_bucket[b]->entry;
|
||||
}
|
||||
}
|
||||
|
||||
Entry& getCreateEntry(const Key& key) {
|
||||
bool ignore;
|
||||
@@ -871,7 +912,7 @@ public:
|
||||
|
||||
void getKeys(Array<Key>& keyArray) const {
|
||||
keyArray.resize(0, DONT_SHRINK_UNDERLYING_ARRAY);
|
||||
for (size_t i = 0; i < m_numBuckets; i++) {
|
||||
for (size_t i = 0; i < m_numBuckets; ++i) {
|
||||
Node* node = m_bucket[i];
|
||||
while (node != NULL) {
|
||||
keyArray.append(node->entry.key);
|
||||
@@ -880,14 +921,27 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
/** Will contain duplicate values if they exist in the table. This array is parallel to the one returned by getKeys() if the table has not been modified. */
|
||||
void getValues(Array<Value>& valueArray) const {
|
||||
valueArray.resize(0, DONT_SHRINK_UNDERLYING_ARRAY);
|
||||
for (size_t i = 0; i < m_numBuckets; ++i) {
|
||||
Node* node = m_bucket[i];
|
||||
while (node != NULL) {
|
||||
valueArray.append(node->entry.value);
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Calls delete on all of the keys and then clears the table.
|
||||
*/
|
||||
void deleteKeys() {
|
||||
for (size_t i = 0; i < m_numBuckets; i++) {
|
||||
for (size_t i = 0; i < m_numBuckets; ++i) {
|
||||
Node* node = m_bucket[i];
|
||||
while (node != NULL) {
|
||||
delete node->entry.key;
|
||||
node->entry.key = NULL;
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
@@ -912,6 +966,37 @@ public:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class H, class E>
|
||||
bool operator==(const Table<Key, Value, H, E>& other) const {
|
||||
if (size() != other.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (Iterator it = begin(); it.hasMore(); ++it) {
|
||||
const Value* v = other.getPointer(it->key);
|
||||
if ((v == NULL) || (*v != it->value)) {
|
||||
// Either the key did not exist or the value was not the same
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// this and other have the same number of keys, so we don't
|
||||
// have to check for extra keys in other.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class H, class E>
|
||||
bool operator!=(const Table<Key, Value, H, E>& other) const {
|
||||
return ! (*this == other);
|
||||
}
|
||||
|
||||
void debugPrintStatus() {
|
||||
debugPrintf("Deepest bucket size = %d\n", (int)debugGetDeepestBucketSize());
|
||||
debugPrintf("Average bucket size = %g\n", debugGetAverageBucketSize());
|
||||
debugPrintf("Load factor = %g\n", debugGetLoad());
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
77
deps/g3dlite/include/G3D/TextInput.h
vendored
77
deps/g3dlite/include/G3D/TextInput.h
vendored
@@ -1,16 +1,16 @@
|
||||
/**
|
||||
@file TextInput.h
|
||||
\file G3D/TextInput.h
|
||||
|
||||
Simple text lexer/tokenizer.
|
||||
|
||||
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
\maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
|
||||
@cite Based on a lexer written by Aaron Orenstein.
|
||||
\cite Based on a lexer written by Aaron Orenstein.
|
||||
|
||||
@created 2002-11-27
|
||||
@edited 2010-07-03
|
||||
\created 2002-11-27
|
||||
\edited 2013-03-25
|
||||
|
||||
Copyright 2000-2010, Morgan McGuire.
|
||||
Copyright 2000-2013, Morgan McGuire.
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
@@ -148,7 +148,9 @@ public:
|
||||
|
||||
|
||||
/**
|
||||
A simple style tokenizer for reading text files. TextInput handles a
|
||||
\brief A simple tokenizer for parsing text files.
|
||||
|
||||
TextInput handles a
|
||||
superset of C++,Java, Matlab, and Bash code text including single
|
||||
line comments, block comments, quoted strings with escape sequences,
|
||||
and operators. TextInput recognizes several categories of tokens,
|
||||
@@ -191,7 +193,7 @@ public:
|
||||
|
||||
<B>Examples</B>
|
||||
|
||||
<PRE>
|
||||
\code
|
||||
TextInput ti(TextInput::FROM_STRING, "name = \"Max\", height = 6");
|
||||
|
||||
Token t;
|
||||
@@ -206,15 +208,15 @@ public:
|
||||
|
||||
std::string name = ti.read().sval;
|
||||
ti.read();
|
||||
</PRE>
|
||||
\endcode
|
||||
|
||||
<PRE>
|
||||
\code
|
||||
TextInput ti(TextInput::FROM_STRING, "name = \"Max\", height = 6");
|
||||
ti.readSymbols("name", "=");
|
||||
std::string name = ti.readString();
|
||||
ti.readSymbols(",", "height", "=");
|
||||
double height = ti. readNumber();
|
||||
</PRE>
|
||||
\endcode
|
||||
|
||||
Assumes that the file is not modified once opened.
|
||||
*/
|
||||
@@ -329,14 +331,15 @@ public:
|
||||
int startingLineNumberOffset;
|
||||
|
||||
/**
|
||||
Parse -1.#IND00 as the floating point number returned by
|
||||
nan(), -1.#INF00 as -G3D::inf(), and 1.#INF00 as G3D::inf().
|
||||
|
||||
Parse "-1.#IND00" as the floating point number returned by
|
||||
G3D::nan(), "-1.#INF00" as - G3D::inf(), and "1.#INF00" as G3D::inf().
|
||||
|
||||
Note that the C99 standard specifies that a variety of formats
|
||||
like "nan" are to be used; these are supported by
|
||||
G3D::TextInput::Settings::simpleFloatSpecials.
|
||||
|
||||
An alternative to specifying msvcFloatSpecials is to read numbers as:
|
||||
\htmlonly
|
||||
<pre>
|
||||
Token x = t.read();
|
||||
Token y = t.peek();
|
||||
@@ -349,6 +352,7 @@ public:
|
||||
}
|
||||
// ... similar cases for inf
|
||||
</pre>
|
||||
\endhtmlonly
|
||||
|
||||
If the single-comment character was #, the floating point
|
||||
special format overrides the comment and will be parsed
|
||||
@@ -398,9 +402,12 @@ public:
|
||||
|
||||
Settings();
|
||||
};
|
||||
|
||||
|
||||
private:
|
||||
|
||||
/** \sa pushSettings / popSettings */
|
||||
Array<Settings> settingsStack;
|
||||
|
||||
std::deque<Token> stack;
|
||||
|
||||
/**
|
||||
@@ -477,7 +484,7 @@ private:
|
||||
Read the next token, returning an END token if no more input is
|
||||
available.
|
||||
*/
|
||||
Token nextToken();
|
||||
void nextToken(Token& t);
|
||||
|
||||
/**
|
||||
Helper for nextToken. Appends characters to t._string until the end
|
||||
@@ -488,6 +495,8 @@ private:
|
||||
*/
|
||||
void parseQuotedString(unsigned char delimiter, Token& t);
|
||||
|
||||
void initFromString(const char* str, int len, const Settings& settings);
|
||||
|
||||
public:
|
||||
|
||||
class TokenException : public ParseError {
|
||||
@@ -569,9 +578,25 @@ public:
|
||||
*/
|
||||
TextInput(FS fs, const std::string& str, const Settings& settings = Settings());
|
||||
|
||||
/** Creates input directly from a fixed-length, non-NULL terminated string. The first argument must be
|
||||
TextInput::FROM_STRING.
|
||||
*/
|
||||
TextInput(FS fs, const char* str, size_t strLen, const Settings& settings = Settings());
|
||||
|
||||
/** Returns true while there are tokens remaining. */
|
||||
bool hasMore();
|
||||
|
||||
/** Temporarily switch parsing to use \a settings. Note that this will override the currently recorded sourceFilename unless you explicitly set it back.
|
||||
\sa popSettings */
|
||||
void pushSettings(const Settings& settings) {
|
||||
settingsStack.push(options);
|
||||
options = settings;
|
||||
}
|
||||
|
||||
void popSettings() {
|
||||
options = settingsStack.pop();
|
||||
}
|
||||
|
||||
/** Read the next token (which will be the END token if ! hasMore()).
|
||||
|
||||
Signed numbers can be handled in one of two modes. If the option
|
||||
@@ -589,10 +614,13 @@ public:
|
||||
*/
|
||||
Token read();
|
||||
|
||||
/** Avoids the copy of read() */
|
||||
void read(Token& t);
|
||||
|
||||
/** Calls read() until the result is not a newline or comment */
|
||||
Token readSignificant();
|
||||
|
||||
/** Read one token (or possibly two) as a number or throws
|
||||
/** Read one token (or possibly two, for minus sign) as a number or throws
|
||||
WrongTokenType, and returns the number.
|
||||
|
||||
If the first token in the input is a number, it is returned directly.
|
||||
@@ -608,6 +636,10 @@ public:
|
||||
*/
|
||||
double readNumber();
|
||||
|
||||
/** Reads a number that must be in C integer format:
|
||||
<code> [ '+' | '-' ] #+ | '0x'#+</code> */
|
||||
int readInteger();
|
||||
|
||||
bool readBoolean();
|
||||
|
||||
/** Reads a string token or throws WrongTokenType, and returns the token.
|
||||
@@ -643,7 +675,7 @@ public:
|
||||
input stream is a string but does not match the @p s parameter. When
|
||||
an exception is thrown, no tokens are consumed.
|
||||
|
||||
\sa readString(), readStringToken(), readUntilNewlineAsString()
|
||||
\sa readString(), readStringToken(), readUntilNewlineAsString(), readUntilDelimiterAsString()
|
||||
*/
|
||||
void readString(const std::string& s);
|
||||
|
||||
@@ -653,6 +685,12 @@ public:
|
||||
end of file token (if they are enabled for parsing).*/
|
||||
std::string readUntilNewlineAsString();
|
||||
|
||||
/** Read from the beginning of the next token until the following delimiter character
|
||||
and return the result as a string, ignoring all parsing in between. The delimiter
|
||||
is not returned in the string, and the following token read will begin at the delimiter or
|
||||
end of file token (if they are enabled for parsing).*/
|
||||
std::string readUntilDelimiterAsString(const char delimiter1, const char delimiter2 = '\0');
|
||||
|
||||
/** Reads a comment token or throws WrongTokenType, and returns the token.
|
||||
|
||||
Use this method (rather than readComment) if you want the token's
|
||||
@@ -734,6 +772,9 @@ public:
|
||||
*/
|
||||
Token readSymbolToken();
|
||||
|
||||
/** Avoids the copy of readSymbolToken() */
|
||||
void readSymbolToken(Token& t);
|
||||
|
||||
/** Like readSymbolToken, but returns the token's string.
|
||||
|
||||
Use this method (rather than readSymbolToken) if you want the token's
|
||||
|
||||
29
deps/g3dlite/include/G3D/TextOutput.h
vendored
29
deps/g3dlite/include/G3D/TextOutput.h
vendored
@@ -1,16 +1,16 @@
|
||||
/**
|
||||
@file TextOutput.h
|
||||
\file G3D/TextOutput.h
|
||||
|
||||
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
@created 2004-06-21
|
||||
@edited 2006-10-24
|
||||
\maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
\created 2004-06-21
|
||||
\edited 2011-05-24
|
||||
|
||||
Copyright 2000-2007, Morgan McGuire.
|
||||
Copyright 2000-2012, Morgan McGuire.
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef G3D_TEXTOUTPUT_H
|
||||
#define G3D_TEXTOUTPUT_H
|
||||
#ifndef G3D_TextOutput_h
|
||||
#define G3D_TextOutput_h
|
||||
|
||||
#include "G3D/platform.h"
|
||||
#include "G3D/Array.h"
|
||||
@@ -112,7 +112,7 @@ public:
|
||||
convertNewlines(true),
|
||||
trueSymbol("true"),
|
||||
falseSymbol("false") {
|
||||
#ifdef G3D_WIN32
|
||||
#ifdef G3D_WINDOWS
|
||||
newlineStyle = NEWLINE_WINDOWS;
|
||||
#else
|
||||
newlineStyle = NEWLINE_UNIX;
|
||||
@@ -156,6 +156,9 @@ private:
|
||||
/** the newline character(s) */
|
||||
std::string newline;
|
||||
|
||||
/** Starts at 1 */
|
||||
int m_currentLine;
|
||||
|
||||
void setOptions(const Settings& _opt);
|
||||
|
||||
/** Converts to the desired newlines. Called from vprintf */
|
||||
@@ -175,6 +178,11 @@ public:
|
||||
/** Constructs a text output that can later be commited to a string instead of a file.*/
|
||||
explicit TextOutput(const Settings& options = Settings());
|
||||
|
||||
/** Returns one plus the number of newlines written since the output was created. */
|
||||
int line() const {
|
||||
return m_currentLine;
|
||||
}
|
||||
|
||||
/** Commit to the filename specified on the constructor.
|
||||
<B>Not</B> called from the destructor; you must call
|
||||
it yourself.
|
||||
@@ -206,6 +214,9 @@ public:
|
||||
void writeNewline();
|
||||
void writeNewlines(int numLines);
|
||||
|
||||
/** If the most recently written character was a space, remove it and return true. Can be called repeatedly to back up over multiple spaces. */
|
||||
bool deleteSpace();
|
||||
|
||||
/** The symbol is written without quotes. Symbols are required to begin with a
|
||||
letter or underscore and contain only letters, underscores, and numbers
|
||||
or be a C++ symbol (e.g. "{", "(", "++", etc.)
|
||||
@@ -213,6 +224,8 @@ public:
|
||||
printed with a trailing space.*/
|
||||
void writeSymbol(const std::string& string);
|
||||
|
||||
void writeSymbol(char s);
|
||||
|
||||
/** Convenient idiom for writing multiple symbols in a row, e.g.
|
||||
writeSymbols("name", "="); The empty symbols are not written.
|
||||
*/
|
||||
|
||||
25
deps/g3dlite/include/G3D/ThreadSet.h
vendored
25
deps/g3dlite/include/G3D/ThreadSet.h
vendored
@@ -1,14 +1,16 @@
|
||||
#ifndef G3D_THREADSET_H
|
||||
#define G3D_THREADSET_H
|
||||
#ifndef G3D_ThreadSet_h
|
||||
#define G3D_ThreadSet_h
|
||||
|
||||
#include "G3D/platform.h"
|
||||
#include "G3D/Array.h"
|
||||
#include "G3D/ReferenceCount.h"
|
||||
#include "G3D/GThread.h"
|
||||
#include "G3D/GMutex.h"
|
||||
#include "G3D/SpawnBehavior.h"
|
||||
|
||||
namespace G3D {
|
||||
|
||||
class GThread;
|
||||
|
||||
/** Manages a set of threads. All methods are threadsafe except for
|
||||
the iterator begin/end.
|
||||
|
||||
@@ -18,8 +20,8 @@ public:
|
||||
/** Intended to allow future use with a template parameter.*/
|
||||
typedef GThread Thread;
|
||||
|
||||
typedef ReferenceCountedPointer<Thread> ThreadRef;
|
||||
typedef ReferenceCountedPointer<ThreadSet> Ref;
|
||||
typedef shared_ptr<Thread> ThreadRef;
|
||||
typedef shared_ptr<ThreadSet> Ref;
|
||||
typedef Array<ThreadRef>::Iterator Iterator;
|
||||
typedef Array<ThreadRef>::ConstIterator ConstIterator;
|
||||
|
||||
@@ -41,13 +43,14 @@ public:
|
||||
|
||||
/** Start all threads that are not currently started.
|
||||
|
||||
@param lastThreadBehavior If USE_CURRENT_THREAD, takes the last unstarted thread and executes it manually on
|
||||
the current thread. This helps to take full advantage of the machine when
|
||||
running a large number of jobs and avoids the overhead of a thread start for single-thread groups.
|
||||
Note that this forces start() to block until
|
||||
that thread is complete.
|
||||
@param lastThreadBehavior If USE_CURRENT_THREAD, takes the
|
||||
last unstarted thread and executes it manually on the current
|
||||
thread. This helps to take full advantage of the machine when
|
||||
running a large number of jobs and avoids the overhead of a
|
||||
thread start for single-thread groups. Note that this forces
|
||||
start() to block until that thread is complete.
|
||||
*/
|
||||
void start(GThread::SpawnBehavior lastThreadBehavior = GThread::USE_NEW_THREAD) const;
|
||||
void start(SpawnBehavior lastThreadBehavior = USE_NEW_THREAD) const;
|
||||
|
||||
/** Terminate all threads that are currently started */
|
||||
void terminate() const;
|
||||
|
||||
32
deps/g3dlite/include/G3D/Triangle.h
vendored
32
deps/g3dlite/include/G3D/Triangle.h
vendored
@@ -1,19 +1,19 @@
|
||||
/**
|
||||
@file Triangle.h
|
||||
\file G3D/Triangle.h
|
||||
|
||||
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
\maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
|
||||
@created 2003-04-05
|
||||
@edited 2008-10-06
|
||||
\created 2003-04-05
|
||||
\edited 2011-06-20
|
||||
|
||||
@cite Random point method by Greg Turk, Generating random points in triangles. In A. S. Glassner, ed., Graphics Gems, pp. 24-28. Academic Press, 1990
|
||||
\cite Random point method by Greg Turk, Generating random points in triangles. In A. S. Glassner, ed., Graphics Gems, pp. 24-28. Academic Press, 1990
|
||||
|
||||
Copyright 2000-2009, Morgan McGuire.
|
||||
Copyright 2000-2012, Morgan McGuire.
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef G3D_TRIANGLE_H
|
||||
#define G3D_TRIANGLE_H
|
||||
#ifndef G3D_Triangle_h
|
||||
#define G3D_Triangle_h
|
||||
|
||||
#include "G3D/platform.h"
|
||||
#include "G3D/g3dmath.h"
|
||||
@@ -55,19 +55,19 @@ private:
|
||||
void init(const Vector3& v0, const Vector3& v1, const Vector3& v2);
|
||||
|
||||
public:
|
||||
|
||||
|
||||
Triangle(class BinaryInput& b);
|
||||
void serialize(class BinaryOutput& b);
|
||||
void deserialize(class BinaryInput& b);
|
||||
void serialize(class BinaryOutput& b);
|
||||
void deserialize(class BinaryInput& b);
|
||||
|
||||
Triangle();
|
||||
|
||||
Triangle(const Vector3& v0, const Vector3& v1, const Vector3& v2);
|
||||
Triangle(const Point3& v0, const Point3& v1, const Point3& v2);
|
||||
|
||||
~Triangle();
|
||||
|
||||
/** 0, 1, or 2 */
|
||||
inline const Vector3& vertex(int n) const {
|
||||
inline const Point3& vertex(int n) const {
|
||||
debugAssert((n >= 0) && (n < 3));
|
||||
return _vertex[n];
|
||||
}
|
||||
@@ -91,15 +91,15 @@ public:
|
||||
const Vector3& normal() const;
|
||||
|
||||
/** Barycenter */
|
||||
Vector3 center() const;
|
||||
Point3 center() const;
|
||||
|
||||
const Plane& plane() const;
|
||||
|
||||
/** Returns a random point in the triangle. */
|
||||
Vector3 randomPoint() const;
|
||||
Point3 randomPoint() const;
|
||||
|
||||
inline void getRandomSurfacePoint
|
||||
(Vector3& P,
|
||||
(Point3& P,
|
||||
Vector3& N = Vector3::ignore()) const {
|
||||
P = randomPoint();
|
||||
N = normal();
|
||||
|
||||
68
deps/g3dlite/include/G3D/UprightFrame.h
vendored
68
deps/g3dlite/include/G3D/UprightFrame.h
vendored
@@ -1,25 +1,24 @@
|
||||
/**
|
||||
@file UprightFrame.h
|
||||
|
||||
@author Morgan McGuire, http://graphics.cs.williams.edu
|
||||
\file G3D/UprightFrame.h
|
||||
\author Morgan McGuire, http://graphics.cs.williams.edu
|
||||
*/
|
||||
|
||||
#ifndef G3D_UPRIGHTFRAME_H
|
||||
#define G3D_UPRIGHTFRAME_H
|
||||
#ifndef G3D_UprightFrame_h
|
||||
#define G3D_UprightFrame_h
|
||||
|
||||
#include "G3D/platform.h"
|
||||
#include "G3D/Spline.h"
|
||||
#include "G3D/Vector3.h"
|
||||
#include "G3D/Any.h"
|
||||
#include "G3D/CoordinateFrame.h"
|
||||
|
||||
namespace G3D {
|
||||
|
||||
/**
|
||||
Coordinate frame expressed in Euler angles.
|
||||
Unlike a G3D::Quat, UprightFrame always keeps the reference frame from rolling about its own z axis.
|
||||
Particularly useful for cameras.
|
||||
\brief Coordinate frame expressed in Euler angles.
|
||||
Unlike a G3D::Quat, UprightFrame always keeps the reference frame from rolling about its own z axis.
|
||||
Particularly useful for cameras.
|
||||
|
||||
@sa G3D::CoordinateFrame, G3D::Matrix4, G3D::PhysicsFrame, G3D::UprightSpline, G3D::UprightSplineManipulator
|
||||
\sa G3D::CoordinateFrame, G3D::Matrix4, G3D::PhysicsFrame, G3D::UprightSpline, G3D::UprightSplineManipulator
|
||||
*/
|
||||
class UprightFrame {
|
||||
public:
|
||||
@@ -32,18 +31,32 @@ public:
|
||||
/** In radians about the Y-axis */
|
||||
float yaw;
|
||||
|
||||
inline UprightFrame(const Vector3& t = Vector3::zero(), float p = 0, float y = 0)
|
||||
UprightFrame(const Vector3& t = Vector3::zero(), float p = 0, float y = 0)
|
||||
: translation(t), pitch(p), yaw(y) {}
|
||||
|
||||
UprightFrame(const CoordinateFrame& cframe);
|
||||
|
||||
/** Constructs an UprightFrame from an Any object.
|
||||
|
||||
The Any format for UprightFrame is:
|
||||
|
||||
pitch = ##,
|
||||
translation = Vector3(),
|
||||
yaw = ##
|
||||
*/
|
||||
explicit UprightFrame(const Any& any);
|
||||
|
||||
CoordinateFrame toCoordinateFrame() const;
|
||||
Any toAny() const;
|
||||
|
||||
UprightFrame& operator=(const Any& any);
|
||||
|
||||
/** Supports implicit cast to CoordinateFrame */
|
||||
inline operator CoordinateFrame() const {
|
||||
operator CoordinateFrame() const {
|
||||
return toCoordinateFrame();
|
||||
}
|
||||
|
||||
CoordinateFrame toCoordinateFrame() const;
|
||||
|
||||
/** Required for use with spline */
|
||||
UprightFrame operator+(const UprightFrame& other) const;
|
||||
|
||||
@@ -61,8 +74,10 @@ public:
|
||||
void deserialize(class BinaryInput& b);
|
||||
};
|
||||
|
||||
/** Shortest-path linear velocity spline for camera positions. Always keeps the camera from rolling.
|
||||
@sa G3D::UprightSplineManipulator, G3D::UprightFrame
|
||||
/**
|
||||
\brief Shortest-path linear velocity spline for camera positions. Always keeps the camera from rolling.
|
||||
|
||||
\sa G3D::UprightSplineManipulator, G3D::UprightFrame
|
||||
*/
|
||||
class UprightSpline : public Spline<UprightFrame> {
|
||||
protected:
|
||||
@@ -72,10 +87,29 @@ protected:
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
UprightSpline();
|
||||
|
||||
|
||||
/** Constructs an UprightSpline from an Any object.
|
||||
|
||||
The Any format for UprightSpline is:
|
||||
|
||||
controls = (UprightFrame, ...),
|
||||
times = (##, ...),
|
||||
cyclic = bool
|
||||
|
||||
The controls and times arrays must have the same length.
|
||||
*/
|
||||
explicit UprightSpline(const Any& any);
|
||||
|
||||
virtual Any toAny(const std::string& myName) const override;
|
||||
|
||||
Any toAny() const;
|
||||
|
||||
UprightSpline& operator=(const Any& any);
|
||||
|
||||
void serialize(class BinaryOutput& b) const;
|
||||
void deserialize(class BinaryInput& b);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
96
deps/g3dlite/include/G3D/Vector2.h
vendored
96
deps/g3dlite/include/G3D/Vector2.h
vendored
@@ -1,19 +1,19 @@
|
||||
/**
|
||||
@file Vector2.h
|
||||
\file G3D/Vector2.h
|
||||
|
||||
2D vector class
|
||||
|
||||
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
\maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
|
||||
@created 2001-06-02
|
||||
@edited 2008-11-30
|
||||
\created 2001-06-02
|
||||
\edited 2011-11-30
|
||||
|
||||
Copyright 2000-2009, Morgan McGuire.
|
||||
Copyright 2000-2012, Morgan McGuire.
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef G3D_VECTOR2_H
|
||||
#define G3D_VECTOR2_H
|
||||
#ifndef G3D_Vector2_h
|
||||
#define G3D_Vector2_h
|
||||
|
||||
#include <string>
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "G3D/Table.h"
|
||||
#include "G3D/HashTrait.h"
|
||||
#include "G3D/Vector2int16.h"
|
||||
#include "G3D/Vector2unorm16.h"
|
||||
#include "G3D/Random.h"
|
||||
|
||||
namespace G3D {
|
||||
@@ -29,6 +30,7 @@ namespace G3D {
|
||||
class Vector2;
|
||||
class Vector3;
|
||||
class Vector4;
|
||||
class Vector2int32;
|
||||
class Any;
|
||||
|
||||
/**
|
||||
@@ -51,7 +53,7 @@ public:
|
||||
Vector2(const Any& any);
|
||||
|
||||
/** Converts the Vector2 to an Any. */
|
||||
operator Any() const;
|
||||
Any toAny() const;
|
||||
|
||||
/** Creates the zero vector */
|
||||
Vector2();
|
||||
@@ -62,6 +64,12 @@ public:
|
||||
Vector2(double coordinate[2]);
|
||||
Vector2(const Vector2& other);
|
||||
Vector2(const Vector2int16& other);
|
||||
Vector2(const Vector2unorm16& other);
|
||||
|
||||
// explicit because of precision loss
|
||||
explicit Vector2(const Vector2int32& other);
|
||||
|
||||
Vector2& operator=(const Any& a);
|
||||
|
||||
void serialize(class BinaryOutput& b) const;
|
||||
void deserialize(class BinaryInput& b);
|
||||
@@ -83,6 +91,11 @@ public:
|
||||
/** Returns true if this vector has finite length */
|
||||
bool isFinite() const;
|
||||
|
||||
/** True if any field is NaN */
|
||||
bool isNaN() const {
|
||||
return G3D::isNaN(x) || G3D::isNaN(y);
|
||||
}
|
||||
|
||||
/** Returns true if this vector has length == 0 */
|
||||
bool isZero() const;
|
||||
|
||||
@@ -94,6 +107,11 @@ public:
|
||||
Vector2 operator-(const Vector2& v) const;
|
||||
Vector2 operator*(float s) const;
|
||||
|
||||
/** Raise each component of this vector to a power */
|
||||
Vector2 pow(float p) const {
|
||||
return Vector2(powf(x, p), powf(y, p));
|
||||
}
|
||||
|
||||
/** Array (pointwise) multiplication */
|
||||
Vector2 operator*(const Vector2& v) const;
|
||||
|
||||
@@ -138,12 +156,19 @@ public:
|
||||
|
||||
// vector operations
|
||||
|
||||
/** */
|
||||
/** Magnitude of the vector */
|
||||
float length() const;
|
||||
|
||||
/** Returns a unit-length vector */
|
||||
/**
|
||||
Returns a unit-length version of this vector.
|
||||
Returns nan if length is almost zero.
|
||||
*/
|
||||
Vector2 direction() const;
|
||||
|
||||
/** Returns Vector2::zero() is magnitude is almost zero,
|
||||
otherwise returns unit-length vector. */
|
||||
Vector2 directionOrZero() const;
|
||||
|
||||
/**
|
||||
Potentially less accurate but faster than direction().
|
||||
Only works if System::hasSSE is true.
|
||||
@@ -155,15 +180,35 @@ public:
|
||||
float squaredLength() const;
|
||||
float dot(const Vector2& s) const;
|
||||
|
||||
/**
|
||||
Make this vector have unit length and return the old length.
|
||||
If the vector length was less than tolerance, do not normalize.
|
||||
*/
|
||||
float unitize(float fTolerance = 1e-06);
|
||||
/** Componentwise absolute value */
|
||||
Vector2 abs() const {
|
||||
return Vector2(fabs(x), fabs(y));
|
||||
}
|
||||
|
||||
/** Component-wise minimum */
|
||||
Vector2 min(const Vector2& v) const;
|
||||
|
||||
/** Component-wise maximum */
|
||||
Vector2 max(const Vector2& v) const;
|
||||
|
||||
/** Component-wise argmax(abs(), v.abs()).
|
||||
|
||||
For the larger magnitude vector, simply use <code>(a.squaredMagnitude() > b.squaredMagnitude) ? a : b</code>.
|
||||
\sa max
|
||||
*/
|
||||
Vector2 maxAbs(const Vector2& v) const {
|
||||
return Vector2(::fabsf(x) > ::fabsf(v.x) ? x : v.x, ::fabsf(y) > ::fabsf(v.y) ? y : v.y);
|
||||
}
|
||||
|
||||
/** Component-wise argmin(abs(), v.abs()).
|
||||
|
||||
For the smaller magnitude vector, simply use <code>(a.squaredMagnitude() < b.squaredMagnitude) ? a : b</code>.
|
||||
\sa max
|
||||
*/
|
||||
Vector2 minAbs(const Vector2& v) const {
|
||||
return Vector2(::fabsf(x) < ::fabsf(v.x) ? x : v.x, ::fabsf(y) < ::fabsf(v.y) ? y : v.y);
|
||||
}
|
||||
|
||||
/** Uniformly distributed random vector on the unit sphere */
|
||||
static Vector2 random(Random& r = Random::common());
|
||||
|
||||
@@ -263,7 +308,8 @@ inline Vector2::Vector2 (const Vector2& rkVector) {
|
||||
|
||||
inline Vector2::Vector2 (const Vector2int16& v) : x(v.x), y(v.y) {
|
||||
}
|
||||
|
||||
inline Vector2::Vector2 (const Vector2unorm16& v) : x(float(v.x)), y(float(v.y)) {
|
||||
}
|
||||
|
||||
inline float& Vector2::operator[] (int i) {
|
||||
return ((float*)this)[i];
|
||||
@@ -385,6 +431,16 @@ inline Vector2 Vector2::direction () const {
|
||||
}
|
||||
}
|
||||
|
||||
inline Vector2 Vector2::directionOrZero() const {
|
||||
float mag = length();
|
||||
if (mag < 0.0000001f) {
|
||||
return Vector2::zero();
|
||||
} else if (mag < 1.00001f && mag > 0.99999f) {
|
||||
return *this;
|
||||
} else {
|
||||
return *this * (1.0f / mag);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline float Vector2::dot (const Vector2& rkVector) const {
|
||||
@@ -424,15 +480,19 @@ inline bool Vector2::isFinite() const {
|
||||
|
||||
|
||||
inline bool Vector2::isZero() const {
|
||||
return (x == 0.0f) && (y == 0.0f);
|
||||
return G3D::fuzzyEq(fabsf(x) + fabsf(y), 0.0f);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline bool Vector2::isUnit() const {
|
||||
return squaredLength() == 1.0f;
|
||||
return G3D::fuzzyEq(squaredLength(), 1.0f);
|
||||
}
|
||||
|
||||
typedef Vector2 Point2;
|
||||
void serialize(const Vector2& v, class BinaryOutput& b);
|
||||
void deserialize(Vector2& v, class BinaryInput& b);
|
||||
|
||||
} // namespace G3D
|
||||
|
||||
template <>
|
||||
|
||||
33
deps/g3dlite/include/G3D/Vector2int16.h
vendored
33
deps/g3dlite/include/G3D/Vector2int16.h
vendored
@@ -4,14 +4,14 @@
|
||||
@maintainer Morgan McGuire, matrix@brown.edu
|
||||
|
||||
@created 2003-08-09
|
||||
@edited 2004-01-03
|
||||
@edited 2010-01-03
|
||||
|
||||
Copyright 2000-2006, Morgan McGuire.
|
||||
Copyright 2000-2012, Morgan McGuire.
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef VECTOR2INT16_H
|
||||
#define VECTOR2INT16_H
|
||||
#ifndef Vector2int16_h
|
||||
#define Vector2int16_h
|
||||
|
||||
#include "G3D/platform.h"
|
||||
#include "G3D/g3dmath.h"
|
||||
@@ -19,12 +19,13 @@
|
||||
|
||||
namespace G3D {
|
||||
|
||||
class Any;
|
||||
/**
|
||||
\class Vector2int16
|
||||
A Vector2 that packs its fields into uint16s.
|
||||
A Vector2 that packs its fields into G3D::int16 s.
|
||||
*/
|
||||
G3D_BEGIN_PACKED_CLASS(2)
|
||||
class Vector2int16 {
|
||||
Vector2int16 {
|
||||
private:
|
||||
// Hidden operators
|
||||
bool operator<(const Vector2int16&) const;
|
||||
@@ -38,8 +39,14 @@ public:
|
||||
|
||||
Vector2int16() : x(0), y(0) {}
|
||||
Vector2int16(G3D::int16 _x, G3D::int16 _y) : x(_x), y(_y){}
|
||||
Vector2int16(const class Vector2& v);
|
||||
Vector2int16(class BinaryInput& bi);
|
||||
explicit Vector2int16(const class Vector2& v);
|
||||
explicit Vector2int16(class BinaryInput& bi);
|
||||
explicit Vector2int16(const class Any& a);
|
||||
explicit Vector2int16(const class Vector2int32& v);
|
||||
|
||||
Any toAny() const;
|
||||
|
||||
Vector2int16& operator=(const Any& a);
|
||||
|
||||
inline G3D::int16& operator[] (int i) {
|
||||
debugAssert(((unsigned int)i) <= 1);
|
||||
@@ -63,6 +70,10 @@ public:
|
||||
return Vector2int16(x * other.x, y * other.y);
|
||||
}
|
||||
|
||||
Vector2int16 operator-() const {
|
||||
return Vector2int16(-x, -y);
|
||||
}
|
||||
|
||||
inline Vector2int16 operator*(const int s) const {
|
||||
return Vector2int16(x * s, y * s);
|
||||
}
|
||||
@@ -73,6 +84,10 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool isZero() const {
|
||||
return (x == 0) && (y == 0);
|
||||
}
|
||||
|
||||
/** Shifts both x and y */
|
||||
inline Vector2int16 operator>>(const int s) const {
|
||||
return Vector2int16(x >> s, y >> s);
|
||||
@@ -118,6 +133,8 @@ public:
|
||||
}
|
||||
G3D_END_PACKED_CLASS(2)
|
||||
|
||||
typedef Vector2int16 Point2int16;
|
||||
|
||||
}
|
||||
|
||||
template<> struct HashTrait<G3D::Vector2int16> {
|
||||
|
||||
134
deps/g3dlite/include/G3D/Vector2int32.h
vendored
Normal file
134
deps/g3dlite/include/G3D/Vector2int32.h
vendored
Normal file
@@ -0,0 +1,134 @@
|
||||
/**
|
||||
@file G3D/Vector2int32.h
|
||||
|
||||
@maintainer Morgan McGuire, matrix@brown.edu
|
||||
|
||||
@created 2003-08-09
|
||||
@edited 2010-09-03
|
||||
|
||||
Copyright 2000-2012, Morgan McGuire.
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef G3D_Vector2int32_h
|
||||
#define G3D_Vector2int32_h
|
||||
|
||||
#include "G3D/platform.h"
|
||||
#include "G3D/g3dmath.h"
|
||||
#include "G3D/HashTrait.h"
|
||||
|
||||
namespace G3D {
|
||||
|
||||
/**
|
||||
\class Vector2int32
|
||||
A Vector2 that packs its fields into int32s.
|
||||
*/
|
||||
G3D_BEGIN_PACKED_CLASS(2)
|
||||
Vector2int32 {
|
||||
private:
|
||||
// Hidden operators
|
||||
bool operator<(const Vector2int32&) const;
|
||||
bool operator>(const Vector2int32&) const;
|
||||
bool operator<=(const Vector2int32&) const;
|
||||
bool operator>=(const Vector2int32&) const;
|
||||
|
||||
public:
|
||||
G3D::int32 x;
|
||||
G3D::int32 y;
|
||||
|
||||
Vector2int32() : x(0), y(0) {}
|
||||
Vector2int32(G3D::int32 _x, G3D::int32 _y) : x(_x), y(_y){}
|
||||
explicit Vector2int32(const class Vector2& v);
|
||||
explicit Vector2int32(class BinaryInput& bi);
|
||||
Vector2int32(const class Vector2int16& v);
|
||||
|
||||
inline G3D::int32& operator[] (int i) {
|
||||
debugAssert(((unsigned int)i) <= 1);
|
||||
return ((G3D::int32*)this)[i];
|
||||
}
|
||||
|
||||
inline const G3D::int32& operator[] (int i) const {
|
||||
debugAssert(((unsigned int)i) <= 1);
|
||||
return ((G3D::int32*)this)[i];
|
||||
}
|
||||
|
||||
inline Vector2int32 operator+(const Vector2int32& other) const {
|
||||
return Vector2int32(x + other.x, y + other.y);
|
||||
}
|
||||
|
||||
inline Vector2int32 operator-(const Vector2int32& other) const {
|
||||
return Vector2int32(x - other.x, y - other.y);
|
||||
}
|
||||
|
||||
inline Vector2int32 operator-() const {
|
||||
return Vector2int32(-x, -y);
|
||||
}
|
||||
|
||||
inline Vector2int32 operator*(const Vector2int32& other) const {
|
||||
return Vector2int32(x * other.x, y * other.y);
|
||||
}
|
||||
|
||||
inline Vector2int32 operator*(const int s) const {
|
||||
return Vector2int32(x * s, y * s);
|
||||
}
|
||||
|
||||
inline Vector2int32& operator+=(const Vector2int32& other) {
|
||||
x += other.x;
|
||||
y += other.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** Shifts both x and y */
|
||||
inline Vector2int32 operator>>(const int s) const {
|
||||
return Vector2int32(x >> s, y >> s);
|
||||
}
|
||||
|
||||
/** Shifts both x and y */
|
||||
inline Vector2int32 operator<<(const int s) const {
|
||||
return Vector2int32(x << s, y << s);
|
||||
}
|
||||
|
||||
inline Vector2int32& operator-=(const Vector2int32& other) {
|
||||
x -= other.x;
|
||||
y -= other.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Vector2int32& operator*=(const Vector2int32& other) {
|
||||
x *= other.x;
|
||||
y *= other.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vector2int32 clamp(const Vector2int32& lo, const Vector2int32& hi);
|
||||
|
||||
inline bool operator==(const Vector2int32& other) const {
|
||||
return (x == other.x) && (y == other.y);
|
||||
}
|
||||
|
||||
inline bool operator!= (const Vector2int32& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
Vector2int32 max(const Vector2int32& v) const {
|
||||
return Vector2int32(iMax(x, v.x), iMax(y, v.y));
|
||||
}
|
||||
|
||||
Vector2int32 min(const Vector2int32& v) const {
|
||||
return Vector2int32(iMin(x, v.x), iMin(y, v.y));
|
||||
}
|
||||
|
||||
void serialize(class BinaryOutput& bo) const;
|
||||
void deserialize(class BinaryInput& bi);
|
||||
}
|
||||
G3D_END_PACKED_CLASS(2)
|
||||
|
||||
typedef Vector2int32 Point2int32;
|
||||
|
||||
} // namespace G3D
|
||||
|
||||
template<> struct HashTrait<G3D::Vector2int32> {
|
||||
static size_t hashCode(const G3D::Vector2int32& key) { return static_cast<size_t>(key.x ^ ((int)key.y << 1)); }
|
||||
};
|
||||
|
||||
#endif
|
||||
91
deps/g3dlite/include/G3D/Vector2unorm16.h
vendored
Normal file
91
deps/g3dlite/include/G3D/Vector2unorm16.h
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
/**
|
||||
\file G3D/Vector2unorm16.h
|
||||
|
||||
\maintainer Morgan McGuire, morgan@cs.williams.edu
|
||||
|
||||
\created 2003-03-13
|
||||
\edited 2012-03-13
|
||||
|
||||
Copyright 2000-2012, Morgan McGuire.
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef Vector2unorm16_h
|
||||
#define Vector2unorm16_h
|
||||
|
||||
#include "G3D/platform.h"
|
||||
#include "G3D/g3dmath.h"
|
||||
#include "G3D/HashTrait.h"
|
||||
#include "G3D/unorm16.h"
|
||||
|
||||
namespace G3D {
|
||||
|
||||
class Any;
|
||||
/**
|
||||
\class Vector2unorm16
|
||||
|
||||
A Vector2 that packs its fields into G3D::unorm16%s. This is mostly
|
||||
useful for texture coordinates that are on the range [0, 1].
|
||||
|
||||
\sa Vector2int16
|
||||
*/
|
||||
G3D_BEGIN_PACKED_CLASS(2)
|
||||
Vector2unorm16 {
|
||||
private:
|
||||
// Hidden operators
|
||||
bool operator<(const Vector2unorm16&) const;
|
||||
bool operator>(const Vector2unorm16&) const;
|
||||
bool operator<=(const Vector2unorm16&) const;
|
||||
bool operator>=(const Vector2unorm16&) const;
|
||||
|
||||
public:
|
||||
G3D::unorm16 x;
|
||||
G3D::unorm16 y;
|
||||
|
||||
Vector2unorm16() {}
|
||||
Vector2unorm16(G3D::unorm16 _x, G3D::unorm16 _y) : x(_x), y(_y){}
|
||||
Vector2unorm16(float _x, float _y) : x(_x), y(_y){}
|
||||
explicit Vector2unorm16(const class Vector2& v);
|
||||
explicit Vector2unorm16(class BinaryInput& bi);
|
||||
explicit Vector2unorm16(const class Any& a);
|
||||
|
||||
Any toAny() const;
|
||||
|
||||
Vector2unorm16& operator=(const Any& a);
|
||||
|
||||
inline G3D::unorm16& operator[] (int i) {
|
||||
debugAssert(((unsigned int)i) <= 1);
|
||||
return ((G3D::unorm16*)this)[i];
|
||||
}
|
||||
|
||||
inline const G3D::unorm16& operator[] (int i) const {
|
||||
debugAssert(((unsigned int)i) <= 1);
|
||||
return ((G3D::unorm16*)this)[i];
|
||||
}
|
||||
|
||||
inline bool operator== (const Vector2unorm16& rkVector) const {
|
||||
return ((int32*)this)[0] == ((int32*)&rkVector)[0];
|
||||
}
|
||||
|
||||
inline bool operator!= (const Vector2unorm16& rkVector) const {
|
||||
return ((int32*)this)[0] != ((int32*)&rkVector)[0];
|
||||
}
|
||||
|
||||
void serialize(class BinaryOutput& bo) const;
|
||||
void deserialize(class BinaryInput& bi);
|
||||
size_t hashCode() const {
|
||||
return static_cast<size_t>(x.bits() + ((int)y.bits() << 16));
|
||||
}
|
||||
|
||||
}
|
||||
G3D_END_PACKED_CLASS(2)
|
||||
|
||||
typedef Vector2unorm16 Point2unorm16;
|
||||
|
||||
}
|
||||
|
||||
template<> struct HashTrait<G3D::Vector2unorm16> {
|
||||
static size_t hashCode(const G3D::Vector2unorm16& key) { return key.hashCode(); }
|
||||
};
|
||||
|
||||
#endif
|
||||
156
deps/g3dlite/include/G3D/Vector3.h
vendored
156
deps/g3dlite/include/G3D/Vector3.h
vendored
@@ -1,13 +1,14 @@
|
||||
/**
|
||||
@file Vector3.h
|
||||
|
||||
\file Vector3.h
|
||||
|
||||
3D vector class
|
||||
|
||||
\maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
|
||||
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
\created 2001-06-02
|
||||
\edited 2010-12-25
|
||||
|
||||
@created 2001-06-02
|
||||
@edited 2009-11-01
|
||||
Copyright 2000-2009, Morgan McGuire.
|
||||
Copyright 2000-2012, Morgan McGuire.
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
@@ -36,7 +37,7 @@ class Any;
|
||||
/**
|
||||
<B>Swizzles</B>
|
||||
Vector classes have swizzle operators, e.g. <CODE>v.xy()</CODE>, that
|
||||
allow selection of arbitrary sub-fields. These cannot be used as write
|
||||
allow selection of arbitrary sub-fields. These cannot be used as write
|
||||
masks. Examples
|
||||
|
||||
<PRE>
|
||||
@@ -72,29 +73,37 @@ public:
|
||||
/** Initializes to zero */
|
||||
Vector3();
|
||||
|
||||
/** \param any Must either Vector3(#, #, #) or Vector3 {x = #, y = #, z = #}*/
|
||||
Vector3(const Any& any);
|
||||
/**
|
||||
\param any Must either Vector3(#, #, #) or Vector3 {x = #, y = #, z = #}.
|
||||
Because Point3 is a typedef for Vector3 in the current implementation,
|
||||
this constructor accepts Point3(#, #, #), etc. as well.
|
||||
|
||||
*/
|
||||
explicit Vector3(const Any& any);
|
||||
|
||||
/** Converts the Vector3 to an Any, using the specified \a name instead of "Vector3" */
|
||||
Any toAny(const std::string& name) const;
|
||||
|
||||
/** Converts the Vector3 to an Any. */
|
||||
operator Any() const;
|
||||
Any toAny() const;
|
||||
|
||||
/** Divides by 127 */
|
||||
Vector3(const Vector4int8&);
|
||||
Vector3(const class Vector2& v, float z);
|
||||
Vector3(const class Vector3int32& v);
|
||||
explicit Vector3(class BinaryInput& b);
|
||||
Vector3(float _x, float _y, float _z);
|
||||
explicit Vector3(const class Vector2& v, float _z);
|
||||
explicit Vector3(float coordinate[3]);
|
||||
explicit Vector3(double coordinate[3]);
|
||||
Vector3(const class Vector3int16& v);
|
||||
explicit Vector3(class TextInput& t);
|
||||
explicit Vector3(class TextInput& t);
|
||||
explicit Vector3(const class Color3& c);
|
||||
|
||||
/** Format is three float32's */
|
||||
/** Format is three float32's */
|
||||
void serialize(class BinaryOutput& b) const;
|
||||
void deserialize(class BinaryInput& b);
|
||||
|
||||
/** Format is "(%f, %f, %f)" */
|
||||
/** Format is "(%f, %f, %f)" */
|
||||
void serialize(class TextOutput& t) const;
|
||||
void deserialize(class TextInput& t);
|
||||
|
||||
@@ -106,6 +115,10 @@ public:
|
||||
const float& __fastcall operator[] (int i) const;
|
||||
float& operator[] (int i);
|
||||
|
||||
bool nonZero() const {
|
||||
return (x != 0) || (y != 0) || (z != 0);
|
||||
}
|
||||
|
||||
enum Axis {X_AXIS=0, Y_AXIS=1, Z_AXIS=2, DETECT_AXIS=-1};
|
||||
|
||||
/**
|
||||
@@ -115,12 +128,8 @@ public:
|
||||
Axis primaryAxis() const;
|
||||
|
||||
// assignment and comparison
|
||||
Vector3& __fastcall operator= (const Vector3& rkVector);
|
||||
/* requried as of C++ 11 */
|
||||
#if __cplusplus >= 201103L
|
||||
Vector3(const Vector3&) = default;
|
||||
Vector3(Vector3&&) = default;
|
||||
#endif
|
||||
Vector3& operator=(const Vector3& rkVector) = default;
|
||||
Vector3& operator=(const Any& a);
|
||||
bool operator== (const Vector3& rkVector) const;
|
||||
bool operator!= (const Vector3& rkVector) const;
|
||||
size_t hashCode() const;
|
||||
@@ -130,12 +139,19 @@ public:
|
||||
/** Returns true if this vector has finite length. */
|
||||
bool isFinite() const;
|
||||
|
||||
/** True if any field is nan */
|
||||
bool isNaN() const;
|
||||
|
||||
/** Returns true if this vector has length ~= 0 */
|
||||
bool isZero() const;
|
||||
|
||||
/** Returns true if this vector has length ~= 1 */
|
||||
bool isUnit() const;
|
||||
|
||||
/** Returns a vector that is \a this translated towards \a goal with a maximum translation of \a maxTranslation. */
|
||||
Vector3 movedTowards(const Vector3& goal, float maxTranslation) const;
|
||||
void moveTowards(const Vector3& goal, float maxTranslation);
|
||||
|
||||
// arithmetic operations
|
||||
Vector3 __fastcall operator+ (const Vector3& v) const;
|
||||
Vector3 __fastcall operator- (const Vector3& v) const;
|
||||
@@ -158,12 +174,18 @@ public:
|
||||
Vector3& __fastcall operator/= (const Vector3& v);
|
||||
|
||||
/** Same as magnitude */
|
||||
float length() const;
|
||||
float length() const;
|
||||
|
||||
float magnitude() const;
|
||||
|
||||
/** Raise each component of this vector to a power */
|
||||
Vector3 pow(float p) const {
|
||||
return Vector3(powf(x, p), powf(y, p), powf(z, p));
|
||||
}
|
||||
|
||||
/**
|
||||
The result is a nan vector if the length is almost zero.
|
||||
Returns a unit-length version of this vector.
|
||||
Returns nan if length is almost zero.
|
||||
*/
|
||||
Vector3 direction() const;
|
||||
|
||||
@@ -184,7 +206,7 @@ public:
|
||||
|
||||
<PRE>
|
||||
V' N V
|
||||
|
||||
|
||||
r ^ -,
|
||||
\ | /
|
||||
\|/
|
||||
@@ -196,17 +218,17 @@ public:
|
||||
|
||||
/**
|
||||
See also G3D::Ray::reflect.
|
||||
The length is 1.
|
||||
The length is 1.
|
||||
<PRE>
|
||||
V' N V
|
||||
|
||||
|
||||
r ^ /
|
||||
\ | /
|
||||
\|'-
|
||||
</PRE>
|
||||
*/
|
||||
Vector3 reflectionDirection(const Vector3& normal) const;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Returns Vector3::zero() if the length is nearly zero, otherwise
|
||||
@@ -228,7 +250,7 @@ public:
|
||||
where iExit is the index of refraction for the
|
||||
previous material and iEnter is the index of refraction
|
||||
for the new material. Like Vector3::reflectionDirection,
|
||||
the result has length 1 and is
|
||||
the result has length 1 and is
|
||||
pointed <I>away</I> from the intersection.
|
||||
|
||||
Returns Vector3::zero() in the case of total internal refraction.
|
||||
@@ -242,7 +264,7 @@ public:
|
||||
See also G3D::Ray::refract.
|
||||
<PRE>
|
||||
N V
|
||||
|
||||
|
||||
^ /
|
||||
| /
|
||||
|'-
|
||||
@@ -270,11 +292,9 @@ public:
|
||||
float squaredLength() const;
|
||||
|
||||
float squaredMagnitude () const;
|
||||
|
||||
|
||||
float __fastcall dot(const Vector3& rkVector) const;
|
||||
|
||||
float unitize(float tolerance = 1e-06);
|
||||
|
||||
|
||||
/** Cross product. Note that two cross products in a row
|
||||
can be computed more cheaply: v1 x (v2 x v3) = (v1 dot v3) v2 - (v1 dot v2) v3.
|
||||
*/
|
||||
@@ -320,18 +340,29 @@ public:
|
||||
G3D::clamp(z, low, high));
|
||||
}
|
||||
|
||||
|
||||
inline Vector3 floor() const {
|
||||
return G3D::Vector3(::floor(x), ::floor(y), ::floor(z));
|
||||
}
|
||||
|
||||
|
||||
inline Vector3 round() const {
|
||||
return Vector3(G3D::round(x), G3D::round(y), G3D::round(z));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Linear interpolation
|
||||
*/
|
||||
inline Vector3 lerp(const Vector3& v, float alpha) const {
|
||||
return (*this) + (v - *this) * alpha;
|
||||
return (*this) + (v - *this) * alpha;
|
||||
}
|
||||
|
||||
/** Gram-Schmidt orthonormalization. */
|
||||
static void orthonormalize (Vector3 akVector[3]);
|
||||
|
||||
/** \brief Random unit vector, uniformly distributed on the sphere.
|
||||
|
||||
/** \brief Random unit vector, uniformly distributed on the sphere.
|
||||
|
||||
Distribution rendered by G3D::DirectionHistogram:
|
||||
\image html vector3-random.png
|
||||
*/
|
||||
@@ -339,8 +370,8 @@ public:
|
||||
|
||||
/** \brief Random unit vector, distributed according to \f$\max(\cos \theta,0)\f$.
|
||||
|
||||
That is, so that the probability of \f$\vec{V}\f$ is proportional
|
||||
to \f$\max(\vec{v} \cdot \vec{n}, 0)\f$. Useful in photon mapping for
|
||||
That is, so that the probability of \f$\vec{V}\f$ is proportional
|
||||
to \f$\max(\vec{v} \cdot \vec{n}, 0)\f$. Useful in photon mapping for
|
||||
Lambertian scattering.
|
||||
|
||||
Distribution rendered by G3D::DirectionHistogram:
|
||||
@@ -352,6 +383,8 @@ public:
|
||||
*/
|
||||
static Vector3 cosHemiRandom(const Vector3& n, Random& r = Random::common());
|
||||
|
||||
static Vector3 cosSphereRandom(const Vector3& n, Random& r = Random::common());
|
||||
|
||||
/** \brief Random unit vector, distributed according to \f$\max(\cos^k \theta,0)\f$.
|
||||
|
||||
That is, so that the probability of \f$\vec{V}\f$ is
|
||||
@@ -375,14 +408,6 @@ public:
|
||||
*/
|
||||
static Vector3 hemiRandom(const Vector3& normal, Random& r = Random::common());
|
||||
|
||||
/** Input W must be initialize to a nonzero vector, output is {U,V,W}
|
||||
an orthonormal basis. A hint is provided about whether or not W
|
||||
is already unit length.
|
||||
@deprecated Use getTangents
|
||||
*/
|
||||
static void generateOrthonormalBasis (Vector3& rkU, Vector3& rkV,
|
||||
Vector3& rkW, bool bUnitLengthW = true);
|
||||
|
||||
inline float sum() const {
|
||||
return x + y + z;
|
||||
}
|
||||
@@ -399,7 +424,7 @@ public:
|
||||
static const Vector3& unitZ();
|
||||
static const Vector3& inf();
|
||||
static const Vector3& nan();
|
||||
|
||||
|
||||
/** Smallest (most negative) representable vector */
|
||||
static const Vector3& minFinite();
|
||||
|
||||
@@ -410,16 +435,16 @@ public:
|
||||
/** Creates two orthonormal tangent vectors X and Y such that
|
||||
if Z = this, X x Y = Z.*/
|
||||
inline void getTangents(Vector3& X, Vector3& Y) const {
|
||||
debugAssertM(G3D::fuzzyEq(length(), 1.0f),
|
||||
debugAssertM(G3D::fuzzyEq(length(), 1.0f),
|
||||
"makeAxes requires Z to have unit length");
|
||||
|
||||
|
||||
// Choose another vector not perpendicular
|
||||
X = (abs(x) < 0.9f) ? Vector3::unitX() : Vector3::unitY();
|
||||
|
||||
|
||||
// Remove the part that is parallel to Z
|
||||
X -= *this * this->dot(X);
|
||||
X /= X.length();
|
||||
|
||||
|
||||
Y = this->cross(X);
|
||||
}
|
||||
|
||||
@@ -554,6 +579,8 @@ public:
|
||||
static Vector3& ignore();
|
||||
};
|
||||
|
||||
|
||||
|
||||
inline G3D::Vector3 operator*(float s, const G3D::Vector3& v) {
|
||||
return v * s;
|
||||
}
|
||||
@@ -600,14 +627,6 @@ inline float& Vector3::operator[] (int 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 {
|
||||
@@ -755,8 +774,7 @@ inline Vector3 Vector3::cross (const Vector3& rkVector) const {
|
||||
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;
|
||||
return kCross.direction();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -771,7 +789,7 @@ inline Vector3 Vector3::max(const Vector3 &v) const {
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
inline bool Vector3::isZero() const {
|
||||
return G3D::fuzzyEq(squaredMagnitude(), 0.0f);
|
||||
return G3D::fuzzyEq(fabsf(x) + fabsf(y) + fabsf(z), 0.0f);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -780,6 +798,22 @@ inline bool Vector3::isUnit() const {
|
||||
return G3D::fuzzyEq(squaredMagnitude(), 1.0f);
|
||||
}
|
||||
|
||||
/**
|
||||
Points are technically distinct mathematical entities from vectors.
|
||||
Actually distinguishing them at the class level tends to add lots of
|
||||
boilerplate (e.g., (P - Point3::zero()).direction()
|
||||
vs. P.direction()), so many programmers prefer use a single class,
|
||||
as GLSL does.
|
||||
|
||||
G3D provides this typedef as a way of documenting arguments that are
|
||||
locations in space and not directions. Beware that points and
|
||||
vectors are interchangable from the compiler's point of view, and
|
||||
that the programmer must track which is really which. */
|
||||
typedef Vector3 Point3;
|
||||
|
||||
void serialize(const Vector3& v, class BinaryOutput& b);
|
||||
void deserialize(Vector3& v, class BinaryInput& b);
|
||||
|
||||
} // namespace G3D
|
||||
|
||||
|
||||
|
||||
67
deps/g3dlite/include/G3D/Vector3int16.h
vendored
67
deps/g3dlite/include/G3D/Vector3int16.h
vendored
@@ -1,16 +1,17 @@
|
||||
/**
|
||||
@file Vector3int16.h
|
||||
\file G3D/Vector3int16.h
|
||||
|
||||
@maintainer Morgan McGuire, matrix@brown.edu
|
||||
\maintainer Morgan McGuire, matrix@brown.edu
|
||||
|
||||
@created 2003-04-07
|
||||
@edited 2003-06-24
|
||||
Copyright 2000-2004, Morgan McGuire.
|
||||
\created 2003-04-07
|
||||
\edited 2011-06-24
|
||||
|
||||
Copyright 2000-2012, Morgan McGuire.
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef VECTOR3INT16_H
|
||||
#define VECTOR3INT16_H
|
||||
#ifndef G3D_Vector3int16_h
|
||||
#define G3D_Vector3int16_h
|
||||
|
||||
#include "G3D/platform.h"
|
||||
#include "G3D/g3dmath.h"
|
||||
@@ -19,6 +20,7 @@
|
||||
#ifdef _MSC_VER
|
||||
// Turn off "conditional expression is constant" warning; MSVC generates this
|
||||
// for debug assertions in inlined methods.
|
||||
#pragma warning (push)
|
||||
#pragma warning (disable : 4127)
|
||||
#endif
|
||||
|
||||
@@ -30,7 +32,7 @@ namespace G3D {
|
||||
A Vector3 that packs its fields into uint16s.
|
||||
*/
|
||||
G3D_BEGIN_PACKED_CLASS(2)
|
||||
class Vector3int16 {
|
||||
Vector3int16 {
|
||||
private:
|
||||
// Hidden operators
|
||||
bool operator<(const Vector3int16&) const;
|
||||
@@ -45,8 +47,8 @@ public:
|
||||
|
||||
Vector3int16() : x(0), y(0), z(0) {}
|
||||
Vector3int16(G3D::int16 _x, G3D::int16 _y, G3D::int16 _z) : x(_x), y(_y), z(_z) {}
|
||||
Vector3int16(const class Vector3& v);
|
||||
Vector3int16(class BinaryInput& bi);
|
||||
explicit Vector3int16(const class Vector3& v);
|
||||
explicit Vector3int16(class BinaryInput& bi);
|
||||
|
||||
void serialize(class BinaryOutput& bo) const;
|
||||
void deserialize(class BinaryInput& bi);
|
||||
@@ -98,6 +100,9 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
static Vector3int16 floor(const Vector3& v);
|
||||
static Vector3int16 ceil(const Vector3& v);
|
||||
|
||||
inline bool operator== (const Vector3int16& rkVector) const {
|
||||
return ( x == rkVector.x && y == rkVector.y && z == rkVector.z );
|
||||
}
|
||||
@@ -106,6 +111,10 @@ public:
|
||||
return ( x != rkVector.x || y != rkVector.y || z != rkVector.z );
|
||||
}
|
||||
|
||||
int dot(const Vector3int16& v) const {
|
||||
return x * v.x + y * v.y + z * v.z;
|
||||
}
|
||||
|
||||
Vector3int16 max(const Vector3int16& v) const {
|
||||
return Vector3int16(std::max(x, v.x), std::max(y, v.y), std::max(z, v.z));
|
||||
}
|
||||
@@ -115,13 +124,49 @@ public:
|
||||
}
|
||||
|
||||
std::string toString() const;
|
||||
|
||||
|
||||
Vector3int16 operator-() const {
|
||||
return Vector3int16(-x, -y, -z);
|
||||
}
|
||||
|
||||
Vector3int16 operator<<(int i) const {
|
||||
return Vector3int16(x << i, y << i, z << i);
|
||||
}
|
||||
|
||||
Vector3int16 operator>>(int i) const {
|
||||
return Vector3int16(x >> i, y >> i, z >> i);
|
||||
}
|
||||
|
||||
Vector3int16 operator>>(const Vector3int16& v) const {
|
||||
return Vector3int16(x >> v.x, y >> v.y, z >> v.z);
|
||||
}
|
||||
|
||||
Vector3int16 operator<<(const Vector3int16& v) const {
|
||||
return Vector3int16(x << v.x, y << v.y, z << v.z);
|
||||
}
|
||||
|
||||
Vector3int16 operator&(int16 i) const {
|
||||
return Vector3int16(x & i, y & i, z & i);
|
||||
}
|
||||
|
||||
Vector3int16 operator&(const Vector3int16& v) const {
|
||||
return Vector3int16(x & v.x, y & v.y, z & v.z);
|
||||
}
|
||||
}
|
||||
G3D_END_PACKED_CLASS(2)
|
||||
|
||||
}
|
||||
typedef Vector3int16 Point3int16;
|
||||
|
||||
} // namespace G3D
|
||||
|
||||
template <> struct HashTrait<G3D::Vector3int16> {
|
||||
static size_t hashCode(const G3D::Vector3int16& key) { return static_cast<size_t>(key.x + ((int)key.y << 5) + ((int)key.z << 10)); }
|
||||
};
|
||||
|
||||
|
||||
#ifdef G3D_WINDOWS
|
||||
#pragma warning( pop )
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
97
deps/g3dlite/include/G3D/Vector3int32.h
vendored
97
deps/g3dlite/include/G3D/Vector3int32.h
vendored
@@ -1,29 +1,32 @@
|
||||
/**
|
||||
@file Vector3int32.h
|
||||
@file G3D/Vector3int32.h
|
||||
|
||||
@maintainer Morgan McGuire, matrix@brown.edu
|
||||
|
||||
@created 2008-07-01
|
||||
@edited 2008-07-01
|
||||
Copyright 2000-2009, Morgan McGuire.
|
||||
@edited 2011-01-01
|
||||
Copyright 2000-2012, Morgan McGuire.
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef VECTOR3INT32_H
|
||||
#define VECTOR3INT32_H
|
||||
#ifndef G3D_Vector3int32_h
|
||||
#define G3D_Vector3int32_h
|
||||
|
||||
#include "G3D/platform.h"
|
||||
#include "G3D/g3dmath.h"
|
||||
#include "G3D/HashTrait.h"
|
||||
#include "G3D/Crypto.h"
|
||||
|
||||
namespace G3D {
|
||||
|
||||
class Any;
|
||||
|
||||
/**
|
||||
\ Vector3int32
|
||||
A Vector3 that packs its fields into uint32s.
|
||||
*/
|
||||
G3D_BEGIN_PACKED_CLASS(4)
|
||||
class Vector3int32 {
|
||||
Vector3int32 {
|
||||
private:
|
||||
// Hidden operators
|
||||
bool operator<(const Vector3int32&) const;
|
||||
@@ -38,9 +41,21 @@ public:
|
||||
|
||||
Vector3int32() : x(0), y(0), z(0) {}
|
||||
Vector3int32(int _x, int _y, int _z) : x(_x), y(_y), z(_z) {}
|
||||
Vector3int32(const class Vector2int32& v, int _z);
|
||||
Vector3int32(const class Vector2int16& v, int _z);
|
||||
Vector3int32(const class Vector3int16& v);
|
||||
Vector3int32(const class Vector3& v);
|
||||
Vector3int32(class BinaryInput& bi);
|
||||
Vector3int32(const Any& any);
|
||||
Any toAny() const;
|
||||
|
||||
/** Rounds to the nearest int */
|
||||
explicit Vector3int32(const class Vector3& v);
|
||||
explicit Vector3int32(class BinaryInput& bi);
|
||||
|
||||
static Vector3int32 truncate(const class Vector3& v);
|
||||
|
||||
bool nonZero() const {
|
||||
return (x != 0) || (y != 0) || (z != 0);
|
||||
}
|
||||
|
||||
void serialize(class BinaryOutput& bo) const;
|
||||
void deserialize(class BinaryInput& bi);
|
||||
@@ -71,32 +86,42 @@ public:
|
||||
return Vector3int32(x * s, y * s, z * s);
|
||||
}
|
||||
|
||||
inline Vector3int32& operator+=(const Vector3int32& other) {
|
||||
/** Integer division */
|
||||
inline Vector3int32 operator/(const Vector3int32& other) const {
|
||||
return Vector3int32(x / other.x, y / other.y, z / other.z);
|
||||
}
|
||||
|
||||
/** Integer division */
|
||||
inline Vector3int32 operator/(const int s) const {
|
||||
return Vector3int32(x / s, y / s, z / s);
|
||||
}
|
||||
|
||||
Vector3int32& operator+=(const Vector3int32& other) {
|
||||
x += other.x;
|
||||
y += other.y;
|
||||
z += other.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Vector3int32& operator-=(const Vector3int32& other) {
|
||||
Vector3int32& operator-=(const Vector3int32& other) {
|
||||
x -= other.x;
|
||||
y -= other.y;
|
||||
z -= other.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Vector3int32& operator*=(const Vector3int32& other) {
|
||||
Vector3int32& operator*=(const Vector3int32& other) {
|
||||
x *= other.x;
|
||||
y *= other.y;
|
||||
z *= other.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline bool operator== (const Vector3int32& rkVector) const {
|
||||
bool operator== (const Vector3int32& rkVector) const {
|
||||
return ( x == rkVector.x && y == rkVector.y && z == rkVector.z );
|
||||
}
|
||||
|
||||
inline bool operator!= (const Vector3int32& rkVector) const {
|
||||
bool operator!= (const Vector3int32& rkVector) const {
|
||||
return ( x != rkVector.x || y != rkVector.y || z != rkVector.z );
|
||||
}
|
||||
|
||||
@@ -108,20 +133,64 @@ public:
|
||||
return Vector3int32(iMin(x, v.x), iMin(y, v.y), iMin(z, v.z));
|
||||
}
|
||||
|
||||
Vector3int32 operator-() const {
|
||||
return Vector3int32(-x, -y, -z);
|
||||
}
|
||||
|
||||
std::string toString() const;
|
||||
|
||||
Vector3int32 operator<<(int i) const {
|
||||
return Vector3int32(x << i, y << i, z << i);
|
||||
}
|
||||
|
||||
Vector3int32 operator>>(int i) const {
|
||||
return Vector3int32(x >> i, y >> i, z >> i);
|
||||
}
|
||||
|
||||
Vector3int32 operator>>(const Vector3int32& v) const {
|
||||
return Vector3int32(x >> v.x, y >> v.y, z >> v.z);
|
||||
}
|
||||
|
||||
Vector3int32 operator<<(const Vector3int32& v) const {
|
||||
return Vector3int32(x << v.x, y << v.y, z << v.z);
|
||||
}
|
||||
|
||||
Vector3int32 operator&(int16 i) const {
|
||||
return Vector3int32(x & i, y & i, z & i);
|
||||
}
|
||||
|
||||
// 2-char swizzles
|
||||
|
||||
Vector2int32 xx() const;
|
||||
Vector2int32 yx() const;
|
||||
Vector2int32 zx() const;
|
||||
Vector2int32 xy() const;
|
||||
Vector2int32 yy() const;
|
||||
Vector2int32 zy() const;
|
||||
Vector2int32 xz() const;
|
||||
Vector2int32 yz() const;
|
||||
Vector2int32 zz() const;
|
||||
}
|
||||
G3D_END_PACKED_CLASS(4)
|
||||
|
||||
}
|
||||
typedef Vector3int32 Point3int32;
|
||||
|
||||
Vector3int32 iFloor(const Vector3&);
|
||||
|
||||
} // namespace G3D
|
||||
|
||||
template <> struct HashTrait<G3D::Vector3int32> {
|
||||
static size_t hashCode(const G3D::Vector3int32& key) {
|
||||
return G3D::superFastHash(&key, sizeof(key));
|
||||
//return G3D::Crypto::crc32(&key, sizeof(key));
|
||||
/*
|
||||
// Mask for the top bit of a uint32
|
||||
const G3D::uint32 top = (1UL << 31);
|
||||
// Mask for the bottom 10 bits of a uint32
|
||||
const G3D::uint32 bot = 0x000003FF;
|
||||
return static_cast<size_t>(((key.x & top) | ((key.y & top) >> 1) | ((key.z & top) >> 2)) |
|
||||
(((key.x & bot) << 19) ^ ((key.y & bot) << 10) ^ (key.z & bot)));
|
||||
*/
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
11
deps/g3dlite/include/G3D/Vector4.h
vendored
11
deps/g3dlite/include/G3D/Vector4.h
vendored
@@ -47,10 +47,11 @@ private:
|
||||
public:
|
||||
|
||||
/** \param any Must either Vector4(#, #, #, #) or Vector3 {x = #, y = #, z = #, w =#}*/
|
||||
Vector4(const Any& any);
|
||||
explicit Vector4(const Any& any);
|
||||
|
||||
Vector4& operator=(const Any& a);
|
||||
/** Converts the Vector4 to an Any. */
|
||||
operator Any() const;
|
||||
Any toAny() const;
|
||||
|
||||
// construction
|
||||
Vector4();
|
||||
@@ -698,7 +699,11 @@ inline float Vector4::squaredLength() const {
|
||||
return x * x + y * y + z * z + w * w;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void serialize(const Vector4& v, class BinaryOutput& b);
|
||||
void deserialize(Vector4& v, class BinaryInput& b);
|
||||
|
||||
} // G3D
|
||||
|
||||
template <> struct HashTrait<G3D::Vector4> {
|
||||
static size_t hashCode(const G3D::Vector4& key) { return key.hashCode(); }
|
||||
|
||||
6
deps/g3dlite/include/G3D/Vector4int8.h
vendored
6
deps/g3dlite/include/G3D/Vector4int8.h
vendored
@@ -51,14 +51,14 @@ public:
|
||||
inline Vector4int8() : x(0), y(0), z(0), w(0) {}
|
||||
|
||||
/** Multiplies the source by 127 and clamps to (-128, 127) when converting */
|
||||
Vector4int8(const Vector4& source);
|
||||
explicit Vector4int8(const Vector4& source);
|
||||
|
||||
/** Multiplies the source by 127 and clamps to (-128, 127) when converting */
|
||||
Vector4int8(const Vector3& source, int8 w);
|
||||
explicit Vector4int8(const Vector3& source, int8 w);
|
||||
|
||||
inline Vector4int8(int8 x, int8 y, int8 z, int8 w) : x(x), y(y), z(z), w(w) {}
|
||||
|
||||
Vector4int8(class BinaryInput& b);
|
||||
explicit Vector4int8(class BinaryInput& b);
|
||||
void serialize(class BinaryOutput& b) const;
|
||||
void deserialize(class BinaryInput& b);
|
||||
|
||||
|
||||
77
deps/g3dlite/include/G3D/WeakCache.h
vendored
77
deps/g3dlite/include/G3D/WeakCache.h
vendored
@@ -1,16 +1,16 @@
|
||||
/**
|
||||
@file WeakCache.h
|
||||
\file G3D/WeakCache.h
|
||||
|
||||
@maintainer Morgan McGuire, graphics3d.com
|
||||
\maintainer Morgan McGuire, graphics3d.com
|
||||
|
||||
@created 2007-05-16
|
||||
@edited 2007-05-16
|
||||
\created 2007-05-16
|
||||
\edited 2012-01-02
|
||||
|
||||
Copyright 2000-2007, Morgan McGuire.
|
||||
Copyright 2000-2012, Morgan McGuire.
|
||||
All rights reserved.
|
||||
*/
|
||||
#ifndef G3D_WEAKCACHE_H
|
||||
#define G3D_WEAKCACHE_H
|
||||
#ifndef G3D_WeakCache_h
|
||||
#define G3D_WeakCache_h
|
||||
|
||||
#include "G3D/ReferenceCount.h"
|
||||
#include "G3D/Table.h"
|
||||
@@ -31,10 +31,10 @@ namespace G3D {
|
||||
|
||||
Example:
|
||||
<pre>
|
||||
WeakCache<std::string, TextureRef> textureCache;
|
||||
WeakCache<std::string, shared_ptr<Texture>> textureCache;
|
||||
|
||||
TextureRef loadTexture(std::string s) {
|
||||
TextureRef t = textureCache[s];
|
||||
shared_ptr<Texture> loadTexture(std::string s) {
|
||||
shared_ptr<Texture> t = textureCache[s];
|
||||
|
||||
if (t.isNull()) {
|
||||
t = Texture::fromFile(s);
|
||||
@@ -49,7 +49,7 @@ namespace G3D {
|
||||
*/
|
||||
template<class Key, class ValueRef>
|
||||
class WeakCache {
|
||||
typedef WeakReferenceCountedPointer<typename ValueRef::element_type> ValueWeakRef;
|
||||
typedef weak_ptr<typename ValueRef::element_type> ValueWeakRef;
|
||||
|
||||
private:
|
||||
|
||||
@@ -62,17 +62,34 @@ public:
|
||||
ValueRef operator[](const Key& k) {
|
||||
if (table.containsKey(k)) {
|
||||
ValueWeakRef w = table[k];
|
||||
ValueRef s = w.createStrongPtr();
|
||||
if (s.isNull()) {
|
||||
ValueRef s = w.lock();
|
||||
if (! s) {
|
||||
// This object has been collected; clean out its key
|
||||
table.remove(k);
|
||||
}
|
||||
return s;
|
||||
} else {
|
||||
return NULL;
|
||||
return ValueRef();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void getValues(Array<ValueRef>& values) {
|
||||
Array<Key> keys;
|
||||
table.getKeys(keys);
|
||||
for (int i = 0; i < keys.size(); ++i) {
|
||||
ValueRef value = (*this)[keys[i]];
|
||||
if(notNull(value)) {
|
||||
values.append(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void clear() {
|
||||
table.clear();
|
||||
}
|
||||
|
||||
void set(const Key& k, ValueRef v) {
|
||||
table.set(k, v);
|
||||
}
|
||||
@@ -85,38 +102,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
#if 0 // To turn off all WeakCaching
|
||||
template<class Key, class ValueRef>
|
||||
class WeakCache {
|
||||
private:
|
||||
|
||||
Table<Key, ValueRef> table;
|
||||
|
||||
public:
|
||||
/**
|
||||
Returns NULL if the object is not in the cache
|
||||
*/
|
||||
ValueRef operator[](const Key& k) {
|
||||
if (table.containsKey(k)) {
|
||||
return table[k];
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void set(const Key& k, ValueRef v) {
|
||||
table.set(k, v);
|
||||
}
|
||||
|
||||
/** Removes k from the cache or does nothing if it is not currently in the cache.*/
|
||||
void remove(const Key& k) {
|
||||
if (table.containsKey(k)) {
|
||||
table.remove(k);
|
||||
}
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
26
deps/g3dlite/include/G3D/Welder.h
vendored
26
deps/g3dlite/include/G3D/Welder.h
vendored
@@ -22,30 +22,38 @@ public:
|
||||
/** Surfaces with normals that are within this angle of each
|
||||
other are considered to be curved. Default value is toRadians(70.0f).*/
|
||||
float normalSmoothingAngle;
|
||||
float vertexWeldRadius;
|
||||
float textureWeldRadius;
|
||||
float normalWeldRadius;
|
||||
|
||||
/** Default value is 0 */
|
||||
float vertexWeldRadius;
|
||||
|
||||
float textureWeldRadius;
|
||||
|
||||
float normalWeldRadius;
|
||||
|
||||
inline Settings(float normalSmoothAngle = toRadians(70.0f)) :
|
||||
normalSmoothingAngle(normalSmoothAngle),
|
||||
vertexWeldRadius(0.0001f),
|
||||
vertexWeldRadius(0.001f),
|
||||
textureWeldRadius(0.0001f),
|
||||
normalWeldRadius(0.01f) {}
|
||||
|
||||
|
||||
Settings(const Any& any);
|
||||
operator Any() const;
|
||||
|
||||
Any toAny() const;
|
||||
|
||||
void serialize(class BinaryOutput& b) const;
|
||||
|
||||
void deserialize(class BinaryInput& b);
|
||||
};
|
||||
|
||||
/**
|
||||
Mutates geometry, texCoord, and indexArray so that the output has collocated vertices collapsed (welded).
|
||||
Mutates geometry, texCoord, and indexArray so that the output has
|
||||
collocated vertices collapsed (welded).
|
||||
|
||||
@param vertices Input and output
|
||||
@param textureCoords Input and output
|
||||
@param normals Output only
|
||||
@param indices Input and output. This is an array of trilist indices.
|
||||
@param oldToNewIndex Output argument
|
||||
@param normalSmoothingAngle Varies from 0 (flat shading) to toRadians(180) for extremely smooth shading. Default is toRadians(70)
|
||||
*/
|
||||
static void weld(
|
||||
Array<Vector3>& vertices,
|
||||
@@ -61,8 +69,6 @@ public:
|
||||
@param textureCoords Input and output
|
||||
@param normals Output only
|
||||
@param indices Input and output. This is an array of trilist indices.
|
||||
@param oldToNewIndex Output argument
|
||||
@param normalSmoothingAngle Varies from 0 (flat shading) to toRadians(180) for extremely smooth shading. Default is toRadians(70)
|
||||
*/
|
||||
inline static void weld(
|
||||
Array<Vector3>& vertices,
|
||||
|
||||
20
deps/g3dlite/include/G3D/WrapMode.h
vendored
20
deps/g3dlite/include/G3D/WrapMode.h
vendored
@@ -1,12 +1,12 @@
|
||||
/**
|
||||
@file WrapMode.h
|
||||
\file G3D/WrapMode.h
|
||||
|
||||
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
\maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
|
||||
@created 2007-04-17
|
||||
@edited 2010-04-17
|
||||
\created 2007-04-17
|
||||
\edited 2010-04-17
|
||||
|
||||
Copyright 2000-2010, Morgan McGuire.
|
||||
Copyright 2000-2012, Morgan McGuire.
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
|
||||
#include "G3D/platform.h"
|
||||
#include "G3D/enumclass.h"
|
||||
#include "G3D/Any.h"
|
||||
|
||||
#ifdef IGNORE
|
||||
# undef IGNORE
|
||||
@@ -62,9 +61,7 @@ public:
|
||||
ZERO,
|
||||
IGNORE,
|
||||
ERROR
|
||||
};
|
||||
|
||||
private:
|
||||
} value;
|
||||
|
||||
static const char* toString(int i, Value& v) {
|
||||
static const char* str[] = {"CLAMP", "TILE", "ZERO", "IGNORE", "ERROR", NULL};
|
||||
@@ -76,14 +73,11 @@ private:
|
||||
return s;
|
||||
}
|
||||
|
||||
Value value;
|
||||
|
||||
public:
|
||||
|
||||
G3D_DECLARE_ENUM_CLASS_METHODS(WrapMode);
|
||||
|
||||
};
|
||||
|
||||
|
||||
} // namespace G3D
|
||||
|
||||
G3D_DECLARE_ENUM_CLASS_HASHCODE(G3D::WrapMode);
|
||||
|
||||
10
deps/g3dlite/include/G3D/XML.h
vendored
10
deps/g3dlite/include/G3D/XML.h
vendored
@@ -7,7 +7,7 @@
|
||||
@created 2010-02-11
|
||||
@edited 2010-02-24
|
||||
|
||||
Copyright 2000-2010, Morgan McGuire.
|
||||
Copyright 2000-2012, Morgan McGuire.
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
@@ -52,6 +52,7 @@ end with "-->" e.g.,
|
||||
|
||||
\sa G3D::Any, http://www.grinninglizard.com/tinyxml/
|
||||
|
||||
\htmlonly
|
||||
<pre>
|
||||
<foo key0="value0" key1="value1">
|
||||
child0 ...
|
||||
@@ -59,6 +60,7 @@ end with "-->" e.g.,
|
||||
child2 ...
|
||||
</foo>
|
||||
</pre>
|
||||
\endhtmlonly
|
||||
*/
|
||||
class XML {
|
||||
public:
|
||||
@@ -117,7 +119,7 @@ public:
|
||||
return m_attribute;
|
||||
}
|
||||
|
||||
const Array<XML> childArray() const {
|
||||
const Array<XML>& childArray() const {
|
||||
return m_child;
|
||||
}
|
||||
|
||||
@@ -127,7 +129,7 @@ public:
|
||||
}
|
||||
|
||||
/** Attribute table size; zero for a TAG */
|
||||
int numAttributes() const {
|
||||
size_t numAttributes() const {
|
||||
return m_attribute.size();
|
||||
}
|
||||
|
||||
@@ -142,7 +144,7 @@ public:
|
||||
return m_attribute[k];
|
||||
}
|
||||
|
||||
const bool containsAttribute(const std::string& k) const {
|
||||
bool containsAttribute(const std::string& k) const {
|
||||
return m_attribute.containsKey(k);
|
||||
}
|
||||
|
||||
|
||||
37
deps/g3dlite/include/G3D/constants.h
vendored
37
deps/g3dlite/include/G3D/constants.h
vendored
@@ -26,20 +26,13 @@ public:
|
||||
TRIANGLE_STRIP = 0x0005,
|
||||
TRIANGLE_FAN = 0x0006,
|
||||
QUADS = 0x0007,
|
||||
QUAD_STRIP = 0x0008
|
||||
QUAD_STRIP = 0x0008,
|
||||
PATCHES = 0x000E
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
static const char* toString(int i, Value& v) {
|
||||
static const char* str[] = {"POINTS", "LINES", "LINE_STRIP", "TRIANGLES", "TRIANGLE_FAN", "QUADS", "QUAD_STRIP", NULL};
|
||||
static const Value val[] = {POINTS, LINES, LINE_STRIP, TRIANGLES, TRIANGLE_FAN, QUADS, QUAD_STRIP};
|
||||
const char* s = str[i];
|
||||
if (s) {
|
||||
v = val[i];
|
||||
}
|
||||
return s;
|
||||
}
|
||||
static const char* toString(int i, Value& v);
|
||||
|
||||
Value value;
|
||||
|
||||
@@ -49,7 +42,7 @@ public:
|
||||
};
|
||||
|
||||
|
||||
/** Values for SuperSurface::GPUGeom::refractionHint. */
|
||||
/** Values for UniversalSurface::GPUGeom::refractionHint. */
|
||||
class RefractionQuality {
|
||||
public:
|
||||
enum Value {
|
||||
@@ -77,15 +70,7 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
static const char* toString(int i, Value& v) {
|
||||
static const char* str[] = {"NONE", "STATIC_ENV", "DYNAMIC_FLAT", "DYNAMIC_FLAT_MULTILAYER", "DYNAMIC_ENV", "BEST", NULL};
|
||||
static const Value val[] = {NONE, STATIC_ENV, DYNAMIC_FLAT, DYNAMIC_FLAT_MULTILAYER, DYNAMIC_ENV, BEST};
|
||||
const char* s = str[i];
|
||||
if (s) {
|
||||
v = val[i];
|
||||
}
|
||||
return s;
|
||||
}
|
||||
static const char* toString(int i, Value& v);
|
||||
|
||||
Value value;
|
||||
|
||||
@@ -95,7 +80,7 @@ public:
|
||||
};
|
||||
|
||||
|
||||
/** Values for SuperSurface::GPUGeom::mirrorHint. */
|
||||
/** Values for UniversalSurface::GPUGeom::mirrorHint. */
|
||||
class MirrorQuality {
|
||||
public:
|
||||
|
||||
@@ -119,15 +104,7 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
static const char* toString(int i, Value& v) {
|
||||
static const char* str[] = {"NONE", "STATIC_ENV", "DYNAMIC_PLANAR", "DYNAMIC_ENV", "BEST", NULL};
|
||||
static const Value val[] = {NONE, STATIC_ENV, DYNAMIC_PLANAR, DYNAMIC_ENV, BEST};
|
||||
const char* s = str[i];
|
||||
if (s) {
|
||||
v = val[i];
|
||||
}
|
||||
return s;
|
||||
}
|
||||
static const char* toString(int i, Value& v);
|
||||
|
||||
Value value;
|
||||
|
||||
|
||||
22
deps/g3dlite/include/G3D/debug.h
vendored
22
deps/g3dlite/include/G3D/debug.h
vendored
@@ -1,17 +1,17 @@
|
||||
/**
|
||||
@file debug.h
|
||||
\file debug.h
|
||||
|
||||
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
\maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
|
||||
@created 2001-08-26
|
||||
@edited 2006-02-16
|
||||
\created 2001-08-26
|
||||
\edited 2008-08-16
|
||||
|
||||
Copyright 2000-2006, Morgan McGuire.
|
||||
Copyright 2000-2006, Morgan McGuire.
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef G3D_DEBUG_H
|
||||
#define G3D_DEBUG_H
|
||||
#ifndef G3D_debug_h
|
||||
#define G3D_debug_h
|
||||
|
||||
#include "G3D/platform.h"
|
||||
#ifdef _MSC_VER
|
||||
@@ -38,7 +38,9 @@ namespace G3D {
|
||||
inline bool isValidHeapPointer(const void* x) {
|
||||
#ifdef _MSC_VER
|
||||
return
|
||||
(x != (void*)0xcccccccc) && (x != (void*)0xdeadbeef) && (x != (void*)0xfeeefeee);
|
||||
(x != NULL) &&
|
||||
(x != (void*)0xcccccccc) && (x != (void*)0xdeadbeef) && (x != (void*)0xfeeefeee) &&
|
||||
(x != (void*)0xcdcdcdcd) && (x != (void*)0xabababab) && (x != (void*)0xfdfdfdfd);
|
||||
#else
|
||||
return x != NULL;
|
||||
#endif
|
||||
@@ -51,7 +53,9 @@ inline bool isValidHeapPointer(const void* x) {
|
||||
*/
|
||||
inline bool isValidPointer(const void* x) {
|
||||
#ifdef _MSC_VER
|
||||
return x != ((void*)0xcccccccc) && (x != (void*)0xdeadbeef) && (x != (void*)0xfeeefeee);
|
||||
return (x != NULL) &&
|
||||
(x != (void*)0xcccccccc) && (x != (void*)0xdeadbeef) && (x != (void*)0xfeeefeee) &&
|
||||
(x != (void*)0xcdcdcdcd) && (x != (void*)0xabababab) && (x != (void*)0xfdfdfdfd);
|
||||
#else
|
||||
return x != NULL;
|
||||
#endif
|
||||
|
||||
180
deps/g3dlite/include/G3D/enumclass.h
vendored
180
deps/g3dlite/include/G3D/enumclass.h
vendored
@@ -1,30 +1,39 @@
|
||||
/**
|
||||
@file G3D/enumclass.h
|
||||
\file G3D/enumclass.h
|
||||
|
||||
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
@created 2007-01-27
|
||||
@edited 2007-07-20
|
||||
\maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
\created 2007-01-27
|
||||
\edited 2013-04-09
|
||||
*/
|
||||
#ifndef G3D_enumclass_h
|
||||
#define G3D_enumclass_h
|
||||
|
||||
#include "G3D/platform.h"
|
||||
#include "G3D/HashTrait.h"
|
||||
#include "G3D/BinaryInput.h"
|
||||
#include "G3D/BinaryOutput.h"
|
||||
#include "G3D/TextOutput.h"
|
||||
#include "G3D/Any.h"
|
||||
|
||||
namespace G3D {
|
||||
namespace _internal {
|
||||
const char** smartEnumParseNames(const char* enumValList);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
\def G3D_DECLARE_ENUM_CLASS_METHODS
|
||||
|
||||
\brief Creates a series of methods that turn a class into a scoped enumeration.
|
||||
|
||||
Uses the "Intelligent Enum" design pattern
|
||||
http://www.codeguru.com/cpp/cpp/cpp_mfc/article.php/c4001/
|
||||
Example of use:
|
||||
|
||||
Enum classes are initialized to their zero value by default.
|
||||
|
||||
You must implement the following method before calling G3D_DECLARE_ENUM_CLASS_METHODS, as either:
|
||||
|
||||
<pre>
|
||||
\code
|
||||
class Resource {
|
||||
public:
|
||||
enum Value {FUEL, FOOD, WATER} value;
|
||||
|
||||
// i is the position the enum value in Value (not the enum value itself)
|
||||
static const char* toString(int i, Value& v) {
|
||||
static const char* str[] = {"FUEL", "FOOD", "WATER", NULL}; // Whatever your enum values are
|
||||
static const Value val[] = {FUEL, FOOD, WATER}; // Whatever your enum values are
|
||||
@@ -34,29 +43,42 @@
|
||||
}
|
||||
return s;
|
||||
}
|
||||
</pre>
|
||||
|
||||
See GLG3D/GKey.h for an example.
|
||||
G3D_DECLARE_ENUM_CLASS_METHODS(Resource);
|
||||
};
|
||||
G3D_DECLARE_ENUM_CLASS_HASHCODE(Resource);
|
||||
\endcode
|
||||
|
||||
Extends the "Intelligent Enum" design pattern
|
||||
http://www.codeguru.com/cpp/cpp/cpp_mfc/article.php/c4001/
|
||||
|
||||
Enum classes are initialized to their zero value by default.
|
||||
|
||||
See GLG3D/GKey.h and G3D/WrapMode for an example.
|
||||
\sa G3D_DECLARE_ENUM_CLASS_HASHCODE
|
||||
*/
|
||||
#define G3D_DECLARE_ENUM_CLASS_METHODS(Classname)\
|
||||
private: \
|
||||
void fromString(const std::string& x) {\
|
||||
Value v;\
|
||||
Value v = (Value)0;\
|
||||
const char* s;\
|
||||
int i = 0;\
|
||||
\
|
||||
do {\
|
||||
s = toString(i, v);\
|
||||
if (s == NULL) { return; /** Needed to get correct compilation on gcc */ } \
|
||||
if (x == s) {\
|
||||
value = v;\
|
||||
return;\
|
||||
}\
|
||||
++i;\
|
||||
} while (s);\
|
||||
} while (true);\
|
||||
}\
|
||||
\
|
||||
public:\
|
||||
static const char* classname() {\
|
||||
return #Classname;\
|
||||
}\
|
||||
\
|
||||
const char* toString() const {\
|
||||
const char* s;\
|
||||
@@ -69,37 +91,36 @@ public:\
|
||||
}\
|
||||
++i;\
|
||||
}\
|
||||
return NULL;\
|
||||
}\
|
||||
\
|
||||
explicit Classname(const std::string& x) : value((Value)0) {\
|
||||
fromString(x);\
|
||||
}\
|
||||
\
|
||||
Classname(const Any& a) : value((Value)0) {\
|
||||
explicit Classname(const G3D::Any& a) : value((Value)0) { \
|
||||
fromString(a.string());\
|
||||
}\
|
||||
\
|
||||
operator Any() const {\
|
||||
return Any(toString());\
|
||||
G3D::Any toAny() const { \
|
||||
return G3D::Any(toString()); \
|
||||
}\
|
||||
\
|
||||
Classname(char v) : value((Value)v) {}\
|
||||
explicit Classname(char v) : value((Value)v) {}\
|
||||
\
|
||||
Classname() : value((Value)0) {}\
|
||||
\
|
||||
Classname(const Value v) : value(v) {}\
|
||||
\
|
||||
explicit Classname(int v) : value((Value)v) {}\
|
||||
\
|
||||
/** Support cast back to the Value type, which is needed to allow implicit assignment inside unions. */\
|
||||
/*inline operator Value() const {
|
||||
return value;
|
||||
}*/\
|
||||
\
|
||||
operator int() const {\
|
||||
return (int)value;\
|
||||
}\
|
||||
\
|
||||
Classname& operator=(const Any& a) {\
|
||||
value = Classname(a).value;\
|
||||
return *this;\
|
||||
}\
|
||||
\
|
||||
bool operator== (const Classname other) const {\
|
||||
return value == other.value;\
|
||||
@@ -181,15 +202,16 @@ public:\
|
||||
return (unsigned int)value;\
|
||||
}\
|
||||
\
|
||||
void serialize(BinaryOutput& b) const {\
|
||||
void serialize(G3D::BinaryOutput& b) const { \
|
||||
b.writeInt32(value);\
|
||||
}\
|
||||
\
|
||||
void deserialize(BinaryInput& b) {\
|
||||
void deserialize(G3D::BinaryInput& b) { \
|
||||
value = (Value)b.readInt32();\
|
||||
}
|
||||
|
||||
/** \def G3D_DECLARE_ENUM_CLASS_HASHCODE
|
||||
Must be used at top level (i.e., not inside a class or namespace), with a fully qualified class name.
|
||||
*/
|
||||
#define G3D_DECLARE_ENUM_CLASS_HASHCODE(Classname)\
|
||||
template <> struct HashTrait<Classname::Value> \
|
||||
@@ -202,4 +224,108 @@ template <> struct HashTrait<Classname>
|
||||
static size_t hashCode(Classname key) { return static_cast<size_t>(key.hashCode()); } \
|
||||
};
|
||||
|
||||
/**
|
||||
\def G3D_DECLARE_ENUM_CLASS
|
||||
|
||||
\code
|
||||
// Arguments may not have initializer expressions. Arguments may contain comments.
|
||||
// Namespaces aren't *required*, this example just shows how to use them.
|
||||
namespace Foo {
|
||||
G3D_DECLARE_ENUM_CLASS(Day, SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY);
|
||||
}
|
||||
G3D_DECLARE_ENUM_CLASS_HASHCODE(Foo::Day);
|
||||
...
|
||||
|
||||
using namespace Foo;
|
||||
// Example use of the smart enum
|
||||
Day d = Day::TUESDAY;
|
||||
Day d2("SATURDAY");
|
||||
Any a(d);
|
||||
d = a;
|
||||
printf("%s = %d\n", d.toString(), d.value);
|
||||
\endcode
|
||||
|
||||
\sa G3D_DECLARE_ENUM_CLASS_METHODS, G3D_DECLARE_ENUM_CLASS_HASHCODE, G3D::enumToJavaScriptDeclaration, G3D_BEGIN_ENUM_CLASS_DECLARATION
|
||||
*/
|
||||
#define G3D_DECLARE_ENUM_CLASS(ClassName, ...)\
|
||||
G3D_BEGIN_ENUM_CLASS_DECLARATION(ClassName, __VA_ARGS__);\
|
||||
G3D_END_ENUM_CLASS_DECLARATION();
|
||||
|
||||
/** \def G3D_BEGIN_ENUM_CLASS_DECLARATION
|
||||
|
||||
\code
|
||||
G3D_BEGIN_ENUM_CLASS_DECLARATION(Day, SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY);
|
||||
// Put extra methods here, e.g.,
|
||||
Value nextValue() { ... }
|
||||
G3D_END_ENUM_CLASS_DECLARATION();
|
||||
}
|
||||
G3D_DECLARE_ENUM_CLASS_HASHCODE(Foo::Day);
|
||||
|
||||
\endcode
|
||||
\sa G3D_DECLARE_ENUM_CLASS, G3D_END_ENUM_CLASS_DECLARATION
|
||||
*/
|
||||
#define G3D_BEGIN_ENUM_CLASS_DECLARATION(ClassName, ...)\
|
||||
class ClassName {\
|
||||
public:\
|
||||
enum Value {\
|
||||
__VA_ARGS__\
|
||||
} value;\
|
||||
\
|
||||
/* The static variables here may be duplicated in different shared object binaries (DLLs), but that's ok--we only depend on their values, not their uniqueness. See also http://stackoverflow.com/questions/11962918/local-static-variable-is-instantiated-multiple-times-why */\
|
||||
static const char* toString(int i, Value& v) {\
|
||||
static const char** str = G3D::_internal::smartEnumParseNames(#__VA_ARGS__);\
|
||||
static const Value val[] = {__VA_ARGS__};\
|
||||
const char* s = str[i];\
|
||||
if (s) { v = val[i]; }\
|
||||
return s;\
|
||||
}\
|
||||
\
|
||||
G3D_DECLARE_ENUM_CLASS_METHODS(ClassName);
|
||||
|
||||
/** \def G3D_END_ENUM_CLASS_DECLARATION
|
||||
\sa G3D_BEGIN_ENUM_CLASS_DECLARATION */
|
||||
#define G3D_END_ENUM_CLASS_DECLARATION() }
|
||||
|
||||
|
||||
namespace G3D {
|
||||
|
||||
/**
|
||||
\brief Generates JavaScript source code defining an enum equivalent to
|
||||
EnumClass.
|
||||
|
||||
\code
|
||||
TextOutput t("WrapMode.js");
|
||||
enumToJavaScriptDeclaration<WrapMode, WrapMode::Value>(t);
|
||||
t.commit();
|
||||
\endcode
|
||||
*/
|
||||
template<class EnumClass, class EnumClassValue>
|
||||
void enumToJavaScriptDeclaration(TextOutput& t) {
|
||||
t.printf("/* BEGIN GENERATED CODE. The following was automatically generated by G3D::enumToJavaScriptDeclaration(). Do not edit it manually. */\n\n");
|
||||
t.printf("var %s = (function (propList) {", EnumClass::classname()); t.writeNewline();
|
||||
t.pushIndent(); {
|
||||
t.printf("// Define immutable properties"); t.writeNewline();
|
||||
t.printf("var en = {};"); t.writeNewline();
|
||||
t.printf("for (var i = 0; i < propList.length; i += 2)"); t.writeNewline();
|
||||
t.pushIndent(); {
|
||||
t.printf("Object.defineProperty(en, propList[i], {enumerable: true, value: propList[i + 1]});"); t.writeNewline();
|
||||
} t.popIndent();
|
||||
t.printf("return en;");
|
||||
t.writeNewline();
|
||||
} t.popIndent();
|
||||
t.printf("})([");
|
||||
int i = 0;
|
||||
EnumClassValue m;
|
||||
const char* s = EnumClass::toString(i, m);
|
||||
while (notNull(s)) {
|
||||
t.printf("\"%s\", %d, ", s, int(m));
|
||||
++i;
|
||||
s = EnumClass::toString(i, m);
|
||||
}
|
||||
// JavaScript allows a trailing comma
|
||||
t.printf("]);"); t.writeNewline();
|
||||
t.printf("/* END GENERATED CODE */"); t.writeNewline();
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
44
deps/g3dlite/include/G3D/fileutils.h
vendored
44
deps/g3dlite/include/G3D/fileutils.h
vendored
@@ -4,9 +4,9 @@
|
||||
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
|
||||
@author 2002-06-06
|
||||
@edited 2010-03-06
|
||||
@edited 2011-03-06
|
||||
|
||||
Copyright 2000-2010, Morgan McGuire.
|
||||
Copyright 2000-2012, Morgan McGuire.
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
@@ -20,42 +20,16 @@
|
||||
#include "G3D/Set.h"
|
||||
#include "G3D/g3dmath.h"
|
||||
|
||||
#ifdef G3D_WIN32
|
||||
#ifdef G3D_WINDOWS
|
||||
// For chdir, mkdir, etc.
|
||||
# include <direct.h>
|
||||
#endif
|
||||
|
||||
namespace G3D {
|
||||
|
||||
namespace _internal {
|
||||
extern Set<std::string> currentFilesUsed;
|
||||
}
|
||||
|
||||
/** Returns all the files used by G3D and GLG3D during the current execution. */
|
||||
Array<std::string> filesUsed();
|
||||
|
||||
std::string readWholeFile(
|
||||
const std::string& filename);
|
||||
|
||||
|
||||
/** Reads from a zip file and decompresses the desired contents
|
||||
into memory. Does not support recursive zip calls (i.e. a .zip
|
||||
stored within another .zip)
|
||||
|
||||
@param file the path, of the format C:\\...\\something.zip\\...\\desiredfile.ext
|
||||
@param data a pointer to the memory where the file will be stored
|
||||
@param length the size of the file decompressed to memory */
|
||||
void zipRead(const std::string& file,
|
||||
void*& data,
|
||||
size_t& length);
|
||||
|
||||
|
||||
/** Closes the contents of a zip file that had been decompressed to
|
||||
memory. Must be called in tandem with zipRead() to avoid memory
|
||||
leaks.
|
||||
|
||||
@param data the pointer to the decompressed file in memory */
|
||||
void zipClose(void* data);
|
||||
|
||||
/** Returns the contents of a text file as a single string */
|
||||
std::string readWholeFile
|
||||
(const std::string& filename);
|
||||
|
||||
|
||||
/**
|
||||
@@ -88,8 +62,8 @@ FILE* createTempFile();
|
||||
*/
|
||||
bool zipfileExists
|
||||
(const std::string& filename,
|
||||
std::string& outZipfile,
|
||||
std::string& outInternalFile);
|
||||
std::string& outZipfile,
|
||||
std::string& outInternalFile);
|
||||
|
||||
bool zipfileExists(const std::string& filename);
|
||||
|
||||
|
||||
2
deps/g3dlite/include/G3D/g3dfnmatch.h
vendored
2
deps/g3dlite/include/G3D/g3dfnmatch.h
vendored
@@ -42,7 +42,7 @@
|
||||
|
||||
namespace G3D {
|
||||
|
||||
#if defined(G3D_WIN32)
|
||||
#if defined(G3D_WINDOWS)
|
||||
|
||||
# if ! defined(FNM_NOMATCH)
|
||||
# define FNM_NOMATCH 1 /* Match failed. */
|
||||
|
||||
279
deps/g3dlite/include/G3D/g3dmath.h
vendored
279
deps/g3dlite/include/G3D/g3dmath.h
vendored
@@ -7,9 +7,9 @@
|
||||
@cite highestBit by Jukka Liimatta
|
||||
|
||||
@created 2001-06-02
|
||||
@edited 2009-04-07
|
||||
@edited 2013-01-27
|
||||
|
||||
Copyright 2000-2006, Morgan McGuire.
|
||||
Copyright 2000-2013, Morgan McGuire.
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
@@ -29,8 +29,9 @@
|
||||
#include <float.h>
|
||||
#include <limits>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1000)
|
||||
// Visual Studio is missing inttypes.h
|
||||
# ifndef PRId64
|
||||
# define PRId64 "I64d"
|
||||
@@ -58,6 +59,16 @@
|
||||
#undef min
|
||||
#undef max
|
||||
|
||||
/**
|
||||
\def G3D_DECLARE_SYMBOL(s)
|
||||
Defines SYMBOL_s as a static const std::string with the value s.
|
||||
Useful for avoiding heap allocation from C-string constants being
|
||||
converted at runtime.
|
||||
*/
|
||||
#define G3D_DECLARE_SYMBOL(s) \
|
||||
static const std::string SYMBOL_##s = #s
|
||||
|
||||
|
||||
namespace G3D {
|
||||
|
||||
#ifdef _MSC_VER
|
||||
@@ -65,59 +76,61 @@ inline double __fastcall drand48() {
|
||||
return ::rand() / double(RAND_MAX);
|
||||
}
|
||||
|
||||
#if !defined(_WIN64)
|
||||
|
||||
/**
|
||||
Win32 implementation of the C99 fast rounding routines.
|
||||
# ifdef _M_IX86
|
||||
// 32-bit
|
||||
/**
|
||||
Win32 implementation of the C99 fast rounding routines.
|
||||
|
||||
@cite routines are
|
||||
Copyright (C) 2001 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
|
||||
@cite routines are
|
||||
Copyright (C) 2001 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this file for any
|
||||
purpose is hereby granted without fee, provided that the above copyright
|
||||
and this permission notice appear in all copies. No representations are
|
||||
made about the suitability of this software for any purpose. It is
|
||||
provided "as is" without express or implied warranty.
|
||||
*/
|
||||
Permission to use, copy, modify, distribute, and sell this file for any
|
||||
purpose is hereby granted without fee, provided that the above copyright
|
||||
and this permission notice appear in all copies. No representations are
|
||||
made about the suitability of this software for any purpose. It is
|
||||
provided "as is" without express or implied warranty.
|
||||
*/
|
||||
|
||||
__inline long int lrint (double flt) {
|
||||
int intgr;
|
||||
|
||||
_asm {
|
||||
fld flt
|
||||
fistp intgr
|
||||
};
|
||||
__inline long int lrint (double flt) {
|
||||
int intgr;
|
||||
|
||||
return intgr;
|
||||
}
|
||||
_asm {
|
||||
fld flt
|
||||
fistp intgr
|
||||
};
|
||||
|
||||
__inline long int lrintf(float flt) {
|
||||
int intgr;
|
||||
return intgr;
|
||||
}
|
||||
|
||||
_asm {
|
||||
fld flt
|
||||
fistp intgr
|
||||
};
|
||||
__inline long int lrintf(float flt) {
|
||||
int intgr;
|
||||
|
||||
return intgr;
|
||||
}
|
||||
_asm {
|
||||
fld flt
|
||||
fistp intgr
|
||||
};
|
||||
|
||||
#else
|
||||
return intgr;
|
||||
}
|
||||
# else
|
||||
// 64-bit
|
||||
|
||||
__inline long int lrintf(float flt) {
|
||||
return (long int)(flt + 0.5f);
|
||||
}
|
||||
|
||||
__inline long int lrint (double flt) {
|
||||
return (long int)floor(flt+0.5f);
|
||||
return (long int)(flt + 0.5);
|
||||
}
|
||||
|
||||
__inline long int lrintf(float flt) {
|
||||
return (long int)floorf(flt+0.5f);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
#define fuzzyEpsilon (0.00001f)
|
||||
#define fuzzyEpsilon64 (0.0000005)
|
||||
#define fuzzyEpsilon32 (0.00001f)
|
||||
|
||||
/**
|
||||
This value should not be tested against directly, instead
|
||||
G3D::isNan() and G3D::isFinite() will return reliable results. */
|
||||
@@ -147,23 +160,14 @@ inline double twoPi() {
|
||||
return 6.28318531;
|
||||
}
|
||||
|
||||
typedef signed char int8;
|
||||
typedef unsigned char uint8;
|
||||
typedef short int16;
|
||||
typedef unsigned short uint16;
|
||||
typedef int int32;
|
||||
typedef unsigned int uint32;
|
||||
|
||||
#ifdef _MSC_EXTENSIONS
|
||||
typedef __int64 int64;
|
||||
typedef unsigned __int64 uint64;
|
||||
#elif ! defined(_MSC_VER)
|
||||
typedef int64_t int64;
|
||||
typedef uint64_t uint64;
|
||||
#else
|
||||
typedef long long int64;
|
||||
typedef unsigned long long uint64;
|
||||
#endif
|
||||
typedef int8_t int8;
|
||||
typedef uint8_t uint8;
|
||||
typedef int16_t int16;
|
||||
typedef uint16_t uint16;
|
||||
typedef int32_t int32;
|
||||
typedef uint32_t uint32;
|
||||
typedef int64_t int64;
|
||||
typedef uint64_t uint64;
|
||||
|
||||
typedef float float32;
|
||||
typedef double float64;
|
||||
@@ -207,7 +211,14 @@ inline int iSign(float f) {
|
||||
return iSign((double)f);
|
||||
}
|
||||
|
||||
inline double round(double f) {
|
||||
return floor(f + 0.5f);
|
||||
}
|
||||
|
||||
inline float round(float f) {
|
||||
return floor(f + 0.5f);
|
||||
}
|
||||
|
||||
/**
|
||||
Fast round to integer using the lrint routine.
|
||||
Typically 6x faster than casting to integer.
|
||||
@@ -256,6 +267,11 @@ inline bool isNaN(int x) {
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool isNaN(uint64 x) {
|
||||
(void)x;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
Computes x % 3.
|
||||
*/
|
||||
@@ -339,6 +355,7 @@ int highestBit(uint32 x);
|
||||
*/
|
||||
bool fuzzyEq(double a, double b);
|
||||
|
||||
|
||||
/** True if a is definitely not equal to b.
|
||||
Guaranteed false if a == b.
|
||||
Possibly false when a != b.*/
|
||||
@@ -393,6 +410,7 @@ inline double log2(int x) {
|
||||
* True if num is a power of two.
|
||||
*/
|
||||
bool isPow2(int num);
|
||||
bool isPow2(uint64 num);
|
||||
|
||||
bool isOdd(int num);
|
||||
bool isEven(int num);
|
||||
@@ -455,7 +473,7 @@ inline double rsqrt(double x) {
|
||||
/** @deprecated Use rsq */
|
||||
inline float rsqrt(float x) {
|
||||
// TODO: default this to using the SSE2 instruction
|
||||
return 1.0 / sqrtf(x);
|
||||
return 1.0f / sqrtf(x);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -526,59 +544,59 @@ inline int iCeil (double 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;
|
||||
}
|
||||
if (val <= low) {
|
||||
return low;
|
||||
} else if (val >= hi) {
|
||||
return hi;
|
||||
} else {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
inline int16 iClamp(int16 val, int16 low, int16 hi) {
|
||||
debugAssert(low <= hi);
|
||||
if (val <= low) {
|
||||
return low;
|
||||
} else if (val >= hi) {
|
||||
return hi;
|
||||
} else {
|
||||
return val;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
if (val < 0) {
|
||||
return ((val % hi) + hi) % hi;
|
||||
} else {
|
||||
return val % hi;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -651,11 +669,11 @@ inline double aTan2 (double fY, double fX) {
|
||||
inline double sign (double fValue) {
|
||||
if (fValue > 0.0) {
|
||||
return 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
if (fValue < 0.0) {
|
||||
return -1.0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0.0;
|
||||
}
|
||||
@@ -663,11 +681,11 @@ inline double sign (double fValue) {
|
||||
inline float sign (float fValue) {
|
||||
if (fValue > 0.0f) {
|
||||
return 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
if (fValue < 0.0f) {
|
||||
return -1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
return 0.0f;
|
||||
}
|
||||
@@ -759,6 +777,16 @@ inline bool isPow2(int num) {
|
||||
return ((num & -num) == num);
|
||||
}
|
||||
|
||||
inline bool isPow2(uint64 x) {
|
||||
// See http://www.exploringbinary.com/ten-ways-to-check-if-an-integer-is-a-power-of-two-in-c/, method #9
|
||||
return ((x != 0) && !(x & (x - 1)));
|
||||
}
|
||||
|
||||
inline bool isPow2(uint32 x) {
|
||||
// See http://www.exploringbinary.com/ten-ways-to-check-if-an-integer-is-a-power-of-two-in-c/, method #9
|
||||
return ((x != 0) && !(x & (x - 1)));
|
||||
}
|
||||
|
||||
inline bool isOdd(int num) {
|
||||
return (num & 1) == 1;
|
||||
}
|
||||
@@ -801,12 +829,31 @@ inline double eps(double a, double b) {
|
||||
(void)b;
|
||||
const double aa = abs(a) + 1.0;
|
||||
if (aa == inf()) {
|
||||
return fuzzyEpsilon;
|
||||
return fuzzyEpsilon64;
|
||||
} else {
|
||||
return fuzzyEpsilon * aa;
|
||||
return fuzzyEpsilon64 * aa;
|
||||
}
|
||||
}
|
||||
|
||||
inline float eps(float a, float 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 float aa = (float)abs(a) + 1.0f;
|
||||
if (aa == inf()) {
|
||||
return fuzzyEpsilon32;
|
||||
} else {
|
||||
return fuzzyEpsilon32 * aa;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline bool fuzzyEq(float a, float b) {
|
||||
return (a == b) || (abs(a - b) <= eps(a, b));
|
||||
}
|
||||
|
||||
inline bool fuzzyEq(double a, double b) {
|
||||
return (a == b) || (abs(a - b) <= eps(a, b));
|
||||
}
|
||||
@@ -850,9 +897,47 @@ inline uint16 flipEndian16(const uint16 x) {
|
||||
return (x << 8) | ((x & 0xFF00) >> 8);
|
||||
}
|
||||
|
||||
/** The GLSL smoothstep function */
|
||||
inline float smoothstep(float edge0, float edge1, float x) {
|
||||
// Scale, bias and saturate x to 0..1 range
|
||||
x = clamp((x - edge0) / (edge1 - edge0), 0.0f, 1.0f);
|
||||
|
||||
// Evaluate polynomial
|
||||
return x * x * (3 - 2 * x);
|
||||
}
|
||||
|
||||
|
||||
/** Perlin's C2 continous variation on smoothstep() */
|
||||
inline float smootherstep(float edge0, float edge1, float x) {
|
||||
|
||||
// Scale, and saturate x to 0..1 range
|
||||
x = clamp((x - edge0) / (edge1 - edge0), 0.0f, 1.0f);
|
||||
|
||||
// Evaluate polynomial
|
||||
return x * x * x * (x * (x * 6 - 15) + 10);
|
||||
}
|
||||
|
||||
|
||||
/** Computes |b|^e * sign(b) */
|
||||
inline float signedPow(float b, float e) {
|
||||
return sign(b) * powf(fabsf(b), e);
|
||||
}
|
||||
|
||||
|
||||
/** Computes |b|^e * sign(b) */
|
||||
inline double signedPow(double b, double e) {
|
||||
return sign(b) * pow(abs(b), e);
|
||||
}
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace std {
|
||||
inline int pow(int a, int b) {
|
||||
return (int)::pow(double(a), double(b));
|
||||
}
|
||||
|
||||
}
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning (pop)
|
||||
#endif
|
||||
|
||||
2
deps/g3dlite/include/G3D/netheaders.h
vendored
2
deps/g3dlite/include/G3D/netheaders.h
vendored
@@ -3,7 +3,7 @@
|
||||
|
||||
#include "G3D/platform.h"
|
||||
|
||||
#ifdef G3D_WIN32
|
||||
#ifdef G3D_WINDOWS
|
||||
# if (G3D_WINSOCK_MAJOR_VERSION == 2)
|
||||
# include <winsock2.h>
|
||||
# elif (G3D_WINSOCK_MAJOR_VERSION == 1)
|
||||
|
||||
2
deps/g3dlite/include/G3D/networkHelpers.h
vendored
2
deps/g3dlite/include/G3D/networkHelpers.h
vendored
@@ -85,7 +85,7 @@
|
||||
|
||||
|
||||
#ifndef _SOCKLEN_T
|
||||
# if defined(G3D_WIN32) || defined(G3D_OSX)
|
||||
# if defined(G3D_WINDOWS) || defined(G3D_OSX)
|
||||
typedef int socklen_t;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
224
deps/g3dlite/include/G3D/platform.h
vendored
224
deps/g3dlite/include/G3D/platform.h
vendored
@@ -1,22 +1,26 @@
|
||||
/**
|
||||
@file platform.h
|
||||
\file platform.h
|
||||
|
||||
\#defines for platform specific issues.
|
||||
|
||||
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
\maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
|
||||
@created 2003-06-09
|
||||
@edited 2010-08-11
|
||||
Copyright 2000-2012, Morgan McGuire.
|
||||
All rights reserved.
|
||||
|
||||
\created 2003-06-09
|
||||
\edited 2013-01-03
|
||||
*/
|
||||
|
||||
#ifndef G3D_platform_h
|
||||
#define G3D_platform_h
|
||||
|
||||
/**
|
||||
\def G3D_VER
|
||||
The version number of G3D in the form: MmmBB ->
|
||||
version M.mm [beta BB]
|
||||
*/
|
||||
#define G3D_VER 80100
|
||||
#define G3D_VER 90000
|
||||
|
||||
// fatal error for unsupported architectures
|
||||
#if defined(__powerpc__)
|
||||
@@ -31,13 +35,15 @@
|
||||
# undef _DEBUG
|
||||
#endif
|
||||
|
||||
/** @def G3D_DEBUG()
|
||||
/** \def G3D_DEBUG
|
||||
Defined if G3D is built in debug mode. */
|
||||
#if !defined(G3D_DEBUG) && (defined(_DEBUG) || defined(G3D_DEBUGRELEASE))
|
||||
# define G3D_DEBUG
|
||||
#endif
|
||||
|
||||
/** These control the version of Winsock used by G3D.
|
||||
/**
|
||||
\def G3D_WINSOCK_MAJOR_VERSION
|
||||
These control the version of Winsock used by G3D.
|
||||
Version 2.0 is standard for G3D 6.09 and later.
|
||||
Version 1.1 is standard for G3D 6.08 and earlier.
|
||||
*/
|
||||
@@ -49,10 +55,15 @@
|
||||
#define __fastcall
|
||||
#endif
|
||||
|
||||
/** \def G3D_WINDOWS*/
|
||||
/** \def G3D_FREEBSD2*/
|
||||
/** \def G3D_LINUX*/
|
||||
/** \def G3D_OSX */
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define G3D_WIN32
|
||||
# define G3D_WINDOWS
|
||||
#elif defined(__MINGW32__)
|
||||
#define G3D_WIN32
|
||||
#define G3D_WINDOWS
|
||||
#undef __MSVCRT_VERSION__
|
||||
#define __MSVCRT_VERSION__ 0x0601
|
||||
#include <windows.h>
|
||||
@@ -61,8 +72,6 @@
|
||||
#define G3D_LINUX
|
||||
#elif defined(__linux__)
|
||||
#define G3D_LINUX
|
||||
#elif defined(__CYGWIN__)
|
||||
#define G3D_LINUX
|
||||
#elif defined(__APPLE__)
|
||||
#define G3D_LINUX
|
||||
|
||||
@@ -70,25 +79,26 @@
|
||||
// pi as a constant, which creates a conflict with G3D
|
||||
#define __FP__
|
||||
#else
|
||||
#error Unknown platform
|
||||
#error Unknown platform
|
||||
#endif
|
||||
|
||||
/** \def G3D_64BIT */
|
||||
/** \def G3D_32BIT */
|
||||
|
||||
|
||||
|
||||
/** Define the g++ thread-local syntax on all platforms (since the MSVC version would be hard to emulate with a macro) */
|
||||
#if defined(_MSC_VER)
|
||||
# define __thread __declspec(thread)
|
||||
#endif
|
||||
|
||||
// Detect 64-bit under various compilers
|
||||
#if (defined(_M_X64) || defined(_WIN64) || defined(__LP64__) || defined(_LP64))
|
||||
# define G3D_64BIT
|
||||
#if defined(WIN32)
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
#else
|
||||
# define G3D_32BIT
|
||||
#endif
|
||||
|
||||
// Strongly encourage inlining on gcc
|
||||
#ifdef __GNUC__
|
||||
#define inline __inline__
|
||||
#endif
|
||||
|
||||
|
||||
// Verify that the supported compilers are being used and that this is a known
|
||||
// processor.
|
||||
|
||||
@@ -96,13 +106,14 @@
|
||||
# ifndef __GNUC__
|
||||
# error G3D only supports the gcc compiler on Linux.
|
||||
# endif
|
||||
# define G3D_NO_FFMPEG
|
||||
#endif
|
||||
|
||||
#ifdef G3D_OSX
|
||||
# ifndef __GNUC__
|
||||
# error G3D only supports the gcc compiler on OS X.
|
||||
# endif
|
||||
|
||||
|
||||
# if defined(__i386__)
|
||||
# define G3D_OSX_INTEL
|
||||
# elif defined(__PPC__)
|
||||
@@ -115,11 +126,13 @@
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// Microsoft Visual C++ 10.0 = 1600
|
||||
// Microsoft Visual C++ 9.0 = 1500
|
||||
// Microsoft Visual C++ 8.0 ("Express") = 1400
|
||||
// Microsoft Visual C++ 7.1 ("2003") _MSC_VER = 1310
|
||||
// Microsoft Visual C++ 7.0 ("2002") _MSC_VER = 1300
|
||||
// Microsoft Visual C++ 6.0 _MSC_VER = 1200
|
||||
// Microsoft Visual C++ 5.0 _MSC_VER = 1100
|
||||
// Microsoft Visual C++ 7.1 ("2003") _MSC_VER = 1310
|
||||
// Microsoft Visual C++ 7.0 ("2002") _MSC_VER = 1300
|
||||
// Microsoft Visual C++ 6.0 _MSC_VER = 1200
|
||||
// Microsoft Visual C++ 5.0 _MSC_VER = 1100
|
||||
|
||||
// Turn off warnings about deprecated C routines
|
||||
# pragma warning (disable : 4996)
|
||||
@@ -128,8 +141,16 @@
|
||||
// for debug assertions in inlined methods.
|
||||
# pragma warning (disable : 4127)
|
||||
|
||||
/** @def G3D_DEPRECATED()
|
||||
Creates deprecated warning. */
|
||||
/** \def G3D_DEPRECATED()
|
||||
Creates deprecated warning at compile time when used.
|
||||
|
||||
Example:
|
||||
\code
|
||||
int G3D_DEPRECATED sum(int a, int b) {
|
||||
return a + b;
|
||||
}
|
||||
\endcode
|
||||
*/
|
||||
# define G3D_DEPRECATED __declspec(deprecated)
|
||||
|
||||
// Prevent Winsock conflicts by hiding the winsock API
|
||||
@@ -140,14 +161,12 @@
|
||||
|
||||
// Disable 'name too long for browse information' warning
|
||||
# pragma warning (disable : 4786)
|
||||
// TODO: remove
|
||||
# pragma warning (disable : 4244)
|
||||
|
||||
# define restrict
|
||||
|
||||
/** @def G3D_CHECK_PRINTF_METHOD_ARGS()
|
||||
Enables printf parameter validation on gcc. */
|
||||
# define G3D_CHECK_PRINTF_ARGS
|
||||
# define G3D_CHECK_PRINTF_ARGS
|
||||
|
||||
/** @def G3D_CHECK_PRINTF_METHOD_ARGS()
|
||||
Enables printf parameter validation on gcc. */
|
||||
@@ -173,50 +192,34 @@
|
||||
|
||||
// DLL runtime
|
||||
#ifndef _DLL
|
||||
#define _DLL
|
||||
#define _DLL
|
||||
#endif
|
||||
|
||||
// Multithreaded runtime
|
||||
#ifndef _MT
|
||||
#define _MT 1
|
||||
#define _MT 1
|
||||
#endif
|
||||
|
||||
// Ensure that we aren't forced into the static lib
|
||||
#ifdef _STATIC_CPPLIB
|
||||
#undef _STATIC_CPPLIB
|
||||
#undef _STATIC_CPPLIB
|
||||
#endif
|
||||
|
||||
#ifdef _DEBUG
|
||||
#pragma comment (linker, "/NODEFAULTLIB:LIBCMTD.LIB")
|
||||
#pragma comment (linker, "/NODEFAULTLIB:LIBCPMTD.LIB")
|
||||
#pragma comment (linker, "/NODEFAULTLIB:LIBCPD.LIB")
|
||||
#pragma comment (linker, "/DEFAULTLIB:MSVCPRTD.LIB")
|
||||
#pragma comment(linker, "/NODEFAULTLIB:LIBCD.LIB")
|
||||
#pragma comment(linker, "/DEFAULTLIB:MSVCRTD.LIB")
|
||||
#else
|
||||
#pragma comment(linker, "/NODEFAULTLIB:LIBC.LIB")
|
||||
#pragma comment(linker, "/DEFAULTLIB:MSVCRT.LIB")
|
||||
#pragma comment (linker, "/NODEFAULTLIB:LIBCMT.LIB")
|
||||
#pragma comment (linker, "/NODEFAULTLIB:LIBCPMT.LIB")
|
||||
#pragma comment(linker, "/NODEFAULTLIB:LIBCP.LIB")
|
||||
#pragma comment (linker, "/DEFAULTLIB:MSVCPRT.LIB")
|
||||
#endif
|
||||
|
||||
// Now set up external linking
|
||||
|
||||
# ifdef _DEBUG
|
||||
// zlib was linked against the release MSVCRT; force
|
||||
// the debug version.
|
||||
# pragma comment(linker, "/NODEFAULTLIB:MSVCRT.LIB")
|
||||
# endif
|
||||
#ifdef _DEBUG
|
||||
// Some of the support libraries are always built in Release.
|
||||
// Make sure the debug runtime library is linked in
|
||||
#pragma comment(linker, "/NODEFAULTLIB:MSVCRT.LIB")
|
||||
#pragma comment(linker, "/NODEFAULTLIB:MSVCPRT.LIB")
|
||||
#endif
|
||||
|
||||
|
||||
# ifndef WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN 1
|
||||
# endif
|
||||
|
||||
|
||||
# define NOMINMAX 1
|
||||
# ifndef NOMINMAX
|
||||
# define NOMINMAX 1
|
||||
# endif
|
||||
# ifndef _WIN32_WINNT
|
||||
# define _WIN32_WINNT 0x0500
|
||||
# endif
|
||||
@@ -230,8 +233,9 @@
|
||||
# endif
|
||||
|
||||
|
||||
/** @def G3D_START_AT_MAIN()
|
||||
Defines necessary wrapper around WinMain on Windows to allow transfer of execution to main(). */
|
||||
/** \def G3D_START_AT_MAIN()
|
||||
Makes Windows programs using the WINDOWS subsystem invoke main() at program start by
|
||||
defining a WinMain(). Does nothing on other operating systems.*/
|
||||
# define G3D_START_AT_MAIN()\
|
||||
int WINAPI G3D_WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw);\
|
||||
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) {\
|
||||
@@ -269,7 +273,7 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) {\
|
||||
# define __stdcall __attribute__((stdcall))
|
||||
# endif
|
||||
|
||||
# elif defined(__x86_64__)
|
||||
# elif defined(__x86_64__) || defined(__arm) || defined(__aarch64__)
|
||||
|
||||
# ifndef __cdecl
|
||||
# define __cdecl
|
||||
@@ -299,7 +303,7 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) {\
|
||||
|
||||
|
||||
/**
|
||||
@def STR(expression)
|
||||
\def STR(expression)
|
||||
|
||||
Creates a string from the expression. Frequently used with G3D::Shader
|
||||
to express shading programs inline.
|
||||
@@ -319,26 +323,100 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) {\
|
||||
# define PRAGMA(x) _Pragma(#x)
|
||||
#endif
|
||||
|
||||
/** @def G3D_BEGIN_PACKED_CLASS(byteAlign)
|
||||
Switch to tight alignment
|
||||
/** \def G3D_BEGIN_PACKED_CLASS(byteAlign)
|
||||
Switch to tight alignment.
|
||||
|
||||
\code
|
||||
G3D_BEGIN_PACKED_CLASS(1)
|
||||
ThreeBytes {
|
||||
public:
|
||||
uint8 a, b, c;
|
||||
}
|
||||
G3D_END_PACKED_CLASS(1)
|
||||
\endcode
|
||||
|
||||
|
||||
See G3D::Color3uint8 for an example.*/
|
||||
#ifdef _MSC_VER
|
||||
# define G3D_BEGIN_PACKED_CLASS(byteAlign) PRAGMA( pack(push, byteAlign) )
|
||||
#ifdef __GNUC__
|
||||
# define G3D_BEGIN_PACKED_CLASS(byteAlign) class __attribute((__packed__))
|
||||
#elif defined(_MSC_VER)
|
||||
# define G3D_BEGIN_PACKED_CLASS(byteAlign) PRAGMA( pack(push, byteAlign) ) class
|
||||
#else
|
||||
# define G3D_BEGIN_PACKED_CLASS(byteAlign)
|
||||
# define G3D_BEGIN_PACKED_CLASS(byteAlign) class
|
||||
#endif
|
||||
|
||||
/** @def G3D_END_PACKED_CLASS(byteAlign)
|
||||
/** \def G3D_END_PACKED_CLASS(byteAlign)
|
||||
End switch to tight alignment
|
||||
|
||||
See G3D::Color3uint8 for an example.*/
|
||||
#ifdef _MSC_VER
|
||||
# define G3D_END_PACKED_CLASS(byteAlign) ; PRAGMA( pack(pop) )
|
||||
#elif defined(__GNUC__)
|
||||
#ifdef __GNUC__
|
||||
# define G3D_END_PACKED_CLASS(byteAlign) __attribute((aligned(byteAlign))) ;
|
||||
#elif defined(_MSC_VER)
|
||||
# define G3D_END_PACKED_CLASS(byteAlign) ; PRAGMA( pack(pop) )
|
||||
#else
|
||||
# define G3D_END_PACKED_CLASS(byteAlign) ;
|
||||
#endif
|
||||
|
||||
|
||||
// Header guard
|
||||
// Bring in shared_ptr and weak_ptr
|
||||
#if (defined(__GNUC__) && defined(__APPLE__)) || defined(__linux__)
|
||||
#include <ciso646> // Defines _LIBCC_VERSION if linking against libc++ or does nothing
|
||||
#endif
|
||||
#if (!defined(_LIBCPP_VERSION) && defined(__APPLE__)) || (!defined(_LIBCPP_VERSION) && defined(__linux__))
|
||||
# include <tr1/memory>
|
||||
#else
|
||||
# include <memory>
|
||||
#endif
|
||||
|
||||
namespace G3D {
|
||||
#if (!defined(_LIBCPP_VERSION) && defined(__APPLE__)) || (!defined(_LIBCPP_VERSION) && defined(__linux__))
|
||||
using std::tr1::shared_ptr;
|
||||
using std::tr1::weak_ptr;
|
||||
using std::tr1::dynamic_pointer_cast;
|
||||
using std::tr1::static_pointer_cast;
|
||||
using std::tr1::enable_shared_from_this;
|
||||
#else
|
||||
using std::shared_ptr;
|
||||
using std::weak_ptr;
|
||||
using std::dynamic_pointer_cast;
|
||||
using std::static_pointer_cast;
|
||||
using std::enable_shared_from_this;
|
||||
#endif
|
||||
|
||||
/** Options for initG3D and initGLG3D. */
|
||||
class G3DSpecification {
|
||||
public:
|
||||
/**
|
||||
\brief Should G3D spawn its own network thread?
|
||||
|
||||
If true, G3D will spawn a thread for network management on the first invocation of G3D::NetServer::create or
|
||||
G3D::NetConnection::connectToServer.
|
||||
|
||||
If false and networking is used, the application must explicitly invoke G3D::serviceNetwork() regularly to allow the network
|
||||
code to run.
|
||||
|
||||
In either case, the network API is threadsafe.
|
||||
|
||||
Default: true.
|
||||
*/
|
||||
bool threadedNetworking;
|
||||
|
||||
G3DSpecification() : threadedNetworking(true) {}
|
||||
|
||||
virtual ~G3DSpecification() {}
|
||||
};
|
||||
|
||||
|
||||
namespace _internal {
|
||||
/** Set by initG3D, defined in initG3D.cpp */
|
||||
G3DSpecification& g3dInitializationSpecification();
|
||||
}
|
||||
}
|
||||
|
||||
// See http://stackoverflow.com/questions/2670816/how-can-i-use-the-compile-time-constant-line-in-a-string
|
||||
// For use primarily with NUMBER_TO_STRING(__LINE__)
|
||||
#define NUMBER_TO_STRING(x) NUMBER_TO_STRING2(x)
|
||||
#define NUMBER_TO_STRING2(x) #x
|
||||
#define __LINE_AS_STRING__ NUMBER_TO_STRING(__LINE__)
|
||||
|
||||
#endif // Header guard
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user