CubicSpline class created. Temp spline rendering stuff in AMV.
This commit is contained in:
@@ -4,6 +4,11 @@ The StepMania 5 Changelog covers all post-sm-ssc changes. For a list of changes
|
||||
from StepMania 4 alpha 5 to sm-ssc v1.2.5, see Changelog_sm-ssc.txt.
|
||||
________________________________________________________________________________
|
||||
|
||||
2014/12/26
|
||||
----------
|
||||
* [NoteField] Columns turned into actors that can be fetched with
|
||||
GetColumnActors. [kyzentun]
|
||||
|
||||
2014/12/20
|
||||
----------
|
||||
* [Preferences] AllowMultipleHighScoreWithSameName, ComboContinuesBetweenSongs
|
||||
|
||||
@@ -272,6 +272,7 @@
|
||||
<Function name='GetDiffuse'/>
|
||||
<Function name='GetDiffuseAlpha'/>
|
||||
<Function name='GetEffectDelta'/>
|
||||
<Function name='GetFakeParent'/>
|
||||
<Function name='GetGlow'/>
|
||||
<Function name='GetHAlign'/>
|
||||
<Function name='GetHeight'/>
|
||||
@@ -301,6 +302,7 @@
|
||||
<Function name='Real'/>
|
||||
<Function name='RealInverse'/>
|
||||
<Function name='RunCommandsRecursively'/>
|
||||
<Function name='SetFakeParent'/>
|
||||
<Function name='SetHeight'/>
|
||||
<Function name='SetSize'/>
|
||||
<Function name='SetTextureFiltering'/>
|
||||
@@ -968,6 +970,7 @@
|
||||
<Class base='ActorFrame' name='NoteField'>
|
||||
<Function name='DidHoldNote'/>
|
||||
<Function name='DidTapNote'/>
|
||||
<Function name='GetColumnActors'/>
|
||||
<Function name='SetPressed'/>
|
||||
<Function name='SetDidHoldNoteCallback'/>
|
||||
<Function name='SetDidTapNoteCallback'/>
|
||||
|
||||
@@ -831,6 +831,12 @@ save yourself some time, copy this for undocumented things:
|
||||
<Function name='GetParent' return='Actor' arguments=''>
|
||||
Returns the Actor's parent, or <code>nil</code> if it doesn't have one.
|
||||
</Function>
|
||||
<Function name='GetFakeParent' return='Actor' arguments=''>
|
||||
Returns the Actor's fake parent, or <code>nil</code> if it doesn't have one.
|
||||
</Function>
|
||||
<Function name='SetFakeParent' return='' arguments='Actor p'>
|
||||
Sets the Actor's fake parent to p, or clears it if p is nil.
|
||||
</Function>
|
||||
<Function name='GetVisible' return='bool' arguments=''>
|
||||
Returns the Actor's visibility.
|
||||
</Function>
|
||||
@@ -2953,6 +2959,9 @@ save yourself some time, copy this for undocumented things:
|
||||
Makes the NoteField act as if a tap note was hit in the column, with the given score and bright setting. <br />
|
||||
The callback for DidTapNote will not be called.
|
||||
</Function>
|
||||
<Function name='GetColumnActors' return='{actor}' arguments=''>
|
||||
Returns a table of the actors for the columns.
|
||||
</Function>
|
||||
<Function name='SetDidHoldNoteCallback' return= '' arguments='function callback'>
|
||||
Same as SetDidTapNoteCallback, but for hold notes. Uses HoldNoteScore instead of TapNoteScore.
|
||||
</Function>
|
||||
|
||||
@@ -1739,6 +1739,32 @@ public:
|
||||
pParent->PushSelf(L);
|
||||
return 1;
|
||||
}
|
||||
static int GetFakeParent(T* p, lua_State *L)
|
||||
{
|
||||
Actor* fake= p->GetFakeParent();
|
||||
if(fake == NULL)
|
||||
{
|
||||
lua_pushnil(L);
|
||||
}
|
||||
else
|
||||
{
|
||||
fake->PushSelf(L);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
static int SetFakeParent(T* p, lua_State* L)
|
||||
{
|
||||
if(lua_isnoneornil(L, 1))
|
||||
{
|
||||
p->SetFakeParent(NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
Actor* fake= Luna<Actor>::check(L, 1);
|
||||
p->SetFakeParent(fake);
|
||||
}
|
||||
COMMON_RETURN_SELF;
|
||||
}
|
||||
static int Draw( T* p, lua_State *L )
|
||||
{
|
||||
LUA->YieldLua();
|
||||
@@ -1910,6 +1936,8 @@ public:
|
||||
|
||||
ADD_METHOD( GetName );
|
||||
ADD_METHOD( GetParent );
|
||||
ADD_METHOD( GetFakeParent );
|
||||
ADD_METHOD( SetFakeParent );
|
||||
|
||||
ADD_METHOD( Draw );
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "RageLog.h"
|
||||
#include "RageDisplay.h"
|
||||
#include "RageTexture.h"
|
||||
#include "RageTimer.h"
|
||||
#include "RageUtil.h"
|
||||
#include "ActorUtil.h"
|
||||
#include "Foreach.h"
|
||||
@@ -62,6 +63,9 @@ ActorMultiVertex::ActorMultiVertex()
|
||||
|
||||
_EffectMode = EffectMode_Normal;
|
||||
_TextureMode = TextureMode_Modulate;
|
||||
_using_spline= false;
|
||||
_spline.redimension(3);
|
||||
_spline.loop= false;
|
||||
}
|
||||
|
||||
ActorMultiVertex::~ActorMultiVertex()
|
||||
@@ -73,6 +77,8 @@ ActorMultiVertex::ActorMultiVertex( const ActorMultiVertex &cpy ):
|
||||
Actor( cpy )
|
||||
{
|
||||
#define CPY(a) a = cpy.a
|
||||
CPY( _spline );
|
||||
CPY( _using_spline );
|
||||
CPY( AMV_Tweens );
|
||||
CPY( AMV_current );
|
||||
CPY( AMV_start );
|
||||
@@ -194,6 +200,75 @@ void ActorMultiVertex::SetVertexCoords( int index, float TexCoordX, float TexCoo
|
||||
AMV_DestTweenState().vertices[index].t = RageVector2( TexCoordX, TexCoordY );
|
||||
}
|
||||
|
||||
bool ActorMultiVertex::GetUseSpline()
|
||||
{
|
||||
return _using_spline;
|
||||
}
|
||||
|
||||
void ActorMultiVertex::SetUseSpline(bool use)
|
||||
{
|
||||
_using_spline= use;
|
||||
}
|
||||
|
||||
void ActorMultiVertex::SplineSetPoint(size_t i, float x , float y , float z)
|
||||
{
|
||||
vector<float> v(3);
|
||||
v[0]= x; v[1]= y; v[2]= z;
|
||||
_spline.set_point(i, v);
|
||||
}
|
||||
|
||||
void ActorMultiVertex::SplineResize(size_t s)
|
||||
{
|
||||
_spline.resize(s);
|
||||
}
|
||||
|
||||
size_t ActorMultiVertex::SplineSize()
|
||||
{
|
||||
return _spline.size();
|
||||
}
|
||||
|
||||
void ActorMultiVertex::SplineSolve()
|
||||
{
|
||||
if(_spline.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
_spline.solve();
|
||||
float num_parts= 0.0f;
|
||||
size_t num_verts= GetNumVertices();
|
||||
switch(GetDestDrawMode())
|
||||
{
|
||||
case DrawMode_Quads:
|
||||
break;
|
||||
case DrawMode_QuadStrip:
|
||||
break;
|
||||
case DrawMode_Fan:
|
||||
break;
|
||||
case DrawMode_Strip:
|
||||
break;
|
||||
case DrawMode_Triangles:
|
||||
break;
|
||||
case DrawMode_LineStrip:
|
||||
{
|
||||
float conversion= static_cast<float>(_spline.size()-1) / static_cast<float>(num_verts-1);
|
||||
if(_spline.loop)
|
||||
{
|
||||
conversion= static_cast<float>(_spline.size()) / static_cast<float>(num_verts-1);
|
||||
}
|
||||
for(size_t i= 0; i < num_verts; ++i)
|
||||
{
|
||||
float t= i * conversion;
|
||||
vector<float> p;
|
||||
_spline.evaluate(t, p);
|
||||
SetVertexPos(i, p[0], p[1], p[2]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DrawMode_SymmetricQuadStrip:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ActorMultiVertex::DrawPrimitives()
|
||||
{
|
||||
Actor::SetGlobalRenderStates(); // set Actor-specified render states
|
||||
@@ -658,6 +733,48 @@ public:
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
DEFINE_METHOD(GetUseSpline, GetUseSpline());
|
||||
DEFINE_METHOD(SplineGetLoop, SplineGetLoop());
|
||||
static int SplineSetLoop(T* p, lua_State* L)
|
||||
{
|
||||
p->SplineSetLoop(lua_toboolean(L, 1));
|
||||
COMMON_RETURN_SELF;
|
||||
}
|
||||
static int SplineSize(T* p, lua_State* L)
|
||||
{
|
||||
lua_pushnumber(L, p->SplineSize());
|
||||
return 1;
|
||||
}
|
||||
static int SetUseSpline(T* p, lua_State* L)
|
||||
{
|
||||
p->SetUseSpline(lua_toboolean(L, 1));
|
||||
COMMON_RETURN_SELF;
|
||||
}
|
||||
static int SplineSetPoint(T* p, lua_State* L)
|
||||
{
|
||||
size_t i= IArg(1)-1;
|
||||
if(i >= p->SplineSize())
|
||||
{
|
||||
luaL_error(L, "Spline point index greater than the number of points.");
|
||||
}
|
||||
p->SplineSetPoint(i, FArg(2), FArg(3), FArg(4));
|
||||
COMMON_RETURN_SELF;
|
||||
}
|
||||
static int SplineResize(T* p, lua_State* L)
|
||||
{
|
||||
int s= IArg(1);
|
||||
if(s < 0)
|
||||
{
|
||||
luaL_error(L, "Negative spline size not allowed.");
|
||||
}
|
||||
p->SplineResize(static_cast<size_t>(s));
|
||||
COMMON_RETURN_SELF;
|
||||
}
|
||||
static int SplineSolve(T* p, lua_State* L)
|
||||
{
|
||||
p->SplineSolve();
|
||||
COMMON_RETURN_SELF;
|
||||
}
|
||||
|
||||
LunaActorMultiVertex()
|
||||
{
|
||||
@@ -679,6 +796,15 @@ public:
|
||||
ADD_METHOD( GetCurrFirstToDraw );
|
||||
ADD_METHOD( GetCurrNumToDraw );
|
||||
|
||||
ADD_METHOD(GetUseSpline);
|
||||
ADD_METHOD(SetUseSpline);
|
||||
ADD_METHOD(SplineGetLoop);
|
||||
ADD_METHOD(SplineSetLoop);
|
||||
ADD_METHOD(SplineSize);
|
||||
ADD_METHOD(SplineResize);
|
||||
ADD_METHOD(SplineSetPoint);
|
||||
ADD_METHOD(SplineSolve);
|
||||
|
||||
// Copy from RageTexture
|
||||
ADD_METHOD( SetTexture );
|
||||
ADD_METHOD( GetTexture );
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "Actor.h"
|
||||
#include "RageDisplay.h"
|
||||
#include "RageMath.h"
|
||||
#include "RageTextureID.h"
|
||||
|
||||
enum DrawMode
|
||||
@@ -102,11 +103,23 @@ public:
|
||||
void SetVertexColor( int index , RageColor c );
|
||||
void SetVertexCoords( int index , float TexCoordX , float TexCoordY );
|
||||
|
||||
bool GetUseSpline();
|
||||
void SetUseSpline(bool use);
|
||||
bool SplineGetLoop() { return _spline.loop; }
|
||||
void SplineSetLoop(bool loop) { _spline.loop= loop; }
|
||||
void SplineSetPoint(size_t i, float x , float y , float z);
|
||||
void SplineResize(size_t s);
|
||||
size_t SplineSize();
|
||||
void SplineSolve();
|
||||
|
||||
virtual void PushSelf( lua_State *L );
|
||||
|
||||
private:
|
||||
RageTexture* _Texture;
|
||||
|
||||
CubicSplineN _spline;
|
||||
bool _using_spline;
|
||||
|
||||
vector<RageSpriteVertex> _Vertices;
|
||||
vector<AMV_TweenState> AMV_Tweens;
|
||||
AMV_TweenState AMV_current;
|
||||
|
||||
+2
-2
@@ -179,7 +179,7 @@ private:
|
||||
float m_fYReverseOffsetPixels;
|
||||
};
|
||||
|
||||
// So, this is a bit screwy, and it's all because routine forces rendering
|
||||
// So, this is a bit screwy, and it's partly because routine forces rendering
|
||||
// notes from different noteskins in the same column.
|
||||
// NoteColumnRenderer exists to hold all the data needed for rendering a
|
||||
// column and apply any transforms from that column's actor to the
|
||||
@@ -188,7 +188,7 @@ private:
|
||||
// actors so they can move with the rest of the column. I didn't use
|
||||
// ActorProxy because the receptor/ghost actors need to pull in the parent
|
||||
// state of their rows and the parent state of the column. -Kyz
|
||||
class NoteColumnRenderer : public ActorFrame
|
||||
class NoteColumnRenderer : public Actor
|
||||
{
|
||||
public:
|
||||
NoteDisplay* m_displays[PLAYER_INVALID+1];
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
#include "global.h"
|
||||
#include "RageLog.h"
|
||||
#include "RageMath.h"
|
||||
#include "RageTypes.h"
|
||||
#include <float.h>
|
||||
@@ -695,6 +696,265 @@ void RageBezier2D::SetFromBezier(
|
||||
m_Y.SetFromBezier( fC1Y, fC2Y, fC3Y, fC4Y );
|
||||
}
|
||||
|
||||
// CubicSpline implementation written by Kyzentun 2014/12/27
|
||||
|
||||
void CubicSpline::solve_looped()
|
||||
{
|
||||
if(check_minimum_size()) { return; }
|
||||
size_t last= m_points.size();
|
||||
vector<float> results(m_points.size());
|
||||
vector<float> diagonals(m_points.size());
|
||||
results[0]= 3 * (m_points[1].a - m_points[last-1].a);
|
||||
diagonals[0]= 4.0f;
|
||||
prep_inner(last, diagonals, results);
|
||||
results[last-1]= 3 * (m_points[0].a - m_points[last-2].a);
|
||||
diagonals[last-1]= 4.0f;
|
||||
|
||||
// The steps to solve the system of equations look like this:
|
||||
// | 4 1 0 0 1 | -> | 4 0 0 0 1 | -> | 4 0 0 0 0 | -> | 4 0 0 0 0 |
|
||||
// | 1 4 1 0 0 | -> | 0 d 1 0 x | -> | 0 d 1 0 x | -> | 0 d 0 0 x |
|
||||
// | 0 1 4 1 0 | -> | 0 1 4 1 0 | -> | 0 1 4 1 0 | -> | 0 0 d 1 x |
|
||||
// | 0 0 1 4 1 | -> | 0 0 1 4 1 | -> | 0 0 1 4 1 | -> | 0 0 1 4 1 |
|
||||
// | 1 0 0 1 4 | -> | 1 x 0 1 4 | -> | 0 x 0 1 q | -> | 0 x x 1 q |
|
||||
// V
|
||||
// | 4 0 0 0 0 | -> | 4 0 0 0 0 | -> | 4 0 0 0 0 | -> | 4 0 0 0 0 |
|
||||
// | 0 d 0 0 0 | -> | 0 d 0 0 0 | -> | 0 d 0 0 0 | -> | 0 d 0 0 0 |
|
||||
// | 0 0 d 1 x | -> | 0 0 d 0 x | -> | 0 0 d 0 0 | -> | 0 0 d 0 0 |
|
||||
// | 0 0 1 d 1 | -> | 0 0 0 d n | -> | 0 0 0 d n | -> | 0 0 0 d 0 |
|
||||
// | 0 0 x 1 r | -> | 0 0 x n r | -> | 0 0 0 n s | -> | 0 0 0 0 t |
|
||||
// Each time through the loop performs two of these steps, 4 operations.
|
||||
|
||||
size_t end= last-1;
|
||||
size_t stop= end-1;
|
||||
float cedge= 1.0f; // [ri][cl]
|
||||
float redge= 1.0f; // [rl][ci]
|
||||
// The loop stops before end because the case where [ri][cl] == [ri][ci+1]
|
||||
// needs special handling.
|
||||
for(size_t i= 0; i < stop; ++i)
|
||||
{
|
||||
float next_cedge= 0.0f; // [ri+1][ce]
|
||||
float next_redge= 0.0f; // [re][ci+1]
|
||||
// Operation: Add col[i] / -[ri][ci] to col[i+1] to zero [ri][ci+1].
|
||||
float diag_recip= 1.0f / diagonals[i];
|
||||
diagonals[i+1]-= diag_recip;
|
||||
next_redge-= redge * diag_recip;
|
||||
// Operation: Add row[i] / -[ri][ci] to row[i+1] to zero [ri+1][ci].
|
||||
results[i+1]-= results[i] * diag_recip;
|
||||
next_cedge-= cedge * diag_recip;
|
||||
// Operation: Add col[i] * -(cedge/[ri][ci]) to col[e] to zero cedge.
|
||||
diagonals[end]-= redge * (cedge / diagonals[i]);
|
||||
cedge= next_cedge; // Do not use cedge after this point in the loop.
|
||||
// Operation: Add row[i] * -(redge/[ri][ci]) to row[e] to zero redge.
|
||||
results[end]-= results[i] * (redge / diagonals[i]);
|
||||
redge= next_redge; // Do not use redge after this point in the loop.
|
||||
}
|
||||
// [rs][ce] is 1 - cedge, [re][cs] is 1 - redge
|
||||
// Operation: Add col[s] * -([rs][ce] / [rs][cs]) to col[e] to zero redge.
|
||||
diagonals[end]-= redge * ((1.0f - cedge) / diagonals[stop]);
|
||||
// Operation: Add row[s] * -([re][cs] / [rs][cs]) to row[e] to zero redge.
|
||||
results[end]-= results[stop] * ((1.0f - redge) / diagonals[stop]);
|
||||
|
||||
set_results(last, diagonals, results);
|
||||
}
|
||||
|
||||
void CubicSpline::solve_straight()
|
||||
{
|
||||
if(check_minimum_size()) { return; }
|
||||
size_t last= m_points.size();
|
||||
vector<float> results(m_points.size());
|
||||
vector<float> diagonals(m_points.size());
|
||||
results[0]= 3 * (m_points[1].a - m_points[0].a);
|
||||
diagonals[0]= 2.0f;
|
||||
prep_inner(last, diagonals, results);
|
||||
results[last-1]= 3 * (m_points[last-1].a - m_points[last-2].a);
|
||||
diagonals[last-1]= 2.0f;
|
||||
|
||||
// The system of equations to be solved looks like this:
|
||||
// | 2 1 0 0 | = | results[0] |
|
||||
// | 1 4 1 0 | = | results[1] |
|
||||
// | 0 1 4 1 | = | results[2] |
|
||||
// | 0 0 1 2 | = | results[3] |
|
||||
// Operations are carefully chosen to only modify the values in the
|
||||
// diagonals and the results, leaving the 1s unchanged.
|
||||
// Operation: Add col[0] * -.5 to col[1] to zero [r0][c1].
|
||||
diagonals[1]-= .5f;
|
||||
// Operation: Add row[0] * -.5 to row[1] to zero [r1][c0].
|
||||
results[1]-= results[0] * .5f;
|
||||
for(size_t i= 1; i < last - 1; ++i)
|
||||
{
|
||||
float diag_recip= 1.0f / diagonals[i];
|
||||
// Operation: Add col[i] / -[ri][ci] to col[i+1] to zero [ri][ci+1].
|
||||
diagonals[i+1]-= diag_recip;
|
||||
// Operation: Add row[i] / -[ri][ci] to row[i+1] to zero [ri+1][ci];
|
||||
results[i]-= results[i-1] * diag_recip;
|
||||
}
|
||||
set_results(last, diagonals, results);
|
||||
}
|
||||
|
||||
bool CubicSpline::check_minimum_size()
|
||||
{
|
||||
size_t last= m_points.size();
|
||||
if(last < 2) { return true; }
|
||||
if(last == 2)
|
||||
{
|
||||
m_points[0].b= m_points[1].a - m_points[0].a;
|
||||
m_points[0].c= m_points[0].d= 0.0f;
|
||||
// These will be used in the looping case.
|
||||
m_points[1].b= m_points[0].a - m_points[1].a;
|
||||
m_points[1].c= m_points[1].d= 0.0f;
|
||||
return true;
|
||||
}
|
||||
float a= m_points[0].a;
|
||||
for(size_t i= 1; i < m_points.size(); ++i)
|
||||
{
|
||||
m_points[i].b= m_points[i].c= m_points[i].d= 0.0f;
|
||||
if(m_points[i].a != a) { return false; }
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CubicSpline::prep_inner(size_t last, vector<float>& diagonals, vector<float>& results)
|
||||
{
|
||||
for(size_t i= 1; i < last - 1; ++i)
|
||||
{
|
||||
results[i]= 3 * (m_points[i+1].a - m_points[i-1].a);
|
||||
diagonals[i]= 4.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void CubicSpline::set_results(size_t last, vector<float>& diagonals, vector<float>& results)
|
||||
{
|
||||
// No more operations left, everything not a diagonal should be zero now.
|
||||
for(size_t i= 0; i < last; ++i)
|
||||
{
|
||||
results[i]/= diagonals[i];
|
||||
}
|
||||
// Now we can go through and set the b, c, d values of each point.
|
||||
// b, c, d values of the last point are not set because they are unused.
|
||||
for(size_t i= 0; i < last; ++i)
|
||||
{
|
||||
size_t next= (i+1) % last;
|
||||
float diff= m_points[next].a - m_points[i].a;
|
||||
m_points[i].b= results[i];
|
||||
m_points[i].c= (3 * diff) - (2 * results[i]) - results[next];
|
||||
m_points[i].d= (2 * -diff) + results[i] + results[next];
|
||||
}
|
||||
// Solving is now complete.
|
||||
}
|
||||
|
||||
float CubicSpline::evaluate(float t, bool loop)
|
||||
{
|
||||
if(loop)
|
||||
{
|
||||
t= fmodf(t, m_points.size());
|
||||
}
|
||||
int flort= static_cast<int>(t);
|
||||
if(flort < 0)
|
||||
{
|
||||
return m_points[0].a;
|
||||
}
|
||||
size_t p= min(static_cast<size_t>(flort), m_points.size()-1);
|
||||
float tfrac= t - static_cast<float>(flort);
|
||||
float tsq= tfrac * tfrac;
|
||||
float tcub= tsq * tfrac;
|
||||
return m_points[p].a + (m_points[p].b * tfrac) +
|
||||
(m_points[p].c * tsq) + (m_points[p].d * tcub);
|
||||
}
|
||||
|
||||
void CubicSpline::set_point(size_t i, float v)
|
||||
{
|
||||
ASSERT_M(i < m_points.size(), "CubicSpline::set_point requires the index to be less than the number of points.");
|
||||
m_points[i].a= v;
|
||||
}
|
||||
|
||||
void CubicSpline::resize(size_t s)
|
||||
{
|
||||
m_points.resize(s);
|
||||
}
|
||||
|
||||
size_t CubicSpline::size()
|
||||
{
|
||||
return m_points.size();
|
||||
}
|
||||
|
||||
bool CubicSpline::empty()
|
||||
{
|
||||
return m_points.empty();
|
||||
}
|
||||
|
||||
void CubicSplineN::solve()
|
||||
{
|
||||
if(loop)
|
||||
{
|
||||
for(spline_cont_t::iterator spline= m_splines.begin();
|
||||
spline != m_splines.end(); ++spline)
|
||||
{
|
||||
spline->solve_looped();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(spline_cont_t::iterator spline= m_splines.begin();
|
||||
spline != m_splines.end(); ++spline)
|
||||
{
|
||||
spline->solve_straight();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CubicSplineN::evaluate(float t, vector<float>& v)
|
||||
{
|
||||
for(spline_cont_t::iterator spline= m_splines.begin();
|
||||
spline != m_splines.end(); ++spline)
|
||||
{
|
||||
v.push_back(spline->evaluate(t, loop));
|
||||
}
|
||||
}
|
||||
|
||||
void CubicSplineN::set_point(size_t i, vector<float> const& v)
|
||||
{
|
||||
ASSERT_M(v.size() == m_splines.size(), "CubicSplineN::set_point requires the passed point to be the same dimension as the spline.");
|
||||
for(size_t n= 0; n < m_splines.size(); ++n)
|
||||
{
|
||||
m_splines[n].set_point(i, v[n]);
|
||||
}
|
||||
}
|
||||
|
||||
void CubicSplineN::resize(size_t s)
|
||||
{
|
||||
for(spline_cont_t::iterator spline= m_splines.begin();
|
||||
spline != m_splines.end(); ++spline)
|
||||
{
|
||||
spline->resize(s);
|
||||
}
|
||||
}
|
||||
|
||||
size_t CubicSplineN::size()
|
||||
{
|
||||
if(!m_splines.empty())
|
||||
{
|
||||
return m_splines[0].size();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool CubicSplineN::empty()
|
||||
{
|
||||
return m_splines.empty() || m_splines[0].empty();
|
||||
}
|
||||
|
||||
void CubicSplineN::redimension(size_t d)
|
||||
{
|
||||
m_splines.resize(d);
|
||||
}
|
||||
|
||||
size_t CubicSplineN::dimension()
|
||||
{
|
||||
return m_splines.size();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001-2006 Chris Danford, Glenn Maynard
|
||||
* All rights reserved.
|
||||
|
||||
@@ -85,6 +85,43 @@ private:
|
||||
RageQuadratic m_Y;
|
||||
};
|
||||
|
||||
struct CubicSpline
|
||||
{
|
||||
void solve_looped();
|
||||
void solve_straight();
|
||||
float evaluate(float t, bool loop);
|
||||
void set_point(size_t i, float v);
|
||||
void resize(size_t s);
|
||||
size_t size();
|
||||
bool empty();
|
||||
private:
|
||||
bool check_minimum_size();
|
||||
void prep_inner(size_t last, vector<float>& diagonals, vector<float>& results);
|
||||
void set_results(size_t last, vector<float>& diagonals, vector<float>& results);
|
||||
|
||||
struct SplinePoint
|
||||
{
|
||||
float a, b, c, d;
|
||||
};
|
||||
vector<SplinePoint> m_points;
|
||||
};
|
||||
|
||||
struct CubicSplineN
|
||||
{
|
||||
void solve();
|
||||
void evaluate(float t, vector<float>& v);
|
||||
void set_point(size_t i, vector<float> const& v);
|
||||
void resize(size_t s);
|
||||
size_t size();
|
||||
void redimension(size_t d);
|
||||
size_t dimension();
|
||||
bool empty();
|
||||
typedef vector<CubicSpline> spline_cont_t;
|
||||
bool loop;
|
||||
private:
|
||||
spline_cont_t m_splines;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user