committed by
Jan-Peter Zurek
10 changed files with 393 additions and 26 deletions
@ -0,0 +1,81 @@ |
|||||
|
<UserControl xmlns="https://github.com/avaloniaui" |
||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" |
||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" |
||||
|
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" |
||||
|
x:Class="RenderDemo.Pages.Transform3DPage"> |
||||
|
<UserControl.Styles> |
||||
|
<Styles> |
||||
|
<Styles.Resources> |
||||
|
<Template x:Key="Acorn"> |
||||
|
<Path Fill="White" Stretch="Uniform" |
||||
|
Data="F1 M 16.6309,18.6563C 17.1309, |
||||
|
8.15625 29.8809,14.1563 29.8809, |
||||
|
14.1563C 30.8809,11.1563 34.1308, |
||||
|
11.4063 34.1308,11.4063C 33.5,12 |
||||
|
34.6309,13.1563 34.6309,13.1563C |
||||
|
32.1309,13.1562 31.1309,14.9062 |
||||
|
31.1309,14.9062C 41.1309,23.9062 |
||||
|
32.6309,27.9063 32.6309,27.9062C |
||||
|
24.6309,24.9063 21.1309,22.1562 |
||||
|
16.6309,18.6563 Z M 16.6309,19.9063C |
||||
|
21.6309,24.1563 25.1309,26.1562 |
||||
|
31.6309,28.6562C 31.6309,28.6562 |
||||
|
26.3809,39.1562 18.3809,36.1563C |
||||
|
18.3809,36.1563 18,38 16.3809,36.9063C |
||||
|
15,36 16.3809,34.9063 16.3809,34.9063C |
||||
|
16.3809,34.9063 10.1309,30.9062 16.6309,19.9063 Z"/> |
||||
|
</Template> |
||||
|
<Template x:Key="Heart"> |
||||
|
<Path Fill="Red" Stretch="Uniform" Data=" |
||||
|
M 272.70141,238.71731 |
||||
|
C 206.46141,238.71731 152.70146,292.4773 152.70146,358.71731 |
||||
|
C 152.70146,493.47282 288.63461,528.80461 381.26391,662.02535 |
||||
|
C 468.83815,529.62199 609.82641,489.17075 609.82641,358.71731 |
||||
|
C 609.82641,292.47731 556.06651,238.7173 489.82641,238.71731 |
||||
|
C 441.77851,238.71731 400.42481,267.08774 381.26391,307.90481 |
||||
|
C 362.10311,267.08773 320.74941,238.7173 272.70141,238.71731 z "/> |
||||
|
</Template> |
||||
|
</Styles.Resources> |
||||
|
<Style Selector="Border.Test"> |
||||
|
<Setter Property="Margin" Value="15"/> |
||||
|
<Setter Property="Width" Value="100"/> |
||||
|
<Setter Property="Height" Value="100"/> |
||||
|
<Setter Property="Child" Value="{StaticResource Acorn}"/> |
||||
|
</Style> |
||||
|
</Styles> |
||||
|
</UserControl.Styles> |
||||
|
<Grid> |
||||
|
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" ClipToBounds="False"> |
||||
|
<StackPanel.Clock> |
||||
|
<Clock /> |
||||
|
</StackPanel.Clock> |
||||
|
<StackPanel ClipToBounds="False"> |
||||
|
<Border Classes="Test" Background="DarkRed"> |
||||
|
<Border.RenderTransform> |
||||
|
<Transform3D RotationY="{Binding RotationY}" |
||||
|
Depth="{Binding Depth}" |
||||
|
RotationX="{Binding RotationX}" |
||||
|
RotationZ="{Binding RotationZ}" |
||||
|
X="{Binding X}" |
||||
|
Y="{Binding Y}" |
||||
|
Z="{Binding Z}" /> |
||||
|
</Border.RenderTransform> |
||||
|
</Border> |
||||
|
<TextBlock>X-Rotation:</TextBlock> |
||||
|
<Slider Minimum="0" Maximum="360" Value="{Binding RotationX}" Width="100" TickFrequency="1"></Slider> |
||||
|
<TextBlock>Y-Rotation:</TextBlock> |
||||
|
<Slider Minimum="0" Maximum="360" Value="{Binding RotationY}" Width="100" TickFrequency="1"></Slider> |
||||
|
<TextBlock>Z-Rotation:</TextBlock> |
||||
|
<Slider Minimum="0" Maximum="360" Value="{Binding RotationZ}" Width="100" TickFrequency="1"></Slider> |
||||
|
<TextBlock>X:</TextBlock> |
||||
|
<Slider Minimum="-100" Maximum="100" Value="{Binding X}" Width="100" TickFrequency="1"></Slider> |
||||
|
<TextBlock>Y:</TextBlock> |
||||
|
<Slider Minimum="-100" Maximum="100" Value="{Binding Y}" Width="100" TickFrequency="1"></Slider> |
||||
|
<TextBlock>Z:</TextBlock> |
||||
|
<Slider Minimum="-100" Maximum="100" Value="{Binding Z}" Width="100" TickFrequency="1"></Slider> |
||||
|
</StackPanel> |
||||
|
</StackPanel> |
||||
|
</Grid> |
||||
|
</UserControl> |
||||
|
|
||||
@ -0,0 +1,21 @@ |
|||||
|
using Avalonia; |
||||
|
using Avalonia.Controls; |
||||
|
using Avalonia.Markup.Xaml; |
||||
|
using RenderDemo.ViewModels; |
||||
|
|
||||
|
namespace RenderDemo.Pages; |
||||
|
|
||||
|
public class Transform3DPage : UserControl |
||||
|
{ |
||||
|
public Transform3DPage() |
||||
|
{ |
||||
|
InitializeComponent(); |
||||
|
this.DataContext = new Transform3DPageViewModel(); |
||||
|
} |
||||
|
|
||||
|
private void InitializeComponent() |
||||
|
{ |
||||
|
AvaloniaXamlLoader.Load(this); |
||||
|
} |
||||
|
} |
||||
|
|
||||
@ -0,0 +1,61 @@ |
|||||
|
using System; |
||||
|
using MiniMvvm; |
||||
|
using Avalonia.Animation; |
||||
|
|
||||
|
namespace RenderDemo.ViewModels |
||||
|
{ |
||||
|
public class Transform3DPageViewModel : ViewModelBase |
||||
|
{ |
||||
|
private double _roationX = 0; |
||||
|
private double _rotationY = 0; |
||||
|
private double _rotationZ = 0; |
||||
|
|
||||
|
private double _x = 0; |
||||
|
private double _y = 0; |
||||
|
private double _z = 0; |
||||
|
|
||||
|
private double _depth = 200; |
||||
|
|
||||
|
public double RoationX |
||||
|
{ |
||||
|
get => _roationX; |
||||
|
set => RaiseAndSetIfChanged(ref _roationX, value); |
||||
|
} |
||||
|
|
||||
|
public double RotationY |
||||
|
{ |
||||
|
get => _rotationY; |
||||
|
set => RaiseAndSetIfChanged(ref _rotationY, value); |
||||
|
} |
||||
|
|
||||
|
public double RotationZ |
||||
|
{ |
||||
|
get => _rotationZ; |
||||
|
set => RaiseAndSetIfChanged(ref _rotationZ, value); |
||||
|
} |
||||
|
|
||||
|
public double Depth |
||||
|
{ |
||||
|
get => _depth; |
||||
|
set => RaiseAndSetIfChanged(ref _depth, value); |
||||
|
} |
||||
|
|
||||
|
public double X |
||||
|
{ |
||||
|
get => _x; |
||||
|
set => RaiseAndSetIfChanged(ref _x, value); |
||||
|
} |
||||
|
|
||||
|
public double Y |
||||
|
{ |
||||
|
get => _y; |
||||
|
set => RaiseAndSetIfChanged(ref _y, value); |
||||
|
} |
||||
|
|
||||
|
public double Z |
||||
|
{ |
||||
|
get => _z; |
||||
|
set => RaiseAndSetIfChanged(ref _z, value); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,192 @@ |
|||||
|
using System; |
||||
|
using System.Numerics; |
||||
|
|
||||
|
namespace Avalonia.Media; |
||||
|
|
||||
|
public class Transform3D : Transform |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Defines the <see cref="RotationX"/> property.
|
||||
|
/// </summary>
|
||||
|
public static readonly StyledProperty<double> s_rotationXProperty = |
||||
|
AvaloniaProperty.Register<Transform3D, double>(nameof(RotationX)); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Defines the <see cref="RotationY"/> property.
|
||||
|
/// </summary>
|
||||
|
public static readonly StyledProperty<double> s_rotationYProperty = |
||||
|
AvaloniaProperty.Register<Transform3D, double>(nameof(RotationY)); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Defines the <see cref="RotationZ"/> property.
|
||||
|
/// </summary>
|
||||
|
public static readonly StyledProperty<double> s_rotationZProperty = |
||||
|
AvaloniaProperty.Register<Transform3D, double>(nameof(RotationZ)); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Defines the <see cref="Depth"/> property.
|
||||
|
/// </summary>
|
||||
|
public static readonly StyledProperty<double> s_depthProperty = |
||||
|
AvaloniaProperty.Register<Transform3D, double>(nameof(Depth)); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Defines the <see cref="CenterX"/> property.
|
||||
|
/// </summary>
|
||||
|
public static readonly StyledProperty<double> s_centerXProperty = |
||||
|
AvaloniaProperty.Register<Transform3D, double>(nameof(CenterX)); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Defines the <see cref="CenterY"/> property.
|
||||
|
/// </summary>
|
||||
|
public static readonly StyledProperty<double> s_centerYProperty = |
||||
|
AvaloniaProperty.Register<Transform3D, double>(nameof(CenterY)); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Defines the <see cref="CenterY"/> property.
|
||||
|
/// </summary>
|
||||
|
public static readonly StyledProperty<double> s_xProperty = |
||||
|
AvaloniaProperty.Register<Transform3D, double>(nameof(X)); |
||||
|
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Defines the <see cref="CenterY"/> property.
|
||||
|
/// </summary>
|
||||
|
public static readonly StyledProperty<double> s_yProperty = |
||||
|
AvaloniaProperty.Register<Transform3D, double>(nameof(Y)); |
||||
|
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Defines the <see cref="CenterY"/> property.
|
||||
|
/// </summary>
|
||||
|
public static readonly StyledProperty<double> s_zProperty = |
||||
|
AvaloniaProperty.Register<Transform3D, double>(nameof(Z)); |
||||
|
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="Transform3D"/> class.
|
||||
|
/// </summary>
|
||||
|
public Transform3D() |
||||
|
{ |
||||
|
this.GetObservable(s_rotationXProperty).Subscribe(_ => RaiseChanged()); |
||||
|
this.GetObservable(s_rotationYProperty).Subscribe(_ => RaiseChanged()); |
||||
|
this.GetObservable(s_rotationZProperty).Subscribe(_ => RaiseChanged()); |
||||
|
this.GetObservable(s_depthProperty).Subscribe(_ => RaiseChanged()); |
||||
|
this.GetObservable(s_centerXProperty).Subscribe(_ => RaiseChanged()); |
||||
|
this.GetObservable(s_centerYProperty).Subscribe(_ => RaiseChanged()); |
||||
|
this.GetObservable(s_xProperty).Subscribe(_ => RaiseChanged()); |
||||
|
this.GetObservable(s_yProperty).Subscribe(_ => RaiseChanged()); |
||||
|
this.GetObservable(s_zProperty).Subscribe(_ => RaiseChanged()); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="Transform3D"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="rotationX">The skew angle of X-axis, in degrees.</param>
|
||||
|
/// <param name="rotationY">The skew angle of Y-axis, in degrees.</param>
|
||||
|
/// <param name="rotationZ"></param>
|
||||
|
public Transform3D( |
||||
|
double rotationX, |
||||
|
double rotationY, |
||||
|
double rotationZ, |
||||
|
double depth, |
||||
|
double centerX, |
||||
|
double centerY) : this() |
||||
|
{ |
||||
|
RotationX = rotationX; |
||||
|
RotationY = rotationY; |
||||
|
RotationZ = rotationZ; |
||||
|
Depth = depth; |
||||
|
CenterX = centerX; |
||||
|
CenterY = centerY; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets or sets the X property.
|
||||
|
/// </summary>
|
||||
|
public double RotationX |
||||
|
{ |
||||
|
get => GetValue(s_rotationXProperty); |
||||
|
set => SetValue(s_rotationXProperty, value); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets or sets the Y property.
|
||||
|
/// </summary>
|
||||
|
public double RotationY |
||||
|
{ |
||||
|
get => GetValue(s_rotationYProperty); |
||||
|
set => SetValue(s_rotationYProperty, value); |
||||
|
} |
||||
|
|
||||
|
public double RotationZ |
||||
|
{ |
||||
|
get => GetValue(s_rotationZProperty); |
||||
|
set => SetValue(s_rotationZProperty, value); |
||||
|
} |
||||
|
|
||||
|
public double Depth |
||||
|
{ |
||||
|
get => GetValue(s_depthProperty); |
||||
|
set => SetValue(s_depthProperty, value); |
||||
|
} |
||||
|
|
||||
|
public double CenterX |
||||
|
{ |
||||
|
get => GetValue(s_centerXProperty); |
||||
|
set => SetValue(s_centerXProperty, value); |
||||
|
} |
||||
|
|
||||
|
public double CenterY |
||||
|
{ |
||||
|
get => GetValue(s_centerYProperty); |
||||
|
set => SetValue(s_centerYProperty, value); |
||||
|
} |
||||
|
|
||||
|
public double X |
||||
|
{ |
||||
|
get => GetValue(s_xProperty); |
||||
|
set => SetValue(s_xProperty, value); |
||||
|
} |
||||
|
|
||||
|
public double Y |
||||
|
{ |
||||
|
get => GetValue(s_yProperty); |
||||
|
set => SetValue(s_yProperty, value); |
||||
|
} |
||||
|
|
||||
|
public double Z |
||||
|
{ |
||||
|
get => GetValue(s_zProperty); |
||||
|
set => SetValue(s_zProperty, value); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the transform's <see cref="Matrix"/>.
|
||||
|
/// </summary>
|
||||
|
public override Matrix Value |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
var matrix44 = Matrix4x4.Identity; |
||||
|
|
||||
|
matrix44 *= Matrix4x4.CreateTranslation((float)X, (float)Y, (float)Z); |
||||
|
|
||||
|
matrix44 *= Matrix4x4.CreateRotationX((float)Matrix.ToRadians(RotationX)); |
||||
|
matrix44 *= Matrix4x4.CreateRotationY((float)Matrix.ToRadians(RotationY)); |
||||
|
matrix44 *= Matrix4x4.CreateRotationZ((float)Matrix.ToRadians(RotationZ)); |
||||
|
|
||||
|
var matrix = new Matrix( |
||||
|
matrix44.M11, |
||||
|
matrix44.M12, |
||||
|
matrix44.M14, |
||||
|
matrix44.M21, |
||||
|
matrix44.M22, |
||||
|
matrix44.M24, |
||||
|
matrix44.M41, |
||||
|
matrix44.M42, |
||||
|
matrix44.M44); |
||||
|
|
||||
|
return matrix; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue