Vue d’ensemble des transformations 3D
Cette rubrique explique comment appliquer des transformations à des modèles 3D dans le système graphique WPF (Windows Presentation Foundation). Les transformations permettent au développeur de repositionner, redimensionner et réorienter des modèles sans modifier les valeurs de base qui les définissent.
Espace de coordonnées 3D
Le contenu graphique 3D dans Windows Presentation Foundation (WPF) est encapsulé dans un élément, Viewport3Dqui peut participer à la structure d’élément à deux dimensions. Le système graphique traite Viewport3D comme un élément visuel à deux dimensions comme beaucoup d’autres dans Windows Presentation Foundation (WPF). Viewport3D fonctionne comme une fenêtre, ou plus précisément une fenêtre d’affichage, dans une scène 3D. Plus précisément, il s’agit d’une surface sur laquelle une scène 3D est projetée. Bien que vous puissiez utiliser Viewport3D avec d’autres objets de dessin 2D dans le même graphique de scène, vous ne pouvez pas interagir entre les objets 2D et 3D dans un Viewport3D. Dans la discussion suivante, l’espace de coordonnées décrit est contenu par l’élément Viewport3D.
Le système de coordonnées Windows Presentation Foundation (WPF) pour les graphiques 2D localise l’origine en haut à gauche de l’aire de rendu (généralement l’écran). Dans le système 2D, les valeurs positives de l’axe des x passent à droite et les valeurs positives de l’axe y se poursuivent vers le bas. Dans le système de coordonnées 3D, cependant, l’origine se trouve au centre de l’écran, avec des valeurs d’axe x positives qui passent vers la droite, mais les valeurs de l’axe y positives se poursuivent vers le haut, et les valeurs de l’axe z positif se poursuivent vers l’extérieur de l’origine, vers la visionneuse.
Comparaison du système de coordonnées
L’espace défini par ces axes est le cadre stationnaire de référence pour les objets 3D dans Windows Presentation Foundation (WPF). Lorsque vous générez des modèles dans cet espace et créez des lumières et des caméras pour les consulter, il est utile de distinguer ce frame stationnaire de référence, ou « espace universel » du frame local de référence que vous créez pour chaque modèle lorsque vous lui appliquez des transformations. N’oubliez également pas que les objets dans l’espace universel peuvent sembler entièrement différents, ou ne pas du tout être visibles, en fonction des paramètres de lumière et de caméra, mais que la position de la caméra ne modifie pas l’emplacement des objets dans l’espace universel.
Transformation de modèles
Lorsque vous créez des modèles, ils ont un emplacement particulier dans la scène. Pour déplacer ces modèles dans la scène, pour les faire pivoter ou pour modifier leur taille, il n’est pas pratique de modifier les vertex qui définissent les modèles eux-mêmes. Au lieu de cela, comme en 2D, vous appliquez des transformations aux modèles.
Chaque objet de modèle a une Transform propriété avec laquelle vous pouvez déplacer, réorienter ou redimensionner le modèle. Lorsque vous appliquez une transformation, vous décalez tous les points du modèle par le vecteur ou la valeur que la transformation spécifie. En d’autres termes, vous avez transformé l’espace de coordonnées dans lequel le modèle est défini (« espace de modèle »), mais vous n’avez pas modifié les valeurs qui composent la géométrie du modèle dans le système de coordonnées de la scène entière (« espace universel »).
Transformations de translation
Les transformations 3D héritent de la classe Transform3Dde base abstraite ; elles incluent les classes TranslateTransform3Dde transformation affine, ScaleTransform3Det RotateTransform3D. Le système 3D Windows Presentation Foundation (WPF) fournit également une MatrixTransform3D classe qui vous permet de spécifier les mêmes transformations dans des opérations de matrice plus concises.
TranslateTransform3Ddéplace tous les points du Model3D dans la direction du vecteur de décalage que vous spécifiez avec les propriétés et OffsetZOffsetYles OffsetXpropriétés. Par exemple, en prenant un vertex d’un cube à (2,2,2), un vecteur de décalage de (0, 1,6, 1) déplacerait ce vertex de (2,2,2) à (2, 3,6, 3). Le vertex du cube est toujours (2,2,2) dans l’espace du modèle, mais désormais l’espace du modèle a modifié sa relation à l’espace universel afin que (2,2,2) dans l’espace du modèle soit (2, 3,6, 3) dans l’espace universel.
Translation avec décalage
Les exemples de code suivants montrent comment appliquer une translation.
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
<DockPanel>
<Viewbox>
<Canvas Width="600" Height="201">
<!-- The Viewport3D provides a rendering surface for 3-D visual content. -->
<Viewport3D Name="MyAnimatedObject"
ClipToBounds="True" Width="600" Height="150"
Canvas.Left="0" Canvas.Top="10">
<!-- Defines the camera used to view the 3D object. -->
<Viewport3D.Camera>
<PerspectiveCamera x:Name="myPerspectiveCamera" Position="0,0,2" LookDirection="0,0,-1"
FieldOfView="60" />
</Viewport3D.Camera>
<!-- The ModelVisual3D children contain the 3D models -->
<Viewport3D.Children>
<!-- This ModelVisual3D defines the light cast in the scene. Without light, the
3D object cannot be seen. -->
<ModelVisual3D>
<ModelVisual3D.Content>
<DirectionalLight Color="#FFFFFF" Direction="-0.612372,-0.5,-0.612372" />
</ModelVisual3D.Content>
</ModelVisual3D>
<ModelVisual3D>
<ModelVisual3D.Content>
<GeometryModel3D>
<!-- The geometry specifes the shape of the 3D plane. In this case, a flat sheet is created. -->
<GeometryModel3D.Geometry>
<MeshGeometry3D
TriangleIndices="0,1,2 3,4,5 "
Normals="0,0,1 0,0,1 0,0,1 0,0,1 0,0,1 0,0,1 "
TextureCoordinates="0,0 1,0 1,1 1,1 0,1 0,0 "
Positions="-0.5,-0.5,0.5 0.5,-0.5,0.5 0.5,0.5,0.5 0.5,0.5,0.5 -0.5,0.5,0.5 -0.5,-0.5,0.5 " />
</GeometryModel3D.Geometry>
<!-- The material specifies the material applied to the plane. In this case it is a linear gradient.-->
<GeometryModel3D.Material>
<MaterialGroup>
<DiffuseMaterial>
<DiffuseMaterial.Brush>
<SolidColorBrush Color="Cyan" Opacity="0.3"/>
</DiffuseMaterial.Brush>
</DiffuseMaterial>
</MaterialGroup>
</GeometryModel3D.Material>
<!-- The Transform specifies how to transform the 3D object. The OffsetX property is animated
in the Storyboard below. -->
<GeometryModel3D.Transform>
<TranslateTransform3D x:Name="myTranslateTransform3D" OffsetX="0" OffsetY="0" OffsetZ="0" />
</GeometryModel3D.Transform>
</GeometryModel3D>
</ModelVisual3D.Content>
</ModelVisual3D>
</Viewport3D.Children>
<!-- Trigger the TranslateTransform3D animation when the 3D object loads. -->
<Viewport3D.Triggers>
<EventTrigger RoutedEvent="Viewport3D.Loaded">
<BeginStoryboard>
<Storyboard>
<!-- This animation animates the OffsetX property of the TranslateTransform3D. -->
<DoubleAnimation
Storyboard.TargetName="myTranslateTransform3D"
Storyboard.TargetProperty="OffsetX"
To="-0.8"
AutoReverse="True" RepeatBehavior="Forever" />
<!-- If you want to animate OffsetY and/or OffsetZ, create similar DoubleAnimations
respectively. -->
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Viewport3D.Triggers>
</Viewport3D>
</Canvas>
</Viewbox>
</DockPanel>
</Page>
Transformations d’échelle
ScaleTransform3D modifie l’échelle du modèle par un vecteur d’échelle spécifié avec référence à un point central. Spécifiez une échelle uniforme, qui met à l’échelle du modèle par la même valeur dans les axes X, Y et Z, pour modifier la taille du modèle proportionnellement. Par exemple, la définition des propriétés et ScaleYScaleZ des propriétés de ScaleXla transformation sur 0,5 moitié de la taille du modèle ; la définition des mêmes propriétés sur 2 double son échelle dans les trois axes.
Exemple de ScaleVector
En spécifiant une transformation d’échelle non uniforme, une transformation d’échelle dont les valeurs X, Y et Z ne sont pas toutes les mêmes, vous pouvez provoquer l’étirement ou la contraction d’un modèle dans une ou deux dimensions sans affecter les autres. Par exemple, la valeur ScaleX 1, ScaleY la valeur 2 et ScaleZ la valeur 1 entraîne la double hauteur du modèle transformé, mais reste inchangée le long des axes X et Z.
Par défaut, ScaleTransform3D étire ou contracte les sommets par rapport à l’origine (0,0,0). Si le modèle que vous souhaitez transformer n’est pas tiré de l’origine, toutefois, la mise à l’échelle du modèle à partir de l’origine ne met pas à l’échelle le modèle « en place ». Au lieu de cela, lorsque les sommets du modèle sont multipliés par le vecteur d’échelle, l’opération d’échelle aura l’effet de traduire le modèle et de la mettre à l’échelle.
Exemple de centre de mise à l’échelle
Pour mettre à l’échelle un modèle « en place », spécifiez le centre du modèle en définissant les propriétés et CenterYCenterZ les propriétés de CenterXScaleTransform3D. Cela garantit que le système graphique met à l’échelle l’espace du modèle, puis le traduit en centre sur le système spécifié Point3D. À l’inverse, si vous avez généré le modèle par rapport à l’origine et que vous spécifiez un autre point, attendez-vous à ce que le modèle transformé soit déplacé par rapport à l’origine.
Transformations de rotation
Vous pouvez faire pivoter un modèle en 3D de plusieurs façons différentes. Une rotation classique spécifie un axe et un angle de rotation autour de cet axe. La RotateTransform3D classe vous permet de définir une Rotation3D valeur avec sa Rotation propriété. Vous spécifiez Axis ensuite et Angle les propriétés sur rotation3D, dans ce cas un AxisAngleRotation3D, pour définir la transformation. Les exemples suivants font pivoter un modèle de 60 degrés autour de l’axe Y.
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
<DockPanel>
<Viewbox>
<Canvas Width="321" Height="201">
<!-- The Viewport3D provides a rendering surface for 3-D visual content. -->
<Viewport3D Name="MyAnimatedObject"
ClipToBounds="True" Width="150" Height="150"
Canvas.Left="0" Canvas.Top="10">
<!-- Defines the camera used to view the 3D object. -->
<Viewport3D.Camera>
<PerspectiveCamera x:Name="myPerspectiveCamera" Position="0,0,2" LookDirection="0,0,-1"
FieldOfView="60" />
</Viewport3D.Camera>
<!-- The ModelVisual3D children contain the 3D models -->
<Viewport3D.Children>
<!-- Two ModelVisual3D define the lights cast in the scene. Without light, the
3D object cannot be seen. Also, the direction of the lights affect shadowing. -->
<ModelVisual3D>
<ModelVisual3D.Content>
<DirectionalLight Color="#FFFFFF" Direction="-0.612372,-0.5,-0.612372" />
</ModelVisual3D.Content>
</ModelVisual3D>
<ModelVisual3D>
<ModelVisual3D.Content>
<DirectionalLight Color="#FFFFFF" Direction="0.612372,-0.5,-0.612372" />
</ModelVisual3D.Content>
</ModelVisual3D>
<ModelVisual3D>
<ModelVisual3D.Content>
<GeometryModel3D>
<!-- The geometry specifes the shape of the 3D plane. In this case, a flat sheet is created. -->
<GeometryModel3D.Geometry>
<MeshGeometry3D
TriangleIndices="0,1,2 3,4,5 "
Normals="0,0,1 0,0,1 0,0,1 0,0,1 0,0,1 0,0,1 "
TextureCoordinates="0,0 1,0 1,1 1,1 0,1 0,0 "
Positions="-0.5,-0.5,0.5 0.5,-0.5,0.5 0.5,0.5,0.5 0.5,0.5,0.5 -0.5,0.5,0.5 -0.5,-0.5,0.5 " />
</GeometryModel3D.Geometry>
<!-- The material specifies the material applied to the plane. In this case it is a linear gradient.-->
<GeometryModel3D.Material>
<MaterialGroup>
<DiffuseMaterial>
<DiffuseMaterial.Brush>
<LinearGradientBrush StartPoint="0,0.5" EndPoint="1,0.5">
<LinearGradientBrush.GradientStops>
<GradientStop Color="Yellow" Offset="0" />
<GradientStop Color="Red" Offset="0.25" />
<GradientStop Color="Blue" Offset="0.75" />
<GradientStop Color="LimeGreen" Offset="1" />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</DiffuseMaterial.Brush>
</DiffuseMaterial>
</MaterialGroup>
</GeometryModel3D.Material>
<!-- The Transform specifies how to transform the 3D object. The properties of the
Rotation object are animated causing the 3D object to rotate and "wobble" (see Storyboard below).-->
<GeometryModel3D.Transform>
<RotateTransform3D>
<RotateTransform3D.Rotation>
<AxisAngleRotation3D x:Name="myAngleRotation" Axis="0,3,0" Angle="40" />
</RotateTransform3D.Rotation>
</RotateTransform3D>
</GeometryModel3D.Transform>
</GeometryModel3D>
</ModelVisual3D.Content>
</ModelVisual3D>
</Viewport3D.Children>
<!-- Trigger the rotation animation when the 3D object loads. -->
<Viewport3D.Triggers>
<EventTrigger RoutedEvent="Viewport3D.Loaded">
<BeginStoryboard>
<Storyboard>
<!-- This animation animates the Angle property of the AxisAngleRotation3D
making the 3D object rotate from -60 degrees to 60 degrees. -->
<DoubleAnimation
Storyboard.TargetName="myAngleRotation"
Storyboard.TargetProperty="Angle"
From="-60" To="60" Duration="0:0:4" AutoReverse="True" RepeatBehavior="Forever"/>
<!-- This animation animates the Axis property of the AxisAngleRotation3D
making the 3D wobble as it rotates. -->
<Vector3DAnimation
Storyboard.TargetName="myAngleRotation"
Storyboard.TargetProperty="Axis"
From="0,3,0" To="1,0,1" Duration="0:0:4" AutoReverse="True" RepeatBehavior="Forever"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Viewport3D.Triggers>
</Viewport3D>
</Canvas>
</Viewbox>
</DockPanel>
</Page>
Remarque :Windows Presentation Foundation (WPF) 3D est un système droitier, ce qui signifie qu’une valeur d’angle positive pour une rotation entraîne une rotation dans le sens inverse des aiguilles d’une montre sur l’axe.
Les rotations d’angle d’axe supposent une rotation à propos de l’origine si une valeur n’est pas spécifiée pour le CenterX, CenterYet CenterZ les propriétés sur RotateTransform3D. Comme avec la mise à l’échelle, il est utile de garder l’esprit que la rotation transforme l’espace de coordonnées entier du modèle. Si le modèle n’a pas été créé par rapport à l’origine ou a été déplacé précédemment, la rotation peut « pivoter » autour de l’origine au lieu de tourner sur place.
Rotation avec nouveau centre spécifié
Pour faire pivoter le modèle « sur place », spécifiez le centre réel du modèle en tant que centre de la rotation. Étant donné que la géométrie est généralement modelée par rapport à l’origine, vous pouvez généralement obtenir le résultat attendu d’un ensemble de transformations en redimensionnant d’abord le modèle (par mise à l’échelle), puis en définissant son orientation (par rotation) et enfin en le déplaçant vers l’emplacement souhaité (par translation).
Exemple de rotation
Les rotations axe/angle fonctionnent bien pour les transformations statiques et certaines animations. Toutefois, envisagez la rotation d’un modèle de cube à 60 degrés autour de l’axe X, puis de 45 degrés autour de l’axe Z. Vous pouvez décrire cette transformation sous forme de deux transformations affines discrètes ou de matrice. Toutefois, il peut être difficile d’animer une rotation définie de cette façon. Même si les positions de début et de fin du modèle calculées par les deux approches sont les mêmes, les positions intermédiaires prises par le modèle sont incertaines en matière de calcul. Les quaternions représentent une autre façon de calculer l’interpolation entre le début et la fin d’une rotation.
Un quaternion représente un axe dans l’espace 3D et une rotation autour de cet axe. Par exemple, un quaternion peut représenter un axe (1,1,2) et une rotation de 50 degrés. La capacité des quaternions à définir des rotations vient des opérations que vous pouvez effectuer dessus : composition et interpolation. La composition de deux quaternions appliqués à une géométrie signifie « faire pivoter la géométrie autour de l’axe2 par rotation2, puis la faire pivoter autour de l’axe1 par rotation1 ». En utilisant la composition, vous pouvez combiner les deux rotations sur la géométrie pour obtenir un quaternion unique qui représente le résultat. Étant donné que l’interpolation de quaternion peut calculer un chemin fluide et raisonnable d’un axe et d’une orientation à l’autre, vous pouvez interpoler de du quaternion d’origine vers le quaternion composé pour effectuer une transition en douceur d’un autre à l’autre, ce qui vous permet d’animer la transformation. Pour les modèles que vous souhaitez animer, vous pouvez spécifier une destination Quaternion pour la rotation à l’aide d’une QuaternionRotation3D pour la Rotation propriété.
Utilisation des collections de transformations
Lorsque vous générez une scène, il est courant d’appliquer plusieurs transformations à un modèle. Ajoutez des transformations à la Children collection de la Transform3DGroup classe pour regrouper les transformations de façon pratique pour s’appliquer à différents modèles de la scène. Il est souvent utile de réutiliser une transformation dans plusieurs groupes, de la même façon que vous pouvez réutiliser un modèle en appliquant un ensemble de transformations différent à chaque instance. Notez que l’ordre dans lequel les transformations sont ajoutées à la collection est important : les transformations de la collection sont appliquées de la première à la dernière.
Animation de transformations
L’implémentation 3D de Windows Presentation Foundation (WPF) participe au même système de minutage et d’animation que les graphiques 2D. En d’autres termes, pour animer une scène 3D, animez les propriétés de ses modèles. Il est possible d’animer directement des propriétés de primitives, mais il est généralement plus facile d’animer des transformations qui modifient la position ou l’apparence de modèles. Étant donné que les transformations peuvent être appliquées à des objets ainsi qu’à Model3DGroup des modèles individuels, il est possible d’appliquer un ensemble d’animations aux enfants d’un Model3Dgroup et à un autre ensemble d’animations à un groupe d’objets. Pour plus d’informations sur le minutage et le système d’animation Windows Presentation Foundation (WPF), consultez Vue d’ensemble de l’animation et Vue d’ensemble des storyboards.
Pour animer un objet dans Windows Presentation Foundation (WPF), créez un chronologie, définissez une animation (qui est vraiment une modification de la valeur de propriété au fil du temps) et spécifiez la propriété à laquelle appliquer l’animation. Cette propriété doit être une propriété d’un FrameworkElement. Étant donné que tous les objets d’une scène 3D sont des enfants de Viewport3D, les propriétés ciblées par toute animation que vous souhaitez appliquer à la scène sont des propriétés des propriétés de Viewport3D. Il est important de déterminer le chemin d’accès de la propriété vers l’animation avec précaution, car la syntaxe peut être complexe.
Supposons que vous souhaitez faire pivoter un objet sur place, mais aussi appliquer un mouvement oscillant pour exposer une plus grande partie de l’objet à afficher. Vous pouvez choisir d’appliquer une RotateTransform3D.RotateTransform3D au modèle et animer son axe de rotation d’un vecteur à un autre. L’exemple de code suivant illustre l’application d’une Vector3DAnimation propriété Axis de la rotation3D de la transformation, en supposant que la rotationTransform3D soit l’une des plusieurs transformations appliquées au modèle avec un TransformGroup.
//Define a rotation
RotateTransform3D myRotateTransform = new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 1, 0), 1));
'Define a rotation
Dim myRotateTransform As New RotateTransform3D(New AxisAngleRotation3D(New Vector3D(0, 1, 0), 1))
Vector3DAnimation myVectorAnimation = new Vector3DAnimation(new Vector3D(-1, -1, -1), new Duration(TimeSpan.FromMilliseconds(5000)));
myVectorAnimation.RepeatBehavior = RepeatBehavior.Forever;
Dim myVectorAnimation As New Vector3DAnimation(New Vector3D(-1, -1, -1), New Duration(TimeSpan.FromMilliseconds(5000)))
myVectorAnimation.RepeatBehavior = RepeatBehavior.Forever
Utilisez une syntaxe similaire pour cibler d’autres propriétés de transformation pour déplacer ou redimensionner l’objet. Par exemple, vous pouvez appliquer une Point3DAnimation à la propriété ScaleCenter sur une transformation de mise à l’échelle pour provoquer une déformation fluide d’un modèle.
Bien que les exemples précédents transforment les propriétés de , il est également possible de GeometryModel3Dtransformer les propriétés d’autres modèles dans la scène. En animant des translations appliquées aux objets Light, par exemple, vous pouvez créer des effets de lumière et d’ombre qui peuvent modifier considérablement l’apparence de vos modèles.
Étant donné que les caméras sont également des modèles, il est aussi possible de transformer les propriétés de la caméra. Même si vous pouvez tout à fait modifier l’apparence de la scène en transformant les distances sur le plan de la position de la caméra (en transformant ainsi la projection de scène entière), notez que beaucoup d’effets que vous obtenez de cette façon peuvent ne pas paraître aussi « visuellement cohérents » que les transformations appliquées à l’emplacement ou la position des modèles dans la scène.
Voir aussi
.NET Desktop feedback