Browse Source

Rename transform.

Re-add depth.
Add slider to preview for showing effect of depth.
pull/7402/head
Jan-Peter Zurek 4 years ago
parent
commit
9fdb48d0c4
  1. 89
      samples/RenderDemo/Pages/Transform3DPage.axaml
  2. 44
      samples/RenderDemo/ViewModels/Transform3DPageViewModel.cs
  3. 2
      src/Avalonia.Visuals/Animation/Animators/TransformAnimator.cs
  4. 195
      src/Avalonia.Visuals/Media/Rotate3DTransform.cs
  5. 178
      src/Avalonia.Visuals/Media/Transform3D.cs

89
samples/RenderDemo/Pages/Transform3DPage.axaml

@ -2,7 +2,7 @@
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="200" d:DesignHeight="200"
mc:Ignorable="d" d:DesignWidth="400" d:DesignHeight="400"
x:Class="RenderDemo.Pages.Transform3DPage">
<UserControl.Styles>
<Styles>
@ -16,10 +16,10 @@
</Template>
</Styles.Resources>
<Style Selector="Border.Test">
<Setter Property="Canvas.Top" Value="-50" />
<Setter Property="Canvas.Left" Value="-50" />
<Setter Property="Width" Value="100" />
<Setter Property="Height" Value="100" />
<Setter Property="Canvas.Top" Value="-100" />
<Setter Property="Canvas.Left" Value="-100" />
<Setter Property="Width" Value="200" />
<Setter Property="Height" Value="200" />
<Setter Property="Child" Value="{StaticResource Acorn}" />
<Setter Property="BorderThickness" Value="2" />
<Setter Property="BorderBrush" Value="Black" />
@ -29,23 +29,23 @@
<Animation Duration="0:0:5"
IterationCount="Infinite">
<KeyFrame Cue="0%">
<Setter Property="Transform3D.RotationX" Value="0" />
<Setter Property="Rotate3DTransform.RotationX" Value="0" />
<Setter Property="ZIndex" Value="4" />
</KeyFrame>
<KeyFrame Cue="25%">
<Setter Property="Transform3D.RotationX" Value="90" />
<Setter Property="Rotate3DTransform.RotationX" Value="90" />
<Setter Property="ZIndex" Value="1" />
</KeyFrame>
<KeyFrame Cue="50%">
<Setter Property="Transform3D.RotationX" Value="180" />
<Setter Property="Rotate3DTransform.RotationX" Value="180" />
<Setter Property="ZIndex" Value="1" />
</KeyFrame>
<KeyFrame Cue="75%">
<Setter Property="Transform3D.RotationX" Value="270" />
<Setter Property="Rotate3DTransform.RotationX" Value="270" />
<Setter Property="ZIndex" Value="1" />
</KeyFrame>
<KeyFrame Cue="100%">
<Setter Property="Transform3D.RotationX" Value="360" />
<Setter Property="Rotate3DTransform.RotationX" Value="360" />
<Setter Property="ZIndex" Value="4" />
</KeyFrame>
</Animation>
@ -56,23 +56,23 @@
<Animation Duration="0:0:5"
IterationCount="Infinite">
<KeyFrame Cue="0%">
<Setter Property="Transform3D.RotationX" Value="90" />
<Setter Property="Rotate3DTransform.RotationX" Value="90" />
<Setter Property="ZIndex" Value="1" />
</KeyFrame>
<KeyFrame Cue="25%">
<Setter Property="Transform3D.RotationX" Value="180" />
<Setter Property="Rotate3DTransform.RotationX" Value="180" />
<Setter Property="ZIndex" Value="1" />
</KeyFrame>
<KeyFrame Cue="50%">
<Setter Property="Transform3D.RotationX" Value="270" />
<Setter Property="Rotate3DTransform.RotationX" Value="270" />
<Setter Property="ZIndex" Value="1" />
</KeyFrame>
<KeyFrame Cue="75%">
<Setter Property="Transform3D.RotationX" Value="360" />
<Setter Property="Rotate3DTransform.RotationX" Value="360" />
<Setter Property="ZIndex" Value="4" />
</KeyFrame>
<KeyFrame Cue="100%">
<Setter Property="Transform3D.RotationX" Value="450" />
<Setter Property="Rotate3DTransform.RotationX" Value="450" />
<Setter Property="ZIndex" Value="1" />
</KeyFrame>
</Animation>
@ -83,23 +83,23 @@
<Animation Duration="0:0:5"
IterationCount="Infinite">
<KeyFrame Cue="0%">
<Setter Property="Transform3D.RotationX" Value="180" />
<Setter Property="Rotate3DTransform.RotationX" Value="180" />
<Setter Property="ZIndex" Value="1" />
</KeyFrame>
<KeyFrame Cue="25%">
<Setter Property="Transform3D.RotationX" Value="270" />
<Setter Property="Rotate3DTransform.RotationX" Value="270" />
<Setter Property="ZIndex" Value="1" />
</KeyFrame>
<KeyFrame Cue="50%">
<Setter Property="Transform3D.RotationX" Value="360" />
<Setter Property="Rotate3DTransform.RotationX" Value="360" />
<Setter Property="ZIndex" Value="4" />
</KeyFrame>
<KeyFrame Cue="75%">
<Setter Property="Transform3D.RotationX" Value="450" />
<Setter Property="Rotate3DTransform.RotationX" Value="450" />
<Setter Property="ZIndex" Value="1" />
</KeyFrame>
<KeyFrame Cue="100%">
<Setter Property="Transform3D.RotationX" Value="540" />
<Setter Property="Rotate3DTransform.RotationX" Value="540" />
<Setter Property="ZIndex" Value="1" />
</KeyFrame>
</Animation>
@ -110,23 +110,23 @@
<Animation Duration="0:0:5"
IterationCount="Infinite">
<KeyFrame Cue="0%">
<Setter Property="Transform3D.RotationX" Value="270" />
<Setter Property="Rotate3DTransform.RotationX" Value="270" />
<Setter Property="ZIndex" Value="1" />
</KeyFrame>
<KeyFrame Cue="25%">
<Setter Property="Transform3D.RotationX" Value="360" />
<Setter Property="Rotate3DTransform.RotationX" Value="360" />
<Setter Property="ZIndex" Value="4" />
</KeyFrame>
<KeyFrame Cue="50%">
<Setter Property="Transform3D.RotationX" Value="450" />
<Setter Property="Rotate3DTransform.RotationX" Value="450" />
<Setter Property="ZIndex" Value="1" />
</KeyFrame>
<KeyFrame Cue="75%">
<Setter Property="Transform3D.RotationX" Value="540" />
<Setter Property="Rotate3DTransform.RotationX" Value="540" />
<Setter Property="ZIndex" Value="1" />
</KeyFrame>
<KeyFrame Cue="100%">
<Setter Property="Transform3D.RotationX" Value="630" />
<Setter Property="Rotate3DTransform.RotationX" Value="630" />
<Setter Property="ZIndex" Value="1" />
</KeyFrame>
</Animation>
@ -134,7 +134,7 @@
</Style>
</Styles>
</UserControl.Styles>
<Grid>
<Grid RowDefinitions="*,Auto">
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" ClipToBounds="False">
<StackPanel.Clock>
<Clock />
@ -142,45 +142,34 @@
<Canvas ClipToBounds="False">
<Border Classes="Test Rect1" Background="DarkRed">
<Border.RenderTransform>
<Transform3D RotationY="0"
RotationX="0"
RotationZ="0"
CenterX="0"
CenterY="0"
CenterZ="-50" />
<Rotate3DTransform CenterZ="-100"
Depth="{Binding Depth}"/>
</Border.RenderTransform>
</Border>
<Border Classes="Test Rect2" Background="DarkGreen">
<Border.RenderTransform>
<Transform3D RotationY="0"
RotationX="0"
RotationZ="0"
CenterX="0"
CenterY="0"
CenterZ="-50" />
<Rotate3DTransform CenterZ="-100"
Depth="{Binding Depth}"/>
</Border.RenderTransform>
</Border>
<Border Classes="Test Rect3" Background="DarkBlue">
<Border.RenderTransform>
<Transform3D RotationY="0"
RotationX="0"
RotationZ="0"
CenterX="0"
CenterY="0"
CenterZ="-50" />
<Rotate3DTransform CenterZ="-100"
Depth="{Binding Depth}"/>
</Border.RenderTransform>
</Border>
<Border Classes="Test Rect4" Background="Orange">
<Border.RenderTransform>
<Transform3D RotationY="0"
RotationX="0"
RotationZ="0"
CenterX="0"
CenterY="0"
CenterZ="-50" />
<Rotate3DTransform CenterZ="-100"
Depth="{Binding Depth}"/>
</Border.RenderTransform>
</Border>
</Canvas>
</StackPanel>
<StackPanel Grid.Row="1">
<TextBlock>Depth: </TextBlock>
<TextBlock Text="{Binding Depth}" />
<Slider VerticalAlignment="Bottom" Value="{Binding Depth}" Minimum="100" Maximum="300" />
</StackPanel>
</Grid>
</UserControl>

44
samples/RenderDemo/ViewModels/Transform3DPageViewModel.cs

@ -6,56 +6,12 @@ namespace RenderDemo.ViewModels
{
public class Transform3DPageViewModel : ViewModelBase
{
private double _rotationX = 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 RotationX
{
get => _rotationX;
set => RaiseAndSetIfChanged(ref _rotationX, 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);
}
}
}

2
src/Avalonia.Visuals/Animation/Animators/TransformAnimator.cs

@ -43,7 +43,7 @@ namespace Avalonia.Animation.Animators
normalTransform.Children.Add(new SkewTransform());
normalTransform.Children.Add(new RotateTransform());
normalTransform.Children.Add(new TranslateTransform());
normalTransform.Children.Add(new Transform3D());
normalTransform.Children.Add(new Rotate3DTransform());
ctrl.RenderTransform = normalTransform;
}

195
src/Avalonia.Visuals/Media/Rotate3DTransform.cs

@ -0,0 +1,195 @@
using System;
using System.Numerics;
namespace Avalonia.Media;
/// <summary>
/// Non-Affine 3D transformation for rotating an visual around a definable axis
/// </summary>
public class Rotate3DTransform : Transform
{
/// <summary>
/// Defines the <see cref="RotationX"/> property.
/// </summary>
public static readonly StyledProperty<double> RotationXProperty =
AvaloniaProperty.Register<Rotate3DTransform, double>(nameof(RotationX));
/// <summary>
/// Defines the <see cref="RotationY"/> property.
/// </summary>
public static readonly StyledProperty<double> RotationYProperty =
AvaloniaProperty.Register<Rotate3DTransform, double>(nameof(RotationY));
/// <summary>
/// Defines the <see cref="RotationZ"/> property.
/// </summary>
public static readonly StyledProperty<double> RotationZProperty =
AvaloniaProperty.Register<Rotate3DTransform, double>(nameof(RotationZ));
/// <summary>
/// Defines the <see cref="CenterX"/> property.
/// </summary>
public static readonly StyledProperty<double> CenterXProperty =
AvaloniaProperty.Register<Rotate3DTransform, double>(nameof(CenterX));
/// <summary>
/// Defines the <see cref="CenterY"/> property.
/// </summary>
public static readonly StyledProperty<double> CenterYProperty =
AvaloniaProperty.Register<Rotate3DTransform, double>(nameof(CenterY));
/// <summary>
/// Defines the <see cref="CenterZ"/> property.
/// </summary>
public static readonly StyledProperty<double> CenterZProperty =
AvaloniaProperty.Register<Rotate3DTransform, double>(nameof(CenterZ));
/// <summary>
/// Defines the <see cref="Depth"/> property.
/// </summary>
public static readonly StyledProperty<double> DepthProperty =
AvaloniaProperty.Register<Rotate3DTransform, double>(nameof(Depth));
/// <summary>
/// Initializes a new instance of the <see cref="Rotate3DTransform"/> class.
/// </summary>
public Rotate3DTransform()
{
this.GetObservable(RotationXProperty).Subscribe(_ => RaiseChanged());
this.GetObservable(RotationYProperty).Subscribe(_ => RaiseChanged());
this.GetObservable(RotationZProperty).Subscribe(_ => RaiseChanged());
this.GetObservable(CenterXProperty).Subscribe(_ => RaiseChanged());
this.GetObservable(CenterYProperty).Subscribe(_ => RaiseChanged());
this.GetObservable(CenterZProperty).Subscribe(_ => RaiseChanged());
}
/// <summary>
/// Initializes a new instance of the <see cref="Rotate3DTransform"/> class.
/// </summary>
/// <param name="rotationX">The rotation around the X-Axis</param>
/// <param name="rotationY">The rotation around the Y-Axis</param>
/// <param name="rotationZ">The rotation around the Z-Axis</param>
/// <param name="centerX">The origin of the X-Axis</param>
/// <param name="centerY">The origin of the Y-Axis</param>
/// <param name="centerZ">The origin of the Z-Axis</param>
public Rotate3DTransform(
double rotationX,
double rotationY,
double rotationZ,
double centerX,
double centerY,
double centerZ) : this()
{
RotationX = rotationX;
RotationY = rotationY;
RotationZ = rotationZ;
CenterX = centerX;
CenterY = centerY;
CenterZ = centerZ;
}
/// <summary>
/// Sets the rotation around the X-Axis
/// </summary>
public double RotationX
{
get => GetValue(RotationXProperty);
set => SetValue(RotationXProperty, value);
}
/// <summary>
/// Sets the rotation around the Y-Axis
/// </summary>
public double RotationY
{
get => GetValue(RotationYProperty);
set => SetValue(RotationYProperty, value);
}
/// <summary>
/// Sets the rotation around the Z-Axis
/// </summary>
public double RotationZ
{
get => GetValue(RotationZProperty);
set => SetValue(RotationZProperty, value);
}
/// <summary>
/// Moves the origin of the X-Axis
/// </summary>
public double CenterX
{
get => GetValue(CenterXProperty);
set => SetValue(CenterXProperty, value);
}
/// <summary>
/// Moves the origin of the Y-Axis
/// </summary>
public double CenterY
{
get => GetValue(CenterYProperty);
set => SetValue(CenterYProperty, value);
}
/// <summary>
/// Moves the origin of the Z-Axis
/// </summary>
public double CenterZ
{
get => GetValue(CenterZProperty);
set => SetValue(CenterZProperty, value);
}
/// <summary>
/// Affects the depth of the rotation effect
/// </summary>
public double Depth
{
get => GetValue(DepthProperty);
set => SetValue(DepthProperty, value);
}
/// <summary>
/// Gets the transform's <see cref="Matrix"/>.
/// </summary>
public override Matrix Value
{
get
{
var matrix44 = Matrix4x4.Identity;
matrix44 *= Matrix4x4.CreateTranslation(-(float)CenterX, -(float)CenterY, -(float)CenterZ);
matrix44 *= Matrix4x4.CreateRotationX((float)Matrix.ToRadians(RotationX));
matrix44 *= Matrix4x4.CreateRotationY((float)Matrix.ToRadians(RotationY));
matrix44 *= Matrix4x4.CreateRotationZ((float)Matrix.ToRadians(RotationZ));
matrix44 *= Matrix4x4.CreateTranslation((float)CenterX, (float)CenterY, (float)CenterZ);
if (Depth != 0)
{
var perspectiveMatrix = Matrix4x4.Identity;
perspectiveMatrix.M34 = -1 / (float)Depth;
matrix44 *= perspectiveMatrix;
}
var matrix = new Matrix(
matrix44.M11,
matrix44.M12,
matrix44.M14,
matrix44.M21,
matrix44.M22,
matrix44.M24,
matrix44.M41,
matrix44.M42,
matrix44.M44);
return matrix;
}
}
}

178
src/Avalonia.Visuals/Media/Transform3D.cs

@ -1,178 +0,0 @@
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> RotationXProperty =
AvaloniaProperty.Register<Transform3D, double>(nameof(RotationX));
/// <summary>
/// Defines the <see cref="RotationY"/> property.
/// </summary>
public static readonly StyledProperty<double> RotationYProperty =
AvaloniaProperty.Register<Transform3D, double>(nameof(RotationY));
/// <summary>
/// Defines the <see cref="RotationZ"/> property.
/// </summary>
public static readonly StyledProperty<double> RotationZProperty =
AvaloniaProperty.Register<Transform3D, double>(nameof(RotationZ));
/// <summary>
/// Defines the <see cref="CenterX"/> property.
/// </summary>
public static readonly StyledProperty<double> CenterXProperty =
AvaloniaProperty.Register<Transform3D, double>(nameof(CenterX));
/// <summary>
/// Defines the <see cref="CenterY"/> property.
/// </summary>
public static readonly StyledProperty<double> CenterYProperty =
AvaloniaProperty.Register<Transform3D, double>(nameof(CenterY));
/// <summary>
/// Defines the <see cref="CenterZ"/> property.
/// </summary>
public static readonly StyledProperty<double> CenterZProperty =
AvaloniaProperty.Register<Transform3D, double>(nameof(CenterZ));
/// <summary>
/// Initializes a new instance of the <see cref="Transform3D"/> class.
/// </summary>
public Transform3D()
{
this.GetObservable(RotationXProperty).Subscribe(_ => RaiseChanged());
this.GetObservable(RotationYProperty).Subscribe(_ => RaiseChanged());
this.GetObservable(RotationZProperty).Subscribe(_ => RaiseChanged());
this.GetObservable(CenterXProperty).Subscribe(_ => RaiseChanged());
this.GetObservable(CenterYProperty).Subscribe(_ => RaiseChanged());
this.GetObservable(CenterXProperty).Subscribe(_ => RaiseChanged());
this.GetObservable(CenterYProperty).Subscribe(_ => RaiseChanged());
this.GetObservable(CenterZProperty).Subscribe(_ => RaiseChanged());
}
/// <summary>
/// Initializes a new instance of the <see cref="Transform3D"/> class.
/// </summary>
/// <param name="rotationX">The rotation around the X-Axis</param>
/// <param name="rotationY">The rotation around the Y-Axis</param>
/// <param name="rotationZ">The rotation around the Z-Axis</param>
/// <param name="originCenterX">The origin of the X-Axis</param>
/// <param name="originCenterY">The origin of the Y-Axis</param>
/// <param name="originCenterZ">The origin of the Z-Axis</param>
public Transform3D(
double rotationX,
double rotationY,
double rotationZ,
double originCenterX,
double originCenterY,
double originCenterZ) : this()
{
RotationX = rotationX;
RotationY = rotationY;
RotationZ = rotationZ;
CenterX = originCenterX;
CenterY = originCenterY;
CenterZ = originCenterZ;
}
/// <summary>
/// Sets the rotation around the X-Axis
/// </summary>
public double RotationX
{
get => GetValue(RotationXProperty);
set => SetValue(RotationXProperty, value);
}
/// <summary>
/// Sets the rotation around the Y-Axis
/// </summary>
public double RotationY
{
get => GetValue(RotationYProperty);
set => SetValue(RotationYProperty, value);
}
/// <summary>
/// Sets the rotation around the Z-Axis
/// </summary>
public double RotationZ
{
get => GetValue(RotationZProperty);
set => SetValue(RotationZProperty, value);
}
/// <summary>
/// Moves the origin of the X-Axis
/// </summary>
public double CenterX
{
get => GetValue(CenterXProperty);
set => SetValue(CenterXProperty, value);
}
/// <summary>
/// Moves the origin of the Y-Axis
/// </summary>
public double CenterY
{
get => GetValue(CenterYProperty);
set => SetValue(CenterYProperty, value);
}
/// <summary>
/// Moves the origin of the Z-Axis
/// </summary>
public double CenterZ
{
get => GetValue(CenterZProperty);
set => SetValue(CenterZProperty, value);
}
/// <summary>
/// Gets the transform's <see cref="Matrix"/>.
/// </summary>
public override Matrix Value
{
get
{
var matrix44 = Matrix4x4.Identity;
matrix44 *= Matrix4x4.CreateTranslation(-(float)CenterX, -(float)CenterY, -(float)CenterZ);
matrix44 *= Matrix4x4.CreateRotationX((float)Matrix.ToRadians(RotationX));
matrix44 *= Matrix4x4.CreateRotationY((float)Matrix.ToRadians(RotationY));
matrix44 *= Matrix4x4.CreateRotationZ((float)Matrix.ToRadians(RotationZ));
matrix44 *= Matrix4x4.CreateTranslation((float)CenterX, (float)CenterY, (float)CenterZ);
var perspectiveMatrix = Matrix4x4.Identity;
perspectiveMatrix.M34 = -1 / (float)50;
matrix44 *= perspectiveMatrix;
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…
Cancel
Save