Implement base math for the easings, OUTIN is missing for the moment, alter displayed BPM depending on the SongSpeed variable
This commit is contained in:
parent
f81afdd89d
commit
3b7dfe07c2
273
TJAPlayer3/Helpers/HEasingMethods.cs
Normal file
273
TJAPlayer3/Helpers/HEasingMethods.cs
Normal file
@ -0,0 +1,273 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web.Security;
|
||||
|
||||
namespace TJAPlayer3
|
||||
{
|
||||
internal class HEasingMethods
|
||||
{
|
||||
public enum EEaseType
|
||||
{
|
||||
IN = 0,
|
||||
OUT,
|
||||
INOUT,
|
||||
OUTIN
|
||||
}
|
||||
|
||||
public enum EEaseFunction
|
||||
{
|
||||
LINEAR = 0,
|
||||
SINE,
|
||||
QUAD,
|
||||
CUBIC,
|
||||
QUART,
|
||||
QUINT,
|
||||
EXPO,
|
||||
CIRC,
|
||||
ELASTIC,
|
||||
BACK,
|
||||
BOUNCE
|
||||
}
|
||||
|
||||
private static readonly Dictionary<EEaseFunction, Func<EEaseType, double, double>> _easeMethods = new Dictionary<EEaseFunction, Func<EEaseType, double, double>>()
|
||||
{
|
||||
[EEaseFunction.LINEAR] = _easeLinear,
|
||||
[EEaseFunction.SINE] = _easeSine,
|
||||
[EEaseFunction.QUAD] = _easeQuad,
|
||||
[EEaseFunction.CUBIC] = _easeCubic,
|
||||
[EEaseFunction.QUART] = _easeQuart,
|
||||
[EEaseFunction.QUINT] = _easeQuint,
|
||||
[EEaseFunction.EXPO] = _easeExpo,
|
||||
[EEaseFunction.CIRC] = _easeCirc,
|
||||
[EEaseFunction.ELASTIC] = _easeElastic,
|
||||
[EEaseFunction.BACK] = _easeBack,
|
||||
[EEaseFunction.BOUNCE] = _easeBounce,
|
||||
};
|
||||
|
||||
private static double _easeLinear(EEaseType type, double x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
private static double _easeSine(EEaseType type, double x)
|
||||
{
|
||||
switch (type) {
|
||||
case EEaseType.IN:
|
||||
default:
|
||||
return 1 - Math.Cos((x * Math.PI) / 2.0);
|
||||
case EEaseType.OUT:
|
||||
return Math.Sin((x * Math.PI) / 2.0);
|
||||
case EEaseType.INOUT:
|
||||
return -(Math.Cos(x * Math.PI) - 1) / 2.0;
|
||||
case EEaseType.OUTIN:
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
private static double _easeQuad(EEaseType type, double x)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case EEaseType.IN:
|
||||
default:
|
||||
return x * x;
|
||||
case EEaseType.OUT:
|
||||
return 1 - (1 - x) * (1 - x);
|
||||
case EEaseType.INOUT:
|
||||
return x < 0.5 ? 2 * x * x : 1 - Math.Pow(-2 * x + 2, 2) / 2.0;
|
||||
case EEaseType.OUTIN:
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
private static double _easeCubic(EEaseType type, double x)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case EEaseType.IN:
|
||||
default:
|
||||
return x * x * x;
|
||||
case EEaseType.OUT:
|
||||
return 1 - Math.Pow(1 - x, 3);
|
||||
case EEaseType.INOUT:
|
||||
return x < 0.5 ? 4 * x * x * x : 1 - Math.Pow(-2 * x + 2, 3) / 2.0;
|
||||
case EEaseType.OUTIN:
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
private static double _easeQuart(EEaseType type, double x)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case EEaseType.IN:
|
||||
default:
|
||||
return x * x * x * x;
|
||||
case EEaseType.OUT:
|
||||
return 1 - Math.Pow(1 - x, 4);
|
||||
case EEaseType.INOUT:
|
||||
return x < 0.5 ? 8 * x * x * x * x : 1 - Math.Pow(-2 * x + 2, 4) / 2.0;
|
||||
case EEaseType.OUTIN:
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
private static double _easeQuint(EEaseType type, double x)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case EEaseType.IN:
|
||||
default:
|
||||
return x * x * x * x * x;
|
||||
case EEaseType.OUT:
|
||||
return 1 - Math.Pow(1 - x, 5);
|
||||
case EEaseType.INOUT:
|
||||
return x < 0.5 ? 16 * x * x * x * x * x : 1 - Math.Pow(-2 * x + 2, 5) / 2.0;
|
||||
case EEaseType.OUTIN:
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
private static double _easeExpo(EEaseType type, double x)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case EEaseType.IN:
|
||||
default:
|
||||
return x == 0 ? 0 : Math.Pow(2, 10 * x - 10);
|
||||
case EEaseType.OUT:
|
||||
return x == 1 ? 1 : 1 - Math.Pow(2, -10 * x);
|
||||
case EEaseType.INOUT:
|
||||
return x == 0
|
||||
? 0
|
||||
: x == 1
|
||||
? 1
|
||||
: x < 0.5
|
||||
? Math.Pow(2, 20 * x - 10) / 2
|
||||
: (2 - Math.Pow(2, -20 * x + 10)) / 2; ;
|
||||
case EEaseType.OUTIN:
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
private static double _easeCirc(EEaseType type, double x)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case EEaseType.IN:
|
||||
default:
|
||||
return 1 - Math.Sqrt(1 - Math.Pow(x, 2));
|
||||
case EEaseType.OUT:
|
||||
return Math.Sqrt(1 - Math.Pow(x - 1, 2));
|
||||
case EEaseType.INOUT:
|
||||
return x < 0.5
|
||||
? (1 - Math.Sqrt(1 - Math.Pow(2 * x, 2))) / 2
|
||||
: (Math.Sqrt(1 - Math.Pow(-2 * x + 2, 2)) + 1) / 2;
|
||||
case EEaseType.OUTIN:
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
private static double _easeBack(EEaseType type, double x)
|
||||
{
|
||||
const double c1 = 1.70158;
|
||||
const double c2 = c1 * 1.525;
|
||||
const double c3 = c1 + 1;
|
||||
switch (type)
|
||||
{
|
||||
case EEaseType.IN:
|
||||
default:
|
||||
return c3 * x * x * x - c1 * x * x;
|
||||
case EEaseType.OUT:
|
||||
return 1 + c3 * Math.Pow(x - 1, 3) + c1 * Math.Pow(x - 1, 2);
|
||||
case EEaseType.INOUT:
|
||||
return x < 0.5
|
||||
? (Math.Pow(2 * x, 2) * ((c2 + 1) * 2 * x - c2)) / 2
|
||||
: (Math.Pow(2 * x - 2, 2) * ((c2 + 1) * (x * 2 - 2) + c2) + 2) / 2;
|
||||
case EEaseType.OUTIN:
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
private static double _easeElastic(EEaseType type, double x)
|
||||
{
|
||||
const double c4 = (2 * Math.PI) / 3;
|
||||
const double c5 = (2 * Math.PI) / 4.5;
|
||||
switch (type)
|
||||
{
|
||||
case EEaseType.IN:
|
||||
default:
|
||||
return x == 0
|
||||
? 0
|
||||
: x == 1
|
||||
? 1
|
||||
: -Math.Pow(2, 10 * x - 10) * Math.Sin((x * 10 - 10.75) * c4);
|
||||
case EEaseType.OUT:
|
||||
return x == 0
|
||||
? 0
|
||||
: x == 1
|
||||
? 1
|
||||
: Math.Pow(2, -10 * x) * Math.Sin((x * 10 - 0.75) * c4) + 1;
|
||||
case EEaseType.INOUT:
|
||||
return x == 0
|
||||
? 0
|
||||
: x == 1
|
||||
? 1
|
||||
: x < 0.5
|
||||
? -(Math.Pow(2, 20 * x - 10) * Math.Sin((20 * x - 11.125) * c5)) / 2
|
||||
: (Math.Pow(2, -20 * x + 10) * Math.Sin((20 * x - 11.125) * c5)) / 2 + 1;
|
||||
case EEaseType.OUTIN:
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
private static double _easeOutBounce(double x)
|
||||
{
|
||||
const double n1 = 7.5625;
|
||||
const double d1 = 2.75;
|
||||
|
||||
if (x < 1 / d1)
|
||||
return n1 * x * x;
|
||||
else if (x < 2 / d1)
|
||||
return n1 * (x -= 1.5 / d1) * x + 0.75;
|
||||
else if (x < 2.5 / d1)
|
||||
return n1 * (x -= 2.25 / d1) * x + 0.9375;
|
||||
else
|
||||
return n1 * (x -= 2.625 / d1) * x + 0.984375;
|
||||
}
|
||||
|
||||
private static double _easeBounce(EEaseType type, double x)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case EEaseType.IN:
|
||||
default:
|
||||
return 1 - _easeOutBounce(1 - x);
|
||||
case EEaseType.OUT:
|
||||
return _easeOutBounce(x);
|
||||
case EEaseType.INOUT:
|
||||
return x < 0.5
|
||||
? (1 - _easeOutBounce(1 - 2 * x)) / 2
|
||||
: (1 + _easeOutBounce(2 * x - 1)) / 2;
|
||||
case EEaseType.OUTIN:
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
public static double tCalculateEaseNorm(EEaseType type, EEaseFunction function, double ratio)
|
||||
{
|
||||
return _easeMethods[function](type, ratio);
|
||||
}
|
||||
|
||||
public static double tCalculateEase(EEaseType type, EEaseFunction function, double timeStart, double timeEnd, double timeCurrent, double valueStart, double valueEnd)
|
||||
{
|
||||
if (timeStart == timeEnd) return valueEnd;
|
||||
double ratio = (timeCurrent - timeStart) / (timeEnd - timeStart);
|
||||
double ratio_eased = _easeMethods[function](type, ratio);
|
||||
return valueStart + ratio_eased * (valueEnd - valueStart);
|
||||
}
|
||||
}
|
||||
}
|
@ -110,7 +110,9 @@ namespace TJAPlayer3
|
||||
{
|
||||
this.long再生開始時のシステム時刻 = CSound管理.rc演奏用タイマ.nシステム時刻ms;
|
||||
this.long再生位置 = cスコア.譜面情報.nデモBGMオフセット;
|
||||
|
||||
this.sound.t再生位置を変更する(cスコア.譜面情報.nデモBGMオフセット);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -171,6 +173,7 @@ namespace TJAPlayer3
|
||||
if(TJAPlayer3.ConfigIni.bBGM音を発声する)
|
||||
this.sound = TJAPlayer3.Sound管理.tサウンドを生成する( strPreviewFilename, ESoundGroup.SongPreview );
|
||||
if (this.sound == null) return;
|
||||
//this.sound.db再生速度 = ((double)TJAPlayer3.ConfigIni.n演奏速度) / 20.0;
|
||||
|
||||
// 2018-08-27 twopointzero - DO attempt to load (or queue scanning) loudness metadata here.
|
||||
// Initialization, song enumeration, and/or interactions may have
|
||||
@ -189,7 +192,7 @@ namespace TJAPlayer3
|
||||
{
|
||||
this.long再生開始時のシステム時刻 = CSound管理.rc演奏用タイマ.nシステム時刻ms;
|
||||
this.long再生位置 = cスコア.譜面情報.nデモBGMオフセット;
|
||||
this.sound.t再生位置を変更する( cスコア.譜面情報.nデモBGMオフセット );
|
||||
this.sound.t再生位置を変更する(cスコア.譜面情報.nデモBGMオフセット);
|
||||
this.long再生位置 = CSound管理.rc演奏用タイマ.nシステム時刻ms - this.long再生開始時のシステム時刻;
|
||||
}
|
||||
//if( long再生位置 == this.sound.n総演奏時間ms - 10 )
|
||||
@ -198,13 +201,7 @@ namespace TJAPlayer3
|
||||
this.str現在のファイル名 = strPreviewFilename;
|
||||
this.tBGMフェードアウト開始();
|
||||
Trace.TraceInformation( "プレビューサウンドを生成しました。({0})", strPreviewFilename );
|
||||
#region[ DTXMania(コメントアウト) ]
|
||||
//this.sound = CDTXMania.Sound管理.tサウンドを生成する( strPreviewFilename );
|
||||
//this.sound.t再生を開始する( true );
|
||||
//this.str現在のファイル名 = strPreviewFilename;
|
||||
//this.tBGMフェードアウト開始();
|
||||
//Trace.TraceInformation( "プレビューサウンドを生成しました。({0})", strPreviewFilename );
|
||||
#endregion
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
@ -3122,18 +3122,25 @@ namespace TJAPlayer3
|
||||
private TitleTextureKey ttkGenerateBPMTexture(C曲リストノード node, Color forecolor, Color backcolor)
|
||||
{
|
||||
var _score = node.arスコア[tFetchDifficulty(node)].譜面情報;
|
||||
var _speed = ((double)TJAPlayer3.ConfigIni.n演奏速度) / 20.0;
|
||||
|
||||
double[] bpms = new double[3] {
|
||||
_score.BaseBpm,
|
||||
_score.MinBpm,
|
||||
_score.MaxBpm
|
||||
_score.BaseBpm * _speed,
|
||||
_score.MinBpm * _speed,
|
||||
_score.MaxBpm * _speed
|
||||
};
|
||||
|
||||
string bpm_str = "BPM: " + bpms[0].ToString();
|
||||
if (bpms[1] != bpms[0] || bpms[2] != bpms[0])
|
||||
bpm_str += " (" + bpms[1].ToString() + "-" + bpms[2].ToString() + ")";
|
||||
|
||||
return new TitleTextureKey(bpm_str, pfBPM, forecolor, backcolor, TJAPlayer3.Skin.SongSelect_BPM_Text_MaxSize);
|
||||
var _color = forecolor;
|
||||
if (_speed > 1)
|
||||
_color = Color.Red;
|
||||
else if (_speed < 1)
|
||||
_color = Color.LightBlue;
|
||||
|
||||
return new TitleTextureKey(bpm_str, pfBPM, _color, backcolor, TJAPlayer3.Skin.SongSelect_BPM_Text_MaxSize);
|
||||
}
|
||||
|
||||
public CTexture ResolveTitleTexture(TitleTextureKey titleTextureKey)
|
||||
|
@ -144,6 +144,7 @@
|
||||
<Compile Include="Databases\DBUnlockables.cs" />
|
||||
<Compile Include="Databases\Databases.cs" />
|
||||
<Compile Include="Databases\DBCharacter.cs" />
|
||||
<Compile Include="Helpers\HEasingMethods.cs" />
|
||||
<Compile Include="Helpers\HPrivateFastFont.cs" />
|
||||
<Compile Include="I18N\CLang_es.cs" />
|
||||
<Compile Include="I18N\CLang_fr.cs" />
|
||||
|
Loading…
Reference in New Issue
Block a user