123
This commit is contained in:
154
CryAnimation/BSplineOpen.h
Normal file
154
CryAnimation/BSplineOpen.h
Normal file
@@ -0,0 +1,154 @@
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CryEngine Source code
|
||||
//
|
||||
// File:BSplineOpen
|
||||
// Declaration of class BSplineVec3d (originally only open, but now
|
||||
// capable of being a closed spline)
|
||||
//
|
||||
// History:
|
||||
// 06/17/2002 :Created by Sergiy Migdalskiy <sergiy@crytek.de>
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
#include "BSplineKnots.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// This is a general B-Spline that can interpolate any values (like vectors or scalars)
|
||||
// that support linear combination operations + and *
|
||||
// Upon construction, you specify the number of unique knots (the extra knots are
|
||||
// automatically added to maintain inclusive boundary condition) and the degree
|
||||
// The number of control ponints you are to supply afterwards through the []
|
||||
// operator is:
|
||||
// numCPs() == nNumKnots + d - 1 // for open spline
|
||||
// numCPs() == nNumKnots - 1 // for closed spline
|
||||
// This is natural spline without derivative boundary conditions.
|
||||
// The total number of extra knots added is 2*d, d for each boundary
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
// Value is the value that's interpolated by this BSpline
|
||||
// Desc is the descriptor class with some static members describing
|
||||
// how to treat the spline: as a closed or open one
|
||||
class BSplineVec3d:
|
||||
public _reference_target_t
|
||||
{
|
||||
public:
|
||||
typedef Vec3 Value;
|
||||
typedef BSplineKnots::Time Time;
|
||||
typedef BSplineKnots::Value BlendValue;
|
||||
|
||||
// number of unique knots passed, and the degree
|
||||
// the array of control points is NOT initialized
|
||||
BSplineVec3d (int numKnots, int nDegree, bool isOpen);
|
||||
~BSplineVec3d(void);
|
||||
|
||||
bool isOpen() {return m_isOpen;}
|
||||
|
||||
// retrieves the number of basis functions (and thus unique control points) involved
|
||||
int numCPs()const
|
||||
{
|
||||
return m_isOpen ? numKnots() + m_nDegree - 1 : numKnots() - 1;
|
||||
}
|
||||
// number of unique knots maintained
|
||||
int numKnots()const
|
||||
{
|
||||
return m_Knots.numKnots() - 2 * m_nDegree;
|
||||
}
|
||||
|
||||
// retrieves a reference to the i-th control point
|
||||
Value& operator [] (int i)
|
||||
{
|
||||
assert (i >= 0 && i < numCPs());
|
||||
return m_arrCPs[i];
|
||||
}
|
||||
|
||||
// retrieves a reference to the i-th control point
|
||||
const Value& operator [] (int i)const
|
||||
{
|
||||
return getCP(i);
|
||||
}
|
||||
|
||||
// retrieves a reference to the i-th control point
|
||||
const Value& getCP (int i) const
|
||||
{
|
||||
assert (i >= 0 && i < numCPs());
|
||||
return m_arrCPs[i];
|
||||
}
|
||||
|
||||
// sets the given control point
|
||||
void setCP (int i, const Value& pt)
|
||||
{
|
||||
assert (i >= 0 && i < numCPs());
|
||||
m_arrCPs[i] = pt;
|
||||
}
|
||||
|
||||
// computes the value of the spline at the given time
|
||||
Value getValue (Time fTime)const;
|
||||
|
||||
// computes the value of the spline at the given time t
|
||||
Value operator () (Time fTime) const
|
||||
{
|
||||
return getValue (fTime);
|
||||
}
|
||||
|
||||
// sets the given unique knot time
|
||||
void setKnotTime (int nKnot, Time fTime);
|
||||
|
||||
// call this after setting all knot times
|
||||
void finalizeKnotTimes();
|
||||
|
||||
// retrieves the knot time, knot index is in the unique knot indexation (i.e. normally 0th != 1st)
|
||||
Time getKnotTime (int nKnot)const;
|
||||
|
||||
// retrives the basis function value for the given control point at the given time
|
||||
BlendValue getBasis (int nControlPoint, Time fTime) const;
|
||||
|
||||
// Returns the basis function starting at knot i (m_Knot internal numeration)
|
||||
// The function is calculated at time t, on the interval nIntervalT (m_Knot numeration)
|
||||
BlendValue getBasis (int i, Time t, int nIntervalT) const;
|
||||
|
||||
// get the d+1 derivative (delta) amplitude at knot k
|
||||
Value getDelta (int k);
|
||||
|
||||
// return the spline degree
|
||||
int getDegree()const
|
||||
{
|
||||
return m_nDegree;
|
||||
}
|
||||
|
||||
// retrives the boundaries of the influence of the given control point, in time:
|
||||
// pTime[0] is the starting knot, pTime[1] is the end knot
|
||||
// NOTE: end knot may be < start knot; it means the support interval is cyclic
|
||||
void getInfluenceInterval (int nControlPoint, int pTime[2]) const;
|
||||
|
||||
// Returns the P (product) penalty for knot closeness, as defined by Mary J. Lindstrom "Penalized Estimation of Free Knot Splines" 1999,
|
||||
// logarithmic form
|
||||
double getKnotProductPenalty()
|
||||
{
|
||||
return m_Knots.getKnotProductPenalty(m_nDegree, m_isOpen?numCPs() : m_nDegree+numKnots()-1);
|
||||
}
|
||||
|
||||
// returns the time at which the given CP has the maximum influence at the curve
|
||||
BSplineKnots::Time getCPPeak (int nControlPoint)
|
||||
{
|
||||
return m_Knots.getBasisPeak (nControlPoint + (m_isOpen?0:m_nDegree), m_nDegree);
|
||||
}
|
||||
protected:
|
||||
// Modifies the given time so that it fits inside the spline boundaries.
|
||||
void fixupTime(Time& fTime)const;
|
||||
|
||||
// degree of the spline
|
||||
const int m_nDegree;
|
||||
|
||||
// array of control ponits
|
||||
TElementaryArray<Value> m_arrCPs;
|
||||
|
||||
// knot array
|
||||
BSplineKnots m_Knots;
|
||||
|
||||
// is the spline open?
|
||||
bool m_isOpen;
|
||||
};
|
||||
|
||||
TYPEDEF_AUTOPTR(BSplineVec3d);
|
||||
Reference in New Issue
Block a user