Vue d’ensemble des graphiques 3D

La fonctionnalité 3D dans Windows Presentation Foundation (WPF) permet aux développeurs de dessiner, transformer et animer des graphiques 3D dans le code de balisage et de procédure. Les développeurs peuvent combiner des graphiques 2D et 3D pour créer des contrôles enrichis, fournir des illustrations complexes de données ou améliorer l’expérience utilisateur de l’interface d’une application. La prise en charge 3D dans WPF n’est pas conçue pour fournir une plateforme de développement de jeux complète. Cette rubrique fournit une vue d’ensemble des fonctionnalités 3D dans le système graphique WPF.

3D dans un conteneur 2D

Le contenu graphique 3D dans WPF est encapsulé dans un élément, Viewport3D, qui 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 WPF. Viewport3D fonctionne comme une fenêtre, un port d’affichage, dans une scène tridimensionnelle. Plus précisément, il s’agit d’une surface sur laquelle une scène 3D est projetée.

Dans une application 2D conventionnelle, utilisez Viewport3D comme vous le feriez pour un autre élément conteneur tel que Grid ou Canvas. 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. Cette rubrique vous explique comment dessiner des graphiques 3D à l’intérieur de la Viewport3D.

Espace de coordonnées 3D

Le système de coordonnées WPF pour les graphiques 2D localise l’origine en haut à gauche de la zone 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 la zone de rendu, 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.

systèmes de coordonnées
Représentations de système de coordonnées 2D et 3D conventionnelles

L’espace défini par ces axes est le cadre stationnaire de référence pour les objets 3D dans WPF. Lorsque vous créez des modèles dans cet espace et créez des lumières et des caméras pour les afficher, il est utile de distinguer ce cadre stationnaire de référence, ou « espace monde », du cadre local de référence que vous créez pour chaque modèle lorsque vous appliquez des transformations à celui-ci. N’oubliez pas aussi que les objets dans l’espace mondial peuvent sembler entièrement différents, ou ne pas être visibles du tout, en fonction des paramètres de lumière et de caméra, mais la position de la caméra ne change pas l’emplacement des objets dans l’espace mondial.

Caméras et projections

Les développeurs qui travaillent en 2D sont habitués à positionner les primitives de dessin sur un écran à deux dimensions. Lorsque vous créez une scène 3D, il est important de vous rappeler que vous créez vraiment une représentation 2D d’objets 3D. Étant donné qu’une scène 3D semble différente en fonction du point de vue du spectateur, vous devez spécifier ce point de vue. La classe Camera vous permet de spécifier ce point de vue pour une scène 3D.

Une autre façon de comprendre comment une scène 3D est représentée sur une surface 2D consiste à décrire la scène comme une projection sur l’aire d’affichage. Le ProjectionCamera vous permet de spécifier différentes projections et leurs propriétés pour modifier la façon dont le spectateur voit les modèles 3D. Une PerspectiveCamera spécifie une projection qui raccourcit la scène. En d’autres termes, la PerspectiveCamera fournit une perspective de point de fuite. Vous pouvez spécifier la position de la caméra dans l’espace de coordonnées de la scène, la direction et le champ de vue de la caméra et un vecteur qui définit la direction de « haut » dans la scène. Le diagramme suivant illustre la projection de la PerspectiveCamera.

Les propriétés NearPlaneDistance et FarPlaneDistance de ProjectionCamera limitent la plage de projection de la caméra. Étant donné que les caméras peuvent être situées n’importe où dans la scène, il est possible que la caméra soit réellement positionnée à l’intérieur d’un modèle ou très près d’un modèle, ce qui rend difficile de distinguer correctement les objets. NearPlaneDistance vous permet de spécifier une distance minimale de la caméra au-delà de laquelle les objets ne seront pas dessinés. À l’inverse, FarPlaneDistance vous permet de spécifier une distance de la caméra au-delà de laquelle les objets ne seront pas dessinés, ce qui garantit que les objets trop éloignés pour être reconnaissables ne seront pas inclus dans la scène.

configuration de la caméra
Position de la caméra

OrthographicCamera spécifie une projection orthogonale d’un modèle 3D à une surface visuelle 2D. Comme d’autres caméras, elle spécifie une position, une direction d’affichage et une direction « vers le haut ». Contrairement à PerspectiveCamera, toutefois, OrthographicCamera décrit une projection qui n’inclut pas de perspective par raccourci. En d'autres termes, OrthographicCamera décrit une boîte d'affichage dont les côtés sont parallèles, au lieu d'une boîte dont les côtés se rejoignent en un point devant la caméra. L’image suivante montre le même modèle que celui affiché à l’aide de PerspectiveCamera et de OrthographicCamera.

Projection orthographique et en perspective
Projections en perspective et orthographiques

Le code suivant montre certains paramètres de caméra classiques.

// Defines the camera used to view the 3D object. In order to view the 3D object,
// the camera must be positioned and pointed such that the object is within view
// of the camera.
PerspectiveCamera myPCamera = new PerspectiveCamera();

// Specify where in the 3D scene the camera is.
myPCamera.Position = new Point3D(0, 0, 2);

// Specify the direction that the camera is pointing.
myPCamera.LookDirection = new Vector3D(0, 0, -1);

// Define camera's horizontal field of view in degrees.
myPCamera.FieldOfView = 60;

// Asign the camera to the viewport
myViewport3D.Camera = myPCamera;
' Defines the camera used to view the 3D object. In order to view the 3D object,
' the camera must be positioned and pointed such that the object is within view 
' of the camera.
Dim myPCamera As New PerspectiveCamera()

' Specify where in the 3D scene the camera is.
myPCamera.Position = New Point3D(0, 0, 2)

' Specify the direction that the camera is pointing.
myPCamera.LookDirection = New Vector3D(0, 0, -1)

' Define camera's horizontal field of view in degrees.
myPCamera.FieldOfView = 60

' Asign the camera to the viewport
myViewport3D.Camera = myPCamera

Modèle et primitives de maillage

Model3D est la classe de base abstraite qui représente un objet 3D générique. Pour créer une scène 3D, vous avez besoin de certains objets à afficher et les objets qui composent le graphique de scène dérivent de Model3D. Actuellement, WPF prend en charge la modélisation de géométries avec GeometryModel3D. La propriété Geometry de ce modèle accepte une primitive de maillage.

Pour créer un modèle, commencez par créer une primitive ou un maillage. Une primitive 3D est une collection de sommets qui forment une seule entité 3D. La plupart des systèmes 3D fournissent des primitives modélisées sur la figure fermée la plus simple : un triangle défini par trois sommets. Étant donné que les trois points d’un triangle sont coplanaires, vous pouvez continuer à ajouter des triangles pour modéliser des formes plus complexes, appelées maillages.

Le système WPF 3D fournit actuellement la classe MeshGeometry3D, qui vous permet de spécifier n’importe quelle géométrie ; elle ne prend actuellement pas en charge les primitives 3D prédéfinies comme les sphères et les formes cubes. Commencez à créer un MeshGeometry3D en spécifiant une liste de sommets de triangle comme propriété Positions. Chaque vertex est spécifié en tant que Point3D. (En XAML, spécifiez cette propriété en tant que liste de nombres regroupés en trois qui représentent les coordonnées de chaque vertex.) Selon sa géométrie, votre maillage peut être composé de nombreux triangles, dont certains partagent les mêmes angles (sommets). Pour dessiner correctement le maillage, wpF a besoin d’informations sur les sommets partagés par les triangles. Vous fournissez ces informations en spécifiant une liste d’index triangles avec la propriété TriangleIndices. Cette liste spécifie l’ordre dans lequel les points spécifiés dans la liste Positions déterminent un triangle.

<GeometryModel3D>
  <GeometryModel3D.Geometry>
          <MeshGeometry3D 
              Positions="-1 -1 0  1 -1 0  -1 1 0  1 1 0"
              Normals="0 0 1  0 0 1  0 0 1  0 0 1"
              TextureCoordinates="0 1  1 1  0 0  1 0   "
              TriangleIndices="0 1 2  1 3 2" />
      </GeometryModel3D.Geometry>
      <GeometryModel3D.Material>
          <DiffuseMaterial>
              <DiffuseMaterial.Brush>
                  <SolidColorBrush Color="Cyan" Opacity="0.3"/>
              </DiffuseMaterial.Brush>
          </DiffuseMaterial>
      </GeometryModel3D.Material>
  <!-- Translate the plane. -->
      <GeometryModel3D.Transform>
          <TranslateTransform3D
            OffsetX="2" OffsetY="0" OffsetZ="-1"   >
          </TranslateTransform3D>
      </GeometryModel3D.Transform>
  </GeometryModel3D>

Dans l’exemple précédent, la liste Positions spécifie quatre sommets pour définir un maillage de rectangle. La propriété TriangleIndices spécifie une liste de deux groupes de trois index. Chaque nombre de la liste fait référence à un décalage dans la liste Positions. Par exemple, les trois premiers sommets spécifiés par la liste Positions sont (-1,-1,0), (1,-1,0)et (-1,1,0). Les trois premiers index spécifiés par la liste TriangleIndices sont 0, 1 et 2, qui correspondent au premier, deuxième et troisième points de la liste Positions. Par conséquent, le premier triangle qui compose le modèle rectangle sera composé de (-1,-1,0) à (1,-1,0) à (-1,1,0), et le deuxième triangle sera déterminé de la même façon.

Vous pouvez continuer à définir le modèle en spécifiant des valeurs pour les propriétés Normals et TextureCoordinates. Pour afficher la surface du modèle, le système graphique a besoin d’informations sur la direction vers laquelle la surface est exposée à un triangle donné. Il utilise ces informations pour effectuer des calculs d’éclairage pour le modèle : les surfaces qui font face directement vers une source de lumière apparaissent plus brillantes que celles inclinées loin de la lumière. Bien que WPF puisse déterminer les vecteurs normaux par défaut à l’aide des coordonnées de position, vous pouvez également spécifier différents vecteurs normaux pour estimer l’apparence des surfaces courbes.

La propriété TextureCoordinates spécifie une collection de Points qui indiquent au système graphique comment mapper les coordonnées qui déterminent comment une texture est dessinée aux sommets du maillage. TextureCoordinates sont spécifiées comme valeur comprise entre zéro et 1, inclus. Comme avec la propriété Normals, le système graphique peut calculer les coordonnées de texture par défaut, mais vous pouvez choisir de définir différentes coordonnées de texture pour contrôler le mappage d’une texture qui inclut une partie d’un modèle répétitif, par exemple. Vous trouverez plus d’informations sur les coordonnées de texture dans les rubriques suivantes ou dans le Kit de développement logiciel (SDK) Direct3D managé.

L’exemple suivant montre comment créer un visage du modèle de cube dans le code procédural. Vous pouvez dessiner l’intégralité du cube sous la forme d’une seule GeometryModel3D; Cet exemple montre comment dessiner le visage du cube en tant que modèle distinct afin d’appliquer des textures distinctes à chaque visage ultérieurement.

MeshGeometry3D side1Plane = new MeshGeometry3D();
Private side1Plane As New MeshGeometry3D()
side1Plane.Positions.Add(new Point3D(-0.5, -0.5, -0.5));
side1Plane.Positions.Add(new Point3D(-0.5, 0.5, -0.5));
side1Plane.Positions.Add(new Point3D(0.5, 0.5, -0.5));
side1Plane.Positions.Add(new Point3D(0.5, 0.5, -0.5));
side1Plane.Positions.Add(new Point3D(0.5, -0.5, -0.5));
side1Plane.Positions.Add(new Point3D(-0.5, -0.5, -0.5));

side1Plane.TriangleIndices.Add(0);
side1Plane.TriangleIndices.Add(1);
side1Plane.TriangleIndices.Add(2);
side1Plane.TriangleIndices.Add(3);
side1Plane.TriangleIndices.Add(4);
side1Plane.TriangleIndices.Add(5);

side1Plane.Normals.Add(new Vector3D(0, 0, -1));
side1Plane.Normals.Add(new Vector3D(0, 0, -1));
side1Plane.Normals.Add(new Vector3D(0, 0, -1));
side1Plane.Normals.Add(new Vector3D(0, 0, -1));
side1Plane.Normals.Add(new Vector3D(0, 0, -1));
side1Plane.Normals.Add(new Vector3D(0, 0, -1));

side1Plane.TextureCoordinates.Add(new Point(1, 0));
side1Plane.TextureCoordinates.Add(new Point(1, 1));
side1Plane.TextureCoordinates.Add(new Point(0, 1));
side1Plane.TextureCoordinates.Add(new Point(0, 1));
side1Plane.TextureCoordinates.Add(new Point(0, 0));
side1Plane.TextureCoordinates.Add(new Point(1, 0));
side1Plane.Positions.Add(New Point3D(-0.5, -0.5, -0.5))
side1Plane.Positions.Add(New Point3D(-0.5, 0.5, -0.5))
side1Plane.Positions.Add(New Point3D(0.5, 0.5, -0.5))
side1Plane.Positions.Add(New Point3D(0.5, 0.5, -0.5))
side1Plane.Positions.Add(New Point3D(0.5, -0.5, -0.5))
side1Plane.Positions.Add(New Point3D(-0.5, -0.5, -0.5))

side1Plane.TriangleIndices.Add(0)
side1Plane.TriangleIndices.Add(1)
side1Plane.TriangleIndices.Add(2)
side1Plane.TriangleIndices.Add(3)
side1Plane.TriangleIndices.Add(4)
side1Plane.TriangleIndices.Add(5)

side1Plane.Normals.Add(New Vector3D(0, 0, -1))
side1Plane.Normals.Add(New Vector3D(0, 0, -1))
side1Plane.Normals.Add(New Vector3D(0, 0, -1))
side1Plane.Normals.Add(New Vector3D(0, 0, -1))
side1Plane.Normals.Add(New Vector3D(0, 0, -1))
side1Plane.Normals.Add(New Vector3D(0, 0, -1))

side1Plane.TextureCoordinates.Add(New Point(1, 0))
side1Plane.TextureCoordinates.Add(New Point(1, 1))
side1Plane.TextureCoordinates.Add(New Point(0, 1))
side1Plane.TextureCoordinates.Add(New Point(0, 1))
side1Plane.TextureCoordinates.Add(New Point(0, 0))
side1Plane.TextureCoordinates.Add(New Point(1, 0))

'

Application de matériaux au modèle

Pour qu’un maillage ressemble à un objet tridimensionnel, il doit avoir une texture appliquée pour couvrir la surface définie par ses sommets et triangles afin qu’elle puisse être allumée et projetée par la caméra. En 2D, vous utilisez la classe Brush pour appliquer des couleurs, des motifs, des dégradés ou d’autres contenus visuels aux zones de l’écran. Toutefois, l’apparence des objets 3D est une fonction du modèle d’éclairage, pas seulement de la couleur ou du motif appliqué à ces objets. Les objets réels reflètent la lumière différemment en fonction de la qualité de leurs surfaces : les surfaces brillantes et brillantes ne ressemblent pas aux surfaces rugueuses ou mates, et certains objets semblent absorber la lumière tandis que d’autres brillent. Vous pouvez appliquer tous les mêmes pinceaux aux objets 3D que vous pouvez appliquer aux objets 2D, mais vous ne pouvez pas les appliquer directement.

Pour définir les caractéristiques de la surface d’un modèle, WPF utilise la classe abstraite Material. Les sous-classes concrètes de Material déterminent certaines des caractéristiques d’apparence de la surface du modèle, et chacune fournit également une propriété Brush à laquelle vous pouvez passer un SolidColorBrush, TileBrush ou VisualBrush.

  • DiffuseMaterial spécifie que le pinceau sera appliqué au modèle comme si ce modèle était allumé de manière diffuse. L’utilisation de DiffuseMaterial ressemble le plus à celle de pinceaux directement sur des modèles 2D ; les surfaces des modèles ne reflètent pas la lumière comme si elles étaient brillantes.

  • SpecularMaterial spécifie que le pinceau sera appliqué au modèle comme si la surface du modèle était dure ou brillante, capable de refléter les surbrillances. Vous pouvez définir le degré auquel la texture suggérera cette qualité réfléchissante, ou « briller », en spécifiant une valeur pour la propriété SpecularPower.

  • EmissiveMaterial vous permet de spécifier que la texture sera appliquée comme si le modèle émetait une lumière égale à la couleur du pinceau. Cela ne rend pas le modèle lumineux ; toutefois, il joue un rôle différent dans l’ombrage qu’il ne le ferait s’il était texturé avec DiffuseMaterial ou SpecularMaterial.

Pour de meilleures performances, les faces arrière d’un GeometryModel3D (ces faces hors de vue parce qu’elles sont sur le côté opposé du modèle par rapport à la caméra) sont éliminées de la scène. Pour spécifier une Material à appliquer à la face arrière d’un modèle comme un plan, définissez la propriété BackMaterial du modèle.

Pour obtenir des qualités de surface, comme des effets lumineux ou réfléchissants, vous pouvez appliquer plusieurs pinceaux différents à un modèle en succession. Vous pouvez appliquer et réutiliser plusieurs matériaux à l’aide de la classe MaterialGroup. Les enfants du MaterialGroup sont appliqués du premier au dernier en plusieurs passes de rendu.

Les exemples de code suivants montrent comment appliquer une couleur unie et un dessin en tant que pinceaux aux modèles 3D.

<GeometryModel3D.Material>
    <DiffuseMaterial>
        <DiffuseMaterial.Brush>
            <SolidColorBrush Color="Cyan" Opacity="0.3"/>
        </DiffuseMaterial.Brush>
    </DiffuseMaterial>
</GeometryModel3D.Material>
<DrawingBrush x:Key="patternBrush" Viewport="0,0,0.1,0.1" TileMode="Tile">
  <DrawingBrush.Drawing>
    <DrawingGroup>
      <DrawingGroup.Children>
        <GeometryDrawing Geometry="M0,0.1 L0.1,0 1,0.9, 0.9,1z"
          Brush="Gray" />
        <GeometryDrawing Geometry="M0.9,0 L1,0.1 0.1,1 0,0.9z"
          Brush="Gray" />
        <GeometryDrawing Geometry="M0.25,0.25 L0.5,0.125 0.75,0.25 0.5,0.5z"
          Brush="#FFFF00" />
        <GeometryDrawing Geometry="M0.25,0.75 L0.5,0.875 0.75,0.75 0.5,0.5z"
          Brush="Black" />
        <GeometryDrawing Geometry="M0.25,0.75 L0.125,0.5 0.25,0.25 0.5,0.5z"
          Brush="#FF0000" />
        <GeometryDrawing Geometry="M0.75,0.25 L0.875,0.5 0.75,0.75 0.5,0.5z"
          Brush="MediumBlue" />
      </DrawingGroup.Children>
    </DrawingGroup>
  </DrawingBrush.Drawing>
</DrawingBrush>
DiffuseMaterial side5Material = new DiffuseMaterial((Brush)Application.Current.Resources["patternBrush"]);
Dim side5Material As New DiffuseMaterial(CType(Application.Current.Resources("patternBrush"), Brush))

Éclairant la scène

Les lumières dans les graphiques 3D font ce que font les lumières dans le monde réel : elles rendent les surfaces visibles. Plus précisément, les lumières déterminent la partie d'une scène qui sera incluse dans la projection. Les objets lumineux dans WPF créent une variété d’effets de lumière et d’ombre et sont modélisés après le comportement de diverses lumières réelles. Incluez au moins une lumière dans votre scène, ou aucun modèle ne sera visible.

Les lumières suivantes dérivent de la classe de base Light:

  • AmbientLight: fournit un éclairage ambiant qui illumine tous les objets uniformément, quel que soit leur emplacement ou leur orientation.

  • DirectionalLight: illumine comme une source de lumière distante. Les lumières directionnelles ont une Direction spécifiée en tant que Vector3D, mais pas d’emplacement spécifié.

  • PointLight: illumine comme une source de lumière proche. Les PointLights ont une position et convertissent la lumière à partir de cette position. Les objets de la scène sont éclairés en fonction de leur position et de leur distance par rapport à la lumière. PointLightBase expose une propriété Range, qui détermine une distance au-delà de laquelle les modèles ne seront pas éclairés par la lumière. PointLight expose également les propriétés d’atténuation, qui déterminent comment l’intensité de la lumière diminue sur la distance. Vous pouvez spécifier des interpolations constantes, linéaires ou quadratiques pour l’atténuation de la lumière.

  • SpotLight: hérite de PointLight. Les projecteurs illuminent comme PointLight et ont à la fois position et direction. Ils projetent la lumière dans une zone en forme de cône définie par InnerConeAngle et OuterConeAngle propriétés, spécifiées en degrés.

Les lumières sont des objets Model3D, ce qui permet de transformer et d'animer leurs propriétés, notamment la position, la couleur, la direction et la portée.

<ModelVisual3D.Content>
    <AmbientLight Color="#333333" />
</ModelVisual3D.Content>
DirectionalLight myDirLight = new DirectionalLight();
Private myDirLight As New DirectionalLight()
myDirLight.Color = Colors.White;
myDirLight.Direction = new Vector3D(-3, -4, -5);
myDirLight.Color = Colors.White
myDirLight.Direction = New Vector3D(-3, -4, -5)
modelGroup.Children.Add(myDirLight);
modelGroup.Children.Add(myDirLight)

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 sommets qui définissent eux-mêmes les modèles. Au lieu de cela, comme en 2D, vous appliquez des transformations aux modèles.

Chaque objet de modèle a une propriété Transform avec laquelle vous pouvez déplacer, réorienter ou redimensionner le modèle. Lorsque vous appliquez une transformation, vous décalerez efficacement tous les points du modèle par le vecteur ou la valeur spécifié par la transformation. En d’autres termes, vous avez transformé l’espace de coordonnées dans lequel le modèle est défini (« espace 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 monde »).

Pour plus d’informations sur la transformation de modèles, consultez Vue d’ensemble des transformations 3D.

Animation de modèles

L’implémentation WPF 3D 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 les propriétés des primitives, mais il est généralement plus facile d’animer des transformations qui changent la position ou l’apparence des modèles. Étant donné que les transformations peuvent être appliquées à des objets Model3DGroup ainsi qu’à des modèles individuels, il est possible d’appliquer un ensemble d’animations à un enfant d’un Model3DGroup et à un autre ensemble d’animations à un groupe d’objets enfants. Vous pouvez également obtenir un large éventail d’effets visuels en animant les propriétés de l’éclairage de votre scène. Enfin, vous pouvez choisir d’animer la projection elle-même en animant la position de la caméra ou le champ de vue. Pour plus d’informations sur le système de minutage et d’animation WPF, consultez la Vue d’ensemble de l’animation, Vue d'ensemble des storyboards, et Vue d'ensemble des objets Freezable.

Pour animer un objet dans WPF, vous créez une 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. É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 de Viewport3D.

Supposons que vous souhaitez faire osciller un modèle. Vous pouvez choisir d’appliquer une RotateTransform3D au modèle et d’animer l’axe de sa rotation d’un vecteur à un autre. L’exemple de code suivant montre comment appliquer une Vector3DAnimation à la propriété Axis de la Rotation3D de la transformation, en supposant que RotateTransform3D est une des multiples 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
myRotateTransform.Rotation.BeginAnimation(AxisAngleRotation3D.AxisProperty, myVectorAnimation);
myRotateTransform.Rotation.BeginAnimation(AxisAngleRotation3D.AxisProperty, myVectorAnimation)
//Add transformation to the model
cube1TransformGroup.Children.Add(myRotateTransform);
'Add transformation to the model
cube1TransformGroup.Children.Add(myRotateTransform)

Ajouter du contenu 3D à la fenêtre

Pour afficher la scène, ajoutez des modèles et des lumières à un Model3DGroup, puis définissez le Model3DGroup comme Content d’un ModelVisual3D. Ajoutez le ModelVisual3D à la collection Children du Viewport3D. Ajoutez des caméras au Viewport3D en définissant sa propriété Camera.

Enfin, ajoutez la Viewport3D à la fenêtre. Lorsque le Viewport3D est inclus comme contenu d’un élément de disposition tel que Canvas, spécifiez la taille du Viewport3D en définissant ses propriétés Height et Width (héritées de FrameworkElement).

<UserControl x:Class="HostingWpfUserControlInWf.UserControl1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    >
  
    <Grid>

      <!-- Place a Label control at the top of the view. -->
      <Label 
                HorizontalAlignment="Center" 
                TextBlock.TextAlignment="Center" 
                FontSize="20" 
                Foreground="Red" 
                Content="Model: Cone"/>

      <!-- Viewport3D is the rendering surface. -->
      <Viewport3D Name="myViewport" >

        <!-- Add a camera. -->
        <Viewport3D.Camera>
          <PerspectiveCamera 
                        FarPlaneDistance="20" 
                        LookDirection="0,0,1" 
                        UpDirection="0,1,0" 
                        NearPlaneDistance="1" 
                        Position="0,0,-3" 
                        FieldOfView="45" />
        </Viewport3D.Camera>

        <!-- Add models. -->
        <Viewport3D.Children>

          <ModelVisual3D>
            <ModelVisual3D.Content>

              <Model3DGroup >
                <Model3DGroup.Children>

                  <!-- Lights, MeshGeometry3D and DiffuseMaterial objects are added to the ModelVisual3D. -->
                  <DirectionalLight Color="#FFFFFFFF" Direction="3,-4,5" />

                  <!-- Define a red cone. -->
                  <GeometryModel3D>

                    <GeometryModel3D.Geometry>
                      <MeshGeometry3D 
    Positions="0.293893 -0.5 0.404509  0.475528 -0.5 0.154509  0 0.5 0  0.475528 -0.5 0.154509  0 0.5 0  0 0.5 0  0.475528 -0.5 0.154509  0.475528 -0.5 -0.154509  0 0.5 0  0.475528 -0.5 -0.154509  0 0.5 0  0 0.5 0  0.475528 -0.5 -0.154509  0.293893 -0.5 -0.404509  0 0.5 0  0.293893 -0.5 -0.404509  0 0.5 0  0 0.5 0  0.293893 -0.5 -0.404509  0 -0.5 -0.5  0 0.5 0  0 -0.5 -0.5  0 0.5 0  0 0.5 0  0 -0.5 -0.5  -0.293893 -0.5 -0.404509  0 0.5 0  -0.293893 -0.5 -0.404509  0 0.5 0  0 0.5 0  -0.293893 -0.5 -0.404509  -0.475528 -0.5 -0.154509  0 0.5 0  -0.475528 -0.5 -0.154509  0 0.5 0  0 0.5 0  -0.475528 -0.5 -0.154509  -0.475528 -0.5 0.154509  0 0.5 0  -0.475528 -0.5 0.154509  0 0.5 0  0 0.5 0  -0.475528 -0.5 0.154509  -0.293892 -0.5 0.404509  0 0.5 0  -0.293892 -0.5 0.404509  0 0.5 0  0 0.5 0  -0.293892 -0.5 0.404509  0 -0.5 0.5  0 0.5 0  0 -0.5 0.5  0 0.5 0  0 0.5 0  0 -0.5 0.5  0.293893 -0.5 0.404509  0 0.5 0  0.293893 -0.5 0.404509  0 0.5 0  0 0.5 0  " 
    Normals="0.7236065,0.4472139,0.5257313  0.2763934,0.4472138,0.8506507  0.5308242,0.4294462,0.7306172  0.2763934,0.4472138,0.8506507  0,0.4294458,0.9030925  0.5308242,0.4294462,0.7306172  0.2763934,0.4472138,0.8506507  -0.2763934,0.4472138,0.8506507  0,0.4294458,0.9030925  -0.2763934,0.4472138,0.8506507  -0.5308242,0.4294462,0.7306172  0,0.4294458,0.9030925  -0.2763934,0.4472138,0.8506507  -0.7236065,0.4472139,0.5257313  -0.5308242,0.4294462,0.7306172  -0.7236065,0.4472139,0.5257313  -0.858892,0.429446,0.279071  -0.5308242,0.4294462,0.7306172  -0.7236065,0.4472139,0.5257313  -0.8944269,0.4472139,0  -0.858892,0.429446,0.279071  -0.8944269,0.4472139,0  -0.858892,0.429446,-0.279071  -0.858892,0.429446,0.279071  -0.8944269,0.4472139,0  -0.7236065,0.4472139,-0.5257313  -0.858892,0.429446,-0.279071  -0.7236065,0.4472139,-0.5257313  -0.5308242,0.4294462,-0.7306172  -0.858892,0.429446,-0.279071  -0.7236065,0.4472139,-0.5257313  -0.2763934,0.4472138,-0.8506507  -0.5308242,0.4294462,-0.7306172  -0.2763934,0.4472138,-0.8506507  0,0.4294458,-0.9030925  -0.5308242,0.4294462,-0.7306172  -0.2763934,0.4472138,-0.8506507  0.2763934,0.4472138,-0.8506507  0,0.4294458,-0.9030925  0.2763934,0.4472138,-0.8506507  0.5308249,0.4294459,-0.7306169  0,0.4294458,-0.9030925  0.2763934,0.4472138,-0.8506507  0.7236068,0.4472141,-0.5257306  0.5308249,0.4294459,-0.7306169  0.7236068,0.4472141,-0.5257306  0.8588922,0.4294461,-0.27907  0.5308249,0.4294459,-0.7306169  0.7236068,0.4472141,-0.5257306  0.8944269,0.4472139,0  0.8588922,0.4294461,-0.27907  0.8944269,0.4472139,0  0.858892,0.429446,0.279071  0.8588922,0.4294461,-0.27907  0.8944269,0.4472139,0  0.7236065,0.4472139,0.5257313  0.858892,0.429446,0.279071  0.7236065,0.4472139,0.5257313  0.5308242,0.4294462,0.7306172  0.858892,0.429446,0.279071  "                   TriangleIndices="0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 " />
                    </GeometryModel3D.Geometry>

                    <GeometryModel3D.Material>
                      <DiffuseMaterial>
                        <DiffuseMaterial.Brush>
                          <SolidColorBrush 
                            Color="Red" 
                            Opacity="1.0"/>
                        </DiffuseMaterial.Brush>
                      </DiffuseMaterial>
                    </GeometryModel3D.Material>

                  </GeometryModel3D>

                </Model3DGroup.Children>
              </Model3DGroup>

            </ModelVisual3D.Content>

          </ModelVisual3D>

        </Viewport3D.Children>

      </Viewport3D>
    </Grid>
  
</UserControl>

Voir aussi