增加单个模型的时间因子参数
This commit is contained in:
@@ -167,6 +167,7 @@ namespace Spine
|
|||||||
// 拷贝渲染设置
|
// 拷贝渲染设置
|
||||||
UsePma = other.UsePma;
|
UsePma = other.UsePma;
|
||||||
Physics = other.Physics;
|
Physics = other.Physics;
|
||||||
|
_animationState.TimeScale = other._animationState.TimeScale;
|
||||||
|
|
||||||
// 拷贝皮肤加载情况
|
// 拷贝皮肤加载情况
|
||||||
_skinLoadStatus = other._skinLoadStatus.ToDictionary();
|
_skinLoadStatus = other._skinLoadStatus.ToDictionary();
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ namespace SpineViewer.Models
|
|||||||
|
|
||||||
public string Physics { get; set; } = ISkeleton.Physics.Update.ToString();
|
public string Physics { get; set; } = ISkeleton.Physics.Update.ToString();
|
||||||
|
|
||||||
|
public float TimeScale { get; set; } = 1f;
|
||||||
|
|
||||||
public float Scale { get; set; } = 1f;
|
public float Scale { get; set; } = 1f;
|
||||||
|
|
||||||
public bool FlipX { get; set; }
|
public bool FlipX { get; set; }
|
||||||
@@ -54,5 +56,15 @@ namespace SpineViewer.Models
|
|||||||
public bool DebugPoints { get; set; }
|
public bool DebugPoints { get; set; }
|
||||||
|
|
||||||
public bool DebugClippings { get; set; }
|
public bool DebugClippings { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AnimationConfigModel
|
||||||
|
{
|
||||||
|
string Name { get; set; } = "";
|
||||||
|
|
||||||
|
float TimeScale { get; set; } = 1f;
|
||||||
|
|
||||||
|
float Alpha { get; set; } = 1f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -129,6 +129,12 @@ namespace SpineViewer.Models
|
|||||||
set { lock (_lock) SetProperty(_spineObject.Physics, value, v => _spineObject.Physics = v); }
|
set { lock (_lock) SetProperty(_spineObject.Physics, value, v => _spineObject.Physics = v); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public float TimeScale
|
||||||
|
{
|
||||||
|
get { lock (_lock) return _spineObject.AnimationState.TimeScale; }
|
||||||
|
set { lock (_lock) SetProperty(_spineObject.AnimationState.TimeScale, Math.Clamp(value, -100f, 100f), v => _spineObject.AnimationState.TimeScale = v); }
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 缩放倍数, 绝对值大小, 两个方向大小不一致时返回 -1, 设置时不会影响正负号
|
/// 缩放倍数, 绝对值大小, 两个方向大小不一致时返回 -1, 设置时不会影响正负号
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -388,6 +394,7 @@ namespace SpineViewer.Models
|
|||||||
|
|
||||||
UsePma = _spineObject.UsePma,
|
UsePma = _spineObject.UsePma,
|
||||||
Physics = _spineObject.Physics.ToString(),
|
Physics = _spineObject.Physics.ToString(),
|
||||||
|
TimeScale = _spineObject.AnimationState.TimeScale,
|
||||||
|
|
||||||
DebugTexture = _spineObject.DebugTexture,
|
DebugTexture = _spineObject.DebugTexture,
|
||||||
DebugBounds = _spineObject.DebugBounds,
|
DebugBounds = _spineObject.DebugBounds,
|
||||||
@@ -427,6 +434,7 @@ namespace SpineViewer.Models
|
|||||||
SetProperty(_spineObject.Skeleton.Y, value.Y, v => _spineObject.Skeleton.Y = v, nameof(Y));
|
SetProperty(_spineObject.Skeleton.Y, value.Y, v => _spineObject.Skeleton.Y = v, nameof(Y));
|
||||||
SetProperty(_spineObject.UsePma, value.UsePma, v => _spineObject.UsePma = v, nameof(UsePma));
|
SetProperty(_spineObject.UsePma, value.UsePma, v => _spineObject.UsePma = v, nameof(UsePma));
|
||||||
SetProperty(_spineObject.Physics, Enum.Parse<ISkeleton.Physics>(value.Physics ?? "Update", true), v => _spineObject.Physics = v, nameof(Physics));
|
SetProperty(_spineObject.Physics, Enum.Parse<ISkeleton.Physics>(value.Physics ?? "Update", true), v => _spineObject.Physics = v, nameof(Physics));
|
||||||
|
SetProperty(_spineObject.AnimationState.TimeScale, value.TimeScale, v => _spineObject.AnimationState.TimeScale = v, nameof(TimeScale));
|
||||||
|
|
||||||
foreach (var name in _spineObject.Data.Skins.Select(v => v.Name).Except(value.LoadedSkins))
|
foreach (var name in _spineObject.Data.Skins.Select(v => v.Name).Except(value.LoadedSkins))
|
||||||
if (_spineObject.SetSkinStatus(name, false))
|
if (_spineObject.SetSkinStatus(name, false))
|
||||||
|
|||||||
@@ -64,6 +64,8 @@
|
|||||||
<s:String x:Key="Str_IsShown">Show</s:String>
|
<s:String x:Key="Str_IsShown">Show</s:String>
|
||||||
<s:String x:Key="Str_UsePma">Premultiply Alpha</s:String>
|
<s:String x:Key="Str_UsePma">Premultiply Alpha</s:String>
|
||||||
<s:String x:Key="Str_Physics">Physics</s:String>
|
<s:String x:Key="Str_Physics">Physics</s:String>
|
||||||
|
<s:String x:Key="Str_TimeScale">Time Scale</s:String>
|
||||||
|
<s:String x:Key="Str_TimeScaleTootltip">Time scale for a single model; a negative value plays the animation in reverse.</s:String>
|
||||||
|
|
||||||
<s:String x:Key="Str_Transform">Transform</s:String>
|
<s:String x:Key="Str_Transform">Transform</s:String>
|
||||||
<s:String x:Key="Str_Scale">Scale</s:String>
|
<s:String x:Key="Str_Scale">Scale</s:String>
|
||||||
|
|||||||
@@ -64,6 +64,8 @@
|
|||||||
<s:String x:Key="Str_IsShown">表示</s:String>
|
<s:String x:Key="Str_IsShown">表示</s:String>
|
||||||
<s:String x:Key="Str_UsePma">プレマルチプライドアルファ</s:String>
|
<s:String x:Key="Str_UsePma">プレマルチプライドアルファ</s:String>
|
||||||
<s:String x:Key="Str_Physics">物理</s:String>
|
<s:String x:Key="Str_Physics">物理</s:String>
|
||||||
|
<s:String x:Key="Str_TimeScale">時間スケール</s:String>
|
||||||
|
<s:String x:Key="Str_TimeScaleTootltip">単一モデルの時間スケール。負の値にするとアニメーションを逆再生します。</s:String>
|
||||||
|
|
||||||
<s:String x:Key="Str_Transform">変換</s:String>
|
<s:String x:Key="Str_Transform">変換</s:String>
|
||||||
<s:String x:Key="Str_Scale">スケール</s:String>
|
<s:String x:Key="Str_Scale">スケール</s:String>
|
||||||
|
|||||||
@@ -64,6 +64,8 @@
|
|||||||
<s:String x:Key="Str_IsShown">显示</s:String>
|
<s:String x:Key="Str_IsShown">显示</s:String>
|
||||||
<s:String x:Key="Str_UsePma">预乘Alpha通道</s:String>
|
<s:String x:Key="Str_UsePma">预乘Alpha通道</s:String>
|
||||||
<s:String x:Key="Str_Physics">物理</s:String>
|
<s:String x:Key="Str_Physics">物理</s:String>
|
||||||
|
<s:String x:Key="Str_TimeScale">时间因子</s:String>
|
||||||
|
<s:String x:Key="Str_TimeScaleTootltip">单个模型的时间因子,取负数时可以倒放动画</s:String>
|
||||||
|
|
||||||
<s:String x:Key="Str_Transform">变换</s:String>
|
<s:String x:Key="Str_Transform">变换</s:String>
|
||||||
<s:String x:Key="Str_Scale">缩放</s:String>
|
<s:String x:Key="Str_Scale">缩放</s:String>
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ namespace SpineViewer.ViewModels.MainWindow
|
|||||||
OnPropertyChanged(nameof(IsShown));
|
OnPropertyChanged(nameof(IsShown));
|
||||||
OnPropertyChanged(nameof(UsePma));
|
OnPropertyChanged(nameof(UsePma));
|
||||||
OnPropertyChanged(nameof(Physics));
|
OnPropertyChanged(nameof(Physics));
|
||||||
|
OnPropertyChanged(nameof(TimeScale));
|
||||||
|
|
||||||
OnPropertyChanged(nameof(Scale));
|
OnPropertyChanged(nameof(Scale));
|
||||||
OnPropertyChanged(nameof(FlipX));
|
OnPropertyChanged(nameof(FlipX));
|
||||||
@@ -217,6 +218,25 @@ namespace SpineViewer.ViewModels.MainWindow
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public float? TimeScale
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_selectedObjects.Length <= 0) return null;
|
||||||
|
var val = _selectedObjects[0].TimeScale;
|
||||||
|
if (_selectedObjects.Skip(1).Any(it => it.TimeScale != val)) return null;
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_selectedObjects.Length <= 0) return;
|
||||||
|
if (value is null) return;
|
||||||
|
foreach (var sp in _selectedObjects) sp.TimeScale = (float)value;
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public float? Scale
|
public float? Scale
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -595,35 +615,44 @@ namespace SpineViewer.ViewModels.MainWindow
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
private static readonly Dictionary<string, string> _singleModelPropertyMap = new()
|
||||||
/// 监听单个模型属性发生变化, 则更新聚合属性值
|
|
||||||
/// </summary>
|
|
||||||
private void SingleModel_PropertyChanged(object? sender, PropertyChangedEventArgs e)
|
|
||||||
{
|
{
|
||||||
if (e.PropertyName == nameof(SpineObjectModel.IsShown)) OnPropertyChanged(nameof(IsShown));
|
{ nameof(SpineObjectModel.IsShown), nameof(IsShown) },
|
||||||
else if (e.PropertyName == nameof(SpineObjectModel.UsePma)) OnPropertyChanged(nameof(UsePma));
|
{ nameof(SpineObjectModel.UsePma), nameof(UsePma) },
|
||||||
else if (e.PropertyName == nameof(SpineObjectModel.Physics)) OnPropertyChanged(nameof(Physics));
|
{ nameof(SpineObjectModel.Physics), nameof(Physics) },
|
||||||
|
{ nameof(SpineObjectModel.TimeScale), nameof(TimeScale) },
|
||||||
|
|
||||||
else if (e.PropertyName == nameof(SpineObjectModel.Scale)) OnPropertyChanged(nameof(Scale));
|
{ nameof(SpineObjectModel.Scale), nameof(Scale) },
|
||||||
else if (e.PropertyName == nameof(SpineObjectModel.FlipX)) OnPropertyChanged(nameof(FlipX));
|
{ nameof(SpineObjectModel.FlipX), nameof(FlipX) },
|
||||||
else if (e.PropertyName == nameof(SpineObjectModel.FlipY)) OnPropertyChanged(nameof(FlipY));
|
{ nameof(SpineObjectModel.FlipY), nameof(FlipY) },
|
||||||
else if (e.PropertyName == nameof(SpineObjectModel.X)) OnPropertyChanged(nameof(X));
|
{ nameof(SpineObjectModel.X), nameof(X) },
|
||||||
else if (e.PropertyName == nameof(SpineObjectModel.Y)) OnPropertyChanged(nameof(Y));
|
{ nameof(SpineObjectModel.Y), nameof(Y) },
|
||||||
|
|
||||||
// Skins 变化在 SkinViewModel 中监听
|
// Skins 变化在 SkinViewModel 中监听
|
||||||
// Slots 变化在 SlotAttachmentViewModel 中监听
|
// Slots 变化在 SlotAttachmentViewModel 中监听
|
||||||
// AnimationTracks 变化在 AnimationTrackViewModel 中监听
|
// AnimationTracks 变化在 AnimationTrackViewModel 中监听
|
||||||
|
|
||||||
else if (e.PropertyName == nameof(SpineObjectModel.DebugTexture)) OnPropertyChanged(nameof(DebugTexture));
|
{ nameof(SpineObjectModel.DebugTexture), nameof(DebugTexture) },
|
||||||
else if (e.PropertyName == nameof(SpineObjectModel.DebugBounds)) OnPropertyChanged(nameof(DebugBounds));
|
{ nameof(SpineObjectModel.DebugBounds), nameof(DebugBounds) },
|
||||||
else if (e.PropertyName == nameof(SpineObjectModel.DebugBones)) OnPropertyChanged(nameof(DebugBones));
|
{ nameof(SpineObjectModel.DebugBones), nameof(DebugBones) },
|
||||||
else if (e.PropertyName == nameof(SpineObjectModel.DebugRegions)) OnPropertyChanged(nameof(DebugRegions));
|
{ nameof(SpineObjectModel.DebugRegions), nameof(DebugRegions) },
|
||||||
else if (e.PropertyName == nameof(SpineObjectModel.DebugMeshHulls)) OnPropertyChanged(nameof(DebugMeshHulls));
|
{ nameof(SpineObjectModel.DebugMeshHulls), nameof(DebugMeshHulls) },
|
||||||
else if (e.PropertyName == nameof(SpineObjectModel.DebugMeshes)) OnPropertyChanged(nameof(DebugMeshes));
|
{ nameof(SpineObjectModel.DebugMeshes), nameof(DebugMeshes) },
|
||||||
else if (e.PropertyName == nameof(SpineObjectModel.DebugBoundingBoxes)) OnPropertyChanged(nameof(DebugBoundingBoxes));
|
{ nameof(SpineObjectModel.DebugBoundingBoxes), nameof(DebugBoundingBoxes) },
|
||||||
else if (e.PropertyName == nameof(SpineObjectModel.DebugPaths)) OnPropertyChanged(nameof(DebugPaths));
|
{ nameof(SpineObjectModel.DebugPaths), nameof(DebugPaths) },
|
||||||
else if (e.PropertyName == nameof(SpineObjectModel.DebugPoints)) OnPropertyChanged(nameof(DebugPoints));
|
{ nameof(SpineObjectModel.DebugPoints), nameof(DebugPoints) },
|
||||||
else if (e.PropertyName == nameof(SpineObjectModel.DebugClippings)) OnPropertyChanged(nameof(DebugClippings));
|
{ nameof(SpineObjectModel.DebugClippings), nameof(DebugClippings) },
|
||||||
|
};
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 监听单个模型属性发生变化, 则更新聚合属性值
|
||||||
|
/// </summary>
|
||||||
|
private void SingleModel_PropertyChanged(object? sender, PropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
if (_singleModelPropertyMap.TryGetValue(e.PropertyName, out var targetProperty))
|
||||||
|
{
|
||||||
|
OnPropertyChanged(targetProperty);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -310,6 +310,7 @@
|
|||||||
<RowDefinition Height="Auto"/>
|
<RowDefinition Height="Auto"/>
|
||||||
<RowDefinition Height="Auto"/>
|
<RowDefinition Height="Auto"/>
|
||||||
<RowDefinition Height="Auto"/>
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
<!-- 显示 -->
|
<!-- 显示 -->
|
||||||
@@ -323,6 +324,10 @@
|
|||||||
<!-- 物理 -->
|
<!-- 物理 -->
|
||||||
<Label Grid.Row="2" Grid.Column="0" Content="{DynamicResource Str_Physics}"/>
|
<Label Grid.Row="2" Grid.Column="0" Content="{DynamicResource Str_Physics}"/>
|
||||||
<ComboBox Grid.Row="2" Grid.Column="1" SelectedValue="{Binding Physics}" ItemsSource="{Binding PhysicsOptions}"/>
|
<ComboBox Grid.Row="2" Grid.Column="1" SelectedValue="{Binding Physics}" ItemsSource="{Binding PhysicsOptions}"/>
|
||||||
|
|
||||||
|
<!-- 时间因子 -->
|
||||||
|
<Label Grid.Row="3" Grid.Column="0" Content="{DynamicResource Str_TimeScale}" ToolTip="{DynamicResource Str_TimeScaleTootltip}"/>
|
||||||
|
<TextBox Grid.Row="3" Grid.Column="1" Text="{Binding TimeScale}" ToolTip="{DynamicResource Str_TimeScaleTootltip}"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</TabItem>
|
</TabItem>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user