first commit
This commit is contained in:
171
include/framework/geometry/curve.h
Normal file
171
include/framework/geometry/curve.h
Normal 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__
|
||||
Reference in New Issue
Block a user