Added rotation and zoom splines to note columns, with the help of a couple new classes. Reorganized args to NoteDisplay functions into helper structures. Made splines have 3 modes controlling their behavior. Hold twisting is now handled by an AA rotation and hold drawing in general is now more complex.
This commit is contained in:
+1
-1
@@ -970,7 +970,7 @@
|
|||||||
<Class base='ActorFrame' name='NoteField'>
|
<Class base='ActorFrame' name='NoteField'>
|
||||||
<Function name='DidHoldNote'/>
|
<Function name='DidHoldNote'/>
|
||||||
<Function name='DidTapNote'/>
|
<Function name='DidTapNote'/>
|
||||||
<Function name='GetColumnActors'/>
|
<Function name='get_column_actors'/>
|
||||||
<Function name='SetPressed'/>
|
<Function name='SetPressed'/>
|
||||||
<Function name='SetDidHoldNoteCallback'/>
|
<Function name='SetDidHoldNoteCallback'/>
|
||||||
<Function name='SetDidTapNoteCallback'/>
|
<Function name='SetDidTapNoteCallback'/>
|
||||||
|
|||||||
@@ -2959,7 +2959,7 @@ 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 />
|
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.
|
The callback for DidTapNote will not be called.
|
||||||
</Function>
|
</Function>
|
||||||
<Function name='GetColumnActors' return='{actor}' arguments=''>
|
<Function name='get_column_actors' return='{actor}' arguments=''>
|
||||||
Returns a table of the actors for the columns.
|
Returns a table of the actors for the columns.
|
||||||
</Function>
|
</Function>
|
||||||
<Function name='SetDidHoldNoteCallback' return= '' arguments='function callback'>
|
<Function name='SetDidHoldNoteCallback' return= '' arguments='function callback'>
|
||||||
|
|||||||
@@ -19,6 +19,14 @@ public:
|
|||||||
return GetYOffset( pPlayerState, iCol, fNoteBeat, fThrowAway, bThrowAway, bAbsolute );
|
return GetYOffset( pPlayerState, iCol, fNoteBeat, fThrowAway, bThrowAway, bAbsolute );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void GetXYZPos(const PlayerState* player_state, int col, float y_offset, float y_reverse_offset, vector<float>& ret, bool with_reverse= true)
|
||||||
|
{
|
||||||
|
ASSERT(ret.size() == 3);
|
||||||
|
ret[0]= GetXPos(player_state, col, y_offset);
|
||||||
|
ret[1]= GetYPos(player_state, col, y_offset, y_reverse_offset, with_reverse);
|
||||||
|
ret[2]= GetZPos(player_state, col, y_offset);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Retrieve the actual display position.
|
* @brief Retrieve the actual display position.
|
||||||
*
|
*
|
||||||
|
|||||||
+184
-19
@@ -265,6 +265,11 @@ void CubicSpline::set_results(size_t last, vector<float>& diagonals, vector<floa
|
|||||||
m_points[i].b= results[i];
|
m_points[i].b= results[i];
|
||||||
m_points[i].c= (3 * diff) - (2 * results[i]) - results[next];
|
m_points[i].c= (3 * diff) - (2 * results[i]) - results[next];
|
||||||
m_points[i].d= (2 * -diff) + results[i] + results[next];
|
m_points[i].d= (2 * -diff) + results[i] + results[next];
|
||||||
|
#define UNNAN(n) if(n != n) { n = 0.0f; }
|
||||||
|
UNNAN(m_points[i].b);
|
||||||
|
UNNAN(m_points[i].c);
|
||||||
|
UNNAN(m_points[i].d);
|
||||||
|
#undef UNNAN
|
||||||
}
|
}
|
||||||
// Solving is now complete.
|
// Solving is now complete.
|
||||||
}
|
}
|
||||||
@@ -275,16 +280,24 @@ float CubicSpline::evaluate(float t, bool loop) const
|
|||||||
{
|
{
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
}
|
}
|
||||||
|
int flort= static_cast<int>(t);
|
||||||
if(loop)
|
if(loop)
|
||||||
{
|
{
|
||||||
float max_t= m_points.size() + 1.0f;
|
float max_t= m_points.size();
|
||||||
while(t > max_t) { t-= max_t; }
|
while(t >= max_t) { t-= max_t; }
|
||||||
while(t < 0.0f) { t+= max_t; }
|
while(t < 0.0f) { t+= max_t; }
|
||||||
|
flort= static_cast<int>(t);
|
||||||
}
|
}
|
||||||
int flort= static_cast<int>(t);
|
else
|
||||||
if(flort < 0)
|
|
||||||
{
|
{
|
||||||
return m_points[0].a;
|
if(flort <= 0)
|
||||||
|
{
|
||||||
|
return m_points[0].a;
|
||||||
|
}
|
||||||
|
else if(static_cast<size_t>(flort) >= m_points.size() - 1)
|
||||||
|
{
|
||||||
|
return m_points[m_points.size() - 1].a;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
size_t p= min(static_cast<size_t>(flort), m_points.size()-1);
|
size_t p= min(static_cast<size_t>(flort), m_points.size()-1);
|
||||||
float tfrac= t - static_cast<float>(flort);
|
float tfrac= t - static_cast<float>(flort);
|
||||||
@@ -294,12 +307,56 @@ float CubicSpline::evaluate(float t, bool loop) const
|
|||||||
(m_points[p].c * tsq) + (m_points[p].d * tcub);
|
(m_points[p].c * tsq) + (m_points[p].d * tcub);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float CubicSpline::evaluate_derivative(float t, bool loop) const
|
||||||
|
{
|
||||||
|
if(m_points.empty())
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
int flort= static_cast<int>(t);
|
||||||
|
if(loop)
|
||||||
|
{
|
||||||
|
float max_t= m_points.size();
|
||||||
|
while(t >= max_t) { t-= max_t; }
|
||||||
|
while(t < 0.0f) { t+= max_t; }
|
||||||
|
flort= static_cast<int>(t);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(static_cast<size_t>(flort) >= m_points.size() - 1)
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
size_t p= min(static_cast<size_t>(flort), m_points.size()-1);
|
||||||
|
float tfrac= t - static_cast<float>(flort);
|
||||||
|
float tsq= tfrac * tfrac;
|
||||||
|
return m_points[p].b + (2.0f * m_points[p].c * tfrac) +
|
||||||
|
(3.0f * m_points[p].d * tsq);
|
||||||
|
}
|
||||||
|
|
||||||
void CubicSpline::set_point(size_t i, float v)
|
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.");
|
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;
|
m_points[i].a= v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CubicSpline::set_coefficients(size_t i, float b, float c, float d)
|
||||||
|
{
|
||||||
|
ASSERT_M(i < m_points.size(), "CubicSpline: point index must be less than the number of points.");
|
||||||
|
m_points[i].b= b;
|
||||||
|
m_points[i].c= c;
|
||||||
|
m_points[i].d= d;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CubicSpline::get_coefficients(size_t i, float& b, float& c, float& d)
|
||||||
|
{
|
||||||
|
ASSERT_M(i < m_points.size(), "CubicSpline: point index must be less than the number of points.");
|
||||||
|
b= m_points[i].b;
|
||||||
|
c= m_points[i].c;
|
||||||
|
d= m_points[i].d;
|
||||||
|
}
|
||||||
|
|
||||||
void CubicSpline::resize(size_t s)
|
void CubicSpline::resize(size_t s)
|
||||||
{
|
{
|
||||||
m_points.resize(s);
|
m_points.resize(s);
|
||||||
@@ -346,6 +403,15 @@ void CubicSplineN::evaluate(float t, vector<float>& v) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CubicSplineN::evaluate_derivative(float t, vector<float>& v) const
|
||||||
|
{
|
||||||
|
for(spline_cont_t::const_iterator spline= m_splines.begin();
|
||||||
|
spline != m_splines.end(); ++spline)
|
||||||
|
{
|
||||||
|
v.push_back(spline->evaluate_derivative(t, loop));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CubicSplineN::set_point(size_t i, vector<float> const& v)
|
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.");
|
ASSERT_M(v.size() == m_splines.size(), "CubicSplineN::set_point requires the passed point to be the same dimension as the spline.");
|
||||||
@@ -356,6 +422,30 @@ void CubicSplineN::set_point(size_t i, vector<float> const& v)
|
|||||||
m_dirty= true;
|
m_dirty= true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CubicSplineN::set_coefficients(size_t i, vector<float> const& b,
|
||||||
|
vector<float> const& c, vector<float> const& d)
|
||||||
|
{
|
||||||
|
ASSERT_M(b.size() == c.size() && c.size() == d.size() &&
|
||||||
|
d.size() == m_splines.size(), "CubicSplineN: coefficient vectors must be "
|
||||||
|
"the same dimension as the spline.");
|
||||||
|
for(size_t n= 0; n < m_splines.size(); ++n)
|
||||||
|
{
|
||||||
|
m_splines[n].set_coefficients(i, b[n], c[n], d[n]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CubicSplineN::get_coefficients(size_t i, vector<float>& b,
|
||||||
|
vector<float>& c, vector<float>& d)
|
||||||
|
{
|
||||||
|
ASSERT_M(b.size() == c.size() && c.size() == d.size() &&
|
||||||
|
d.size() == m_splines.size(), "CubicSplineN: coefficient vectors must be "
|
||||||
|
"the same dimension as the spline.");
|
||||||
|
for(size_t n= 0; n < m_splines.size(); ++n)
|
||||||
|
{
|
||||||
|
m_splines[n].get_coefficients(i, b[n], c[n], d[n]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CubicSplineN::resize(size_t s)
|
void CubicSplineN::resize(size_t s)
|
||||||
{
|
{
|
||||||
for(spline_cont_t::iterator spline= m_splines.begin();
|
for(spline_cont_t::iterator spline= m_splines.begin();
|
||||||
@@ -412,31 +502,47 @@ struct LunaCubicSplineN : Luna<CubicSplineN>
|
|||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
static int evaluate_derivative(T* p, lua_State* L)
|
||||||
|
{
|
||||||
|
vector<float> pos;
|
||||||
|
p->evaluate_derivative(FArg(1), pos);
|
||||||
|
lua_createtable(L, pos.size(), 0);
|
||||||
|
for(size_t i= 0; i < pos.size(); ++i)
|
||||||
|
{
|
||||||
|
lua_pushnumber(L, pos[i]);
|
||||||
|
lua_rawseti(L, -2, i+1);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
static void get_element_table_from_stack(T* p, lua_State* L, int s,
|
||||||
|
size_t limit, vector<float>& ret)
|
||||||
|
{
|
||||||
|
size_t elements= lua_objlen(L, s);
|
||||||
|
// Too many elements is not an error because allowing it allows the user
|
||||||
|
// to reuse the same position data set after changing the dimension size.
|
||||||
|
// The same is true for too few elements.
|
||||||
|
for(size_t e= 0; e < elements; ++e)
|
||||||
|
{
|
||||||
|
lua_rawgeti(L, s, e+1);
|
||||||
|
ret.push_back(FArg(-1));
|
||||||
|
}
|
||||||
|
while(ret.size() < limit)
|
||||||
|
{
|
||||||
|
ret.push_back(0.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
static void set_point_from_stack(T* p, lua_State* L, size_t i, int s)
|
static void set_point_from_stack(T* p, lua_State* L, size_t i, int s)
|
||||||
{
|
{
|
||||||
if(!lua_istable(L, s))
|
if(!lua_istable(L, s))
|
||||||
{
|
{
|
||||||
luaL_error(L, "Spline point must be a table.");
|
luaL_error(L, "Spline point must be a table.");
|
||||||
}
|
}
|
||||||
size_t elements= lua_objlen(L, s);
|
|
||||||
// Too many elements is not an error because allowing it allows the user
|
|
||||||
// to reuse the same position data set after changing the dimension size.
|
|
||||||
// The same is true for too few elements.
|
|
||||||
vector<float> pos;
|
vector<float> pos;
|
||||||
for(size_t e= 0; e < elements; ++e)
|
get_element_table_from_stack(p, L, s, p->dimension(), pos);
|
||||||
{
|
|
||||||
lua_rawgeti(L, s, e+1);
|
|
||||||
pos.push_back(FArg(-1));
|
|
||||||
}
|
|
||||||
while(pos.size() < p->dimension())
|
|
||||||
{
|
|
||||||
pos.push_back(0.0f);
|
|
||||||
}
|
|
||||||
p->set_point(i, pos);
|
p->set_point(i, pos);
|
||||||
}
|
}
|
||||||
static int set_point(T* p, lua_State* L)
|
static int set_point(T* p, lua_State* L)
|
||||||
{
|
{
|
||||||
vector<float> pos;
|
|
||||||
int i= IArg(1)-1;
|
int i= IArg(1)-1;
|
||||||
if(i < 0)
|
if(i < 0)
|
||||||
{
|
{
|
||||||
@@ -449,6 +555,62 @@ struct LunaCubicSplineN : Luna<CubicSplineN>
|
|||||||
set_point_from_stack(p, L, static_cast<size_t>(i), 2);
|
set_point_from_stack(p, L, static_cast<size_t>(i), 2);
|
||||||
COMMON_RETURN_SELF;
|
COMMON_RETURN_SELF;
|
||||||
}
|
}
|
||||||
|
static void set_coefficients_from_stack(T* p, lua_State* L, size_t i, int s)
|
||||||
|
{
|
||||||
|
if(!lua_istable(L, s) || !lua_istable(L, s+1) || !lua_istable(L, s+2))
|
||||||
|
{
|
||||||
|
luaL_error(L, "Spline coefficient args must be three tables.");
|
||||||
|
}
|
||||||
|
size_t limit= p->dimension();
|
||||||
|
vector<float> b; get_element_table_from_stack(p, L, s, limit, b);
|
||||||
|
vector<float> c; get_element_table_from_stack(p, L, s+1, limit, c);
|
||||||
|
vector<float> d; get_element_table_from_stack(p, L, s+2, limit, d);
|
||||||
|
p->set_coefficients(i, b, c, d);
|
||||||
|
}
|
||||||
|
static int set_coefficients(T* p, lua_State* L)
|
||||||
|
{
|
||||||
|
int i= IArg(1)-1;
|
||||||
|
if(i < 0)
|
||||||
|
{
|
||||||
|
luaL_error(L, "Cannot set spline coefficients at index less than 1.");
|
||||||
|
}
|
||||||
|
if(static_cast<size_t>(i) >= p->size())
|
||||||
|
{
|
||||||
|
luaL_error(L, "Cannot set spline coefficients at index greater than size.");
|
||||||
|
}
|
||||||
|
set_coefficients_from_stack(p, L, i, 2);
|
||||||
|
COMMON_RETURN_SELF;
|
||||||
|
}
|
||||||
|
static int get_coefficients(T* p, lua_State* L)
|
||||||
|
{
|
||||||
|
int i= IArg(1)-1;
|
||||||
|
if(i < 0)
|
||||||
|
{
|
||||||
|
luaL_error(L, "Cannot get spline coefficients at index less than 1.");
|
||||||
|
}
|
||||||
|
if(static_cast<size_t>(i) >= p->size())
|
||||||
|
{
|
||||||
|
luaL_error(L, "Cannot get spline coefficients at index greater than size.");
|
||||||
|
}
|
||||||
|
size_t limit= p->dimension();
|
||||||
|
vector<vector<float> > coeff(3);
|
||||||
|
coeff[0].resize(limit);
|
||||||
|
coeff[1].resize(limit);
|
||||||
|
coeff[2].resize(limit);
|
||||||
|
p->get_coefficients(i, coeff[0], coeff[1], coeff[2]);
|
||||||
|
lua_createtable(L, 3, 0);
|
||||||
|
for(size_t co= 0; co < coeff.size(); ++co)
|
||||||
|
{
|
||||||
|
lua_createtable(L, limit, 0);
|
||||||
|
for(size_t v= 0; v < limit; ++v)
|
||||||
|
{
|
||||||
|
lua_pushnumber(L, coeff[co][v]);
|
||||||
|
lua_rawseti(L, -2, v+1);
|
||||||
|
}
|
||||||
|
lua_rawseti(L, -2, co+1);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
static int resize(T* p, lua_State* L)
|
static int resize(T* p, lua_State* L)
|
||||||
{
|
{
|
||||||
int siz= IArg(1);
|
int siz= IArg(1);
|
||||||
@@ -503,7 +665,10 @@ struct LunaCubicSplineN : Luna<CubicSplineN>
|
|||||||
{
|
{
|
||||||
ADD_METHOD(solve);
|
ADD_METHOD(solve);
|
||||||
ADD_METHOD(evaluate);
|
ADD_METHOD(evaluate);
|
||||||
|
ADD_METHOD(evaluate_derivative);
|
||||||
ADD_METHOD(set_point);
|
ADD_METHOD(set_point);
|
||||||
|
ADD_METHOD(set_coefficients);
|
||||||
|
ADD_METHOD(get_coefficients);
|
||||||
ADD_METHOD(resize);
|
ADD_METHOD(resize);
|
||||||
ADD_METHOD(size);
|
ADD_METHOD(size);
|
||||||
ADD_METHOD(redimension);
|
ADD_METHOD(redimension);
|
||||||
|
|||||||
@@ -10,7 +10,10 @@ struct CubicSpline
|
|||||||
void solve_looped();
|
void solve_looped();
|
||||||
void solve_straight();
|
void solve_straight();
|
||||||
float evaluate(float t, bool loop) const;
|
float evaluate(float t, bool loop) const;
|
||||||
|
float evaluate_derivative(float t, bool loop) const;
|
||||||
void set_point(size_t i, float v);
|
void set_point(size_t i, float v);
|
||||||
|
void set_coefficients(size_t i, float b, float c, float d);
|
||||||
|
void get_coefficients(size_t i, float& b, float& c, float& d);
|
||||||
void resize(size_t s);
|
void resize(size_t s);
|
||||||
size_t size() const;
|
size_t size() const;
|
||||||
bool empty() const;
|
bool empty() const;
|
||||||
@@ -33,7 +36,12 @@ struct CubicSplineN
|
|||||||
{}
|
{}
|
||||||
void solve();
|
void solve();
|
||||||
void evaluate(float t, vector<float>& v) const;
|
void evaluate(float t, vector<float>& v) const;
|
||||||
|
void evaluate_derivative(float t, vector<float>& v) const;
|
||||||
void set_point(size_t i, vector<float> const& v);
|
void set_point(size_t i, vector<float> const& v);
|
||||||
|
void set_coefficients(size_t i, vector<float> const& b,
|
||||||
|
vector<float> const& c, vector<float> const& d);
|
||||||
|
void get_coefficients(size_t i, vector<float>& b,
|
||||||
|
vector<float>& c, vector<float>& d);
|
||||||
void resize(size_t s);
|
void resize(size_t s);
|
||||||
size_t size() const;
|
size_t size() const;
|
||||||
void redimension(size_t d);
|
void redimension(size_t d);
|
||||||
|
|||||||
+1
-16
@@ -56,23 +56,8 @@ void GhostArrowRow::Update( float fDeltaTime )
|
|||||||
{
|
{
|
||||||
for( unsigned c=0; c<m_Ghost.size(); c++ )
|
for( unsigned c=0; c<m_Ghost.size(); c++ )
|
||||||
{
|
{
|
||||||
vector<float> spline_pos;
|
|
||||||
(*m_renderers)[c].m_spline.evaluate((*m_renderers)[c].m_receptor_t, spline_pos);
|
|
||||||
m_Ghost[c]->Update( fDeltaTime );
|
m_Ghost[c]->Update( fDeltaTime );
|
||||||
|
(*m_renderers)[c].UpdateReceptorGhostStuff(m_Ghost[c]);
|
||||||
float fX = ArrowEffects::GetXPos( m_pPlayerState, c, 0 );
|
|
||||||
float fY = ArrowEffects::GetYPos( m_pPlayerState, c, 0, m_fYReverseOffsetPixels );
|
|
||||||
float fZ = ArrowEffects::GetZPos( m_pPlayerState, c, 0 );
|
|
||||||
|
|
||||||
m_Ghost[c]->SetX( fX + spline_pos[0] );
|
|
||||||
m_Ghost[c]->SetY( fY + spline_pos[1] );
|
|
||||||
m_Ghost[c]->SetZ( fZ + spline_pos[2] );
|
|
||||||
|
|
||||||
const float fRotation = ArrowEffects::ReceptorGetRotationZ( m_pPlayerState );
|
|
||||||
m_Ghost[c]->SetRotationZ( fRotation );
|
|
||||||
|
|
||||||
const float fZoom = ArrowEffects::GetZoom( m_pPlayerState );
|
|
||||||
m_Ghost[c]->SetZoom( fZoom );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for( unsigned i = 0; i < m_bHoldShowing.size(); ++i )
|
for( unsigned i = 0; i < m_bHoldShowing.size(); ++i )
|
||||||
|
|||||||
+499
-143
@@ -17,6 +17,9 @@
|
|||||||
#include "Foreach.h"
|
#include "Foreach.h"
|
||||||
#include "RageMath.h"
|
#include "RageMath.h"
|
||||||
|
|
||||||
|
static const double PI_180= PI / 180.0;
|
||||||
|
static const double PI_180R= 180.0 / PI;
|
||||||
|
|
||||||
const RString& NoteNotePartToString( NotePart i );
|
const RString& NoteNotePartToString( NotePart i );
|
||||||
/** @brief A foreach loop going through the different NoteParts. */
|
/** @brief A foreach loop going through the different NoteParts. */
|
||||||
#define FOREACH_NotePart( i ) FOREACH_ENUM( NotePart, i )
|
#define FOREACH_NotePart( i ) FOREACH_ENUM( NotePart, i )
|
||||||
@@ -43,6 +46,15 @@ XToString( NoteColorType );
|
|||||||
StringToX( NoteColorType );
|
StringToX( NoteColorType );
|
||||||
LuaXType( NoteColorType );
|
LuaXType( NoteColorType );
|
||||||
|
|
||||||
|
static const char* NoteColumnSplineModeNames[] = {
|
||||||
|
"Disabled",
|
||||||
|
"Offset",
|
||||||
|
"Position",
|
||||||
|
};
|
||||||
|
XToString(NoteColumnSplineMode);
|
||||||
|
StringToX(NoteColumnSplineMode);
|
||||||
|
LuaXType(NoteColumnSplineMode);
|
||||||
|
|
||||||
static bool IsVectorZero( const RageVector2 &v )
|
static bool IsVectorZero( const RageVector2 &v )
|
||||||
{
|
{
|
||||||
return v.x == 0 && v.y == 0;
|
return v.x == 0 && v.y == 0;
|
||||||
@@ -277,6 +289,101 @@ XToString( ActiveType );
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
float NCSplineHandler::BeatToTValue(float song_beat, float note_beat) const
|
||||||
|
{
|
||||||
|
float relative_beat= note_beat;
|
||||||
|
// This allows someone to do something really fancy like having a spline
|
||||||
|
// that extends the length of the song. Think of arrows tracing a path
|
||||||
|
// as the song progresses. -Kyz
|
||||||
|
if(m_subtract_song_beat_from_curr)
|
||||||
|
{
|
||||||
|
relative_beat-= song_beat;
|
||||||
|
return (relative_beat / m_beats_per_t) - m_receptor_t;
|
||||||
|
}
|
||||||
|
return relative_beat / m_beats_per_t;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NCSplineHandler::EvalForBeat(float song_beat, float note_beat, vector<float>& ret) const
|
||||||
|
{
|
||||||
|
float t_value= BeatToTValue(song_beat, note_beat);
|
||||||
|
m_spline.evaluate(t_value, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NCSplineHandler::EvalDerivForBeat(float song_beat, float note_beat, vector<float>& ret) const
|
||||||
|
{
|
||||||
|
float t_value= BeatToTValue(song_beat, note_beat);
|
||||||
|
m_spline.evaluate_derivative(t_value, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NCSplineHandler::EvalForReceptor(float song_beat, vector<float>& ret) const
|
||||||
|
{
|
||||||
|
float t_value= m_receptor_t;
|
||||||
|
if(!m_subtract_song_beat_from_curr)
|
||||||
|
{
|
||||||
|
t_value= song_beat / m_beats_per_t;
|
||||||
|
}
|
||||||
|
m_spline.evaluate(t_value, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NoteColumnRenderArgs::spae_pos_for_beat(PlayerState const* state,
|
||||||
|
float beat, float y_offset, float y_reverse_offset,
|
||||||
|
vector<float>& sp_pos, vector<float>& ae_pos) const
|
||||||
|
{
|
||||||
|
switch(pos_handler->m_spline_mode)
|
||||||
|
{
|
||||||
|
case NCSM_Disabled:
|
||||||
|
ArrowEffects::GetXYZPos(state, column, y_offset, y_reverse_offset, ae_pos);
|
||||||
|
sp_pos.resize(3);
|
||||||
|
// Sure, resize is supposed to call the default constructor, and for
|
||||||
|
// numbers the default constructor is supposed to set it to zero, but
|
||||||
|
// I got bit for relying on that once. -Kyz
|
||||||
|
sp_pos[0]= sp_pos[1]= sp_pos[2]= 0.0f;
|
||||||
|
break;
|
||||||
|
case NCSM_Offset:
|
||||||
|
ArrowEffects::GetXYZPos(state, column, y_offset, y_reverse_offset, ae_pos);
|
||||||
|
pos_handler->EvalForBeat(song_beat, beat, sp_pos);
|
||||||
|
break;
|
||||||
|
case NCSM_Position:
|
||||||
|
pos_handler->EvalForBeat(song_beat, beat, sp_pos);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void NoteColumnRenderArgs::spae_zoom_for_beat(PlayerState const* state, float beat,
|
||||||
|
vector<float>& sp_zoom, vector<float>& ae_zoom) const
|
||||||
|
{
|
||||||
|
switch(zoom_handler->m_spline_mode)
|
||||||
|
{
|
||||||
|
case NCSM_Disabled:
|
||||||
|
ae_zoom[0]= ae_zoom[1]= ae_zoom[2]= ArrowEffects::GetZoom(state);
|
||||||
|
sp_zoom.resize(3);
|
||||||
|
sp_zoom[0]= sp_zoom[1]= sp_zoom[2]= 0.0f;
|
||||||
|
break;
|
||||||
|
case NCSM_Offset:
|
||||||
|
ae_zoom[0]= ae_zoom[1]= ae_zoom[2]= ArrowEffects::GetZoom(state);
|
||||||
|
zoom_handler->EvalForBeat(song_beat, beat, sp_zoom);
|
||||||
|
break;
|
||||||
|
case NCSM_Position:
|
||||||
|
zoom_handler->EvalForBeat(song_beat, beat, sp_zoom);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void NoteColumnRenderArgs::SetPRZForActor(Actor* actor,
|
||||||
|
vector<float> const& sp_pos, vector<float> const& ae_pos,
|
||||||
|
vector<float> const& sp_rot, vector<float> const& ae_rot,
|
||||||
|
vector<float> const& sp_zoom, vector<float> const& ae_zoom) const
|
||||||
|
{
|
||||||
|
actor->SetX(sp_pos[0] + ae_pos[0]);
|
||||||
|
actor->SetY(sp_pos[1] + ae_pos[1]);
|
||||||
|
actor->SetZ(sp_pos[2] + ae_pos[2]);
|
||||||
|
actor->SetRotationX(sp_rot[0] * PI_180R + ae_rot[0]);
|
||||||
|
actor->SetRotationY(sp_rot[1] * PI_180R + ae_rot[1]);
|
||||||
|
actor->SetRotationZ(sp_rot[2] * PI_180R + ae_rot[2]);
|
||||||
|
actor->SetZoomX(sp_zoom[0] + ae_zoom[0]);
|
||||||
|
actor->SetZoomY(sp_zoom[1] + ae_zoom[1]);
|
||||||
|
actor->SetZoomZ(sp_zoom[2] + ae_zoom[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
NoteDisplay::NoteDisplay()
|
NoteDisplay::NoteDisplay()
|
||||||
{
|
{
|
||||||
cache = new NoteMetricCache_t;
|
cache = new NoteMetricCache_t;
|
||||||
@@ -342,15 +449,9 @@ bool NoteDisplay::IsOnScreen( float fBeat, int iCol, int iDrawDistanceAfterTarge
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
float NoteDisplay::BeatToTValue(CommonColumnRenderArgs const& args, float beat) const
|
bool NoteDisplay::DrawHoldsInRange(NoteFieldRenderArgs const& field_args,
|
||||||
{
|
NoteColumnRenderArgs const& column_args,
|
||||||
float song_beat= m_pPlayerState->GetDisplayedPosition().m_fSongBeatVisible;
|
vector<NoteData::TrackMap::const_iterator> const& tap_set)
|
||||||
float relative_beat= beat - song_beat;
|
|
||||||
return (relative_beat / args.beats_per_t) - args.receptor_t;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool NoteDisplay::DrawHoldsInRange(CommonColumnRenderArgs const& args,
|
|
||||||
int column, vector<NoteData::TrackMap::const_iterator> const& tap_set)
|
|
||||||
{
|
{
|
||||||
bool any_upcoming = false;
|
bool any_upcoming = false;
|
||||||
for(vector<NoteData::TrackMap::const_iterator>::const_iterator tapit=
|
for(vector<NoteData::TrackMap::const_iterator>::const_iterator tapit=
|
||||||
@@ -367,18 +468,18 @@ bool NoteDisplay::DrawHoldsInRange(CommonColumnRenderArgs const& args,
|
|||||||
float throw_away;
|
float throw_away;
|
||||||
bool start_past_peak = false;
|
bool start_past_peak = false;
|
||||||
bool end_past_peak = false;
|
bool end_past_peak = false;
|
||||||
float start_y = ArrowEffects::GetYOffset(m_pPlayerState, column,
|
float start_y = ArrowEffects::GetYOffset(m_pPlayerState, column_args.column,
|
||||||
NoteRowToVisibleBeat(m_pPlayerState, start_row), throw_away,
|
NoteRowToVisibleBeat(m_pPlayerState, start_row), throw_away,
|
||||||
start_past_peak);
|
start_past_peak);
|
||||||
float end_y = ArrowEffects::GetYOffset(m_pPlayerState, column,
|
float end_y = ArrowEffects::GetYOffset(m_pPlayerState, column_args.column,
|
||||||
NoteRowToVisibleBeat(m_pPlayerState, end_row), throw_away,
|
NoteRowToVisibleBeat(m_pPlayerState, end_row), throw_away,
|
||||||
end_past_peak);
|
end_past_peak);
|
||||||
bool tail_visible = args.draw_pixels_after_targets <= end_y &&
|
bool tail_visible = field_args.draw_pixels_after_targets <= end_y &&
|
||||||
end_y <= args.draw_pixels_before_targets;
|
end_y <= field_args.draw_pixels_before_targets;
|
||||||
bool head_visible = args.draw_pixels_after_targets <= start_y &&
|
bool head_visible = field_args.draw_pixels_after_targets <= start_y &&
|
||||||
start_y <= args.draw_pixels_before_targets;
|
start_y <= field_args.draw_pixels_before_targets;
|
||||||
bool straddling_visible = start_y <= args.draw_pixels_after_targets &&
|
bool straddling_visible = start_y <= field_args.draw_pixels_after_targets &&
|
||||||
args.draw_pixels_before_targets <= end_y;
|
field_args.draw_pixels_before_targets <= end_y;
|
||||||
bool straddling_peak = start_past_peak && !end_past_peak;
|
bool straddling_peak = start_past_peak && !end_past_peak;
|
||||||
if(!(tail_visible || head_visible || straddling_visible || straddling_peak))
|
if(!(tail_visible || head_visible || straddling_visible || straddling_peak))
|
||||||
{
|
{
|
||||||
@@ -393,21 +494,21 @@ bool NoteDisplay::DrawHoldsInRange(CommonColumnRenderArgs const& args,
|
|||||||
const bool is_holding = tn.HoldResult.bHeld;
|
const bool is_holding = tn.HoldResult.bHeld;
|
||||||
if(hold_ghost_showing)
|
if(hold_ghost_showing)
|
||||||
{
|
{
|
||||||
args.ghost_row->SetHoldShowing(column, tn);
|
field_args.ghost_row->SetHoldShowing(column_args.column, tn);
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT_M(NoteRowToBeat(start_row) > -2000, ssprintf("%i %i %i", start_row, end_row, column));
|
ASSERT_M(NoteRowToBeat(start_row) > -2000, ssprintf("%i %i %i", start_row, end_row, column_args.column));
|
||||||
|
|
||||||
bool in_selection_range = false;
|
bool in_selection_range = false;
|
||||||
if(*args.selection_begin_marker != -1 && *args.selection_end_marker != -1)
|
if(*field_args.selection_begin_marker != -1 && *field_args.selection_end_marker != -1)
|
||||||
{
|
{
|
||||||
in_selection_range = (*args.selection_begin_marker <= start_row &&
|
in_selection_range = (*field_args.selection_begin_marker <= start_row &&
|
||||||
end_row < *args.selection_end_marker);
|
end_row < *field_args.selection_end_marker);
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawHold(tn, args, column, start_row, is_holding, result,
|
DrawHold(tn, field_args, column_args, start_row, is_holding, result,
|
||||||
use_addition_coloring,
|
use_addition_coloring,
|
||||||
in_selection_range ? args.selection_glow : args.fail_fade);
|
in_selection_range ? field_args.selection_glow : field_args.fail_fade);
|
||||||
|
|
||||||
bool note_upcoming = NoteRowToBeat(start_row) >
|
bool note_upcoming = NoteRowToBeat(start_row) >
|
||||||
m_pPlayerState->GetDisplayedPosition().m_fSongBeat;
|
m_pPlayerState->GetDisplayedPosition().m_fSongBeat;
|
||||||
@@ -416,8 +517,9 @@ bool NoteDisplay::DrawHoldsInRange(CommonColumnRenderArgs const& args,
|
|||||||
return any_upcoming;
|
return any_upcoming;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NoteDisplay::DrawTapsInRange(CommonColumnRenderArgs const& args,
|
bool NoteDisplay::DrawTapsInRange(NoteFieldRenderArgs const& field_args,
|
||||||
int column, vector<NoteData::TrackMap::const_iterator> const& tap_set)
|
NoteColumnRenderArgs const& column_args,
|
||||||
|
vector<NoteData::TrackMap::const_iterator> const& tap_set)
|
||||||
{
|
{
|
||||||
bool any_upcoming= false;
|
bool any_upcoming= false;
|
||||||
// draw notes from furthest to closest
|
// draw notes from furthest to closest
|
||||||
@@ -430,8 +532,8 @@ bool NoteDisplay::DrawTapsInRange(CommonColumnRenderArgs const& args,
|
|||||||
// TRICKY: If boomerang is on, then all notes in the range
|
// TRICKY: If boomerang is on, then all notes in the range
|
||||||
// [first_row,last_row] aren't necessarily visible.
|
// [first_row,last_row] aren't necessarily visible.
|
||||||
// Test every note to make sure it's on screen before drawing.
|
// Test every note to make sure it's on screen before drawing.
|
||||||
if(!IsOnScreen(NoteRowToBeat(tap_row), column,
|
if(!IsOnScreen(NoteRowToBeat(tap_row), column_args.column,
|
||||||
args.draw_pixels_after_targets, args.draw_pixels_before_targets))
|
field_args.draw_pixels_after_targets, field_args.draw_pixels_before_targets))
|
||||||
{
|
{
|
||||||
continue; // skip
|
continue; // skip
|
||||||
}
|
}
|
||||||
@@ -451,9 +553,9 @@ bool NoteDisplay::DrawTapsInRange(CommonColumnRenderArgs const& args,
|
|||||||
bool hold_begins_on_this_beat = false;
|
bool hold_begins_on_this_beat = false;
|
||||||
if(DrawHoldHeadForTapsOnSameRow())
|
if(DrawHoldHeadForTapsOnSameRow())
|
||||||
{
|
{
|
||||||
for(int c2= 0; c2 < args.note_data->GetNumTracks(); ++c2)
|
for(int c2= 0; c2 < field_args.note_data->GetNumTracks(); ++c2)
|
||||||
{
|
{
|
||||||
const TapNote &tmp = args.note_data->GetTapNote(c2, tap_row);
|
const TapNote &tmp = field_args.note_data->GetTapNote(c2, tap_row);
|
||||||
if(tmp.type == TapNoteType_HoldHead &&
|
if(tmp.type == TapNoteType_HoldHead &&
|
||||||
tmp.subType == TapNoteSubType_Hold)
|
tmp.subType == TapNoteSubType_Hold)
|
||||||
{
|
{
|
||||||
@@ -467,9 +569,9 @@ bool NoteDisplay::DrawTapsInRange(CommonColumnRenderArgs const& args,
|
|||||||
bool roll_begins_on_this_beat = false;
|
bool roll_begins_on_this_beat = false;
|
||||||
if(DrawRollHeadForTapsOnSameRow())
|
if(DrawRollHeadForTapsOnSameRow())
|
||||||
{
|
{
|
||||||
for(int c2= 0; c2 < args.note_data->GetNumTracks(); ++c2)
|
for(int c2= 0; c2 < field_args.note_data->GetNumTracks(); ++c2)
|
||||||
{
|
{
|
||||||
const TapNote &tmp = args.note_data->GetTapNote(c2, tap_row);
|
const TapNote &tmp = field_args.note_data->GetTapNote(c2, tap_row);
|
||||||
if(tmp.type == TapNoteType_HoldHead &&
|
if(tmp.type == TapNoteType_HoldHead &&
|
||||||
tmp.subType == TapNoteSubType_Roll)
|
tmp.subType == TapNoteSubType_Roll)
|
||||||
{
|
{
|
||||||
@@ -480,19 +582,20 @@ bool NoteDisplay::DrawTapsInRange(CommonColumnRenderArgs const& args,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool in_selection_range = false;
|
bool in_selection_range = false;
|
||||||
if(*args.selection_begin_marker != -1 && *args.selection_end_marker != -1)
|
if(*field_args.selection_begin_marker != -1 && *field_args.selection_end_marker != -1)
|
||||||
{
|
{
|
||||||
in_selection_range = *args.selection_begin_marker <= tap_row &&
|
in_selection_range = *field_args.selection_begin_marker <= tap_row &&
|
||||||
tap_row < *args.selection_end_marker;
|
tap_row < *field_args.selection_end_marker;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_addition = (tn.source == TapNoteSource_Addition);
|
bool is_addition = (tn.source == TapNoteSource_Addition);
|
||||||
bool hopo_possible = (tn.bHopoPossible);
|
bool hopo_possible = (tn.bHopoPossible);
|
||||||
bool use_addition_coloring = is_addition || hopo_possible;
|
bool use_addition_coloring = is_addition || hopo_possible;
|
||||||
DrawTap(tn, args, column, NoteRowToVisibleBeat(m_pPlayerState, tap_row),
|
DrawTap(tn, field_args, column_args,
|
||||||
|
NoteRowToVisibleBeat(m_pPlayerState, tap_row),
|
||||||
hold_begins_on_this_beat, roll_begins_on_this_beat,
|
hold_begins_on_this_beat, roll_begins_on_this_beat,
|
||||||
use_addition_coloring,
|
use_addition_coloring,
|
||||||
in_selection_range ? args.selection_glow : args.fail_fade);
|
in_selection_range ? field_args.selection_glow : field_args.fail_fade);
|
||||||
|
|
||||||
any_upcoming |= NoteRowToBeat(tap_row) >
|
any_upcoming |= NoteRowToBeat(tap_row) >
|
||||||
m_pPlayerState->GetDisplayedPosition().m_fSongBeat;
|
m_pPlayerState->GetDisplayedPosition().m_fSongBeat;
|
||||||
@@ -614,28 +717,24 @@ struct StripBuffer
|
|||||||
};
|
};
|
||||||
|
|
||||||
void NoteDisplay::DrawHoldPart(vector<Sprite*> &vpSpr,
|
void NoteDisplay::DrawHoldPart(vector<Sprite*> &vpSpr,
|
||||||
CommonColumnRenderArgs const& args, int iCol, int fYStep,
|
NoteFieldRenderArgs const& field_args,
|
||||||
|
NoteColumnRenderArgs const& column_args, int fYStep,
|
||||||
float fPercentFadeToFail, float fColorScale, bool bGlow,
|
float fPercentFadeToFail, float fColorScale, bool bGlow,
|
||||||
float fOverlappedTime, float fYTop, float fYBottom, float fYStartPos,
|
float fOverlappedTime, float fYTop, float fYBottom, float fYStartPos,
|
||||||
float fYEndPos, bool bWrapping, bool bAnchorToTop,
|
float fYEndPos, bool bWrapping, bool bAnchorToTop,
|
||||||
bool bFlipTextureVertically, float top_t, float bottom_t)
|
bool bFlipTextureVertically, float top_beat, float bottom_beat)
|
||||||
{
|
{
|
||||||
ASSERT( !vpSpr.empty() );
|
ASSERT( !vpSpr.empty() );
|
||||||
|
|
||||||
|
float ae_zoom= ArrowEffects::GetZoom(m_pPlayerState);
|
||||||
Sprite *pSprite = vpSpr.front();
|
Sprite *pSprite = vpSpr.front();
|
||||||
FOREACH( Sprite *, vpSpr, s )
|
|
||||||
{
|
|
||||||
(*s)->SetZoom( ArrowEffects::GetZoom(m_pPlayerState) );
|
|
||||||
ASSERT( (*s)->GetUnzoomedWidth() == pSprite->GetUnzoomedWidth() );
|
|
||||||
ASSERT( (*s)->GetUnzoomedHeight() == pSprite->GetUnzoomedHeight() );
|
|
||||||
}
|
|
||||||
|
|
||||||
// draw manually in small segments
|
// draw manually in small segments
|
||||||
RectF rect = *pSprite->GetCurrentTextureCoordRect();
|
RectF rect = *pSprite->GetCurrentTextureCoordRect();
|
||||||
if( bFlipTextureVertically )
|
if( bFlipTextureVertically )
|
||||||
swap( rect.top, rect.bottom );
|
swap( rect.top, rect.bottom );
|
||||||
const float fFrameWidth = pSprite->GetZoomedWidth();
|
const float fFrameWidth = pSprite->GetUnzoomedWidth();
|
||||||
const float fFrameHeight = pSprite->GetZoomedHeight();
|
const float fFrameHeight = pSprite->GetUnzoomedHeight() * ae_zoom;
|
||||||
|
|
||||||
/* Only draw the section that's within the range specified. If a hold note is
|
/* Only draw the section that's within the range specified. If a hold note is
|
||||||
* very long, don't process or draw the part outside of the range. Don't change
|
* very long, don't process or draw the part outside of the range. Don't change
|
||||||
@@ -674,6 +773,10 @@ void NoteDisplay::DrawHoldPart(vector<Sprite*> &vpSpr,
|
|||||||
const float fTexCoordRight = rect.right;
|
const float fTexCoordRight = rect.right;
|
||||||
const float fTexCoordCenter = (fTexCoordLeft+fTexCoordRight)/2;
|
const float fTexCoordCenter = (fTexCoordLeft+fTexCoordRight)/2;
|
||||||
|
|
||||||
|
// pos_z_vec will be used later to orient the hold. Read below. -Kyz
|
||||||
|
static RageVector3 const pos_z_vec(0.0f, 0.0f, 1.0f);
|
||||||
|
static RageVector3 const pos_y_vec(0.0f, 1.0f, 0.0f);
|
||||||
|
|
||||||
StripBuffer queue;
|
StripBuffer queue;
|
||||||
for( float fY = fYStartPos; !bLast; fY += fYStep )
|
for( float fY = fYStartPos; !bLast; fY += fYStep )
|
||||||
{
|
{
|
||||||
@@ -683,50 +786,165 @@ void NoteDisplay::DrawHoldPart(vector<Sprite*> &vpSpr,
|
|||||||
bLast = true;
|
bLast = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
float curtsy= top_t;
|
const float fYOffset = ArrowEffects::GetYOffsetFromYPos( m_pPlayerState, column_args.column, fY, m_fYReverseOffsetPixels );
|
||||||
if(top_t != bottom_t)
|
|
||||||
|
float cur_beat= top_beat;
|
||||||
|
if(top_beat != bottom_beat)
|
||||||
{
|
{
|
||||||
curtsy= SCALE(fY, fYTop, fYBottom, top_t, bottom_t);
|
cur_beat= SCALE(fY, fYTop, fYBottom, top_beat, bottom_beat);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fun times ahead with vector math. If the notes are being moved by the
|
||||||
|
// position spline, the vectors used to position the edges of the strip
|
||||||
|
// need to be adjusted or the hold will vanish when the notes move
|
||||||
|
// horizontally.
|
||||||
|
// To accomplish this, we use the derivative at the current point from
|
||||||
|
// AE and the position spline. That gives us the forward vector for the
|
||||||
|
// strip, pointing to where the next center vert will be. (step 1)
|
||||||
|
// The vectors pointing left and right to the edges of the strip are
|
||||||
|
// obtained from the cross product of the forward vector and pos_z_vec.
|
||||||
|
// (unless the forward vec is too close to pos_z_vec or -pos_z_vec, in
|
||||||
|
// which case pos_y_vec is used) The result of a cross product is a
|
||||||
|
// vector perpendicular to both, so forward crossed with pos_z_vec gives
|
||||||
|
// us the left vector. Right is of course -left. (step 2)
|
||||||
|
// After that step, the left and right vectors need to be rotated around
|
||||||
|
// the forward vector axis by the y rotation value, to allow the hold to
|
||||||
|
// twist. (step 3)
|
||||||
|
// Steps will be labeled where they occur below. -Kyz
|
||||||
|
// TODO: Figure out whether it's worth the time investment to figure out
|
||||||
|
// a way to skip the complex vector handling if the spline is disabled.
|
||||||
|
|
||||||
|
vector<float> sp_pos;
|
||||||
|
vector<float> sp_pos_forward;
|
||||||
|
vector<float> sp_rot;
|
||||||
|
vector<float> sp_zoom;
|
||||||
|
vector<float> ae_pos(3, 0.0f);
|
||||||
|
vector<float> ae_rot(3, 0.0f);
|
||||||
|
|
||||||
|
// (step 1 of vector handling, part 1)
|
||||||
|
// ArrowEffects only contributes to the Y component of the vector to
|
||||||
|
// maintain the old behavior of how holds are drawn when they wave back
|
||||||
|
// and forth. -Kyz
|
||||||
|
RageVector3 render_forward(0.0f, 1.0f, 0.0f);
|
||||||
|
column_args.spae_pos_for_beat(m_pPlayerState, cur_beat,
|
||||||
|
fYOffset, m_fYReverseOffsetPixels, sp_pos, ae_pos);
|
||||||
|
// fX and fZ are sp_pos[0] + ae_pos[0] and sp_pos[2] + ae_pos[2]. -Kyz
|
||||||
|
// fY is the actual y position that should be used, not whatever spae
|
||||||
|
// fetched from ArrowEffects. -Kyz
|
||||||
|
switch(column_args.pos_handler->m_spline_mode)
|
||||||
|
{
|
||||||
|
case NCSM_Disabled:
|
||||||
|
ae_pos[1]= fY;
|
||||||
|
sp_pos_forward.resize(3);
|
||||||
|
sp_pos_forward[0]= sp_pos_forward[1]= sp_pos_forward[2]= 0.0f;
|
||||||
|
break;
|
||||||
|
case NCSM_Offset:
|
||||||
|
ae_pos[1]= fY;
|
||||||
|
column_args.pos_handler->EvalDerivForBeat(column_args.song_beat, cur_beat, sp_pos_forward);
|
||||||
|
VectorFloatNormalize(sp_pos_forward);
|
||||||
|
break;
|
||||||
|
case NCSM_Position:
|
||||||
|
ae_pos[1]= 0.0f;
|
||||||
|
render_forward.y= 0.0f;
|
||||||
|
column_args.pos_handler->EvalDerivForBeat(column_args.song_beat, cur_beat, sp_pos_forward);
|
||||||
|
VectorFloatNormalize(sp_pos_forward);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
render_forward.x+= sp_pos_forward[0];
|
||||||
|
render_forward.y+= sp_pos_forward[1];
|
||||||
|
render_forward.z+= sp_pos_forward[2];
|
||||||
|
// Normalize the vector so it'll be easy to test when determining whether
|
||||||
|
// to use pos_z_vec or pos_y_vec for the cross product in step 2.
|
||||||
|
RageVec3Normalize(&render_forward, &render_forward);
|
||||||
|
|
||||||
|
// Holds are only affected by the x axis of the zoom spline because they
|
||||||
|
// are flat sprites. -Kyz
|
||||||
|
float render_width= fFrameWidth;
|
||||||
|
switch(column_args.zoom_handler->m_spline_mode)
|
||||||
|
{
|
||||||
|
case NCSM_Disabled:
|
||||||
|
render_width= fFrameWidth * ae_zoom;
|
||||||
|
break;
|
||||||
|
case NCSM_Offset:
|
||||||
|
column_args.zoom_handler->EvalForBeat(column_args.song_beat, cur_beat, sp_zoom);
|
||||||
|
render_width= fFrameWidth * (ae_zoom + sp_zoom[0]);
|
||||||
|
break;
|
||||||
|
case NCSM_Position:
|
||||||
|
column_args.zoom_handler->EvalForBeat(column_args.song_beat, cur_beat, sp_zoom);
|
||||||
|
render_width= fFrameWidth * sp_zoom[0];
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
vector<float> spline_pos;
|
|
||||||
args.spline->evaluate(curtsy, spline_pos);
|
|
||||||
|
|
||||||
const float fYOffset = ArrowEffects::GetYOffsetFromYPos( m_pPlayerState, iCol, fY, m_fYReverseOffsetPixels );
|
|
||||||
const float fZ = ArrowEffects::GetZPos( m_pPlayerState, iCol, fYOffset ) + spline_pos[2];
|
|
||||||
const float fFrameWidthScale = ArrowEffects::GetFrameWidthScale( m_pPlayerState, fYOffset, fOverlappedTime );
|
const float fFrameWidthScale = ArrowEffects::GetFrameWidthScale( m_pPlayerState, fYOffset, fOverlappedTime );
|
||||||
const float fScaledFrameWidth = fFrameWidth * fFrameWidthScale;
|
const float fScaledFrameWidth = render_width * fFrameWidthScale;
|
||||||
|
|
||||||
float fX = ArrowEffects::GetXPos( m_pPlayerState, iCol, fYOffset ) + spline_pos[0];
|
// Can't use the same code as for taps because hold bodies can only rotate
|
||||||
|
// around the y axis. -Kyz
|
||||||
|
switch(column_args.rot_handler->m_spline_mode)
|
||||||
|
{
|
||||||
|
case NCSM_Disabled:
|
||||||
|
// XXX: Actor rotations use degrees, Math uses radians. Convert here.
|
||||||
|
ae_rot[1]= ArrowEffects::GetRotationY(m_pPlayerState, fYOffset) * PI_180;
|
||||||
|
sp_rot.resize(3);
|
||||||
|
sp_rot[0]= sp_rot[1]= sp_rot[2]= 0.0f;
|
||||||
|
break;
|
||||||
|
case NCSM_Offset:
|
||||||
|
ae_rot[1]= ArrowEffects::GetRotationY(m_pPlayerState, fYOffset) * PI_180;
|
||||||
|
column_args.rot_handler->EvalForBeat(column_args.song_beat, cur_beat, sp_rot);
|
||||||
|
break;
|
||||||
|
case NCSM_Position:
|
||||||
|
column_args.rot_handler->EvalForBeat(column_args.song_beat, cur_beat, sp_rot);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// XXX: Actor rotations use degrees, RageFastCos/Sin use radians. Convert here.
|
RageVector3 center_vert(sp_pos[0] + ae_pos[0],
|
||||||
const float fRotationY = ArrowEffects::GetRotationY( m_pPlayerState, fYOffset ) * PI/180;
|
sp_pos[1] + ae_pos[1], sp_pos[2] + ae_pos[2]);
|
||||||
|
|
||||||
// if we're rotating, we need to modify the X and Z coords for the outer edges.
|
// Special case for hold caps, which have the same top and bottom beat.
|
||||||
const float fRotOffsetX = (fScaledFrameWidth/2) * RageFastCos(fRotationY);
|
if(top_beat == bottom_beat && fY != fYStartPos)
|
||||||
const float fRotOffsetZ = (fScaledFrameWidth/2) * RageFastSin(fRotationY);
|
{
|
||||||
|
center_vert.x+= render_forward.x;
|
||||||
|
center_vert.y+= render_forward.y;
|
||||||
|
center_vert.z+= render_forward.z;
|
||||||
|
}
|
||||||
|
|
||||||
//const float fXLeft = fX - (fScaledFrameWidth/2);
|
const float render_roty= (sp_rot[1] + ae_rot[1]);
|
||||||
const float fXLeft = fX - fRotOffsetX;
|
|
||||||
const float fXCenter = fX;
|
// (step 2 of vector handling)
|
||||||
//const float fXRight = fX + (fScaledFrameWidth/2);
|
RageVector3 render_left;
|
||||||
const float fXRight = fX + fRotOffsetX;
|
if(abs(render_forward.z) > 0.9f) // 0.9 arbitrariliy picked.
|
||||||
const float fZLeft = fZ - fRotOffsetZ;
|
{
|
||||||
const float fZCenter = fZ;
|
RageVec3Cross(&render_left, &render_forward, &pos_y_vec);
|
||||||
const float fZRight = fZ + fRotOffsetZ;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RageVec3Cross(&render_left, &render_forward, &pos_z_vec);
|
||||||
|
}
|
||||||
|
RageAARotate(&render_left, &render_forward, render_roty);
|
||||||
|
const float half_width= fScaledFrameWidth * .5f;
|
||||||
|
render_left.x*= half_width;
|
||||||
|
render_left.y*= half_width;
|
||||||
|
render_left.z*= half_width;
|
||||||
|
|
||||||
|
RageVector3 const left_vert(center_vert.x + render_left.x,
|
||||||
|
center_vert.y + render_left.y, center_vert.z + render_left.z);
|
||||||
|
RageVector3 const right_vert(center_vert.x - render_left.x,
|
||||||
|
center_vert.y - render_left.y, center_vert.z - render_left.z);
|
||||||
|
|
||||||
const float fDistFromTop = fY - fYTop;
|
const float fDistFromTop = fY - fYTop;
|
||||||
float fTexCoordTop = SCALE( fDistFromTop, 0, fFrameHeight, rect.top, rect.bottom );
|
float fTexCoordTop = SCALE( fDistFromTop, 0, fFrameHeight, rect.top, rect.bottom );
|
||||||
fTexCoordTop += fAddToTexCoord;
|
fTexCoordTop += fAddToTexCoord;
|
||||||
|
|
||||||
const float fAlpha = ArrowGetAlphaOrGlow( bGlow, m_pPlayerState, iCol, fYOffset, fPercentFadeToFail, m_fYReverseOffsetPixels, args.draw_pixels_before_targets, args.fade_before_targets );
|
const float fAlpha = ArrowGetAlphaOrGlow( bGlow, m_pPlayerState, column_args.column, fYOffset, fPercentFadeToFail, m_fYReverseOffsetPixels, field_args.draw_pixels_before_targets, field_args.fade_before_targets );
|
||||||
const RageColor color = RageColor(fColorScale,fColorScale,fColorScale,fAlpha);
|
const RageColor color = RageColor(fColorScale,fColorScale,fColorScale,fAlpha);
|
||||||
|
|
||||||
if( fAlpha > 0 )
|
if( fAlpha > 0 )
|
||||||
bAllAreTransparent = false;
|
bAllAreTransparent = false;
|
||||||
|
|
||||||
queue.v[0].p = RageVector3(fXLeft, fY + spline_pos[1], fZLeft); queue.v[0].c = color; queue.v[0].t = RageVector2(fTexCoordLeft, fTexCoordTop);
|
queue.v[0].p = left_vert; queue.v[0].c = color; queue.v[0].t = RageVector2(fTexCoordLeft, fTexCoordTop);
|
||||||
queue.v[1].p = RageVector3(fXCenter, fY + spline_pos[1], fZCenter); queue.v[1].c = color; queue.v[1].t = RageVector2(fTexCoordCenter, fTexCoordTop);
|
queue.v[1].p = center_vert; queue.v[1].c = color; queue.v[1].t = RageVector2(fTexCoordCenter, fTexCoordTop);
|
||||||
queue.v[2].p = RageVector3(fXRight, fY + spline_pos[1], fZRight); queue.v[2].c = color; queue.v[2].t = RageVector2(fTexCoordRight, fTexCoordTop);
|
queue.v[2].p = right_vert; queue.v[2].c = color; queue.v[2].t = RageVector2(fTexCoordRight, fTexCoordTop);
|
||||||
queue.v+=3;
|
queue.v+=3;
|
||||||
|
|
||||||
if( queue.Free() < 3 || bLast )
|
if( queue.Free() < 3 || bLast )
|
||||||
@@ -753,10 +971,11 @@ void NoteDisplay::DrawHoldPart(vector<Sprite*> &vpSpr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void NoteDisplay::DrawHoldBody(const TapNote& tn,
|
void NoteDisplay::DrawHoldBody(const TapNote& tn,
|
||||||
CommonColumnRenderArgs const& args, int iCol, float fBeat,
|
NoteFieldRenderArgs const& field_args,
|
||||||
|
NoteColumnRenderArgs const& column_args, float fBeat,
|
||||||
bool bIsBeingHeld, float fYHead, float fYTail, bool bIsAddition,
|
bool bIsBeingHeld, float fYHead, float fYTail, bool bIsAddition,
|
||||||
float fPercentFadeToFail, float fColorScale, bool bGlow,
|
float fPercentFadeToFail, float fColorScale, bool bGlow,
|
||||||
float top_t, float bottom_t)
|
float top_beat, float bottom_beat)
|
||||||
{
|
{
|
||||||
vector<Sprite*> vpSprTop;
|
vector<Sprite*> vpSprTop;
|
||||||
Sprite *pSpriteTop = GetHoldSprite( m_HoldTopCap, NotePart_HoldTopCap, fBeat, tn.subType == TapNoteSubType_Roll, bIsBeingHeld && !cache->m_bHoldActiveIsAddLayer );
|
Sprite *pSpriteTop = GetHoldSprite( m_HoldTopCap, NotePart_HoldTopCap, fBeat, tn.subType == TapNoteSubType_Roll, bIsBeingHeld && !cache->m_bHoldActiveIsAddLayer );
|
||||||
@@ -780,7 +999,7 @@ void NoteDisplay::DrawHoldBody(const TapNote& tn,
|
|||||||
vpSprBottom.push_back( pSprBottom );
|
vpSprBottom.push_back( pSprBottom );
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool bReverse = m_pPlayerState->m_PlayerOptions.GetCurrent().GetReversePercentForColumn(iCol) > 0.5f;
|
const bool bReverse = m_pPlayerState->m_PlayerOptions.GetCurrent().GetReversePercentForColumn(column_args.column) > 0.5f;
|
||||||
bool bFlipHoldBody = bReverse && cache->m_bFlipHoldBodyWhenReverse;
|
bool bFlipHoldBody = bReverse && cache->m_bFlipHoldBodyWhenReverse;
|
||||||
if( bFlipHoldBody )
|
if( bFlipHoldBody )
|
||||||
{
|
{
|
||||||
@@ -814,55 +1033,56 @@ void NoteDisplay::DrawHoldBody(const TapNote& tn,
|
|||||||
const float fFrameHeightTop = pSpriteTop->GetUnzoomedHeight();
|
const float fFrameHeightTop = pSpriteTop->GetUnzoomedHeight();
|
||||||
const float fFrameHeightBottom = pSpriteBottom->GetUnzoomedHeight();
|
const float fFrameHeightBottom = pSpriteBottom->GetUnzoomedHeight();
|
||||||
|
|
||||||
float fYStartPos = ArrowEffects::GetYPos( m_pPlayerState, iCol,
|
float fYStartPos = ArrowEffects::GetYPos( m_pPlayerState, column_args.column,
|
||||||
args.draw_pixels_after_targets, m_fYReverseOffsetPixels );
|
field_args.draw_pixels_after_targets, m_fYReverseOffsetPixels );
|
||||||
float fYEndPos = ArrowEffects::GetYPos( m_pPlayerState, iCol,
|
float fYEndPos = ArrowEffects::GetYPos( m_pPlayerState, column_args.column,
|
||||||
args.draw_pixels_before_targets, m_fYReverseOffsetPixels );
|
field_args.draw_pixels_before_targets, m_fYReverseOffsetPixels );
|
||||||
if( bReverse )
|
if( bReverse )
|
||||||
swap( fYStartPos, fYEndPos );
|
swap( fYStartPos, fYEndPos );
|
||||||
|
|
||||||
bool bTopAnchor = bReverse && cache->m_bTopHoldAnchorWhenReverse;
|
bool bTopAnchor = bReverse && cache->m_bTopHoldAnchorWhenReverse;
|
||||||
|
|
||||||
// Draw the top cap
|
// Draw the top cap
|
||||||
DrawHoldPart(vpSprTop, args, iCol, fYStep, fPercentFadeToFail,
|
DrawHoldPart(vpSprTop, field_args, column_args, fYStep, fPercentFadeToFail,
|
||||||
fColorScale, bGlow,
|
fColorScale, bGlow,
|
||||||
tn.HoldResult.fOverlappedTime,
|
tn.HoldResult.fOverlappedTime,
|
||||||
fYHead-fFrameHeightTop, fYHead,
|
fYHead-fFrameHeightTop, fYHead,
|
||||||
fYStartPos, fYEndPos,
|
fYStartPos, fYEndPos,
|
||||||
false, bTopAnchor, bFlipHoldBody, top_t, top_t);
|
false, bTopAnchor, bFlipHoldBody, top_beat, top_beat);
|
||||||
|
|
||||||
// Draw the body
|
// Draw the body
|
||||||
DrawHoldPart(vpSprBody, args, iCol, fYStep, fPercentFadeToFail,
|
DrawHoldPart(vpSprBody, field_args, column_args, fYStep, fPercentFadeToFail,
|
||||||
fColorScale, bGlow,
|
fColorScale, bGlow,
|
||||||
tn.HoldResult.fOverlappedTime,
|
tn.HoldResult.fOverlappedTime,
|
||||||
fYHead, fYTail,
|
fYHead, fYTail,
|
||||||
fYStartPos, fYEndPos,
|
fYStartPos, fYEndPos,
|
||||||
true, bTopAnchor, bFlipHoldBody, top_t, bottom_t);
|
true, bTopAnchor, bFlipHoldBody, top_beat, bottom_beat);
|
||||||
|
|
||||||
// Draw the bottom cap
|
// Draw the bottom cap
|
||||||
DrawHoldPart(vpSprBottom, args, iCol, fYStep, fPercentFadeToFail,
|
DrawHoldPart(vpSprBottom, field_args, column_args, fYStep, fPercentFadeToFail,
|
||||||
fColorScale, bGlow,
|
fColorScale, bGlow,
|
||||||
tn.HoldResult.fOverlappedTime,
|
tn.HoldResult.fOverlappedTime,
|
||||||
fYTail, fYTail+fFrameHeightBottom,
|
fYTail, fYTail+fFrameHeightBottom,
|
||||||
max(fYStartPos, fYHead), fYEndPos,
|
max(fYStartPos, fYHead), fYEndPos,
|
||||||
false, bTopAnchor, bFlipHoldBody, bottom_t, bottom_t);
|
false, bTopAnchor, bFlipHoldBody, bottom_beat, bottom_beat);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NoteDisplay::DrawHold(const TapNote& tn,
|
void NoteDisplay::DrawHold(const TapNote& tn,
|
||||||
CommonColumnRenderArgs const& args, int iCol, int iRow, bool bIsBeingHeld,
|
NoteFieldRenderArgs const& field_args,
|
||||||
|
NoteColumnRenderArgs const& column_args, int iRow, bool bIsBeingHeld,
|
||||||
const HoldNoteResult &Result, bool bIsAddition, float fPercentFadeToFail)
|
const HoldNoteResult &Result, bool bIsAddition, float fPercentFadeToFail)
|
||||||
{
|
{
|
||||||
int iEndRow = iRow + tn.iDuration;
|
int iEndRow = iRow + tn.iDuration;
|
||||||
float top_t= BeatToTValue(args, NoteRowToVisibleBeat(m_pPlayerState, iRow));
|
float top_beat= NoteRowToVisibleBeat(m_pPlayerState, iRow);
|
||||||
float bottom_t= BeatToTValue(args, NoteRowToVisibleBeat(m_pPlayerState, iEndRow));
|
float bottom_beat= NoteRowToVisibleBeat(m_pPlayerState, iEndRow);
|
||||||
if(bIsBeingHeld)
|
if(bIsBeingHeld)
|
||||||
{
|
{
|
||||||
top_t= args.receptor_t;
|
top_beat= column_args.song_beat;
|
||||||
}
|
}
|
||||||
|
|
||||||
// bDrawGlowOnly is a little hacky. We need to draw the diffuse part and the glow part one pass at a time to minimize state changes
|
// bDrawGlowOnly is a little hacky. We need to draw the diffuse part and the glow part one pass at a time to minimize state changes
|
||||||
|
|
||||||
bool bReverse = m_pPlayerState->m_PlayerOptions.GetCurrent().GetReversePercentForColumn(iCol) > 0.5f;
|
bool bReverse = m_pPlayerState->m_PlayerOptions.GetCurrent().GetReversePercentForColumn(column_args.column) > 0.5f;
|
||||||
float fStartBeat = NoteRowToBeat( max(tn.HoldResult.iLastHeldRow, iRow) );
|
float fStartBeat = NoteRowToBeat( max(tn.HoldResult.iLastHeldRow, iRow) );
|
||||||
float fThrowAway = 0;
|
float fThrowAway = 0;
|
||||||
|
|
||||||
@@ -872,11 +1092,11 @@ void NoteDisplay::DrawHold(const TapNote& tn,
|
|||||||
if( tn.HoldResult.bActive && tn.HoldResult.fLife > 0 )
|
if( tn.HoldResult.bActive && tn.HoldResult.fLife > 0 )
|
||||||
; // use the default values filled in above
|
; // use the default values filled in above
|
||||||
else
|
else
|
||||||
fStartYOffset = ArrowEffects::GetYOffset( m_pPlayerState, iCol, fStartBeat, fThrowAway, bStartIsPastPeak );
|
fStartYOffset = ArrowEffects::GetYOffset( m_pPlayerState, column_args.column, fStartBeat, fThrowAway, bStartIsPastPeak );
|
||||||
|
|
||||||
float fEndPeakYOffset = 0;
|
float fEndPeakYOffset = 0;
|
||||||
bool bEndIsPastPeak = false;
|
bool bEndIsPastPeak = false;
|
||||||
float fEndYOffset = ArrowEffects::GetYOffset( m_pPlayerState, iCol, NoteRowToBeat(iEndRow), fEndPeakYOffset, bEndIsPastPeak );
|
float fEndYOffset = ArrowEffects::GetYOffset( m_pPlayerState, column_args.column, NoteRowToBeat(iEndRow), fEndPeakYOffset, bEndIsPastPeak );
|
||||||
|
|
||||||
// In boomerang, the arrows reverse direction at Y offset value fPeakAtYOffset.
|
// In boomerang, the arrows reverse direction at Y offset value fPeakAtYOffset.
|
||||||
// If fPeakAtYOffset lies inside of the hold we're drawing, then the we
|
// If fPeakAtYOffset lies inside of the hold we're drawing, then the we
|
||||||
@@ -889,8 +1109,8 @@ void NoteDisplay::DrawHold(const TapNote& tn,
|
|||||||
if( bReverse )
|
if( bReverse )
|
||||||
swap( fStartYOffset, fEndYOffset );
|
swap( fStartYOffset, fEndYOffset );
|
||||||
|
|
||||||
const float fYHead = ArrowEffects::GetYPos( m_pPlayerState, iCol, fStartYOffset, m_fYReverseOffsetPixels );
|
const float fYHead = ArrowEffects::GetYPos( m_pPlayerState, column_args.column, fStartYOffset, m_fYReverseOffsetPixels );
|
||||||
const float fYTail = ArrowEffects::GetYPos( m_pPlayerState, iCol, fEndYOffset, m_fYReverseOffsetPixels );
|
const float fYTail = ArrowEffects::GetYPos( m_pPlayerState, column_args.column, fEndYOffset, m_fYReverseOffsetPixels );
|
||||||
|
|
||||||
const float fColorScale = SCALE( tn.HoldResult.fLife, 0.0f, 1.0f, cache->m_fHoldLetGoGrayPercent, 1.0f );
|
const float fColorScale = SCALE( tn.HoldResult.fLife, 0.0f, 1.0f, cache->m_fHoldLetGoGrayPercent, 1.0f );
|
||||||
|
|
||||||
@@ -899,6 +1119,9 @@ void NoteDisplay::DrawHold(const TapNote& tn,
|
|||||||
/* The body and caps should have no overlap, so their order doesn't matter.
|
/* The body and caps should have no overlap, so their order doesn't matter.
|
||||||
* Draw the head last, so it appears on top. */
|
* Draw the head last, so it appears on top. */
|
||||||
float fBeat = NoteRowToBeat(iRow);
|
float fBeat = NoteRowToBeat(iRow);
|
||||||
|
// Side note: I don't know why these two checks were commented out and I
|
||||||
|
// didn't bother to update them when rewriting the arguments that are
|
||||||
|
// passed to the note drawing functions. -Kyz
|
||||||
/*
|
/*
|
||||||
if( !cache->m_bHoldHeadIsAboveWavyParts )
|
if( !cache->m_bHoldHeadIsAboveWavyParts )
|
||||||
{
|
{
|
||||||
@@ -912,8 +1135,8 @@ void NoteDisplay::DrawHold(const TapNote& tn,
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DrawHoldBody(tn, args, iCol, fBeat, bIsBeingHeld, fYHead, fYTail, bIsAddition, fPercentFadeToFail, fColorScale, false, top_t, bottom_t);
|
DrawHoldBody(tn, field_args, column_args, fBeat, bIsBeingHeld, fYHead, fYTail, bIsAddition, fPercentFadeToFail, fColorScale, false, top_beat, bottom_beat);
|
||||||
DrawHoldBody(tn, args, iCol, fBeat, bIsBeingHeld, fYHead, fYTail, bIsAddition, fPercentFadeToFail, fColorScale, true, top_t, bottom_t);
|
DrawHoldBody(tn, field_args, column_args, fBeat, bIsBeingHeld, fYHead, fYTail, bIsAddition, fPercentFadeToFail, fColorScale, true, top_beat, bottom_beat);
|
||||||
|
|
||||||
/* These set the texture mode themselves. */
|
/* These set the texture mode themselves. */
|
||||||
// this part was modified in pumpmania, where it flips the draw order
|
// this part was modified in pumpmania, where it flips the draw order
|
||||||
@@ -921,56 +1144,76 @@ void NoteDisplay::DrawHold(const TapNote& tn,
|
|||||||
if( cache->m_bHoldTailIsAboveWavyParts )
|
if( cache->m_bHoldTailIsAboveWavyParts )
|
||||||
{
|
{
|
||||||
Actor *pActor = GetHoldActor( m_HoldTail, NotePart_HoldTail, NoteRowToBeat(iRow), tn.subType == TapNoteSubType_Roll, bIsBeingHeld );
|
Actor *pActor = GetHoldActor( m_HoldTail, NotePart_HoldTail, NoteRowToBeat(iRow), tn.subType == TapNoteSubType_Roll, bIsBeingHeld );
|
||||||
DrawActor(tn, pActor, NotePart_HoldTail, args, iCol, bFlipHeadAndTail ? fStartYOffset : fEndYOffset, fBeat, bIsAddition, fPercentFadeToFail, fColorScale, false);
|
DrawActor(tn, pActor, NotePart_HoldTail, field_args, column_args, bFlipHeadAndTail ? fStartYOffset : fEndYOffset, fBeat, bIsAddition, fPercentFadeToFail, fColorScale, false);
|
||||||
}
|
}
|
||||||
if( cache->m_bHoldHeadIsAboveWavyParts )
|
if( cache->m_bHoldHeadIsAboveWavyParts )
|
||||||
{
|
{
|
||||||
Actor *pActor = GetHoldActor( m_HoldHead, NotePart_HoldHead, NoteRowToBeat(iRow), tn.subType == TapNoteSubType_Roll, bIsBeingHeld );
|
Actor *pActor = GetHoldActor( m_HoldHead, NotePart_HoldHead, NoteRowToBeat(iRow), tn.subType == TapNoteSubType_Roll, bIsBeingHeld );
|
||||||
DrawActor(tn, pActor, NotePart_HoldHead, args, iCol, bFlipHeadAndTail ? fEndYOffset : fStartYOffset, fBeat, bIsAddition, fPercentFadeToFail, fColorScale, bIsBeingHeld);
|
DrawActor(tn, pActor, NotePart_HoldHead, field_args, column_args, bFlipHeadAndTail ? fEndYOffset : fStartYOffset, fBeat, bIsAddition, fPercentFadeToFail, fColorScale, bIsBeingHeld);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NoteDisplay::DrawActor(const TapNote& tn, Actor* pActor, NotePart part,
|
void NoteDisplay::DrawActor(const TapNote& tn, Actor* pActor, NotePart part,
|
||||||
CommonColumnRenderArgs const& args, int iCol, float fYOffset, float fBeat,
|
NoteFieldRenderArgs const& field_args, NoteColumnRenderArgs const& column_args, float fYOffset, float fBeat,
|
||||||
bool bIsAddition, float fPercentFadeToFail, float fColorScale,
|
bool bIsAddition, float fPercentFadeToFail, float fColorScale,
|
||||||
bool is_being_held)
|
bool is_being_held)
|
||||||
{
|
{
|
||||||
if (tn.type == TapNoteType_AutoKeysound && !GAMESTATE->m_bInStepEditor) return;
|
if (tn.type == TapNoteType_AutoKeysound && !GAMESTATE->m_bInStepEditor) return;
|
||||||
if(fYOffset < args.draw_pixels_after_targets ||
|
if(fYOffset < field_args.draw_pixels_after_targets ||
|
||||||
fYOffset > args.draw_pixels_before_targets)
|
fYOffset > field_args.draw_pixels_before_targets)
|
||||||
return;
|
return;
|
||||||
float spline_t= BeatToTValue(args, fBeat);
|
float spline_beat= fBeat;
|
||||||
if(is_being_held) { spline_t= args.receptor_t; }
|
if(is_being_held) { spline_beat= column_args.song_beat; }
|
||||||
vector<float> spline_pos;
|
|
||||||
args.spline->evaluate(spline_t, spline_pos);
|
const float fAlpha = ArrowEffects::GetAlpha( m_pPlayerState, column_args.column, fYOffset, fPercentFadeToFail, m_fYReverseOffsetPixels, field_args.draw_pixels_before_targets, field_args.fade_before_targets );
|
||||||
const float fY = ArrowEffects::GetYPos( m_pPlayerState, iCol, fYOffset, m_fYReverseOffsetPixels ) + spline_pos[1];
|
const float fGlow = ArrowEffects::GetGlow( m_pPlayerState, column_args.column, fYOffset, fPercentFadeToFail, m_fYReverseOffsetPixels, field_args.draw_pixels_before_targets, field_args.fade_before_targets );
|
||||||
const float fX = ArrowEffects::GetXPos( m_pPlayerState, iCol, fYOffset ) + spline_pos[0];
|
|
||||||
const float fZ = ArrowEffects::GetZPos( m_pPlayerState, iCol, fYOffset ) + spline_pos[2];
|
|
||||||
const float fAlpha = ArrowEffects::GetAlpha( m_pPlayerState, iCol, fYOffset, fPercentFadeToFail, m_fYReverseOffsetPixels, args.draw_pixels_before_targets, args.fade_before_targets );
|
|
||||||
const float fGlow = ArrowEffects::GetGlow( m_pPlayerState, iCol, fYOffset, fPercentFadeToFail, m_fYReverseOffsetPixels, args.draw_pixels_before_targets, args.fade_before_targets );
|
|
||||||
const RageColor diffuse = RageColor(fColorScale,fColorScale,fColorScale,fAlpha);
|
const RageColor diffuse = RageColor(fColorScale,fColorScale,fColorScale,fAlpha);
|
||||||
const RageColor glow = RageColor(1,1,1,fGlow);
|
const RageColor glow = RageColor(1,1,1,fGlow);
|
||||||
float fRotationX = 0, fRotationZ = 0;
|
|
||||||
const float fRotationY = ArrowEffects::GetRotationY( m_pPlayerState, fYOffset );
|
|
||||||
|
|
||||||
bool bIsHoldHead = tn.type == TapNoteType_HoldHead;
|
bool bIsHoldHead = tn.type == TapNoteType_HoldHead;
|
||||||
bool bIsHoldCap = bIsHoldHead || tn.type == TapNoteType_HoldTail;
|
bool bIsHoldCap = bIsHoldHead || tn.type == TapNoteType_HoldTail;
|
||||||
|
|
||||||
fRotationZ = ArrowEffects::GetRotationZ( m_pPlayerState, fBeat, bIsHoldHead );
|
|
||||||
if( !bIsHoldCap )
|
|
||||||
{
|
|
||||||
fRotationX = ArrowEffects::GetRotationX( m_pPlayerState, fYOffset );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( tn.type != TapNoteType_HoldHead )
|
if( tn.type != TapNoteType_HoldHead )
|
||||||
fColorScale *= ArrowEffects::GetBrightness( m_pPlayerState, fBeat );
|
fColorScale *= ArrowEffects::GetBrightness( m_pPlayerState, fBeat );
|
||||||
|
|
||||||
pActor->SetRotationX( fRotationX );
|
// same logical structure as in UpdateReceptorGhostStuff, I just haven't
|
||||||
pActor->SetRotationY( fRotationY );
|
// figured out a good way to combine them. -Kyz
|
||||||
pActor->SetRotationZ( fRotationZ );
|
vector<float> sp_pos;
|
||||||
pActor->SetXY( fX, fY );
|
vector<float> sp_rot;
|
||||||
pActor->SetZ( fZ );
|
vector<float> sp_zoom;
|
||||||
pActor->SetZoom( ArrowEffects::GetZoom(m_pPlayerState) );
|
vector<float> ae_pos(3, 0.0f);
|
||||||
|
vector<float> ae_rot(3, 0.0f);
|
||||||
|
vector<float> ae_zoom(3, 0.0f);
|
||||||
|
column_args.spae_pos_for_beat(m_pPlayerState, spline_beat,
|
||||||
|
fYOffset, m_fYReverseOffsetPixels, sp_pos, ae_pos);
|
||||||
|
|
||||||
|
switch(column_args.rot_handler->m_spline_mode)
|
||||||
|
{
|
||||||
|
case NCSM_Disabled:
|
||||||
|
if(!bIsHoldCap)
|
||||||
|
{
|
||||||
|
ae_rot[0]= ArrowEffects::GetRotationX(m_pPlayerState, fYOffset);
|
||||||
|
}
|
||||||
|
ae_rot[1]= ArrowEffects::GetRotationY(m_pPlayerState, fYOffset);
|
||||||
|
ae_rot[2]= ArrowEffects::GetRotationZ(m_pPlayerState, fBeat, bIsHoldHead);
|
||||||
|
sp_rot.resize(3);
|
||||||
|
sp_rot[0]= sp_rot[1]= sp_rot[2]= 0.0f;
|
||||||
|
break;
|
||||||
|
case NCSM_Offset:
|
||||||
|
if(!bIsHoldCap)
|
||||||
|
{
|
||||||
|
ae_rot[0]= ArrowEffects::GetRotationX(m_pPlayerState, fYOffset);
|
||||||
|
}
|
||||||
|
ae_rot[1]= ArrowEffects::GetRotationY(m_pPlayerState, fYOffset);
|
||||||
|
ae_rot[2]= ArrowEffects::GetRotationZ(m_pPlayerState, fBeat, bIsHoldHead);
|
||||||
|
column_args.rot_handler->EvalForBeat(column_args.song_beat, spline_beat, sp_rot);
|
||||||
|
break;
|
||||||
|
case NCSM_Position:
|
||||||
|
column_args.rot_handler->EvalForBeat(column_args.song_beat, spline_beat, sp_rot);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
column_args.spae_zoom_for_beat(m_pPlayerState, spline_beat, sp_zoom, ae_zoom);
|
||||||
|
column_args.SetPRZForActor(pActor, sp_pos, ae_pos, sp_rot, ae_rot, sp_zoom, ae_zoom);
|
||||||
// [AJ] this two lines (and how they're handled) piss off many people:
|
// [AJ] this two lines (and how they're handled) piss off many people:
|
||||||
pActor->SetDiffuse( diffuse );
|
pActor->SetDiffuse( diffuse );
|
||||||
pActor->SetGlow( glow );
|
pActor->SetGlow( glow );
|
||||||
@@ -1004,7 +1247,8 @@ void NoteDisplay::DrawActor(const TapNote& tn, Actor* pActor, NotePart part,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void NoteDisplay::DrawTap(const TapNote& tn,
|
void NoteDisplay::DrawTap(const TapNote& tn,
|
||||||
CommonColumnRenderArgs const& args, int iCol, float fBeat,
|
NoteFieldRenderArgs const& field_args,
|
||||||
|
NoteColumnRenderArgs const& column_args, float fBeat,
|
||||||
bool bOnSameRowAsHoldStart, bool bOnSameRowAsRollStart,
|
bool bOnSameRowAsHoldStart, bool bOnSameRowAsRollStart,
|
||||||
bool bIsAddition, float fPercentFadeToFail)
|
bool bIsAddition, float fPercentFadeToFail)
|
||||||
{
|
{
|
||||||
@@ -1078,21 +1322,89 @@ void NoteDisplay::DrawTap(const TapNote& tn,
|
|||||||
pActor->HandleMessage( msg );
|
pActor->HandleMessage( msg );
|
||||||
}
|
}
|
||||||
|
|
||||||
const float fYOffset = ArrowEffects::GetYOffset( m_pPlayerState, iCol, fBeat );
|
const float fYOffset = ArrowEffects::GetYOffset( m_pPlayerState, column_args.column, fBeat );
|
||||||
// this is the line that forces the (1,1,1,x) part of the noteskin diffuse -aj
|
// this is the line that forces the (1,1,1,x) part of the noteskin diffuse -aj
|
||||||
DrawActor(tn, pActor, part, args, iCol, fYOffset, fBeat, bIsAddition, fPercentFadeToFail, 1.0f, false);
|
DrawActor(tn, pActor, part, field_args, column_args, fYOffset, fBeat, bIsAddition, fPercentFadeToFail, 1.0f, false);
|
||||||
|
|
||||||
if( tn.type == TapNoteType_Attack )
|
if( tn.type == TapNoteType_Attack )
|
||||||
pActor->PlayCommand( "UnsetAttack" );
|
pActor->PlayCommand( "UnsetAttack" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NoteColumnRenderer::UpdateReceptorGhostStuff(Actor* receptor) const
|
||||||
|
{
|
||||||
|
PlayerState const* player_state= m_field_render_args->player_state;
|
||||||
|
float song_beat= player_state->GetDisplayedPosition().m_fSongBeatVisible;
|
||||||
|
// sp_* will be filled with the settings from the splines.
|
||||||
|
// ae_* will be filled with the settings from ArrowEffects.
|
||||||
|
// The two together will be applied to the actor.
|
||||||
|
// sp_* will be zeroes in NCSM_Disabled, and ae_* will be zeroes in
|
||||||
|
// NCSM_Position, so the setting step won't have to check the mode. -Kyz
|
||||||
|
// sp_* are sized by the spline evaluate function.
|
||||||
|
vector<float> sp_pos;
|
||||||
|
vector<float> sp_rot;
|
||||||
|
vector<float> sp_zoom;
|
||||||
|
vector<float> ae_pos(3, 0.0f);
|
||||||
|
vector<float> ae_rot(3, 0.0f);
|
||||||
|
vector<float> ae_zoom(3, 0.0f);
|
||||||
|
switch(m_pos_handler.m_spline_mode)
|
||||||
|
{
|
||||||
|
case NCSM_Disabled:
|
||||||
|
ArrowEffects::GetXYZPos(player_state, m_column, 0, m_field_render_args->reverse_offset_pixels, ae_pos);
|
||||||
|
sp_pos.resize(3);
|
||||||
|
// Sure, resize is supposed to call the default constructor, and for
|
||||||
|
// numbers the default constructor is supposed to set it to zero, but
|
||||||
|
// I got bit for relying on that once. -Kyz
|
||||||
|
sp_pos[0]= sp_pos[1]= sp_pos[2]= 0.0f;
|
||||||
|
break;
|
||||||
|
case NCSM_Offset:
|
||||||
|
ArrowEffects::GetXYZPos(player_state, m_column, 0, m_field_render_args->reverse_offset_pixels, ae_pos);
|
||||||
|
m_pos_handler.EvalForReceptor(song_beat, sp_pos);
|
||||||
|
break;
|
||||||
|
case NCSM_Position:
|
||||||
|
m_pos_handler.EvalForReceptor(song_beat, sp_pos);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
switch(m_rot_handler.m_spline_mode)
|
||||||
|
{
|
||||||
|
case NCSM_Disabled:
|
||||||
|
ae_rot[2]= ArrowEffects::ReceptorGetRotationZ(player_state);
|
||||||
|
sp_rot.resize(3);
|
||||||
|
sp_rot[0]= sp_rot[1]= sp_rot[2]= 0.0f;
|
||||||
|
break;
|
||||||
|
case NCSM_Offset:
|
||||||
|
ae_rot[2]= ArrowEffects::ReceptorGetRotationZ(player_state);
|
||||||
|
m_rot_handler.EvalForReceptor(song_beat, sp_rot);
|
||||||
|
break;
|
||||||
|
case NCSM_Position:
|
||||||
|
m_rot_handler.EvalForReceptor(song_beat, sp_rot);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
switch(m_zoom_handler.m_spline_mode)
|
||||||
|
{
|
||||||
|
case NCSM_Disabled:
|
||||||
|
ae_zoom[0]= ae_zoom[1]= ae_zoom[2]= ArrowEffects::GetZoom(player_state);
|
||||||
|
sp_zoom.resize(3);
|
||||||
|
sp_zoom[0]= sp_zoom[1]= sp_zoom[2]= 0.0f;
|
||||||
|
break;
|
||||||
|
case NCSM_Offset:
|
||||||
|
ae_zoom[0]= ae_zoom[1]= ae_zoom[2]= ArrowEffects::GetZoom(player_state);
|
||||||
|
m_zoom_handler.EvalForReceptor(song_beat, sp_zoom);
|
||||||
|
break;
|
||||||
|
case NCSM_Position:
|
||||||
|
m_zoom_handler.EvalForReceptor(song_beat, sp_zoom);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
m_column_render_args.SetPRZForActor(receptor, sp_pos, ae_pos, sp_rot, ae_rot, sp_zoom, ae_zoom);
|
||||||
|
}
|
||||||
|
|
||||||
void NoteColumnRenderer::DrawPrimitives()
|
void NoteColumnRenderer::DrawPrimitives()
|
||||||
{
|
{
|
||||||
m_render_args->spline= &m_spline;
|
m_column_render_args.song_beat= m_field_render_args->player_state->GetDisplayedPosition().m_fSongBeatVisible;
|
||||||
m_render_args->receptor_t= m_receptor_t;
|
m_column_render_args.pos_handler= &m_pos_handler;
|
||||||
m_render_args->beats_per_t= m_beats_per_t;
|
m_column_render_args.rot_handler= &m_rot_handler;
|
||||||
m_render_args->first_beat= NoteRowToBeat(m_render_args->first_row);
|
m_column_render_args.zoom_handler= &m_zoom_handler;
|
||||||
m_render_args->last_beat= NoteRowToBeat(m_render_args->last_row);
|
m_field_render_args->first_beat= NoteRowToBeat(m_field_render_args->first_row);
|
||||||
|
m_field_render_args->last_beat= NoteRowToBeat(m_field_render_args->last_row);
|
||||||
bool any_upcoming= false;
|
bool any_upcoming= false;
|
||||||
// Build lists of holds and taps for each player number, then pass those
|
// Build lists of holds and taps for each player number, then pass those
|
||||||
// lists to the displays to draw.
|
// lists to the displays to draw.
|
||||||
@@ -1101,8 +1413,8 @@ void NoteColumnRenderer::DrawPrimitives()
|
|||||||
vector<vector<NoteData::TrackMap::const_iterator> > holds(PLAYER_INVALID+1);
|
vector<vector<NoteData::TrackMap::const_iterator> > holds(PLAYER_INVALID+1);
|
||||||
vector<vector<NoteData::TrackMap::const_iterator> > taps(PLAYER_INVALID+1);
|
vector<vector<NoteData::TrackMap::const_iterator> > taps(PLAYER_INVALID+1);
|
||||||
NoteData::TrackMap::const_iterator begin, end;
|
NoteData::TrackMap::const_iterator begin, end;
|
||||||
m_render_args->note_data->GetTapNoteRangeInclusive(m_column,
|
m_field_render_args->note_data->GetTapNoteRangeInclusive(m_column,
|
||||||
m_render_args->first_row, m_render_args->last_row+1, begin, end);
|
m_field_render_args->first_row, m_field_render_args->last_row+1, begin, end);
|
||||||
for(; begin != end; ++begin)
|
for(; begin != end; ++begin)
|
||||||
{
|
{
|
||||||
TapNote const& tn= begin->second;
|
TapNote const& tn= begin->second;
|
||||||
@@ -1133,7 +1445,7 @@ void NoteColumnRenderer::DrawPrimitives()
|
|||||||
#define DTS_INNER(pn, tap_set, draw_func, disp) \
|
#define DTS_INNER(pn, tap_set, draw_func, disp) \
|
||||||
if(!tap_set[pn].empty()) \
|
if(!tap_set[pn].empty()) \
|
||||||
{ \
|
{ \
|
||||||
any_upcoming|= disp->draw_func(*m_render_args, m_column, tap_set[pn]); \
|
any_upcoming|= disp->draw_func(*m_field_render_args, m_column_render_args, tap_set[pn]); \
|
||||||
}
|
}
|
||||||
#define DRAW_TAP_SET(tap_set, draw_func) \
|
#define DRAW_TAP_SET(tap_set, draw_func) \
|
||||||
FOREACH_PlayerNumber(pn) \
|
FOREACH_PlayerNumber(pn) \
|
||||||
@@ -1146,12 +1458,12 @@ void NoteColumnRenderer::DrawPrimitives()
|
|||||||
DTS_INNER(PLAYER_INVALID, taps, DrawTapsInRange, m_displays[PLAYER_INVALID]);
|
DTS_INNER(PLAYER_INVALID, taps, DrawTapsInRange, m_displays[PLAYER_INVALID]);
|
||||||
#undef DTS_INNER
|
#undef DTS_INNER
|
||||||
#undef DRAW_TAP_SET
|
#undef DRAW_TAP_SET
|
||||||
m_render_args->receptor_row->SetNoteUpcoming(m_column, any_upcoming);
|
m_field_render_args->receptor_row->SetNoteUpcoming(m_column, any_upcoming);
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "LuaBinding.h"
|
#include "LuaBinding.h"
|
||||||
|
|
||||||
struct LunaNoteColumnRenderer : Luna<NoteColumnRenderer>
|
struct LunaNCSplineHandler : Luna<NCSplineHandler>
|
||||||
{
|
{
|
||||||
static int get_spline(T* p, lua_State* L)
|
static int get_spline(T* p, lua_State* L)
|
||||||
{
|
{
|
||||||
@@ -1166,22 +1478,66 @@ struct LunaNoteColumnRenderer : Luna<NoteColumnRenderer>
|
|||||||
p->member= FArg(1); \
|
p->member= FArg(1); \
|
||||||
COMMON_RETURN_SELF; \
|
COMMON_RETURN_SELF; \
|
||||||
}
|
}
|
||||||
|
#define SET_B(member, name) \
|
||||||
|
static int name(T* p, lua_State* L) \
|
||||||
|
{ \
|
||||||
|
p->member= BArg(1); \
|
||||||
|
COMMON_RETURN_SELF; \
|
||||||
|
}
|
||||||
SET_T(m_receptor_t, set_receptor_t);
|
SET_T(m_receptor_t, set_receptor_t);
|
||||||
SET_T(m_beats_per_t, set_beats_per_t);
|
SET_T(m_beats_per_t, set_beats_per_t);
|
||||||
|
SET_B(m_subtract_song_beat_from_curr, set_subtract_song_beat);
|
||||||
|
#undef SET_T
|
||||||
|
#undef SET_B
|
||||||
|
static int set_spline_mode(T* p, lua_State* L)
|
||||||
|
{
|
||||||
|
p->m_spline_mode= Enum::Check<NoteColumnSplineMode>(L, 1);
|
||||||
|
COMMON_RETURN_SELF;
|
||||||
|
}
|
||||||
|
DEFINE_METHOD(get_spline_mode, m_spline_mode);
|
||||||
|
DEFINE_METHOD(get_subtract_song_beat, m_subtract_song_beat_from_curr);
|
||||||
|
|
||||||
|
LunaNCSplineHandler()
|
||||||
|
{
|
||||||
|
ADD_METHOD(get_spline);
|
||||||
|
ADD_METHOD(get_beats_per_t);
|
||||||
|
ADD_METHOD(set_beats_per_t);
|
||||||
|
ADD_METHOD(get_receptor_t);
|
||||||
|
ADD_METHOD(set_receptor_t);
|
||||||
|
ADD_METHOD(get_spline_mode);
|
||||||
|
ADD_METHOD(set_spline_mode);
|
||||||
|
ADD_METHOD(get_subtract_song_beat);
|
||||||
|
ADD_METHOD(set_subtract_song_beat);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
LUA_REGISTER_CLASS(NCSplineHandler);
|
||||||
|
|
||||||
|
struct LunaNoteColumnRenderer : Luna<NoteColumnRenderer>
|
||||||
|
{
|
||||||
|
#define GET_HANDLER(member, name) \
|
||||||
|
static int name(T* p, lua_State* L) \
|
||||||
|
{ \
|
||||||
|
p->member.PushSelf(L); \
|
||||||
|
return 1; \
|
||||||
|
}
|
||||||
|
GET_HANDLER(m_pos_handler, get_pos_handler);
|
||||||
|
GET_HANDLER(m_rot_handler, get_rot_handler);
|
||||||
|
GET_HANDLER(m_zoom_handler, get_zoom_handler);
|
||||||
|
#undef GET_HANDLER
|
||||||
|
|
||||||
LunaNoteColumnRenderer()
|
LunaNoteColumnRenderer()
|
||||||
{
|
{
|
||||||
ADD_METHOD(get_spline);
|
ADD_METHOD(get_pos_handler);
|
||||||
ADD_METHOD(get_receptor_t);
|
ADD_METHOD(get_rot_handler);
|
||||||
ADD_METHOD(get_beats_per_t);
|
ADD_METHOD(get_zoom_handler);
|
||||||
ADD_METHOD(set_receptor_t);
|
|
||||||
ADD_METHOD(set_beats_per_t);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
LUA_REGISTER_DERIVED_CLASS(NoteColumnRenderer, Actor)
|
LUA_REGISTER_DERIVED_CLASS(NoteColumnRenderer, Actor)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
* NoteColumnRenderer and associated spline stuff (c) Eric Reese 2014-2015
|
||||||
* (c) 2001-2006 Brian Bugh, Ben Nordstrom, Chris Danford, Steve Checkoway
|
* (c) 2001-2006 Brian Bugh, Ben Nordstrom, Chris Danford, Steve Checkoway
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
|
|||||||
+95
-31
@@ -87,16 +87,24 @@ enum ActiveType
|
|||||||
#define FOREACH_ActiveType( i ) FOREACH_ENUM( ActiveType, i )
|
#define FOREACH_ActiveType( i ) FOREACH_ENUM( ActiveType, i )
|
||||||
const RString &ActiveTypeToString( ActiveType at );
|
const RString &ActiveTypeToString( ActiveType at );
|
||||||
|
|
||||||
|
enum NoteColumnSplineMode
|
||||||
|
{
|
||||||
|
NCSM_Disabled,
|
||||||
|
NCSM_Offset,
|
||||||
|
NCSM_Position,
|
||||||
|
NUM_NoteColumnSplineMode,
|
||||||
|
NoteColumnSplineMode_Invalid
|
||||||
|
};
|
||||||
|
|
||||||
// A little pod struct to carry the data the NoteField needs to pass to the
|
// A little pod struct to carry the data the NoteField needs to pass to the
|
||||||
// NoteDisplay during rendering.
|
// NoteDisplay during rendering.
|
||||||
struct CommonColumnRenderArgs
|
struct NoteFieldRenderArgs
|
||||||
{
|
{
|
||||||
|
PlayerState const* player_state; // to look up PlayerOptions
|
||||||
|
float reverse_offset_pixels;
|
||||||
ReceptorArrowRow* receptor_row;
|
ReceptorArrowRow* receptor_row;
|
||||||
GhostArrowRow* ghost_row;
|
GhostArrowRow* ghost_row;
|
||||||
NoteData const* note_data;
|
NoteData const* note_data;
|
||||||
CubicSplineN const* spline;
|
|
||||||
float receptor_t;
|
|
||||||
float beats_per_t;
|
|
||||||
float first_beat;
|
float first_beat;
|
||||||
float last_beat;
|
float last_beat;
|
||||||
int first_row;
|
int first_row;
|
||||||
@@ -110,6 +118,52 @@ struct CommonColumnRenderArgs
|
|||||||
float fade_before_targets;
|
float fade_before_targets;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// NCSplineHandler exists to allow NoteColumnRenderer to have separate
|
||||||
|
// splines for position, rotation, and zoom, while concisely presenting the
|
||||||
|
// same interface for all three.
|
||||||
|
struct NCSplineHandler
|
||||||
|
{
|
||||||
|
NCSplineHandler()
|
||||||
|
{
|
||||||
|
m_spline.redimension(3);
|
||||||
|
m_spline.m_owned_by_actor= true;
|
||||||
|
m_spline_mode= NCSM_Disabled;
|
||||||
|
m_receptor_t= 0.0f;
|
||||||
|
m_beats_per_t= 1.0f;
|
||||||
|
m_subtract_song_beat_from_curr= true;
|
||||||
|
}
|
||||||
|
float BeatToTValue(float song_beat, float note_beat) const;
|
||||||
|
void EvalForBeat(float song_beat, float note_beat, vector<float>& ret) const;
|
||||||
|
void EvalDerivForBeat(float song_beat, float note_beat, vector<float>& ret) const;
|
||||||
|
void EvalForReceptor(float song_beat, vector<float>& ret) const;
|
||||||
|
|
||||||
|
CubicSplineN m_spline;
|
||||||
|
NoteColumnSplineMode m_spline_mode;
|
||||||
|
float m_receptor_t;
|
||||||
|
float m_beats_per_t;
|
||||||
|
bool m_subtract_song_beat_from_curr;
|
||||||
|
|
||||||
|
void PushSelf(lua_State* L);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NoteColumnRenderArgs
|
||||||
|
{
|
||||||
|
void spae_pos_for_beat(PlayerState const* state,
|
||||||
|
float beat, float y_offset, float y_reverse_offset,
|
||||||
|
vector<float>& sp_pos, vector<float>& ae_pos) const;
|
||||||
|
void spae_zoom_for_beat(PlayerState const* state, float beat,
|
||||||
|
vector<float>& sp_zoom, vector<float>& ae_zoom) const;
|
||||||
|
void SetPRZForActor(Actor* actor,
|
||||||
|
vector<float> const& sp_pos, vector<float> const& ae_pos,
|
||||||
|
vector<float> const& sp_rot, vector<float> const& ae_rot,
|
||||||
|
vector<float> const& sp_zoom, vector<float> const& ae_zoom) const;
|
||||||
|
NCSplineHandler const* pos_handler;
|
||||||
|
NCSplineHandler const* rot_handler;
|
||||||
|
NCSplineHandler const* zoom_handler;
|
||||||
|
float song_beat;
|
||||||
|
int column;
|
||||||
|
};
|
||||||
|
|
||||||
/** @brief Draws TapNotes and HoldNotes. */
|
/** @brief Draws TapNotes and HoldNotes. */
|
||||||
class NoteDisplay
|
class NoteDisplay
|
||||||
{
|
{
|
||||||
@@ -122,11 +176,12 @@ public:
|
|||||||
static void Update( float fDeltaTime );
|
static void Update( float fDeltaTime );
|
||||||
|
|
||||||
bool IsOnScreen( float fBeat, int iCol, int iDrawDistanceAfterTargetsPixels, int iDrawDistanceBeforeTargetsPixels ) const;
|
bool IsOnScreen( float fBeat, int iCol, int iDrawDistanceAfterTargetsPixels, int iDrawDistanceBeforeTargetsPixels ) const;
|
||||||
float BeatToTValue(CommonColumnRenderArgs const& args, float beat) const;
|
|
||||||
|
|
||||||
bool DrawHoldsInRange(CommonColumnRenderArgs const& args, int column,
|
bool DrawHoldsInRange(NoteFieldRenderArgs const& field_args,
|
||||||
|
NoteColumnRenderArgs const& column_args,
|
||||||
vector<NoteData::TrackMap::const_iterator> const& tap_set);
|
vector<NoteData::TrackMap::const_iterator> const& tap_set);
|
||||||
bool DrawTapsInRange(CommonColumnRenderArgs const& args, int column,
|
bool DrawTapsInRange(NoteFieldRenderArgs const& field_args,
|
||||||
|
NoteColumnRenderArgs const& column_args,
|
||||||
vector<NoteData::TrackMap::const_iterator> const& tap_set);
|
vector<NoteData::TrackMap::const_iterator> const& tap_set);
|
||||||
/**
|
/**
|
||||||
* @brief Draw the TapNote onto the NoteField.
|
* @brief Draw the TapNote onto the NoteField.
|
||||||
@@ -141,11 +196,13 @@ public:
|
|||||||
* @param fDrawDistanceAfterTargetsPixels how much to draw after the receptors.
|
* @param fDrawDistanceAfterTargetsPixels how much to draw after the receptors.
|
||||||
* @param fDrawDistanceBeforeTargetsPixels how much ot draw before the receptors.
|
* @param fDrawDistanceBeforeTargetsPixels how much ot draw before the receptors.
|
||||||
* @param fFadeInPercentOfDrawFar when to start fading in. */
|
* @param fFadeInPercentOfDrawFar when to start fading in. */
|
||||||
void DrawTap(const TapNote& tn, CommonColumnRenderArgs const& args,
|
void DrawTap(const TapNote& tn, NoteFieldRenderArgs const& field_args,
|
||||||
int iCol, float fBeat, bool bOnSameRowAsHoldStart,
|
NoteColumnRenderArgs const& column_args, float fBeat,
|
||||||
|
bool bOnSameRowAsHoldStart,
|
||||||
bool bOnSameRowAsRollBeat, bool bIsAddition, float fPercentFadeToFail);
|
bool bOnSameRowAsRollBeat, bool bIsAddition, float fPercentFadeToFail);
|
||||||
void DrawHold(const TapNote& tn, CommonColumnRenderArgs const& args,
|
void DrawHold(const TapNote& tn, NoteFieldRenderArgs const& field_args,
|
||||||
int iCol, int iRow, bool bIsBeingHeld, const HoldNoteResult &Result,
|
NoteColumnRenderArgs const& column_args, int iRow, bool bIsBeingHeld,
|
||||||
|
const HoldNoteResult &Result,
|
||||||
bool bIsAddition, float fPercentFadeToFail);
|
bool bIsAddition, float fPercentFadeToFail);
|
||||||
|
|
||||||
bool DrawHoldHeadForTapsOnSameRow() const;
|
bool DrawHoldHeadForTapsOnSameRow() const;
|
||||||
@@ -158,19 +215,22 @@ private:
|
|||||||
Sprite *GetHoldSprite( NoteColorSprite ncs[NUM_HoldType][NUM_ActiveType], NotePart part, float fNoteBeat, bool bIsRoll, bool bIsBeingHeld );
|
Sprite *GetHoldSprite( NoteColorSprite ncs[NUM_HoldType][NUM_ActiveType], NotePart part, float fNoteBeat, bool bIsRoll, bool bIsBeingHeld );
|
||||||
|
|
||||||
void DrawActor(const TapNote& tn, Actor* pActor, NotePart part,
|
void DrawActor(const TapNote& tn, Actor* pActor, NotePart part,
|
||||||
CommonColumnRenderArgs const& args, int iCol, float fYOffset, float fBeat,
|
NoteFieldRenderArgs const& field_args,
|
||||||
|
NoteColumnRenderArgs const& column_args, float fYOffset, float fBeat,
|
||||||
bool bIsAddition, float fPercentFadeToFail, float fColorScale,
|
bool bIsAddition, float fPercentFadeToFail, float fColorScale,
|
||||||
bool is_being_held);
|
bool is_being_held);
|
||||||
void DrawHoldBody(const TapNote& tn, CommonColumnRenderArgs const& args,
|
void DrawHoldBody(const TapNote& tn, NoteFieldRenderArgs const& field_args,
|
||||||
int iCol, float fBeat, bool bIsBeingHeld, float fYHead, float fYTail,
|
NoteColumnRenderArgs const& column_args, float fBeat, bool bIsBeingHeld,
|
||||||
|
float fYHead, float fYTail,
|
||||||
bool bIsAddition, float fPercentFadeToFail, float fColorScale,
|
bool bIsAddition, float fPercentFadeToFail, float fColorScale,
|
||||||
bool bGlow, float top_t, float bottom_t);
|
bool bGlow, float top_beat, float bottom_beat);
|
||||||
void DrawHoldPart(vector<Sprite*> &vpSpr,
|
void DrawHoldPart(vector<Sprite*> &vpSpr,
|
||||||
CommonColumnRenderArgs const& args, int iCol, int fYStep,
|
NoteFieldRenderArgs const& field_args,
|
||||||
|
NoteColumnRenderArgs const& column_args, int fYStep,
|
||||||
float fPercentFadeToFail, float fColorScale, bool bGlow,
|
float fPercentFadeToFail, float fColorScale, bool bGlow,
|
||||||
float fOverlappedTime, float fYTop, float fYBottom, float fYStartPos,
|
float fOverlappedTime, float fYTop, float fYBottom, float fYStartPos,
|
||||||
float fYEndPos, bool bWrapping, bool bAnchorToTop,
|
float fYEndPos, bool bWrapping, bool bAnchorToTop,
|
||||||
bool bFlipTextureVertically, float top_t, float bottom_t);
|
bool bFlipTextureVertically, float top_beat, float bottom_beat);
|
||||||
|
|
||||||
const PlayerState *m_pPlayerState; // to look up PlayerOptions
|
const PlayerState *m_pPlayerState; // to look up PlayerOptions
|
||||||
NoteMetricCache_t *cache;
|
NoteMetricCache_t *cache;
|
||||||
@@ -196,21 +256,24 @@ private:
|
|||||||
// actors so they can move with the rest of the column. I didn't use
|
// 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
|
// ActorProxy because the receptor/ghost actors need to pull in the parent
|
||||||
// state of their rows and the parent state of the column. -Kyz
|
// state of their rows and the parent state of the column. -Kyz
|
||||||
class NoteColumnRenderer : public Actor
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
NoteColumnRenderer()
|
|
||||||
{
|
|
||||||
m_spline.redimension(3);
|
|
||||||
m_spline.m_owned_by_actor= true;
|
|
||||||
}
|
|
||||||
NoteDisplay* m_displays[PLAYER_INVALID+1];
|
|
||||||
CommonColumnRenderArgs* m_render_args;
|
|
||||||
int m_column;
|
|
||||||
float m_receptor_t;
|
|
||||||
float m_beats_per_t;
|
|
||||||
CubicSplineN m_spline;
|
|
||||||
|
|
||||||
|
struct NoteColumnRenderer : public Actor
|
||||||
|
{
|
||||||
|
NoteDisplay* m_displays[PLAYER_INVALID+1];
|
||||||
|
NoteFieldRenderArgs* m_field_render_args;
|
||||||
|
NoteColumnRenderArgs m_column_render_args;
|
||||||
|
int m_column;
|
||||||
|
// m_column_render_args has pointers to these fields that are updated
|
||||||
|
// every frame instead of using m_column_render_args directly so that they
|
||||||
|
// can be moved into a tween state later. -Kyz
|
||||||
|
NCSplineHandler m_pos_handler;
|
||||||
|
NCSplineHandler m_rot_handler;
|
||||||
|
NCSplineHandler m_zoom_handler;
|
||||||
|
|
||||||
|
// UpdateReceptorGhostStuff takes care of the logic for making the ghost
|
||||||
|
// and receptor positions follow the splines. It's called by their row
|
||||||
|
// update functions. -Kyz
|
||||||
|
void UpdateReceptorGhostStuff(Actor* receptor) const;
|
||||||
virtual void DrawPrimitives();
|
virtual void DrawPrimitives();
|
||||||
virtual void PushSelf(lua_State* L);
|
virtual void PushSelf(lua_State* L);
|
||||||
};
|
};
|
||||||
@@ -218,6 +281,7 @@ class NoteColumnRenderer : public Actor
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* NoteColumnRenderer and associated spline stuff (c) Eric Reese 2014-2015
|
||||||
* @file
|
* @file
|
||||||
* @author Brian Bugh, Ben Nordstrom, Chris Danford, Steve Checkoway (c) 2001-2006
|
* @author Brian Bugh, Ben Nordstrom, Chris Danford, Steve Checkoway (c) 2001-2006
|
||||||
* @section LICENSE
|
* @section LICENSE
|
||||||
|
|||||||
+53
-50
@@ -63,11 +63,11 @@ NoteField::NoteField()
|
|||||||
|
|
||||||
// I decided to do it this way because I don't want to dig through
|
// I decided to do it this way because I don't want to dig through
|
||||||
// ScreenEdit to change all the places it touches the markers. -Kyz
|
// ScreenEdit to change all the places it touches the markers. -Kyz
|
||||||
m_ColumnRenderArgs.selection_begin_marker= &m_iBeginMarker;
|
m_FieldRenderArgs.selection_begin_marker= &m_iBeginMarker;
|
||||||
m_ColumnRenderArgs.selection_end_marker= &m_iEndMarker;
|
m_FieldRenderArgs.selection_end_marker= &m_iEndMarker;
|
||||||
m_iBeginMarker = m_iEndMarker = -1;
|
m_iBeginMarker = m_iEndMarker = -1;
|
||||||
|
|
||||||
m_ColumnRenderArgs.fail_fade = -1;
|
m_FieldRenderArgs.fail_fade = -1;
|
||||||
|
|
||||||
m_StepCallback.SetFromNil();
|
m_StepCallback.SetFromNil();
|
||||||
m_SetPressedCallback.SetFromNil();
|
m_SetPressedCallback.SetFromNil();
|
||||||
@@ -192,7 +192,7 @@ void NoteField::Load(
|
|||||||
m_iDrawDistanceBeforeTargetsPixels = iDrawDistanceBeforeTargetsPixels;
|
m_iDrawDistanceBeforeTargetsPixels = iDrawDistanceBeforeTargetsPixels;
|
||||||
ASSERT( m_iDrawDistanceBeforeTargetsPixels >= m_iDrawDistanceAfterTargetsPixels );
|
ASSERT( m_iDrawDistanceBeforeTargetsPixels >= m_iDrawDistanceAfterTargetsPixels );
|
||||||
|
|
||||||
m_ColumnRenderArgs.fail_fade = -1;
|
m_FieldRenderArgs.fail_fade = -1;
|
||||||
|
|
||||||
//int i1 = m_pNoteData->GetNumTracks();
|
//int i1 = m_pNoteData->GetNumTracks();
|
||||||
//int i2 = GAMESTATE->GetCurrentStyle()->m_iColsPerPlayer;
|
//int i2 = GAMESTATE->GetCurrentStyle()->m_iColsPerPlayer;
|
||||||
@@ -248,9 +248,11 @@ void NoteField::Load(
|
|||||||
|
|
||||||
void NoteField::InitColumnRenderers()
|
void NoteField::InitColumnRenderers()
|
||||||
{
|
{
|
||||||
m_ColumnRenderArgs.receptor_row= &(m_pCurDisplay->m_ReceptorArrowRow);
|
m_FieldRenderArgs.player_state= m_pPlayerState;
|
||||||
m_ColumnRenderArgs.ghost_row= &(m_pCurDisplay->m_GhostArrowRow);
|
m_FieldRenderArgs.reverse_offset_pixels= m_fYReverseOffsetPixels;
|
||||||
m_ColumnRenderArgs.note_data= m_pNoteData;
|
m_FieldRenderArgs.receptor_row= &(m_pCurDisplay->m_ReceptorArrowRow);
|
||||||
|
m_FieldRenderArgs.ghost_row= &(m_pCurDisplay->m_GhostArrowRow);
|
||||||
|
m_FieldRenderArgs.note_data= m_pNoteData;
|
||||||
m_ColumnRenderers.resize(GAMESTATE->GetCurrentStyle()->m_iColsPerPlayer);
|
m_ColumnRenderers.resize(GAMESTATE->GetCurrentStyle()->m_iColsPerPlayer);
|
||||||
for(size_t ncr= 0; ncr < m_ColumnRenderers.size(); ++ncr)
|
for(size_t ncr= 0; ncr < m_ColumnRenderers.size(); ++ncr)
|
||||||
{
|
{
|
||||||
@@ -260,7 +262,8 @@ void NoteField::InitColumnRenderers()
|
|||||||
}
|
}
|
||||||
m_ColumnRenderers[ncr].m_displays[PLAYER_INVALID]= &(m_pCurDisplay->display[ncr]);
|
m_ColumnRenderers[ncr].m_displays[PLAYER_INVALID]= &(m_pCurDisplay->display[ncr]);
|
||||||
m_ColumnRenderers[ncr].m_column= ncr;
|
m_ColumnRenderers[ncr].m_column= ncr;
|
||||||
m_ColumnRenderers[ncr].m_render_args= &m_ColumnRenderArgs;
|
m_ColumnRenderers[ncr].m_column_render_args.column= ncr;
|
||||||
|
m_ColumnRenderers[ncr].m_field_render_args= &m_FieldRenderArgs;
|
||||||
}
|
}
|
||||||
m_pCurDisplay->m_ReceptorArrowRow.SetColumnRenderers(m_ColumnRenderers);
|
m_pCurDisplay->m_ReceptorArrowRow.SetColumnRenderers(m_ColumnRenderers);
|
||||||
m_pCurDisplay->m_GhostArrowRow.SetColumnRenderers(m_ColumnRenderers);
|
m_pCurDisplay->m_GhostArrowRow.SetColumnRenderers(m_ColumnRenderers);
|
||||||
@@ -305,11 +308,11 @@ void NoteField::Update( float fDeltaTime )
|
|||||||
cur->m_ReceptorArrowRow.Update( fDeltaTime );
|
cur->m_ReceptorArrowRow.Update( fDeltaTime );
|
||||||
cur->m_GhostArrowRow.Update( fDeltaTime );
|
cur->m_GhostArrowRow.Update( fDeltaTime );
|
||||||
|
|
||||||
if( m_ColumnRenderArgs.fail_fade >= 0 )
|
if( m_FieldRenderArgs.fail_fade >= 0 )
|
||||||
m_ColumnRenderArgs.fail_fade = min( m_ColumnRenderArgs.fail_fade + fDeltaTime/FADE_FAIL_TIME, 1 );
|
m_FieldRenderArgs.fail_fade = min( m_FieldRenderArgs.fail_fade + fDeltaTime/FADE_FAIL_TIME, 1 );
|
||||||
|
|
||||||
// Update fade to failed
|
// Update fade to failed
|
||||||
m_pCurDisplay->m_ReceptorArrowRow.SetFadeToFailPercent( m_ColumnRenderArgs.fail_fade );
|
m_pCurDisplay->m_ReceptorArrowRow.SetFadeToFailPercent( m_FieldRenderArgs.fail_fade );
|
||||||
|
|
||||||
NoteDisplay::Update( fDeltaTime );
|
NoteDisplay::Update( fDeltaTime );
|
||||||
/* Update all NoteDisplays. Hack: We need to call this once per frame, not
|
/* Update all NoteDisplays. Hack: We need to call this once per frame, not
|
||||||
@@ -861,41 +864,41 @@ void NoteField::DrawPrimitives()
|
|||||||
const PlayerOptions ¤t_po = m_pPlayerState->m_PlayerOptions.GetCurrent();
|
const PlayerOptions ¤t_po = m_pPlayerState->m_PlayerOptions.GetCurrent();
|
||||||
|
|
||||||
// Adjust draw range depending on some effects
|
// Adjust draw range depending on some effects
|
||||||
m_ColumnRenderArgs.draw_pixels_after_targets= m_iDrawDistanceAfterTargetsPixels;
|
m_FieldRenderArgs.draw_pixels_after_targets= m_iDrawDistanceAfterTargetsPixels;
|
||||||
// HACK: If boomerang and centered are on, then we want to draw much
|
// HACK: If boomerang and centered are on, then we want to draw much
|
||||||
// earlier so that the notes don't pop on screen.
|
// earlier so that the notes don't pop on screen.
|
||||||
float fCenteredTimesBoomerang =
|
float fCenteredTimesBoomerang =
|
||||||
current_po.m_fScrolls[PlayerOptions::SCROLL_CENTERED] *
|
current_po.m_fScrolls[PlayerOptions::SCROLL_CENTERED] *
|
||||||
current_po.m_fAccels[PlayerOptions::ACCEL_BOOMERANG];
|
current_po.m_fAccels[PlayerOptions::ACCEL_BOOMERANG];
|
||||||
m_ColumnRenderArgs.draw_pixels_after_targets += int(SCALE( fCenteredTimesBoomerang, 0.f, 1.f, 0.f, -SCREEN_HEIGHT/2 ));
|
m_FieldRenderArgs.draw_pixels_after_targets += int(SCALE( fCenteredTimesBoomerang, 0.f, 1.f, 0.f, -SCREEN_HEIGHT/2 ));
|
||||||
m_ColumnRenderArgs.draw_pixels_before_targets = m_iDrawDistanceBeforeTargetsPixels;
|
m_FieldRenderArgs.draw_pixels_before_targets = m_iDrawDistanceBeforeTargetsPixels;
|
||||||
|
|
||||||
float fDrawScale = 1;
|
float fDrawScale = 1;
|
||||||
fDrawScale *= 1 + 0.5f * fabsf( current_po.m_fPerspectiveTilt );
|
fDrawScale *= 1 + 0.5f * fabsf( current_po.m_fPerspectiveTilt );
|
||||||
fDrawScale *= 1 + fabsf( current_po.m_fEffects[PlayerOptions::EFFECT_MINI] );
|
fDrawScale *= 1 + fabsf( current_po.m_fEffects[PlayerOptions::EFFECT_MINI] );
|
||||||
|
|
||||||
m_ColumnRenderArgs.draw_pixels_after_targets = (int)(m_ColumnRenderArgs.draw_pixels_after_targets * fDrawScale);
|
m_FieldRenderArgs.draw_pixels_after_targets = (int)(m_FieldRenderArgs.draw_pixels_after_targets * fDrawScale);
|
||||||
m_ColumnRenderArgs.draw_pixels_before_targets = (int)(m_ColumnRenderArgs.draw_pixels_before_targets * fDrawScale);
|
m_FieldRenderArgs.draw_pixels_before_targets = (int)(m_FieldRenderArgs.draw_pixels_before_targets * fDrawScale);
|
||||||
|
|
||||||
|
|
||||||
// Probe for first and last notes on the screen
|
// Probe for first and last notes on the screen
|
||||||
float fFirstBeatToDraw = FindFirstDisplayedBeat( m_pPlayerState, m_ColumnRenderArgs.draw_pixels_after_targets );
|
float fFirstBeatToDraw = FindFirstDisplayedBeat( m_pPlayerState, m_FieldRenderArgs.draw_pixels_after_targets );
|
||||||
float fLastBeatToDraw = FindLastDisplayedBeat( m_pPlayerState, m_ColumnRenderArgs.draw_pixels_before_targets );
|
float fLastBeatToDraw = FindLastDisplayedBeat( m_pPlayerState, m_FieldRenderArgs.draw_pixels_before_targets );
|
||||||
|
|
||||||
m_pPlayerState->m_fLastDrawnBeat = fLastBeatToDraw;
|
m_pPlayerState->m_fLastDrawnBeat = fLastBeatToDraw;
|
||||||
|
|
||||||
m_ColumnRenderArgs.first_row = BeatToNoteRow(fFirstBeatToDraw);
|
m_FieldRenderArgs.first_row = BeatToNoteRow(fFirstBeatToDraw);
|
||||||
m_ColumnRenderArgs.last_row = BeatToNoteRow(fLastBeatToDraw);
|
m_FieldRenderArgs.last_row = BeatToNoteRow(fLastBeatToDraw);
|
||||||
|
|
||||||
//LOG->Trace( "start = %f.1, end = %f.1", fFirstBeatToDraw-fSongBeat, fLastBeatToDraw-fSongBeat );
|
//LOG->Trace( "start = %f.1, end = %f.1", fFirstBeatToDraw-fSongBeat, fLastBeatToDraw-fSongBeat );
|
||||||
//LOG->Trace( "Drawing elements %d through %d", m_ColumnRenderArgs.first_row, m_ColumnRenderArgs.last_row );
|
//LOG->Trace( "Drawing elements %d through %d", m_FieldRenderArgs.first_row, m_FieldRenderArgs.last_row );
|
||||||
|
|
||||||
#define IS_ON_SCREEN( fBeat ) ( fFirstBeatToDraw <= (fBeat) && (fBeat) <= fLastBeatToDraw && IsOnScreen( fBeat, 0, m_ColumnRenderArgs.draw_pixels_after_targets, m_ColumnRenderArgs.draw_pixels_before_targets ) )
|
#define IS_ON_SCREEN( fBeat ) ( fFirstBeatToDraw <= (fBeat) && (fBeat) <= fLastBeatToDraw && IsOnScreen( fBeat, 0, m_FieldRenderArgs.draw_pixels_after_targets, m_FieldRenderArgs.draw_pixels_before_targets ) )
|
||||||
|
|
||||||
// Draw board
|
// Draw board
|
||||||
if( SHOW_BOARD )
|
if( SHOW_BOARD )
|
||||||
{
|
{
|
||||||
DrawBoard( m_ColumnRenderArgs.draw_pixels_after_targets, m_ColumnRenderArgs.draw_pixels_before_targets );
|
DrawBoard( m_FieldRenderArgs.draw_pixels_after_targets, m_FieldRenderArgs.draw_pixels_before_targets );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw Receptors
|
// Draw Receptors
|
||||||
@@ -918,7 +921,7 @@ void NoteField::DrawPrimitives()
|
|||||||
for (i = 0; i < tSigs.size(); i++)
|
for (i = 0; i < tSigs.size(); i++)
|
||||||
{
|
{
|
||||||
const TimeSignatureSegment *ts = ToTimeSignature(tSigs[i]);
|
const TimeSignatureSegment *ts = ToTimeSignature(tSigs[i]);
|
||||||
int iSegmentEndRow = (i + 1 == tSigs.size()) ? m_ColumnRenderArgs.last_row : tSigs[i+1]->GetRow();
|
int iSegmentEndRow = (i + 1 == tSigs.size()) ? m_FieldRenderArgs.last_row : tSigs[i+1]->GetRow();
|
||||||
|
|
||||||
// beat bars every 16th note
|
// beat bars every 16th note
|
||||||
int iDrawBeatBarsEveryRows = BeatToNoteRow( ((float)ts->GetDen()) / 4 ) / 4;
|
int iDrawBeatBarsEveryRows = BeatToNoteRow( ((float)ts->GetDen()) / 4 ) / 4;
|
||||||
@@ -961,7 +964,7 @@ void NoteField::DrawPrimitives()
|
|||||||
for (i = 0; i < segs[SEGMENT_SCROLL]->size(); i++)
|
for (i = 0; i < segs[SEGMENT_SCROLL]->size(); i++)
|
||||||
{
|
{
|
||||||
ScrollSegment *seg = ToScroll( segs[SEGMENT_SCROLL]->at(i) );
|
ScrollSegment *seg = ToScroll( segs[SEGMENT_SCROLL]->at(i) );
|
||||||
if( seg->GetRow() >= m_ColumnRenderArgs.first_row && seg->GetRow() <= m_ColumnRenderArgs.last_row )
|
if( seg->GetRow() >= m_FieldRenderArgs.first_row && seg->GetRow() <= m_FieldRenderArgs.last_row )
|
||||||
{
|
{
|
||||||
float fBeat = seg->GetBeat();
|
float fBeat = seg->GetBeat();
|
||||||
if( IS_ON_SCREEN(fBeat) )
|
if( IS_ON_SCREEN(fBeat) )
|
||||||
@@ -973,7 +976,7 @@ void NoteField::DrawPrimitives()
|
|||||||
for (i = 0; i < segs[SEGMENT_BPM]->size(); i++)
|
for (i = 0; i < segs[SEGMENT_BPM]->size(); i++)
|
||||||
{
|
{
|
||||||
const BPMSegment *seg = ToBPM( segs[SEGMENT_BPM]->at(i) );
|
const BPMSegment *seg = ToBPM( segs[SEGMENT_BPM]->at(i) );
|
||||||
if( seg->GetRow() >= m_ColumnRenderArgs.first_row && seg->GetRow() <= m_ColumnRenderArgs.last_row )
|
if( seg->GetRow() >= m_FieldRenderArgs.first_row && seg->GetRow() <= m_FieldRenderArgs.last_row )
|
||||||
{
|
{
|
||||||
float fBeat = seg->GetBeat();
|
float fBeat = seg->GetBeat();
|
||||||
if( IS_ON_SCREEN(fBeat) )
|
if( IS_ON_SCREEN(fBeat) )
|
||||||
@@ -985,7 +988,7 @@ void NoteField::DrawPrimitives()
|
|||||||
for (i = 0; i < segs[SEGMENT_STOP]->size(); i++)
|
for (i = 0; i < segs[SEGMENT_STOP]->size(); i++)
|
||||||
{
|
{
|
||||||
const StopSegment *seg = ToStop( segs[SEGMENT_STOP]->at(i) );
|
const StopSegment *seg = ToStop( segs[SEGMENT_STOP]->at(i) );
|
||||||
if( seg->GetRow() >= m_ColumnRenderArgs.first_row && seg->GetRow() <= m_ColumnRenderArgs.last_row )
|
if( seg->GetRow() >= m_FieldRenderArgs.first_row && seg->GetRow() <= m_FieldRenderArgs.last_row )
|
||||||
{
|
{
|
||||||
float fBeat = seg->GetBeat();
|
float fBeat = seg->GetBeat();
|
||||||
if( IS_ON_SCREEN(fBeat) )
|
if( IS_ON_SCREEN(fBeat) )
|
||||||
@@ -997,7 +1000,7 @@ void NoteField::DrawPrimitives()
|
|||||||
for (i = 0; i < segs[SEGMENT_DELAY]->size(); i++)
|
for (i = 0; i < segs[SEGMENT_DELAY]->size(); i++)
|
||||||
{
|
{
|
||||||
const DelaySegment *seg = ToDelay( segs[SEGMENT_DELAY]->at(i) );
|
const DelaySegment *seg = ToDelay( segs[SEGMENT_DELAY]->at(i) );
|
||||||
if( seg->GetRow() >= m_ColumnRenderArgs.first_row && seg->GetRow() <= m_ColumnRenderArgs.last_row )
|
if( seg->GetRow() >= m_FieldRenderArgs.first_row && seg->GetRow() <= m_FieldRenderArgs.last_row )
|
||||||
{
|
{
|
||||||
float fBeat = seg->GetBeat();
|
float fBeat = seg->GetBeat();
|
||||||
if( IS_ON_SCREEN(fBeat) )
|
if( IS_ON_SCREEN(fBeat) )
|
||||||
@@ -1009,7 +1012,7 @@ void NoteField::DrawPrimitives()
|
|||||||
for (i = 0; i < segs[SEGMENT_WARP]->size(); i++)
|
for (i = 0; i < segs[SEGMENT_WARP]->size(); i++)
|
||||||
{
|
{
|
||||||
const WarpSegment *seg = ToWarp( segs[SEGMENT_WARP]->at(i) );
|
const WarpSegment *seg = ToWarp( segs[SEGMENT_WARP]->at(i) );
|
||||||
if( seg->GetRow() >= m_ColumnRenderArgs.first_row && seg->GetRow() <= m_ColumnRenderArgs.last_row )
|
if( seg->GetRow() >= m_FieldRenderArgs.first_row && seg->GetRow() <= m_FieldRenderArgs.last_row )
|
||||||
{
|
{
|
||||||
float fBeat = seg->GetBeat();
|
float fBeat = seg->GetBeat();
|
||||||
if( IS_ON_SCREEN(fBeat) )
|
if( IS_ON_SCREEN(fBeat) )
|
||||||
@@ -1021,7 +1024,7 @@ void NoteField::DrawPrimitives()
|
|||||||
for (i = 0; i < segs[SEGMENT_TIME_SIG]->size(); i++)
|
for (i = 0; i < segs[SEGMENT_TIME_SIG]->size(); i++)
|
||||||
{
|
{
|
||||||
const TimeSignatureSegment *seg = ToTimeSignature( segs[SEGMENT_TIME_SIG]->at(i) );
|
const TimeSignatureSegment *seg = ToTimeSignature( segs[SEGMENT_TIME_SIG]->at(i) );
|
||||||
if( seg->GetRow() >= m_ColumnRenderArgs.first_row && seg->GetRow() <= m_ColumnRenderArgs.last_row )
|
if( seg->GetRow() >= m_FieldRenderArgs.first_row && seg->GetRow() <= m_FieldRenderArgs.last_row )
|
||||||
{
|
{
|
||||||
float fBeat = seg->GetBeat();
|
float fBeat = seg->GetBeat();
|
||||||
if( IS_ON_SCREEN(fBeat) )
|
if( IS_ON_SCREEN(fBeat) )
|
||||||
@@ -1033,7 +1036,7 @@ void NoteField::DrawPrimitives()
|
|||||||
for (i = 0; i < segs[SEGMENT_TICKCOUNT]->size(); i++)
|
for (i = 0; i < segs[SEGMENT_TICKCOUNT]->size(); i++)
|
||||||
{
|
{
|
||||||
const TickcountSegment *seg = ToTickcount( segs[SEGMENT_TICKCOUNT]->at(i) );
|
const TickcountSegment *seg = ToTickcount( segs[SEGMENT_TICKCOUNT]->at(i) );
|
||||||
if( seg->GetRow() >= m_ColumnRenderArgs.first_row && seg->GetRow() <= m_ColumnRenderArgs.last_row )
|
if( seg->GetRow() >= m_FieldRenderArgs.first_row && seg->GetRow() <= m_FieldRenderArgs.last_row )
|
||||||
{
|
{
|
||||||
float fBeat = seg->GetBeat();
|
float fBeat = seg->GetBeat();
|
||||||
if( IS_ON_SCREEN(fBeat) )
|
if( IS_ON_SCREEN(fBeat) )
|
||||||
@@ -1045,7 +1048,7 @@ void NoteField::DrawPrimitives()
|
|||||||
for (i = 0; i < segs[SEGMENT_COMBO]->size(); i++)
|
for (i = 0; i < segs[SEGMENT_COMBO]->size(); i++)
|
||||||
{
|
{
|
||||||
const ComboSegment *seg = ToCombo( segs[SEGMENT_COMBO]->at(i) );
|
const ComboSegment *seg = ToCombo( segs[SEGMENT_COMBO]->at(i) );
|
||||||
if( seg->GetRow() >= m_ColumnRenderArgs.first_row && seg->GetRow() <= m_ColumnRenderArgs.last_row )
|
if( seg->GetRow() >= m_FieldRenderArgs.first_row && seg->GetRow() <= m_FieldRenderArgs.last_row )
|
||||||
{
|
{
|
||||||
float fBeat = seg->GetBeat();
|
float fBeat = seg->GetBeat();
|
||||||
if( IS_ON_SCREEN(fBeat) )
|
if( IS_ON_SCREEN(fBeat) )
|
||||||
@@ -1057,7 +1060,7 @@ void NoteField::DrawPrimitives()
|
|||||||
for (i = 0; i < segs[SEGMENT_LABEL]->size(); i++)
|
for (i = 0; i < segs[SEGMENT_LABEL]->size(); i++)
|
||||||
{
|
{
|
||||||
const LabelSegment *seg = ToLabel( segs[SEGMENT_LABEL]->at(i) );
|
const LabelSegment *seg = ToLabel( segs[SEGMENT_LABEL]->at(i) );
|
||||||
if( seg->GetRow() >= m_ColumnRenderArgs.first_row && seg->GetRow() <= m_ColumnRenderArgs.last_row )
|
if( seg->GetRow() >= m_FieldRenderArgs.first_row && seg->GetRow() <= m_FieldRenderArgs.last_row )
|
||||||
{
|
{
|
||||||
float fBeat = seg->GetBeat();
|
float fBeat = seg->GetBeat();
|
||||||
if( IS_ON_SCREEN(fBeat) )
|
if( IS_ON_SCREEN(fBeat) )
|
||||||
@@ -1069,7 +1072,7 @@ void NoteField::DrawPrimitives()
|
|||||||
for (i = 0; i < segs[SEGMENT_SPEED]->size(); i++)
|
for (i = 0; i < segs[SEGMENT_SPEED]->size(); i++)
|
||||||
{
|
{
|
||||||
const SpeedSegment *seg = ToSpeed( segs[SEGMENT_SPEED]->at(i) );
|
const SpeedSegment *seg = ToSpeed( segs[SEGMENT_SPEED]->at(i) );
|
||||||
if( seg->GetRow() >= m_ColumnRenderArgs.first_row && seg->GetRow() <= m_ColumnRenderArgs.last_row )
|
if( seg->GetRow() >= m_FieldRenderArgs.first_row && seg->GetRow() <= m_FieldRenderArgs.last_row )
|
||||||
{
|
{
|
||||||
float fBeat = seg->GetBeat();
|
float fBeat = seg->GetBeat();
|
||||||
if( IS_ON_SCREEN(fBeat) )
|
if( IS_ON_SCREEN(fBeat) )
|
||||||
@@ -1082,7 +1085,7 @@ void NoteField::DrawPrimitives()
|
|||||||
for (i = 0; i < segs[SEGMENT_FAKE]->size(); i++)
|
for (i = 0; i < segs[SEGMENT_FAKE]->size(); i++)
|
||||||
{
|
{
|
||||||
const FakeSegment *seg = ToFake( segs[SEGMENT_FAKE]->at(i) );
|
const FakeSegment *seg = ToFake( segs[SEGMENT_FAKE]->at(i) );
|
||||||
if( seg->GetRow() >= m_ColumnRenderArgs.first_row && seg->GetRow() <= m_ColumnRenderArgs.last_row )
|
if( seg->GetRow() >= m_FieldRenderArgs.first_row && seg->GetRow() <= m_FieldRenderArgs.last_row )
|
||||||
{
|
{
|
||||||
float fBeat = seg->GetBeat();
|
float fBeat = seg->GetBeat();
|
||||||
if( IS_ON_SCREEN(fBeat) )
|
if( IS_ON_SCREEN(fBeat) )
|
||||||
@@ -1102,8 +1105,8 @@ void NoteField::DrawPrimitives()
|
|||||||
float fSecond = a->fStartSecond;
|
float fSecond = a->fStartSecond;
|
||||||
float fBeat = timing.GetBeatFromElapsedTime( fSecond );
|
float fBeat = timing.GetBeatFromElapsedTime( fSecond );
|
||||||
|
|
||||||
if( BeatToNoteRow(fBeat) >= m_ColumnRenderArgs.first_row &&
|
if( BeatToNoteRow(fBeat) >= m_FieldRenderArgs.first_row &&
|
||||||
BeatToNoteRow(fBeat) <= m_ColumnRenderArgs.last_row)
|
BeatToNoteRow(fBeat) <= m_FieldRenderArgs.last_row)
|
||||||
{
|
{
|
||||||
if( IS_ON_SCREEN(fBeat) )
|
if( IS_ON_SCREEN(fBeat) )
|
||||||
DrawAttackText( fBeat, *a );
|
DrawAttackText( fBeat, *a );
|
||||||
@@ -1121,8 +1124,8 @@ void NoteField::DrawPrimitives()
|
|||||||
FOREACH_CONST(Attack, attacks, a)
|
FOREACH_CONST(Attack, attacks, a)
|
||||||
{
|
{
|
||||||
float fBeat = timing.GetBeatFromElapsedTime(a->fStartSecond);
|
float fBeat = timing.GetBeatFromElapsedTime(a->fStartSecond);
|
||||||
if (BeatToNoteRow(fBeat) >= m_ColumnRenderArgs.first_row &&
|
if (BeatToNoteRow(fBeat) >= m_FieldRenderArgs.first_row &&
|
||||||
BeatToNoteRow(fBeat) <= m_ColumnRenderArgs.last_row &&
|
BeatToNoteRow(fBeat) <= m_FieldRenderArgs.last_row &&
|
||||||
IS_ON_SCREEN(fBeat))
|
IS_ON_SCREEN(fBeat))
|
||||||
{
|
{
|
||||||
this->DrawAttackText(fBeat, *a);
|
this->DrawAttackText(fBeat, *a);
|
||||||
@@ -1206,20 +1209,20 @@ void NoteField::DrawPrimitives()
|
|||||||
{
|
{
|
||||||
int iBegin = m_iBeginMarker;
|
int iBegin = m_iBeginMarker;
|
||||||
int iEnd = m_iEndMarker;
|
int iEnd = m_iEndMarker;
|
||||||
CLAMP( iBegin, m_ColumnRenderArgs.first_row, m_ColumnRenderArgs.last_row );
|
CLAMP( iBegin, m_FieldRenderArgs.first_row, m_FieldRenderArgs.last_row );
|
||||||
CLAMP( iEnd, m_ColumnRenderArgs.first_row, m_ColumnRenderArgs.last_row );
|
CLAMP( iEnd, m_FieldRenderArgs.first_row, m_FieldRenderArgs.last_row );
|
||||||
DrawAreaHighlight( iBegin, iEnd );
|
DrawAreaHighlight( iBegin, iEnd );
|
||||||
}
|
}
|
||||||
else if( m_iBeginMarker != -1 )
|
else if( m_iBeginMarker != -1 )
|
||||||
{
|
{
|
||||||
if( m_iBeginMarker >= m_ColumnRenderArgs.first_row &&
|
if( m_iBeginMarker >= m_FieldRenderArgs.first_row &&
|
||||||
m_iBeginMarker <= m_ColumnRenderArgs.last_row )
|
m_iBeginMarker <= m_FieldRenderArgs.last_row )
|
||||||
DrawMarkerBar( m_iBeginMarker );
|
DrawMarkerBar( m_iBeginMarker );
|
||||||
}
|
}
|
||||||
else if( m_iEndMarker != -1 )
|
else if( m_iEndMarker != -1 )
|
||||||
{
|
{
|
||||||
if( m_iEndMarker >= m_ColumnRenderArgs.first_row &&
|
if( m_iEndMarker >= m_FieldRenderArgs.first_row &&
|
||||||
m_iEndMarker <= m_ColumnRenderArgs.last_row )
|
m_iEndMarker <= m_FieldRenderArgs.last_row )
|
||||||
DrawMarkerBar( m_iEndMarker );
|
DrawMarkerBar( m_iEndMarker );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1233,9 +1236,9 @@ void NoteField::DrawPrimitives()
|
|||||||
ssprintf("NumTracks %d != ColsPerPlayer %d",m_pNoteData->GetNumTracks(),
|
ssprintf("NumTracks %d != ColsPerPlayer %d",m_pNoteData->GetNumTracks(),
|
||||||
GAMESTATE->GetCurrentStyle()->m_iColsPerPlayer));
|
GAMESTATE->GetCurrentStyle()->m_iColsPerPlayer));
|
||||||
|
|
||||||
m_ColumnRenderArgs.selection_glow= SCALE(
|
m_FieldRenderArgs.selection_glow= SCALE(
|
||||||
RageFastCos(RageTimer::GetTimeSinceStartFast()*2), -1, 1, 0.1f, 0.3f);
|
RageFastCos(RageTimer::GetTimeSinceStartFast()*2), -1, 1, 0.1f, 0.3f);
|
||||||
m_ColumnRenderArgs.fade_before_targets= FADE_BEFORE_TARGETS_PERCENT;
|
m_FieldRenderArgs.fade_before_targets= FADE_BEFORE_TARGETS_PERCENT;
|
||||||
|
|
||||||
for( int j=0; j<m_pNoteData->GetNumTracks(); j++ ) // for each arrow column
|
for( int j=0; j<m_pNoteData->GetNumTracks(); j++ ) // for each arrow column
|
||||||
{
|
{
|
||||||
@@ -1248,7 +1251,7 @@ void NoteField::DrawPrimitives()
|
|||||||
|
|
||||||
void NoteField::FadeToFail()
|
void NoteField::FadeToFail()
|
||||||
{
|
{
|
||||||
m_ColumnRenderArgs.fail_fade = max( 0.0f, m_ColumnRenderArgs.fail_fade ); // this will slowly increase every Update()
|
m_FieldRenderArgs.fail_fade = max( 0.0f, m_FieldRenderArgs.fail_fade ); // this will slowly increase every Update()
|
||||||
// don't fade all over again if this is called twice
|
// don't fade all over again if this is called twice
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1446,7 +1449,7 @@ public:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int GetColumnActors(T* p, lua_State* L)
|
static int get_column_actors(T* p, lua_State* L)
|
||||||
{
|
{
|
||||||
lua_createtable(L, p->m_ColumnRenderers.size(), 0);
|
lua_createtable(L, p->m_ColumnRenderers.size(), 0);
|
||||||
for(size_t i= 0; i < p->m_ColumnRenderers.size(); ++i)
|
for(size_t i= 0; i < p->m_ColumnRenderers.size(); ++i)
|
||||||
@@ -1467,7 +1470,7 @@ public:
|
|||||||
ADD_METHOD(SetPressed);
|
ADD_METHOD(SetPressed);
|
||||||
ADD_METHOD(DidTapNote);
|
ADD_METHOD(DidTapNote);
|
||||||
ADD_METHOD(DidHoldNote);
|
ADD_METHOD(DidHoldNote);
|
||||||
ADD_METHOD(GetColumnActors);
|
ADD_METHOD(get_column_actors);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -105,7 +105,7 @@ protected:
|
|||||||
~NoteDisplayCols() { delete [] display; }
|
~NoteDisplayCols() { delete [] display; }
|
||||||
};
|
};
|
||||||
|
|
||||||
CommonColumnRenderArgs m_ColumnRenderArgs;
|
NoteFieldRenderArgs m_FieldRenderArgs;
|
||||||
|
|
||||||
/* All loaded note displays, mapped by their name. */
|
/* All loaded note displays, mapped by their name. */
|
||||||
map<RString, NoteDisplayCols *> m_NoteDisplays;
|
map<RString, NoteDisplayCols *> m_NoteDisplays;
|
||||||
|
|||||||
@@ -41,6 +41,22 @@ void RageVec3Normalize( RageVector3* pOut, const RageVector3* pV )
|
|||||||
pOut->z = pV->z * scale;
|
pOut->z = pV->z * scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VectorFloatNormalize(vector<float>& v)
|
||||||
|
{
|
||||||
|
ASSERT_M(v.size() == 3, "Can't normalize a non-3D vector.");
|
||||||
|
float scale = 1.0f / sqrtf(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
|
||||||
|
v[0]*= scale;
|
||||||
|
v[1]*= scale;
|
||||||
|
v[2]*= scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RageVec3Cross(RageVector3* ret, RageVector3 const* a, RageVector3 const* b)
|
||||||
|
{
|
||||||
|
ret->x= (a->y * b->z) - (a->z * b->y);
|
||||||
|
ret->y= ((a->x * b->z) - (a->z * b->x));
|
||||||
|
ret->z= (a->x * b->y) - (a->y * b->x);
|
||||||
|
}
|
||||||
|
|
||||||
void RageVec3TransformCoord( RageVector3* pOut, const RageVector3* pV, const RageMatrix* pM )
|
void RageVec3TransformCoord( RageVector3* pOut, const RageVector3* pV, const RageMatrix* pM )
|
||||||
{
|
{
|
||||||
RageVector4 temp( pV->x, pV->y, pV->z, 1.0f ); // translate
|
RageVector4 temp( pV->x, pV->y, pV->z, 1.0f ); // translate
|
||||||
@@ -314,6 +330,21 @@ void RageMatrixRotationXYZ( RageMatrix* pOut, float rX, float rY, float rZ )
|
|||||||
pOut->m33 = 1;
|
pOut->m33 = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RageAARotate(RageVector3* inret, RageVector3 const* axis, float angle)
|
||||||
|
{
|
||||||
|
float ha= angle/2.0f;
|
||||||
|
float ca2= RageFastCos(ha);
|
||||||
|
float sa2= RageFastSin(ha);
|
||||||
|
RageVector4 quat(axis->x * sa2, axis->y * sa2, axis->z * sa2, ca2);
|
||||||
|
RageVector4 quatc(-quat.x, -quat.y, -quat.z, ca2);
|
||||||
|
RageVector4 point(inret->x, inret->y, inret->z, 0.0f);
|
||||||
|
RageQuatMultiply(&point, quat, point);
|
||||||
|
RageQuatMultiply(&point, point, quatc);
|
||||||
|
inret->x= point.x;
|
||||||
|
inret->y= point.y;
|
||||||
|
inret->z= point.z;
|
||||||
|
}
|
||||||
|
|
||||||
void RageQuatMultiply( RageVector4* pOut, const RageVector4 &pA, const RageVector4 &pB )
|
void RageQuatMultiply( RageVector4* pOut, const RageVector4 &pA, const RageVector4 &pB )
|
||||||
{
|
{
|
||||||
RageVector4 out;
|
RageVector4 out;
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ void RageVec3AddToBounds( const RageVector3 &p, RageVector3 &mins, RageVector3 &
|
|||||||
|
|
||||||
void RageVec2Normalize( RageVector2* pOut, const RageVector2* pV );
|
void RageVec2Normalize( RageVector2* pOut, const RageVector2* pV );
|
||||||
void RageVec3Normalize( RageVector3* pOut, const RageVector3* pV );
|
void RageVec3Normalize( RageVector3* pOut, const RageVector3* pV );
|
||||||
|
void VectorFloatNormalize(vector<float>& v);
|
||||||
|
void RageVec3Cross(RageVector3* ret, RageVector3 const* a, RageVector3 const* b);
|
||||||
void RageVec3TransformCoord( RageVector3* pOut, const RageVector3* pV, const RageMatrix* pM );
|
void RageVec3TransformCoord( RageVector3* pOut, const RageVector3* pV, const RageMatrix* pM );
|
||||||
void RageVec3TransformNormal( RageVector3* pOut, const RageVector3* pV, const RageMatrix* pM );
|
void RageVec3TransformNormal( RageVector3* pOut, const RageVector3* pV, const RageMatrix* pM );
|
||||||
void RageVec4TransformCoord( RageVector4* pOut, const RageVector4* pV, const RageMatrix* pM );
|
void RageVec4TransformCoord( RageVector4* pOut, const RageVector4* pV, const RageMatrix* pM );
|
||||||
@@ -34,6 +36,7 @@ void RageMatrixRotationX( RageMatrix* pOut, float fTheta );
|
|||||||
void RageMatrixRotationY( RageMatrix* pOut, float fTheta );
|
void RageMatrixRotationY( RageMatrix* pOut, float fTheta );
|
||||||
void RageMatrixRotationZ( RageMatrix* pOut, float fTheta );
|
void RageMatrixRotationZ( RageMatrix* pOut, float fTheta );
|
||||||
void RageMatrixRotationXYZ( RageMatrix* pOut, float rX, float rY, float rZ );
|
void RageMatrixRotationXYZ( RageMatrix* pOut, float rX, float rY, float rZ );
|
||||||
|
void RageAARotate(RageVector3* inret, RageVector3 const* axis, float angle);
|
||||||
void RageQuatFromHPR(RageVector4* pOut, RageVector3 hpr );
|
void RageQuatFromHPR(RageVector4* pOut, RageVector3 hpr );
|
||||||
void RageQuatFromPRH(RageVector4* pOut, RageVector3 prh );
|
void RageQuatFromPRH(RageVector4* pOut, RageVector3 prh );
|
||||||
void RageMatrixFromQuat( RageMatrix* pOut, const RageVector4 q );
|
void RageMatrixFromQuat( RageMatrix* pOut, const RageVector4 q );
|
||||||
|
|||||||
@@ -53,8 +53,6 @@ void ReceptorArrowRow::Update( float fDeltaTime )
|
|||||||
|
|
||||||
for( unsigned c=0; c<m_ReceptorArrow.size(); c++ )
|
for( unsigned c=0; c<m_ReceptorArrow.size(); c++ )
|
||||||
{
|
{
|
||||||
vector<float> spline_pos;
|
|
||||||
(*m_renderers)[c].m_spline.evaluate((*m_renderers)[c].m_receptor_t, spline_pos);
|
|
||||||
// m_fDark==1 or m_fFadeToFailPercent==1 should make fBaseAlpha==0
|
// m_fDark==1 or m_fFadeToFailPercent==1 should make fBaseAlpha==0
|
||||||
float fBaseAlpha = (1 - m_pPlayerState->m_PlayerOptions.GetCurrent().m_fDark);
|
float fBaseAlpha = (1 - m_pPlayerState->m_PlayerOptions.GetCurrent().m_fDark);
|
||||||
if( m_fFadeToFailPercent != -1 )
|
if( m_fFadeToFailPercent != -1 )
|
||||||
@@ -65,18 +63,7 @@ void ReceptorArrowRow::Update( float fDeltaTime )
|
|||||||
m_ReceptorArrow[c]->SetBaseAlpha( fBaseAlpha );
|
m_ReceptorArrow[c]->SetBaseAlpha( fBaseAlpha );
|
||||||
|
|
||||||
// set arrow XYZ
|
// set arrow XYZ
|
||||||
float fX = ArrowEffects::GetXPos( m_pPlayerState, c, 0 );
|
(*m_renderers)[c].UpdateReceptorGhostStuff(m_ReceptorArrow[c]);
|
||||||
const float fY = ArrowEffects::GetYPos( m_pPlayerState, c, 0, m_fYReverseOffsetPixels );
|
|
||||||
const float fZ = ArrowEffects::GetZPos( m_pPlayerState, c, 0 );
|
|
||||||
m_ReceptorArrow[c]->SetX( fX + spline_pos[0] );
|
|
||||||
m_ReceptorArrow[c]->SetY( fY + spline_pos[1] );
|
|
||||||
m_ReceptorArrow[c]->SetZ( fZ + spline_pos[2] );
|
|
||||||
|
|
||||||
const float fRotation = ArrowEffects::ReceptorGetRotationZ( m_pPlayerState );
|
|
||||||
m_ReceptorArrow[c]->SetRotationZ( fRotation );
|
|
||||||
|
|
||||||
const float fZoom = ArrowEffects::GetZoom( m_pPlayerState );
|
|
||||||
m_ReceptorArrow[c]->SetZoom( fZoom );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user