Added offset mode spline to NoteColumnRenderer.

This commit is contained in:
Kyzentun
2014-12-30 13:59:06 -07:00
parent 584f1c8813
commit 0cb08dc8bd
8 changed files with 194 additions and 109 deletions
+12 -10
View File
@@ -269,7 +269,7 @@ void CubicSpline::set_results(size_t last, vector<float>& diagonals, vector<floa
// Solving is now complete. // Solving is now complete.
} }
float CubicSpline::evaluate(float t, bool loop) float CubicSpline::evaluate(float t, bool loop) const
{ {
if(m_points.empty()) if(m_points.empty())
{ {
@@ -277,7 +277,9 @@ float CubicSpline::evaluate(float t, bool loop)
} }
if(loop) if(loop)
{ {
t= fmodf(t, m_points.size()); float max_t= m_points.size() + 1.0f;
while(t > max_t) { t-= max_t; }
while(t < 0.0f) { t+= max_t; }
} }
int flort= static_cast<int>(t); int flort= static_cast<int>(t);
if(flort < 0) if(flort < 0)
@@ -303,12 +305,12 @@ void CubicSpline::resize(size_t s)
m_points.resize(s); m_points.resize(s);
} }
size_t CubicSpline::size() size_t CubicSpline::size() const
{ {
return m_points.size(); return m_points.size();
} }
bool CubicSpline::empty() bool CubicSpline::empty() const
{ {
return m_points.empty(); return m_points.empty();
} }
@@ -335,9 +337,9 @@ void CubicSplineN::solve()
m_dirty= false; m_dirty= false;
} }
void CubicSplineN::evaluate(float t, vector<float>& v) void CubicSplineN::evaluate(float t, vector<float>& v) const
{ {
for(spline_cont_t::iterator spline= m_splines.begin(); for(spline_cont_t::const_iterator spline= m_splines.begin();
spline != m_splines.end(); ++spline) spline != m_splines.end(); ++spline)
{ {
v.push_back(spline->evaluate(t, loop)); v.push_back(spline->evaluate(t, loop));
@@ -364,7 +366,7 @@ void CubicSplineN::resize(size_t s)
m_dirty= true; m_dirty= true;
} }
size_t CubicSplineN::size() size_t CubicSplineN::size() const
{ {
if(!m_splines.empty()) if(!m_splines.empty())
{ {
@@ -373,7 +375,7 @@ size_t CubicSplineN::size()
return 0; return 0;
} }
bool CubicSplineN::empty() bool CubicSplineN::empty() const
{ {
return m_splines.empty() || m_splines[0].empty(); return m_splines.empty() || m_splines[0].empty();
} }
@@ -384,7 +386,7 @@ void CubicSplineN::redimension(size_t d)
m_dirty= true; m_dirty= true;
} }
size_t CubicSplineN::dimension() size_t CubicSplineN::dimension() const
{ {
return m_splines.size(); return m_splines.size();
} }
@@ -440,7 +442,7 @@ struct LunaCubicSplineN : Luna<CubicSplineN>
{ {
luaL_error(L, "Cannot set spline point at index less than 1."); luaL_error(L, "Cannot set spline point at index less than 1.");
} }
if(i >= p->size()) if(static_cast<size_t>(i) >= p->size())
{ {
luaL_error(L, "Cannot set spline point at index greater than size."); luaL_error(L, "Cannot set spline point at index greater than size.");
} }
+8 -8
View File
@@ -9,11 +9,11 @@ struct CubicSpline
{ {
void solve_looped(); void solve_looped();
void solve_straight(); void solve_straight();
float evaluate(float t, bool loop); float evaluate(float t, bool loop) const;
void set_point(size_t i, float v); void set_point(size_t i, float v);
void resize(size_t s); void resize(size_t s);
size_t size(); size_t size() const;
bool empty(); bool empty() const;
private: private:
bool check_minimum_size(); bool check_minimum_size();
void prep_inner(size_t last, vector<float>& results); void prep_inner(size_t last, vector<float>& results);
@@ -29,16 +29,16 @@ private:
struct CubicSplineN struct CubicSplineN
{ {
CubicSplineN() CubicSplineN()
:m_dirty(true), m_owned_by_actor(false) :m_owned_by_actor(false), m_dirty(true)
{} {}
void solve(); void solve();
void evaluate(float t, vector<float>& v); void evaluate(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 resize(size_t s); void resize(size_t s);
size_t size(); size_t size() const;
void redimension(size_t d); void redimension(size_t d);
size_t dimension(); size_t dimension() const;
bool empty(); bool empty() const;
typedef vector<CubicSpline> spline_cont_t; typedef vector<CubicSpline> spline_cont_t;
bool loop; bool loop;
bool m_owned_by_actor; bool m_owned_by_actor;
+6 -3
View File
@@ -42,6 +42,7 @@ void GhostArrowRow::SetColumnRenderers(vector<NoteColumnRenderer>& renderers)
{ {
m_Ghost[c]->SetFakeParent(&(renderers[c])); m_Ghost[c]->SetFakeParent(&(renderers[c]));
} }
m_renderers= &renderers;
} }
GhostArrowRow::~GhostArrowRow() GhostArrowRow::~GhostArrowRow()
@@ -55,15 +56,17 @@ 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 );
float fX = ArrowEffects::GetXPos( m_pPlayerState, c, 0 ); float fX = ArrowEffects::GetXPos( m_pPlayerState, c, 0 );
float fY = ArrowEffects::GetYPos( m_pPlayerState, c, 0, m_fYReverseOffsetPixels ); float fY = ArrowEffects::GetYPos( m_pPlayerState, c, 0, m_fYReverseOffsetPixels );
float fZ = ArrowEffects::GetZPos( m_pPlayerState, c, 0 ); float fZ = ArrowEffects::GetZPos( m_pPlayerState, c, 0 );
m_Ghost[c]->SetX( fX ); m_Ghost[c]->SetX( fX + spline_pos[0] );
m_Ghost[c]->SetY( fY ); m_Ghost[c]->SetY( fY + spline_pos[1] );
m_Ghost[c]->SetZ( fZ ); m_Ghost[c]->SetZ( fZ + spline_pos[2] );
const float fRotation = ArrowEffects::ReceptorGetRotationZ( m_pPlayerState ); const float fRotation = ArrowEffects::ReceptorGetRotationZ( m_pPlayerState );
m_Ghost[c]->SetRotationZ( fRotation ); m_Ghost[c]->SetRotationZ( fRotation );
+1
View File
@@ -26,6 +26,7 @@ protected:
float m_fYReverseOffsetPixels; float m_fYReverseOffsetPixels;
const PlayerState* m_pPlayerState; const PlayerState* m_pPlayerState;
vector<NoteColumnRenderer> const* m_renderers;
vector<Actor *> m_Ghost; vector<Actor *> m_Ghost;
vector<TapNoteSubType> m_bHoldShowing; vector<TapNoteSubType> m_bHoldShowing;
vector<TapNoteSubType> m_bLastHoldShowing; vector<TapNoteSubType> m_bLastHoldShowing;
+120 -62
View File
@@ -342,6 +342,13 @@ bool NoteDisplay::IsOnScreen( float fBeat, int iCol, int iDrawDistanceAfterTarge
return true; return true;
} }
float NoteDisplay::BeatToTValue(CommonColumnRenderArgs const& args, float beat) const
{
float song_beat= m_pPlayerState->GetDisplayedPosition().m_fSongBeatVisible;
float relative_beat= beat - song_beat;
return (relative_beat / args.beats_per_t) - args.receptor_t;
}
bool NoteDisplay::DrawHoldsInRange(CommonColumnRenderArgs const& args, bool NoteDisplay::DrawHoldsInRange(CommonColumnRenderArgs const& args,
int column, vector<NoteData::TrackMap::const_iterator> const& tap_set) int column, vector<NoteData::TrackMap::const_iterator> const& tap_set)
{ {
@@ -398,12 +405,9 @@ bool NoteDisplay::DrawHoldsInRange(CommonColumnRenderArgs const& args,
end_row < *args.selection_end_marker); end_row < *args.selection_end_marker);
} }
DrawHold(tn, column, start_row, is_holding, result, DrawHold(tn, args, column, start_row, is_holding, result,
use_addition_coloring, use_addition_coloring,
in_selection_range ? args.selection_glow : args.fail_fade, in_selection_range ? args.selection_glow : args.fail_fade);
m_fYReverseOffsetPixels, (float)args.draw_pixels_after_targets,
(float)args.draw_pixels_before_targets,
args.draw_pixels_before_targets, args.fade_before_targets);
bool note_upcoming = NoteRowToBeat(start_row) > bool note_upcoming = NoteRowToBeat(start_row) >
m_pPlayerState->GetDisplayedPosition().m_fSongBeat; m_pPlayerState->GetDisplayedPosition().m_fSongBeat;
@@ -485,12 +489,10 @@ bool NoteDisplay::DrawTapsInRange(CommonColumnRenderArgs const& args,
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, column, NoteRowToVisibleBeat(m_pPlayerState, tap_row), DrawTap(tn, args, column, 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 ? args.selection_glow : args.fail_fade);
m_fYReverseOffsetPixels, args.draw_pixels_after_targets,
args.draw_pixels_before_targets, args.fade_before_targets);
any_upcoming |= NoteRowToBeat(tap_row) > any_upcoming |= NoteRowToBeat(tap_row) >
m_pPlayerState->GetDisplayedPosition().m_fSongBeat; m_pPlayerState->GetDisplayedPosition().m_fSongBeat;
@@ -611,12 +613,12 @@ struct StripBuffer
int Free() const { return size - Used(); } int Free() const { return size - Used(); }
}; };
void NoteDisplay::DrawHoldPart( vector<Sprite*> &vpSpr, int iCol, int fYStep, float fPercentFadeToFail, float fColorScale, bool bGlow, void NoteDisplay::DrawHoldPart(vector<Sprite*> &vpSpr,
float fDrawDistanceAfterTargetsPixels, float fDrawDistanceBeforeTargetsPixels, float fFadeInPercentOfDrawFar, CommonColumnRenderArgs const& args, int iCol, int fYStep,
float fOverlappedTime, float fPercentFadeToFail, float fColorScale, bool bGlow,
float fYTop, float fYBottom, float fOverlappedTime, float fYTop, float fYBottom, float fYStartPos,
float fYStartPos, float fYEndPos, float fYEndPos, bool bWrapping, bool bAnchorToTop,
bool bWrapping, bool bAnchorToTop, bool bFlipTextureVertically ) bool bFlipTextureVertically, float top_t, float bottom_t)
{ {
ASSERT( !vpSpr.empty() ); ASSERT( !vpSpr.empty() );
@@ -681,12 +683,20 @@ void NoteDisplay::DrawHoldPart( vector<Sprite*> &vpSpr, int iCol, int fYStep, fl
bLast = true; bLast = true;
} }
float curtsy= top_t;
if(top_t != bottom_t)
{
curtsy= SCALE(fY, fYTop, fYBottom, top_t, bottom_t);
}
vector<float> spline_pos;
args.spline->evaluate(curtsy, spline_pos);
const float fYOffset = ArrowEffects::GetYOffsetFromYPos( m_pPlayerState, iCol, fY, m_fYReverseOffsetPixels ); const float fYOffset = ArrowEffects::GetYOffsetFromYPos( m_pPlayerState, iCol, fY, m_fYReverseOffsetPixels );
const float fZ = ArrowEffects::GetZPos( m_pPlayerState, iCol, fYOffset ); 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 = fFrameWidth * fFrameWidthScale;
float fX = ArrowEffects::GetXPos( m_pPlayerState, iCol, fYOffset ); float fX = ArrowEffects::GetXPos( m_pPlayerState, iCol, fYOffset ) + spline_pos[0];
// XXX: Actor rotations use degrees, RageFastCos/Sin use radians. Convert here. // XXX: Actor rotations use degrees, RageFastCos/Sin use radians. Convert here.
const float fRotationY = ArrowEffects::GetRotationY( m_pPlayerState, fYOffset ) * PI/180; const float fRotationY = ArrowEffects::GetRotationY( m_pPlayerState, fYOffset ) * PI/180;
@@ -708,15 +718,15 @@ void NoteDisplay::DrawHoldPart( vector<Sprite*> &vpSpr, int iCol, int fYStep, fl
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, fDrawDistanceBeforeTargetsPixels, fFadeInPercentOfDrawFar ); const float fAlpha = ArrowGetAlphaOrGlow( bGlow, m_pPlayerState, iCol, fYOffset, fPercentFadeToFail, m_fYReverseOffsetPixels, args.draw_pixels_before_targets, 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, fZLeft); queue.v[0].c = color; queue.v[0].t = RageVector2(fTexCoordLeft, fTexCoordTop); 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[1].p = RageVector3(fXCenter, fY, fZCenter); queue.v[1].c = color; queue.v[1].t = RageVector2(fTexCoordCenter, 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[2].p = RageVector3(fXRight, fY, fZRight); queue.v[2].c = color; queue.v[2].t = RageVector2(fTexCoordRight, 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+=3; queue.v+=3;
if( queue.Free() < 3 || bLast ) if( queue.Free() < 3 || bLast )
@@ -742,8 +752,11 @@ void NoteDisplay::DrawHoldPart( vector<Sprite*> &vpSpr, int iCol, int fYStep, fl
} }
} }
void NoteDisplay::DrawHoldBody( const TapNote& tn, int iCol, float fBeat, bool bIsBeingHeld, float fYHead, float fYTail, bool /* bIsAddition */, float fPercentFadeToFail, float fColorScale, bool bGlow, void NoteDisplay::DrawHoldBody(const TapNote& tn,
float fDrawDistanceAfterTargetsPixels, float fDrawDistanceBeforeTargetsPixels, float fFadeInPercentOfDrawFar ) CommonColumnRenderArgs const& args, int iCol, float fBeat,
bool bIsBeingHeld, float fYHead, float fYTail, bool bIsAddition,
float fPercentFadeToFail, float fColorScale, bool bGlow,
float top_t, float bottom_t)
{ {
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 );
@@ -801,48 +814,51 @@ void NoteDisplay::DrawHoldBody( const TapNote& tn, int iCol, float fBeat, bool b
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, fDrawDistanceAfterTargetsPixels, m_fYReverseOffsetPixels ); float fYStartPos = ArrowEffects::GetYPos( m_pPlayerState, iCol,
float fYEndPos = ArrowEffects::GetYPos( m_pPlayerState, iCol, fDrawDistanceBeforeTargetsPixels, m_fYReverseOffsetPixels ); args.draw_pixels_after_targets, m_fYReverseOffsetPixels );
float fYEndPos = ArrowEffects::GetYPos( m_pPlayerState, iCol,
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( DrawHoldPart(vpSprTop, args, iCol, fYStep, fPercentFadeToFail,
vpSprTop, fColorScale, bGlow,
iCol, fYStep, fPercentFadeToFail, fColorScale, bGlow,
fDrawDistanceAfterTargetsPixels, fDrawDistanceBeforeTargetsPixels, fFadeInPercentOfDrawFar,
tn.HoldResult.fOverlappedTime, tn.HoldResult.fOverlappedTime,
fYHead-fFrameHeightTop, fYHead, fYHead-fFrameHeightTop, fYHead,
fYStartPos, fYEndPos, fYStartPos, fYEndPos,
false, bTopAnchor, bFlipHoldBody ); false, bTopAnchor, bFlipHoldBody, top_t, top_t);
// Draw the body // Draw the body
DrawHoldPart( DrawHoldPart(vpSprBody, args, iCol, fYStep, fPercentFadeToFail,
vpSprBody, fColorScale, bGlow,
iCol, fYStep, fPercentFadeToFail, fColorScale, bGlow,
fDrawDistanceAfterTargetsPixels, fDrawDistanceBeforeTargetsPixels, fFadeInPercentOfDrawFar,
tn.HoldResult.fOverlappedTime, tn.HoldResult.fOverlappedTime,
fYHead, fYTail, fYHead, fYTail,
fYStartPos, fYEndPos, fYStartPos, fYEndPos,
true, bTopAnchor, bFlipHoldBody ); true, bTopAnchor, bFlipHoldBody, top_t, bottom_t);
// Draw the bottom cap // Draw the bottom cap
DrawHoldPart( DrawHoldPart(vpSprBottom, args, iCol, fYStep, fPercentFadeToFail,
vpSprBottom, fColorScale, bGlow,
iCol, fYStep, fPercentFadeToFail, fColorScale, bGlow,
fDrawDistanceAfterTargetsPixels, fDrawDistanceBeforeTargetsPixels, fFadeInPercentOfDrawFar,
tn.HoldResult.fOverlappedTime, tn.HoldResult.fOverlappedTime,
fYTail, fYTail+fFrameHeightBottom, fYTail, fYTail+fFrameHeightBottom,
max(fYStartPos, fYHead), fYEndPos, max(fYStartPos, fYHead), fYEndPos,
false, bTopAnchor, bFlipHoldBody ); false, bTopAnchor, bFlipHoldBody, bottom_t, bottom_t);
} }
void NoteDisplay::DrawHold( const TapNote &tn, int iCol, int iRow, bool bIsBeingHeld, const HoldNoteResult &Result, bool bIsAddition, float fPercentFadeToFail, void NoteDisplay::DrawHold(const TapNote& tn,
float fReverseOffsetPixels, float fDrawDistanceAfterTargetsPixels, float fDrawDistanceBeforeTargetsPixels, float fDrawDistanceBeforeTargetsPixels2, float fFadeInPercentOfDrawFar ) CommonColumnRenderArgs const& args, int iCol, int iRow, bool bIsBeingHeld,
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 bottom_t= BeatToTValue(args, NoteRowToVisibleBeat(m_pPlayerState, iEndRow));
if(bIsBeingHeld)
{
top_t= args.receptor_t;
}
// 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
@@ -873,8 +889,8 @@ void NoteDisplay::DrawHold( const TapNote &tn, int iCol, int iRow, bool bIsBeing
if( bReverse ) if( bReverse )
swap( fStartYOffset, fEndYOffset ); swap( fStartYOffset, fEndYOffset );
const float fYHead = ArrowEffects::GetYPos( m_pPlayerState, iCol, fStartYOffset, fReverseOffsetPixels ); const float fYHead = ArrowEffects::GetYPos( m_pPlayerState, iCol, fStartYOffset, m_fYReverseOffsetPixels );
const float fYTail = ArrowEffects::GetYPos( m_pPlayerState, iCol, fEndYOffset, fReverseOffsetPixels ); const float fYTail = ArrowEffects::GetYPos( m_pPlayerState, iCol, 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 );
@@ -896,8 +912,8 @@ void NoteDisplay::DrawHold( const TapNote &tn, int iCol, int iRow, bool bIsBeing
} }
*/ */
DrawHoldBody( tn, iCol, fBeat, bIsBeingHeld, fYHead, fYTail, bIsAddition, fPercentFadeToFail, fColorScale, false, fDrawDistanceAfterTargetsPixels, fDrawDistanceBeforeTargetsPixels, fFadeInPercentOfDrawFar ); DrawHoldBody(tn, args, iCol, fBeat, bIsBeingHeld, fYHead, fYTail, bIsAddition, fPercentFadeToFail, fColorScale, false, top_t, bottom_t);
DrawHoldBody( tn, iCol, fBeat, bIsBeingHeld, fYHead, fYTail, bIsAddition, fPercentFadeToFail, fColorScale, true, fDrawDistanceAfterTargetsPixels, fDrawDistanceBeforeTargetsPixels, fFadeInPercentOfDrawFar ); DrawHoldBody(tn, args, iCol, fBeat, bIsBeingHeld, fYHead, fYTail, bIsAddition, fPercentFadeToFail, fColorScale, true, top_t, bottom_t);
/* 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
@@ -905,25 +921,33 @@ void NoteDisplay::DrawHold( const TapNote &tn, int iCol, int iRow, bool bIsBeing
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, iCol, bFlipHeadAndTail ? fStartYOffset : fEndYOffset, fBeat, bIsAddition, fPercentFadeToFail, fReverseOffsetPixels, fColorScale, fDrawDistanceAfterTargetsPixels, fDrawDistanceBeforeTargetsPixels, fFadeInPercentOfDrawFar ); DrawActor(tn, pActor, NotePart_HoldTail, args, iCol, 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, iCol, bFlipHeadAndTail ? fEndYOffset : fStartYOffset, fBeat, bIsAddition, fPercentFadeToFail, fReverseOffsetPixels, fColorScale, fDrawDistanceAfterTargetsPixels, fDrawDistanceBeforeTargetsPixels, fFadeInPercentOfDrawFar ); DrawActor(tn, pActor, NotePart_HoldHead, args, iCol, bFlipHeadAndTail ? fEndYOffset : fStartYOffset, fBeat, bIsAddition, fPercentFadeToFail, fColorScale, bIsBeingHeld);
} }
} }
void NoteDisplay::DrawActor( const TapNote& tn, Actor* pActor, NotePart part, int iCol, float fYOffset, float fBeat, bool bIsAddition, float fPercentFadeToFail, float fReverseOffsetPixels, float fColorScale, float fDrawDistanceAfterTargetsPixels, float fDrawDistanceBeforeTargetsPixels, float fFadeInPercentOfDrawFar ) void NoteDisplay::DrawActor(const TapNote& tn, Actor* pActor, NotePart part,
CommonColumnRenderArgs const& args, int iCol, float fYOffset, float fBeat,
bool bIsAddition, float fPercentFadeToFail, float fColorScale,
bool is_being_held)
{ {
if (tn.type == TapNoteType_AutoKeysound && !GAMESTATE->m_bInStepEditor) return; if (tn.type == TapNoteType_AutoKeysound && !GAMESTATE->m_bInStepEditor) return;
if( fYOffset < fDrawDistanceAfterTargetsPixels || fYOffset > fDrawDistanceBeforeTargetsPixels ) if(fYOffset < args.draw_pixels_after_targets ||
fYOffset > args.draw_pixels_before_targets)
return; return;
const float fY = ArrowEffects::GetYPos( m_pPlayerState, iCol, fYOffset, fReverseOffsetPixels ); float spline_t= BeatToTValue(args, fBeat);
const float fX = ArrowEffects::GetXPos( m_pPlayerState, iCol, fYOffset ); if(is_being_held) { spline_t= args.receptor_t; }
const float fZ = ArrowEffects::GetZPos( m_pPlayerState, iCol, fYOffset ); vector<float> spline_pos;
const float fAlpha = ArrowEffects::GetAlpha( m_pPlayerState, iCol, fYOffset, fPercentFadeToFail, m_fYReverseOffsetPixels, fDrawDistanceBeforeTargetsPixels, fFadeInPercentOfDrawFar ); args.spline->evaluate(spline_t, spline_pos);
const float fGlow = ArrowEffects::GetGlow( m_pPlayerState, iCol, fYOffset, fPercentFadeToFail, m_fYReverseOffsetPixels, fDrawDistanceBeforeTargetsPixels, fFadeInPercentOfDrawFar ); const float fY = ArrowEffects::GetYPos( m_pPlayerState, iCol, fYOffset, m_fYReverseOffsetPixels ) + spline_pos[1];
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; float fRotationX = 0, fRotationZ = 0;
@@ -979,13 +1003,10 @@ void NoteDisplay::DrawActor( const TapNote& tn, Actor* pActor, NotePart part, in
} }
} }
void NoteDisplay::DrawTap(const TapNote& tn, int iCol, float fBeat, void NoteDisplay::DrawTap(const TapNote& tn,
CommonColumnRenderArgs const& args, int iCol, float fBeat,
bool bOnSameRowAsHoldStart, bool bOnSameRowAsRollStart, bool bOnSameRowAsHoldStart, bool bOnSameRowAsRollStart,
bool bIsAddition, float fPercentFadeToFail, bool bIsAddition, float fPercentFadeToFail)
float fReverseOffsetPixels,
float fDrawDistanceAfterTargetsPixels,
float fDrawDistanceBeforeTargetsPixels,
float fFadeInPercentOfDrawFar)
{ {
Actor* pActor = NULL; Actor* pActor = NULL;
NotePart part = NotePart_Tap; NotePart part = NotePart_Tap;
@@ -1059,7 +1080,7 @@ void NoteDisplay::DrawTap(const TapNote& tn, int iCol, float fBeat,
const float fYOffset = ArrowEffects::GetYOffset( m_pPlayerState, iCol, fBeat ); const float fYOffset = ArrowEffects::GetYOffset( m_pPlayerState, iCol, 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, iCol, fYOffset, fBeat, bIsAddition, fPercentFadeToFail, fReverseOffsetPixels, 1.0f, fDrawDistanceAfterTargetsPixels, fDrawDistanceBeforeTargetsPixels, fFadeInPercentOfDrawFar ); DrawActor(tn, pActor, part, args, iCol, fYOffset, fBeat, bIsAddition, fPercentFadeToFail, 1.0f, false);
if( tn.type == TapNoteType_Attack ) if( tn.type == TapNoteType_Attack )
pActor->PlayCommand( "UnsetAttack" ); pActor->PlayCommand( "UnsetAttack" );
@@ -1067,6 +1088,11 @@ void NoteDisplay::DrawTap(const TapNote& tn, int iCol, float fBeat,
void NoteColumnRenderer::DrawPrimitives() void NoteColumnRenderer::DrawPrimitives()
{ {
m_render_args->spline= &m_spline;
m_render_args->receptor_t= m_receptor_t;
m_render_args->beats_per_t= m_beats_per_t;
m_render_args->first_beat= NoteRowToBeat(m_render_args->first_row);
m_render_args->last_beat= NoteRowToBeat(m_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.
@@ -1123,6 +1149,38 @@ void NoteColumnRenderer::DrawPrimitives()
m_render_args->receptor_row->SetNoteUpcoming(m_column, any_upcoming); m_render_args->receptor_row->SetNoteUpcoming(m_column, any_upcoming);
} }
#include "LuaBinding.h"
struct LunaNoteColumnRenderer : Luna<NoteColumnRenderer>
{
static int get_spline(T* p, lua_State* L)
{
p->m_spline.PushSelf(L);
return 1;
}
DEFINE_METHOD(get_receptor_t, m_receptor_t);
DEFINE_METHOD(get_beats_per_t, m_beats_per_t);
#define SET_T(member, name) \
static int name(T* p, lua_State* L) \
{ \
p->member= FArg(1); \
COMMON_RETURN_SELF; \
}
SET_T(m_receptor_t, set_receptor_t);
SET_T(m_beats_per_t, set_beats_per_t);
LunaNoteColumnRenderer()
{
ADD_METHOD(get_spline);
ADD_METHOD(get_receptor_t);
ADD_METHOD(get_beats_per_t);
ADD_METHOD(set_receptor_t);
ADD_METHOD(set_beats_per_t);
}
};
LUA_REGISTER_DERIVED_CLASS(NoteColumnRenderer, Actor)
/* /*
* (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.
+38 -21
View File
@@ -2,6 +2,7 @@
#define NOTE_DISPLAY_H #define NOTE_DISPLAY_H
#include "ActorFrame.h" #include "ActorFrame.h"
#include "CubicSpline.h"
#include "NoteData.h" #include "NoteData.h"
#include "PlayerNumber.h" #include "PlayerNumber.h"
#include "GameInput.h" #include "GameInput.h"
@@ -93,10 +94,15 @@ struct CommonColumnRenderArgs
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 last_beat;
int first_row; int first_row;
int last_row; int last_row;
int draw_pixels_before_targets; float draw_pixels_before_targets;
int draw_pixels_after_targets; float draw_pixels_after_targets;
int* selection_begin_marker; int* selection_begin_marker;
int* selection_end_marker; int* selection_end_marker;
float selection_glow; float selection_glow;
@@ -116,6 +122,7 @@ 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(CommonColumnRenderArgs const& args, int column,
vector<NoteData::TrackMap::const_iterator> const& tap_set); vector<NoteData::TrackMap::const_iterator> const& tap_set);
@@ -134,19 +141,14 @@ 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, int iCol, float fBeat, void DrawTap(const TapNote& tn, CommonColumnRenderArgs const& args,
bool bOnSameRowAsHoldStart, bool bOnSameRowAsRollBeat, int iCol, float fBeat, bool bOnSameRowAsHoldStart,
bool bIsAddition, float fPercentFadeToFail, bool bOnSameRowAsRollBeat, bool bIsAddition, float fPercentFadeToFail);
float fReverseOffsetPixels, void DrawHold(const TapNote& tn, CommonColumnRenderArgs const& args,
float fDrawDistanceAfterTargetsPixels, int iCol, int iRow, bool bIsBeingHeld, const HoldNoteResult &Result,
float fDrawDistanceBeforeTargetsPixels, bool bIsAddition, float fPercentFadeToFail);
float fFadeInPercentOfDrawFar );
void DrawHold( const TapNote& tn, int iCol, int iRow, bool bIsBeingHeld, const HoldNoteResult &Result,
bool bIsAddition, float fPercentFadeToFail, float fReverseOffsetPixels, float fDrawDistanceAfterTargetsPixels, float fDrawDistanceBeforeTargetsPixels,
float fDrawDistanceBeforeTargetsPixels2, float fFadeInPercentOfDrawFar );
bool DrawHoldHeadForTapsOnSameRow() const; bool DrawHoldHeadForTapsOnSameRow() const;
bool DrawRollHeadForTapsOnSameRow() const; bool DrawRollHeadForTapsOnSameRow() const;
private: private:
@@ -155,14 +157,20 @@ private:
Actor *GetHoldActor( NoteColorActor nca[NUM_HoldType][NUM_ActiveType], NotePart part, float fNoteBeat, bool bIsRoll, bool bIsBeingHeld ); Actor *GetHoldActor( NoteColorActor nca[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 ); 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, int iCol, float fYOffset, float fBeat, bool bIsAddition, float fPercentFadeToFail, void DrawActor(const TapNote& tn, Actor* pActor, NotePart part,
float fReverseOffsetPixels, float fColorScale, float fDrawDistanceAfterTargetsPixels, float fDrawDistanceBeforeTargetsPixels, float fFadeInPercentOfDrawFar ); CommonColumnRenderArgs const& args, int iCol, float fYOffset, float fBeat,
void DrawHoldBody( const TapNote& tn, int iCol, float fBeat, bool bIsBeingHeld, float fYHead, float fYTail, bool bIsAddition, float fPercentFadeToFail, bool bIsAddition, float fPercentFadeToFail, float fColorScale,
float fColorScale, bool is_being_held);
bool bGlow, float fDrawDistanceAfterTargetsPixels, float fDrawDistanceBeforeTargetsPixels, float fFadeInPercentOfDrawFar ); void DrawHoldBody(const TapNote& tn, CommonColumnRenderArgs const& args,
void DrawHoldPart( vector<Sprite*> &vpSpr, int iCol, int fYStep, float fPercentFadeToFail, float fColorScale, bool bGlow, int iCol, float fBeat, bool bIsBeingHeld, float fYHead, float fYTail,
float fDrawDistanceAfterTargetsPixels, float fDrawDistanceBeforeTargetsPixels, float fFadeInPercentOfDrawFar, float fOverlappedTime, bool bIsAddition, float fPercentFadeToFail, float fColorScale,
float fYTop, float fYBottom, float fYStartPos, float fYEndPos, bool bWrapping, bool bAnchorToTop, bool bFlipTextureVertically ); bool bGlow, float top_t, float bottom_t);
void DrawHoldPart(vector<Sprite*> &vpSpr,
CommonColumnRenderArgs const& args, int iCol, int fYStep,
float fPercentFadeToFail, float fColorScale, bool bGlow,
float fOverlappedTime, float fYTop, float fYBottom, float fYStartPos,
float fYEndPos, bool bWrapping, bool bAnchorToTop,
bool bFlipTextureVertically, float top_t, float bottom_t);
const PlayerState *m_pPlayerState; // to look up PlayerOptions const PlayerState *m_pPlayerState; // to look up PlayerOptions
NoteMetricCache_t *cache; NoteMetricCache_t *cache;
@@ -191,11 +199,20 @@ private:
class NoteColumnRenderer : public Actor class NoteColumnRenderer : public Actor
{ {
public: public:
NoteColumnRenderer()
{
m_spline.redimension(3);
m_spline.m_owned_by_actor= true;
}
NoteDisplay* m_displays[PLAYER_INVALID+1]; NoteDisplay* m_displays[PLAYER_INVALID+1];
CommonColumnRenderArgs* m_render_args; CommonColumnRenderArgs* m_render_args;
int m_column; int m_column;
float m_receptor_t;
float m_beats_per_t;
CubicSplineN m_spline;
virtual void DrawPrimitives(); virtual void DrawPrimitives();
virtual void PushSelf(lua_State* L);
}; };
#endif #endif
+6 -3
View File
@@ -37,6 +37,7 @@ void ReceptorArrowRow::SetColumnRenderers(vector<NoteColumnRenderer>& renderers)
{ {
m_ReceptorArrow[c]->SetFakeParent(&(renderers[c])); m_ReceptorArrow[c]->SetFakeParent(&(renderers[c]));
} }
m_renderers= &renderers;
} }
ReceptorArrowRow::~ReceptorArrowRow() ReceptorArrowRow::~ReceptorArrowRow()
@@ -52,6 +53,8 @@ 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,9 +68,9 @@ void ReceptorArrowRow::Update( float fDeltaTime )
float fX = ArrowEffects::GetXPos( m_pPlayerState, c, 0 ); float fX = ArrowEffects::GetXPos( m_pPlayerState, c, 0 );
const float fY = ArrowEffects::GetYPos( m_pPlayerState, c, 0, m_fYReverseOffsetPixels ); const float fY = ArrowEffects::GetYPos( m_pPlayerState, c, 0, m_fYReverseOffsetPixels );
const float fZ = ArrowEffects::GetZPos( m_pPlayerState, c, 0 ); const float fZ = ArrowEffects::GetZPos( m_pPlayerState, c, 0 );
m_ReceptorArrow[c]->SetX( fX ); m_ReceptorArrow[c]->SetX( fX + spline_pos[0] );
m_ReceptorArrow[c]->SetY( fY ); m_ReceptorArrow[c]->SetY( fY + spline_pos[1] );
m_ReceptorArrow[c]->SetZ( fZ ); m_ReceptorArrow[c]->SetZ( fZ + spline_pos[2] );
const float fRotation = ArrowEffects::ReceptorGetRotationZ( m_pPlayerState ); const float fRotation = ArrowEffects::ReceptorGetRotationZ( m_pPlayerState );
m_ReceptorArrow[c]->SetRotationZ( fRotation ); m_ReceptorArrow[c]->SetRotationZ( fRotation );
+1
View File
@@ -30,6 +30,7 @@ protected:
float m_fYReverseOffsetPixels; float m_fYReverseOffsetPixels;
float m_fFadeToFailPercent; float m_fFadeToFailPercent;
vector<NoteColumnRenderer> const* m_renderers;
vector<ReceptorArrow *> m_ReceptorArrow; vector<ReceptorArrow *> m_ReceptorArrow;
}; };