first commit

This commit is contained in:
2026-06-22 11:49:35 +02:00
commit d805f2ba86
619 changed files with 126873 additions and 0 deletions

View File

@ -0,0 +1,184 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
------------------------------------------------------------------------------*/
#ifndef __NBOUNDINGBOX__
#define __NBOUNDINGBOX__
#include "math/matrix3.h"
namespace GS {
/*!
@short AABB.
@author Emmanuel Julien (ejulien@nworks.fr)
*/
class MinMax
{
protected:
enum
{
ClipNone = 0,
ClipRight = 1,
ClipLeft = 2,
ClipTop = 4,
ClipBottom = 8,
ClipFront = 16,
ClipBack = 32
};
/// Internal use.
uint cc_oc(const Vector4 &min, const Vector4 &max, const Vector4 &p) const
{
uint oc = ClipNone;
if (p.x > max.x) oc |= ClipRight;
else if (p.x < min.x) oc |= ClipLeft;
if (p.y > max.y) oc |= ClipTop;
else if (p.y < min.y) oc |= ClipBottom;
if (p.z > max.z) oc |= ClipBack;
else if (p.z < min.z) oc |= ClipFront;
return oc;
}
/// Internal use.
uint ss_oc(const Vector4 &p) const
{
uint oc = ClipNone;
oc |= p.x > 0 ? ClipRight : ClipLeft;
oc |= p.y > 0 ? ClipTop : ClipBottom;
oc |= p.z > 0 ? ClipBack : ClipFront;
return oc;
}
public:
Vector4 mn, mx;
/// Return the start of the interval on a given axis.
float GetMin(uint axis) const
{ return mn[axis]; }
/// Return the end of the interval on a given axis.
float GetMax(uint axis) const
{ return mx[axis]; }
/// Return whether the MinMax object overlap with another one.
bool TestAxisOverlap(const MinMax &b, uint axis) const
{ return (b.mn[axis] > mx[axis]) || (b.mx[axis] < mn[axis]) ? false : true; }
/// Intersect ray with this minmax.
bool IntersectRay(const Vector4 &o, const Vector4 &d, float &tmin, float &tmax);
/// Returns whether a line intersect with the MinMax.
bool ClassifyLine(const Vector4 &p, const Vector4 &d, Vector4 &i, Vector4 *n = 0) const;
/// Returns whether a segment intersect with the MinMax.
bool ClassifySegment(const Vector4 &p0, const Vector4 &p1, Vector4 &i, Vector4 *n = 0) const;
/// Return whether two MinMax overlap at a given time.
bool TestOverlap(const MinMax &b) const
{
if (mx.x < b.mn.x) return false;
if (mx.y < b.mn.y) return false;
if (mx.z < b.mn.z) return false;
if (b.mx.x < mn.x) return false;
if (b.mx.y < mn.y) return false;
if (b.mx.z < mn.z) return false;
return true;
}
/// Test position.
inline bool IsInside(const Vector4 &p) const
{ return (p.x < mn.x) || (p.y < mn.y) || (p.z < mn.z) || (p.x > mx.x) || (p.y > mx.y) || (p.z > mx.z) ? false : true; }
/// Grow the min~max boundaries to include another min~max structure.
void Grow(const MinMax &b)
{
mn = Vector4::Minimum(b.mn, mn);
mx = Vector4::Maximum(b.mx, mx);
}
/// Grow the min~max boundaries to include a vector.
void Grow(const Vector4 &p)
{
mn = Vector4::Minimum(p, mn);
mx = Vector4::Maximum(p, mx);
}
/// Get the min-max area.
float GetArea() const
{ return (mx.x - mn.x) * (mx.y - mn.y) * (mx.z - mn.z); }
/// Get the min-max center.
Vector4 GetCenter() const
{ return (mn + mx) * 0.5f; }
/// Set min-max.
void Set(const Vector4 &min, const Vector4 &max)
{ mn = min; mx = max; }
/// Set from position and size.
void SetFromPositionSize(const Vector4 &p, const Vector4 &s)
{
mn = p - s * 0.5f;
mx = p + s * 0.5f;
}
void Reset()
{ mn.Set(); mx.Set(); }
/*!
@name Serialization
@{
*/
bool FromMetaTag(NML::Tag &tag);
NML::Tag *AsMetaTag();
/// @}
MinMax() : mn(0, 0, 0), mx(0, 0, 0) {}
MinMax(const Vector4 &min, const Vector4 &max) : mn(min), mx(max) {}
};
/*!
@short Oriented bounding box.
@author Emmanuel Julien (ejulien@nworks.fr)
*/
struct OBB
{
Vector4 bb_position;
Vector4 bb_scale;
Matrix3 bb_rotation;
/// Compute the min/max of the OBB.
void ComputeMinMax(MinMax &minmax);
/*!
@short Transform OBB.
@warning Scaling is not supported.
*/
void Transform(const Matrix4 &mtx);
/// OBB from min~max.
static OBB FromMinMax(const MinMax &minmax)
{ return OBB((minmax.mn + minmax.mx) * 0.5f, minmax.mx - minmax.mn); }
bool FromMetaTag(NML::Tag &tag);
NML::Tag *AsMetaTag();
OBB(const MinMax &minmax)
{ *this = FromMinMax(minmax); }
OBB(const Vector4 &p, const Vector4 &s, const Matrix3 *m = 0)
{
bb_position = p;
bb_scale = s;
if (m)
bb_rotation = *m;
}
OBB() {}
};
} // GS
#endif // __NBOUNDINGBOX__

View File

@ -0,0 +1,171 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NCURVE__
#define __NCURVE__
#include "math/nmath.h"
#include "metafile/nml.h"
#include "reflection/nenum_string.h"
#include "container/narray_list.h"
#include "time/ntime_range.h"
#include "time/ntime.h"
namespace GS {
static const float DefaultCurveOptimizationThreshold = 0.05f;
/*
@short Curve control point.
@author Emmanuel Julien (ejulien@nworks.fr)
*/
struct CurvePoint
{
NPLACEMENT_NEW(Curve)
/// Curve control point shape.
enum Shape
{
Shape_None = 0,
Shape_Linear,
Shape_TCB,
Shape_Hermite,
Shape_Bezier,
Shape_Bezier2,
Shape_Step
};
Shape shape;
Time t;
float v,
tension, continuity, bias,
param[4]; //< TCB parameters.
CurvePoint(const Time &time, float value, Shape shp = Shape_Linear) : t(time), v(value), shape(shp)
{
tension = 0;
continuity = 0;
bias = 0;
param[0] = param[1] = param[2] = param[3] = 0;
}
CurvePoint() : t(0), v(0), shape(Shape_Linear)
{
tension = 0;
continuity = 0;
bias = 0;
param[0] = param[1] = param[2] = param[3] = 0;
}
};
/*!
@short Curve object.
@author Emmanuel Julien (ejulien@nworks.fr)
*/
class Curve
{
public:
NPLACEMENT_NEW(Curve)
enum LoopMode
{
Reset = 0, ///< Returns 0.
Constant, ///< Returns first/last knot value.
Repeat, ///< Warp evaluation time to a value inside curve range and evaluate.
Oscillate, ///< Ping-pong style evaluation.
OffsetAndRepeat ///< Same as repeat but the whole curve is offset with the last knot value.
};
static Reflection::Enum::Dict loop_mode_dict[];
protected:
ArrayList <CurvePoint *> points; ///< Curve knots.
uint Optimize(uint point_count, const CurvePoint *src, CurvePoint *dst, float threshold);
public:
/// Evaluate curve at a given time.
void Evaluate(Time t, float *value, LoopMode loop_mode = Constant, Time loop_start = Time::Inf, Time loop_end = Time::Inf) const;
/// Evaluate incoming tangent to the curve.
float Incoming(const CurvePoint *kf0, const CurvePoint *kf1, const CurvePoint *kf2) const;
/// Evaluate outgoing tangent to the curve.
float Outgoing(const CurvePoint *kf0, const CurvePoint *kf1, const CurvePoint *kfp) const;
/*!
@short Update a control point.
@note The time epsilon is considered on both side of the control
points time. If no point to update is found a new point is
inserted.
*/
void Update(const CurvePoint &, const Time &t_epsilon);
/// Insert a control point.
void Insert(const CurvePoint &);
/// Append a control point to the control point list.
void Append(const CurvePoint &);
/// Delete a curve control point from the channel.
void Delete(CurvePoint *);
/// Get curve time range, very fast.
TimeRange GetTimeRange() const;
/// Get curve value range, requires a full parsing of the knot list.
Range <float> GetValueRange() const;
/// Get curve range length in time.
Time GetDuration() const { return GetTimeRange().valueRange(); }
/// Optimize curve removing the less influential knots.
uint Optimize(float threshold = DefaultCurveOptimizationThreshold);
/// Return the curve control points as an array.
ArrayList <CurvePoint *> &GetPoints() { return points; }
/// Return the number of control point in curve.
uint GetPointCount() const { return points.GetCount(); }
/// Sort curve point array by time.
void Sort();
/*!
@short Set a control point content.
@Note This function does modify the internal ordering of the curve
keys in order to keep them time ordered.
Please use the Sort() function to make sure the curve can
still be correctly evaluated after a key time modification.
*/
void SetPoint(uint index, const CurvePoint &content) const;
/// Allocate a set of control points.
bool AllocatePoint(uint n);
/*!
@short Return the closest point on curve to a given time position.
The default behavior is to return the first point whose time is
greater than the query time.
*/
int GetPointIndex(const Time &time, bool t_greater_than = true) const;
void Clear();
virtual size_t MemoryFootPrint() const { return size_t(points.GetCount()) * sizeof(CurvePoint) + sizeof(Curve); }
bool FromMetaTag(NML::Tag &);
NML::Tag *AsMetaTag() const;
virtual ~Curve();
};
} // GS
#endif // __NCURVE__

View File

@ -0,0 +1,76 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NFRUSTRUM__
#define __NFRUSTRUM__
#include "geometry/plane.h"
class nMatrix4;
namespace GS {
struct Shape;
class MinMax;
/*!
@short Frustum.
@author Emmanuel Julien (ejulien@nworks.fr)
*/
class Frustum
{
public:
enum Visibility
{
Outside = 0,
Inside,
Clipped
};
enum VolumePlane
{
Top = 0,
Bottom,
Left,
Right,
Near,
Far
};
protected:
Vector4 vtx[8]; ///< Frustum vertices.
Plane plane[6]; ///< Frustum planes.
public:
inline const Vector4 *GetVertices() const { return vtx; }
/// Compute perspective frustum volume planes.
void SetPerspective(float fov, float near, float far, const Matrix4 *m = 0, float h_ar = 1, float v_ar = 1);
/// Compute orthographic frustum volume planes.
void SetOrthographic(float width, float height, float near, float far, const Matrix4 *m = 0, float h_ar = 1, float v_ar = 1);
/// Return the visibility flag of a vector set against this frustum.
Visibility ClassifySet(uint count, const Vector4 * const GSRESTRICT set, const float offset = 0) const;
/// Return the visibility flag of a frustum against this frustum.
Visibility ClassifyFrustrum(const Frustum &frustum) const;
/// Return the visibility flag of a sphere against this frustum.
Visibility ClassifySphere(const Vector4 &p, float r) const;
/// Return the visibility flag of a minmax against this frustum.
Visibility ClassifyMinMax(const MinMax &mm, const Matrix4 *m = 0) const;
/// Return the visibility flag of a shape against this frustum.
Visibility ClassifyShape(const Shape &s, const Matrix4 *m = 0) const;
};
} // GS
#endif // __NFRUSTRUM__

View File

@ -0,0 +1,103 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NGEOMETRICTOOLS__
#define __NGEOMETRICTOOLS__
#include "math/vector.h"
namespace GS {
namespace Geometric {
/// Compute 2d triangle area.
float TriArea2D(float x0, float y0, float x1, float y1, float x2, float y2);
/*!
@short Test intersection between a ray and a plane.
@param a Origin of the ray.
@param v Direction of the ray.
@param n Normal of the plane.
@param p A point on the plane.
@param t Output, the parametric 't' value of the point of
intersection.
@return False if the ray is embedded in or coplanar to the plane.
True otherwise.
*/
bool LineIntersectPlane(const Vector4 &a, const Vector4 &v, const Vector4 &n, const Vector4 &p, float &t);
/*!
@short Compute barycentric coordinates.
*/
void Barycentric(const Vector4 &a, const Vector4 &b, const Vector4 &c, const Vector4 &p, float &u, float &v, float &w);
/*!
@short Test intersection between a ray and a plane.
@param a Origin of the ray.
@param v Normalized direction of the ray.
@param c Center of the sphere.
@param r Radius of the sphere.
@param t Output, the parametric 't' value of the points of
intersection. t[0] is the closest point of
intersection to the origin of the ray.
@return False if no intersection.
*/
bool LineIntersectSphere(const Vector4 &a, const Vector4 &v, const Vector4 &c, float r, float t[2]);
/*!
@short Determine the closest points between two lines.
@param a First point on first line.
@param b Second point on first line.
@param u First point on second line.
@param v Second point on second line.
@param t Output, the parametric 't' values of the closest
points on each line. t[0] belongs to (a;b), t[1]
belongs to (u;v).
@return False if both lines are parallel.
*/
bool LineClosestPointToLine(const Vector4 &a, const Vector4 &b, const Vector4 &u, const Vector4 &v, float t[2]);
/*!
@short Determine the closest point to a line from a position in space.
@param a First point on line.
@param b Second point on line.
@param u Location.
@param i Output the closest point on line to u.
@return t Parametric position of i on the [a;b] segment.
If t < 0 or t > 1 then i lies outside the [a;b] segment.
*/
float LineClosestPoint(const Vector4 &a, const Vector4 &b, const Vector4 &u, Vector4 *p = 0);
/*!
@short Determine the closest point to a segment from a position in space.
@param a First point on segment.
@param b Second point on segment.
@param u Location.
@param i Output the closest point on segment to u.
@return t Parametric position of i on the [a;b] segment.
*/
float SegmentClosestPoint(const Vector4 &a, const Vector4 &b, const Vector4 &u, Vector4 *p = 0);
} // Geometric
} // GS
#endif // __NGEOMETRICTOOLS__

View File

@ -0,0 +1,55 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NPLANE__
#define __NPLANE__
#include "math/vector.h"
namespace GS {
/*!
@short Plane.
ax + by + cz + d = 0
@author Emmanuel Julien (ejulien@nworks.fr)
*/
class Plane
{
float d; ///< Distance to origin.
Vector4 p, n; ///< Point in plane and normal.
public:
/// Return plane normal.
inline const Vector4 &GetNormal() const
{ return n; }
/*!
@short Return point distance to plane.
Distance is signed, positive when the point is in front of the plane,
negative otherwise.
*/
inline float DistanceToPlane(const Vector4 &p) const
{ return p.Dot(n) + d; }
/// Set plane from point/normal and an optional transformation matrix.
void Set(const Vector4 *_p, const Vector4 &_n, const Matrix4 * = 0);
/// Set plane three vectors and an optional transformation matrix.
void Set(const Vector4 _p[3], const Matrix4 * = 0);
Plane();
Plane(const Vector4 &_p, const Vector4 &_n, const Matrix4 *_m = 0)
{ Set(&_p, _n, _m); }
};
} // GS
#endif // __NPLANE__

View File

@ -0,0 +1,112 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NRECT__
#define __NRECT__
#include "ntypes.h"
namespace GS {
namespace NML {
class File;
class Tag;
}
/*!
@short Point.
@author Emmanuel Julien (ejulien@nworks.fr)
*/
template <class T> struct Point
{
T x, y;
T operator [] (size_t n) const { return *(&x + n); }
void Set(T _x, T _y)
{ x = _x; y = _y; }
Point(T ux, T uy) : x(ux), y(uy) {}
Point() : x(0), y(0) {}
};
typedef Point <int> iPoint;
typedef Point <float> fPoint;
/*!
@short Rectangle.
@author Emmanuel Julien (ejulien@nworks.fr)
*/
template <class T> struct Rect
{
T sx, sy, ex, ey;
void SetWidth(T w) { ex = sx + w; }
void SetHeight(T h) { ey = sy + h; }
T GetWidth() const { return ex - sx; }
T GetHeight() const { return ey - sy; }
Rect <T> operator * (T v) const
{ return Rect <T> (sx * v, sy * v, ex * v, ey * v); }
Rect <T> operator / (T v) const
{ return Rect <T> (sx / v, sy / v, ex / v, ey / v); }
bool Inside(T x, T y) const
{ return (x > sx) && (y > sy) && (x < ex) && (y < ey); }
bool FitsInside(const Rect <T> &b) const
{ return (GetWidth() <= b.GetWidth()) && (GetHeight() <= b.GetHeight()); }
bool Intersect(const Rect <T> &b) const
{ return ((ex < b.sx) || (ey < b.sy) || (sx > b.ex) || (sy > b.ey)) ? false : true; }
Rect <T> Intersection(const Rect <T> &b) const
{
T _sx = Types::Max(sx, b.sx), _sy = Types::Max(sy, b.sy),
_ex = Types::Min(ex, b.ex), _ey = Types::Min(ey, b.ey);
T n_sx = Types::Min(_sx, _ex), n_sy = Types::Min(_sy, _ey),
n_ex = Types::Max(_sx, _ex), n_ey = Types::Max(_sy, _ey);
return Rect <T> (_sx = n_sx, _sy = n_sy, _ex = n_ex, _ey = n_ey);
}
Rect <T> Grow(T border) const
{ return Rect <T> (sx - border, sy - border, ex + border, ey + border); }
void Set(T usx, T usy, T uex, T uey)
{ sx = usx; sy = usy; ex = uex; ey = uey; }
void Set(T ux = 0, T uy = 0)
{ sx = ux; sy = uy; ex = ux; ey = uy; }
Rect <T> Offset(T x, T y) const
{ return Rect <T> (sx + x, sy + y, ex + x, ey + y); }
Rect <float> AsFloat() const
{ return Rect <float> (float(sx), float(sy), float(ex), float(ey)); }
Rect <int> AsInt() const
{ return Rect <int> (int(sx), int(sy), int(ex), int(ey)); }
NML::Tag *AsMetaTag(const char *id) const;
bool FromMetaTag(NML::Tag &);
static Rect <T> FromWidthHeight(T sx, T sy, T w, T h)
{ return Rect <T> (sx, sy, sx + w, sy + h); }
Rect(const Rect <T> &b) : sx(b.sx), sy(b.sy), ex(b.ex), ey(b.ey) {}
Rect(T usx, T usy, T uex, T uey) : sx(usx), sy(usy), ex(uex), ey(uey) {}
Rect(T usx, T usy) : sx(usx), ex(usx), sy(usy), ey(usy) {}
Rect() : sx(0), sy(0), ex(0), ey(0) {}
};
typedef Rect <int> iRect;
typedef Rect <float> fRect;
} // GS
#endif // __NRECT__

View File

@ -0,0 +1,59 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NSAT__
#define __NSAT__
#include <float.h>
namespace GS {
namespace SAT {
/// SAT overlap test results.
enum Overlap
{
Outside = 0,
Inside, // B inside A
Clipped
};
/// Helper function to test overlap on a given axis.
Overlap TestOverlap(const Vector4 &axis, int ca, const Vector4 *a, int cb, const Vector4 *b)
{
// A interval.
float a_mn = FLT_MAX, a_mx = -FLT_MAX;
for (int n = 0; n < ca; ++n)
{
float d = axis.Dot(a[n]);
if (d < a_mn) a_mn = d;
if (d > a_mx) a_mx = d;
}
// B interval.
float b_mn = FLT_MAX, b_mx = -FLT_MAX;
for (int n = 0; n < cb; ++n)
{
float d = axis.Dot(b[n]);
if (d < b_mn) b_mn = d;
if (d > b_mx) b_mx = d;
}
// Test overlap.
if ((a_mx < b_mn) || (a_mn > b_mx))
return Outside;
if ((b_mn > a_mn) && (b_mx < a_mx))
return Inside;
return Clipped;
}
} // SAT
} // GS
#endif // __NSAT__