Profitez de ce titre dès maintenant, et de millions d'autres, avec un essai gratuit

Seulement $9.99/mois après l'essai. Annulez à tout moment.

Manuel d'apprentissage de la programmation 3D: avec C#5, WPF et Visual Studio 2013

Manuel d'apprentissage de la programmation 3D: avec C#5, WPF et Visual Studio 2013

Lire l'aperçu

Manuel d'apprentissage de la programmation 3D: avec C#5, WPF et Visual Studio 2013

Longueur:
969 pages
9 heures
Sortie:
Aug 13, 2015
ISBN:
9782322000739
Format:
Livre

Description

Ce manuel d'apprentissage s’adresse au développeur et au programmeur, débutant et faux débutant, qui souhaite découvrir et approfondir la modélisation 3D au travers de la programmation et de l’animation des modèles 3D dans un environnement complet 3D (avec C#, XAML et WPF).
Par l'intermédiaire d'un ensemble de 50 projets applicatifs, le lecteur pourra se familiariser avec la programmation 3D, en utilisant la géométrie vectorielle et le calcul matriciel, en apprenant à modéliser des objets 3D, à les insérer dans la scène 3D, et à visualiser la scène 3D sous différents angles grâce aux manipulations 3D.
Sortie:
Aug 13, 2015
ISBN:
9782322000739
Format:
Livre

À propos de l'auteur

Patrice REY est informaticien et formateur indépendant, diplômé en informatique et certifié Microsoft MCTS. Passionné par les technologies Microsoft Silverlight, WPF et DirectX, spécialiste du langage C#, adepte des langages C++, Java et Python, programmeur passionné des API 3D, il vous fait partager sa passion pour le développement et la programmation des applications au travers de cet ouvrage.


Lié à Manuel d'apprentissage de la programmation 3D

Livres associé

Articles associés

Aperçu du livre

Manuel d'apprentissage de la programmation 3D - Patrice Rey

tous.

1

Réaliser une application avec une zone de rendu 3D

La solution de projet P01_ApplicationZoneRendu.sln, placée dans le dossier P01_ApplicationZoneRendu, implémente une application WPF basique composée d'un menu avec des onglets et d'une zone de rendu 3D destinée à restituer une scène 3D composée d'objets 3D modélisés.

Lors de ce premier projet, vous allez apprendre dans un premier temps à créer un projet d'application avec WPF, dans un second temps à ajouter une zone de rendu de type Viewport3D en XAML, et dans un troisième temps à personnaliser une caméra de type PerspectiveCamera pour visualiser une projection 2D d'un contenu 3D.

1.1 - Démarrer un projet applicatif WPF

Pour réaliser une application WPF, il faut commencer par créer un nouveau projet (figure 1.1) en choisissant dans le menu Fichier la rubrique Nouveau -> Projet … (ou bien par le raccourci clavier Ctrl+Maj+N).

FIGURE 1.1

Une fenêtre intitulée Nouveau projet (figure 1.2) s'ouvre pour configurer le type d'application ainsi que différents paramètres. Sur le côté gauche, on commence par cliquer sur la rubrique des modèles Visual C# installés et par choisir le type de modèle installé Bureau Windows (repère 1). On cible un environnement de développement en choisissant le framework .NET 4.5 dans la liste déroulante (repère 2). Au milieu de la fenêtre, la liste des modèles installés qui correspondent aux paramètres choisis s'affiche. Et dans cette liste on sélectionne le modèle Application WPF (repère 3) en cliquant dessus (le modèle est alors surligné dans la liste et une information s'affiche côté droit sur ce qu'il représente). Dans le champ Nom au repère 4, on inscrit le nom que l'on souhaite donner à notre application (ici on inscrit P01_ApplicationZoneRendu par exemple). En cliquant sur le bouton Parcourir au repère 5, une boite de dialogue standard s'ouvre pour sélectionner un emplacement physique sur le disque pour le stockage de la solution de projet. Si l'on souhaite que Visual Studio génère un répertoire portant le nom de la solution et dans lequel il placera tous les fichiers générés, il faut alors cocher la case créer un répertoire pour la solution (repère 6). A noter que nous cocherons systématiquement cette case pour tous les projets réalisés au cours de cet ouvrage. En cliquant sur le bouton OK, Visual Studio procède à l'initialisation du projet. En cliquant sur la fenêtre de l'explorateur de solutions, la solution de projet intitulée P01_ApplicationZoneRendu (correspondant au fichier P01_ApplicationZoneRendu.sln dans le répertoire) est affichée sous forme d'une arborescence de dossiers et de fichiers (repère 7). Les fichiers App.xaml et App.xaml.cs lancent le processus de démarrage de l'application WPF par l'affichage d'une fenêtre de type MainWindow. Le fichier MainWindow.xaml représente la définition XAML de la fenêtre de l'application et le fichier MainWindow.xaml.cs représente le code de programmation C# associé (repère 8).

FIGURE 1.2

La fenêtre créée par le fichier de définition XAML MainWindow.xaml est une fenêtre de type MainWindow héritant de la classe Window. La figure 1.3 visualise un diagramme partiel d'héritage pour la classe MainWindow de façon à mieux appréhender la personnalisation des propriétés de la fenêtre. La fenêtre de type MainWindow se personnalise:

en fixant la propriété héritée Title pour définir le titre affiché de la fenêtre.

en fixant la propriété héritée WindowStartupLocation pour définir la position de la fenêtre lors de son premier affichage; la valeur énumérée CenterScreen indique que l'emplacement de démarrage d'un objet Window correspond au centre de l'écran qui contient le curseur de la souris.

en fixant la propriété héritée ResizeMode pour définir le mode de redimensionnement; la valeur énumérée CanMinimize définit une fenêtre qui peut être uniquement réduite et rétablie; les icones des boutons Réduire et Agrandir sont affichés, mais seul l'icone du bouton Réduire est activé.

en fixant les propriétés héritées Width et Height pour définir les dimensions globales de la fenêtre sur le bureau.

en ajoutant un gestionnaire pour l'événement Loaded qui se produit lorsque l'élément est exposé, rendu, et prêt pour l'interaction.

FIGURE 1.3

x:Name=x_fenetre x:Class=P01_ApplicationZoneRendu.MainWindow

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

Title=P01 Zone Rendu 3D Height=767 Width=827

WindowStartupLocation=CenterScreen Loaded=x_fenetre_Loaded

ResizeMode=CanMinimize>

Dans la fenêtre, l'espace disponible permet de positionner différents contrôles en fonction de ses choix. On choisit de remplir cet espace en positionnant un contrôle x_grid_root de type Grid qui définit une grille flexible qui est composée de colonnes et de lignes. On souhaite que cette grille soit composée d'une colonne et de deux lignes. Pour ajouter une colonne, on développe la propriété ColumnDefinitions de Grid en XAML par et on ajoute un objet de type ColumnDefinition par . Une colonne est personnalisée par sa largeur avec la propriété Width dont on fixe soit une valeur en pixels (par exemple Width = 700 pour une largeur de 700 pixels), soit une valeur * comme par exemple avec Width = * où le sigle * représente la valeur énumérée GridUnitType.Star (la valeur est exprimée sous la forme d'une proportion pondérée d'espace disponible). La colonne unique s'étendra en largeur sur tout l'espace disponible. Pour ajouter une ligne, on développe la propriété RowDefinitions de Grid en XAML par et on ajoute un objet de type RowDefinition par . Une ligne est personnalisée par sa hauteur avec sa propriété Height dont on affecte une valeur en pixels ou une valeur de proportion (avec *). Ici, on définit la première ligne avec une hauteur de 140 pixels et la seconde ligne avec une hauteur occupant l'espace disponible restant.

x:Name=x_fenetre x:Class=P01_ApplicationZoneRendu.MainWindow

Title=P01 Zone Rendu 3D Height=767 Width=827

WindowStartupLocation=CenterScreen Loaded=x_fenetre_Loaded

ResizeMode=CanMinimize>

x:Name=x_grid_root >

140>

*>

*>

Notre grille se compose d'une colonne et de deux lignes. On positionne dans la cellule de la première ligne et de la première colonne un menu x_ruban de type Ribbon. Un objet Ribbon représente l'élément racine d'une interface utilisateur du ruban qui héberge une barre d'outils à accès rapide, un menu d'application, et des onglets (style de menu apparu avec Office 2007). Ce menu sera placé dans la première et unique colonne en affectant la valeur 0 à la propriété attachée Grid.Column. Ce menu sera placé dans la première ligne en affectant la valeur 0 à la propriété attachée Grid.Row. A noter que les index des lignes et colonnes commencent à la valeur 0. La figure 1.4 visualise le résultat obtenu.

FIGURE 1.4

x:Name=x_fenetre x:Class=P01_ApplicationZoneRendu.MainWindow

Title=P01 Zone Rendu 3D Height=767 Width=827

WindowStartupLocation=CenterScreen Loaded=x_fenetre_Loaded

ResizeMode=CanMinimize>

x:Name=x_grid_root >

140>

*>

*>

x:Name=x_ruban SelectedIndex=0 FontSize=14 FontFamily=Verdana

Grid.Column=0 Grid.Row=0>

La fermeture de l'application s'exécute traditionnellement en cliquant sur la croix blanche sur fond rouge en haut et à droite de la fenêtre. Pour personnaliser l'application, nous ajoutons dans le ruban une rubrique Quitter comme le montre la figure 1.5. Un objet Ribbon possède un menu d'application de type RibbonApplicationMenu qui s'affiche en cliquant dessus (menu d'application schématisé par une flèche blanche sur fond bleu en haut et à gauche). La propriété SmallImageSource personnalise le logo à afficher pour représenter ce menu d'application (ici on utilise le fichier image contenu/image/accueil.png).

x_ruban SelectedIndex=0 FontSize=14 FontFamily=Verdana

Grid.Column=0 Grid.Row=0>

KeyTip=F SmallImageSource=contenu/image/accueil.png>

FIGURE 1.5

Un objet RibbonApplicationMenu contient un ensemble de rubriques de type RibbonApplicationMenuItem, les rubriques définissant la composition du menu d'application. Pour ajouter une rubrique Quitter, on ajoute un objet de type RibbonApplicationMenuItem et on personnalise ses propriétés avec la propriété Header qui affiche le nom de la rubrique et la propriété ImageSource qui référence le fichier image à utiliser pour personnaliser la rubrique ajoutée. On ajoute un gestionnaire pour l'événement Click dont l'implémentation consiste à appeler la méthode Close de MainWindow (provoquant la fermeture de la fenêtre par un arrêt de l'application).

x_ruban SelectedIndex=0 FontSize=14 FontFamily=Verdana

Grid.Column=0 Grid.Row=0>

KeyTip=F SmallImageSource=contenu/image/accueil.png>

x:Name=x_rubrique_quitter Header=Quitter

ImageSource=contenu/image/quitter.png Click=x_rubrique_quitter_Click/>

private void x_rubrique_quitter_Click(object sender, RoutedEventArgs e) {

this.Close();

}

1.2 - Ajouter un contrôle de type Viewport3D

La cellule de la première colonne et de la seconde ligne va contenir la zone de rendu 2D de la scène 3D. On positionne dans cette cellule un objet Border en fixant les propriétés attachées Grid.Column à 0 et Grid.Row à 1. La propriété Background, affectée de la valeur LightSkyBlue, représente le fond de remplissage de l'objet Border dont ses dimensions s'étendent sur toute la surface de la cellule par défaut. Un objet Border ne peut héberger qu'un seul élément qui est affecté à sa propriété Child (propriété implicite en XAML). L'élément affecté peut être un simple contrôle ou bien une collection de contrôles hébergés dans un conteneur.

x:Name=x_border_3d Background=LightSkyBlue BorderBrush=Black

BorderThickness=0 Grid.Column=0 Grid.Row=1>

On affecte à la propriété Child de Border (propriété implicite en XAML) un objet Viewport3D qui restitue le contenu 3D dans ses limites de disposition 2D. Cela se traduit en XAML par le code minimal ci-dessous avec l'ajout de x_vp3d_rendu_3d de type Viewport3D:

x:Name=x_border_3d Background=LightSkyBlue BorderBrush=Black

BorderThickness=0 Grid.Column=0 Grid.Row=1>

x:Name=x_vp3d_rendu_3d ClipToBounds=True >

Essayons de comprendre ce que représente l'objet Viewport3D et son utilisation au travers de différentes illustrations. Supposons que l'on ait réalisé la scène 3D de la figure 1.6, scène qui est composée d'un ensemble d'objets 3D avec un plateau, un cube, un cylindre, une sphère, un tore et un cylindre tronqué. L'origine O du repère (XYZ) se trouve au centre du plateau. Cette scène 3D est une scène 3D réaliste dans laquelle on a positionné des objets en utilisant des coordonnées 3D (chaque point ayant une coordonnée x suivant l'axe X, une coordonnée y suivant l'axe Y et une coordonnée z suivant l'axe Z). L'objet Viewport3D est un contrôle qui restitue dans ses dimensions 2D le contenu de la scène 3D qu'il héberge. Pour obtenir une représentation 2D d'un contenu 3D, il faut 3 choses: un point de vue, un plan de près et un plan de loin.

FIGURE 1.6

Le point de vue est l'endroit où l'œil de l'observateur se positionne pour regarder la scène 3D. Ce point de vue est caractérisé par une position 3D dans le repère (XYZ), par une direction du regard (droite qui passe par l'œil et l'origine O du repère), et par une inclinaison. La figure 1.7 schématise par exemple l'œil de l'observateur avec:

sa position qui est de coordonnées x=0, y=0 et z=3,

sa direction du regard qui est représentée par le vecteur (0,0,-3); donc l'œil fixe l'origine du repère.

son inclinaison qui est représentée par le vecteur (0,1,0) c'est-à-dire un vecteur parallèle à l'axe Y du côté positif.

FIGURE 1.7

Le deuxième élément nécessaire est un plan de près. Il s'agit d'un plan positionné à une certaine distance de l'œil de l'observateur (distance appelée distance de près). La figure 1.8 schématise la configuration dans laquelle le plan de près se trouve à 2 unités de l'observateur. A noter que le plan de près est perpendiculaire à la direction du regard et que son inclinaison est identique à celle de l'observateur.

FIGURE 1.8

Le troisième élément nécessaire est un plan de loin. Il s'agit d'un plan positionné à une certaine distance de l'œil de l'observateur (distance appelée distance de loin). La figure 1.9 schématise la configuration. A noter que le plan de loin est perpendiculaire à la direction du regard et que son inclinaison est identique à celle de l'observateur.

FIGURE 1.9

Maintenant que nous avons tous les éléments nécessaires qui sont positionnés (le point de vue, le plan de près et le plan de loin), on peut déterminer un volume d'observation en fonction d'un champ de vision horizontal choisi. Classiquement on choisit la valeur de 45 degrés par défaut. Un champ de vision de valeur supérieure permettra de voir plus de choses par augmentation du volume d'observation et de valeur inférieure permettra de voir moins de choses par diminution du volume d'observation. La figure 1.10 schématise la configuration du volume d'observation.

FIGURE 1.10

Tous les objets 3D se trouvant dans le volume d'observation sont projetés sur le plan de près. Toutes les parties des objets 3D se trouvant hors du volume d'observation ne font pas l'objet de projection sur le plan de près. Cela permet donc d'obtenir une projection 2D d'un environnement 3D en fonction du point de vue, du plan de près, du plan de loin et du champ de vision. Le plan de près est en fait le contrôle Viewport3D qui restitue dans ses dimensions 2D le contenu 3D se trouvant dans le volume d'observation. A noter que nous traitons ici du cas de la projection de type projection perspective (il existe aussi un autre type avec la projection parallèle).

Le diagramme de classes de la figure 1.11 visualise partiellement ce qu'il faut retenir de la classe Viewport3D. Le contrôle Viewport3D hérite de la classe FrameworkElement, et par conséquent il peut être ajouté en XAML. Ses propriétés héritées Width et Height définissent les dimensions 2D d'affichage du contrôle. Sa propriété héritée Name permet de lui assigner un nom de référencement en XAML. Ses propriétés héritées HorizontalAlignment et VerticalAlignment permettent de réaliser les alignements du contrôle quand il est hébergé dans un conteneur parent. Sa propriété héritée Resources permet de stocker des ressources pour une utilisation partagée. La propriété propre Camera de Viewport3D stocke la définition de la caméra dont les paramètres permettent d'établir un rendu 2D du volume d'observation 3D. La propriété Children de Viewport3D est une collection d'objets Visual3D qui stocke la définition des objets 3D sur la scène. Cette propriété Children est une propriété implicite en XAML donc l'écriture peut être omise. Le code ci-dessous définit un code XAML que l'on utilise pour la définition d'un contrôle Viewport3D.

x:Name=x_vp3d_rendu_3d ClipToBounds=True >

Camera>

Children>

FIGURE 1.11

1.3 - Ajouter une caméra de type PerspectiveCamera

La propriété Camera de Viewport3D stocke les paramètres qui permettent d'obtenir un rendu 2D d'une scène 3D. Une caméra n'est rien d'autre que l'œil de l'observateur comme on l'a vu avec les explications des figures 1.7 à 1.10. La caméra définit la projection 2D d'une scène 3D. Il existe deux types de caméras: le type PerspectiveCamera et le type OrthographicCamera.

La classe OrthographicCamera définit une projection orthographique sans perspective. La vue ressemble à une photo prise de loin avec un téléobjectif à grande focale. Les dimensions de la représentation d'un élément sont fixes et indépendantes de sa position. La classe PerspectiveCamera définit une projection avec de la perspective c'est-à-dire contenant un point vers lequel convergent toutes les lignes de fuite. Les figures 1.7 à 1.10 utilisent une projection perspective. La figure 1.12 montre une scène 3D obtenue par une projection orthographique côté gauche (avec une caméra de type OrthographicCamera) et par une projection perspective côté droit (avec une caméra de type PerspectiveCamera).

FIGURE 1.12

Les classes PerspectiveCamera et OrthographicCamera dérivent de la classe abstraite ProjectionCamera. Ces deux classes partagent les propriétés suivantes: Position, LookDirection, UpDirection, NearPlaneDistance et FarPlaneDistance. La propriété Position de type Point3D définit la position de la caméra en coordonnées universelles. La propriété LookDirection de type Vector3D définit la direction de visée de la caméra sous forme d'un vecteur en coordonnées universelles. La propriété UpDirection de type Vector3D est un vecteur qui indique l'inclinaison de la caméra. Par défaut, sa valeur est (0,1,0) ce qui signifie que la verticale de l'image correspond à l'axe Y, valeurs positives vers le haut. Les propriétés NearPlaneDistance et FarPlaneDistance, de type double, permettent d'indiquer les limites de la zone de rendu des éléments visuels respectivement à l'avant-plan et à l'arrière-plan par rapport à la caméra. Les parties des éléments au-delà des limites sont invisibles (parties n'appartenant pas au volume d'observation). Les valeurs par défaut sont respectivement 0.125 et plus l'infini. Ce qui caractérise une projection de type perspective c'est le champ de vision horizontal. La propriété FieldOfView de PerspectiveCamera détermine le champ de vision horizontal de la caméra. L'effet est similaire au zoom d'un appareil photo: une valeur élevée correspond à une vue de type grand-angle et une valeur faible correspond à une vue de type téléobjectif. La figure 1.13 visualise le diagramme partiel de la classe PerspectiveCamera de façon à mieux voir où quelles sont les propriétés propres et les propriétés héritées.

FIGURE 1.13

Dans notre exemple, on ajoute une caméra de type PerspectiveCamera que l'on nomme x_camera en XAML et dont on personnalise:

son emplacement par la propriété Position de type Point3D avec l'écriture Position=0,4,6.

sa direction de visée par la propriété LookDirection de type Vector3D avec l'écriture LookDirection=0,-4,-6.

son inclinaison par la propriété UpDirection de type Vector3D avec l'écriture UpDirection=0,1,0.

la distance de son plan de près par la propriété NearPlaneDistance de type double avec l'écriture NearPlaneDistance=1.

la distance de son plan de loin par la propriété FarPlaneDistance de type double avec l'écriture FarPlaneDistance=50.

son champ de vision horizontal par la propriété FieldOfView de type double avec l'écriture FieldOfView=40.

x:Name=x_vp3d_rendu_3d ClipToBounds=True >

Camera>

x:Name=x_camera Position=0,4,6 LookDirection=0,-4,-6

UpDirection=0,1,0 FieldOfView=40 NearPlaneDistance=1 FarPlaneDistance=50>

Children>

1.4 - Afficher les paramètres de la zone de rendu

Il est souvent nécessaire de pouvoir visualiser les caractéristiques de la zone de rendu de type Viewport3D et de la caméra utilisée de type PerspectiveCamera. Pour cela on ajoute un bouton dans le ruban des menus dans l'onglet Accueil (figure 1.14 au repère 1). Le ruban des menus de type Ribbon est constitué d'onglets de type RibbonTab. La propriété Header de RibbonTab visualise le contenu à afficher pour spécifier une étiquette à l'onglet. Ce contenu est de type object et peut donc représenter n'importe quel objet. A l'intérieur d'un onglet de type RibbonTab, on positionne des groupes de type RibbonGroup dont la propriété Header spécifie l'étiquette à afficher. On ajoute un groupe avec une étiquette Infos dans lequel on positionne un bouton x_ong1_btn_infos de type Button. On personnalise ce bouton en affectant à sa propriété Content une image qui référence le fichier graphique contenu/image/img_infos_camera.png placé en ressource dans l'application (par la propriété ImageSource de Image). En fixant la valeur Hand à la propriété Cursor, au survol du bouton, le curseur prend la forme d'une main avec l'index pointé. En affectant la chaîne Paramètres du rendu 3D à la propriété ToolTip, cette chaîne s'affiche pendant quelques secondes lorsque le pointeur de la souris se trouve sur le bouton (figure 1.14 au repère 2). Le gestionnaire de l'événement Click permet d'afficher un Grid x_grid_infos_rendu_3d, doté d'un fond de remplissage semi-transparent à base de bleu, et affichant au centre un TextBlock x_tbl_grid_rendu_3d pour visualiser des informations au format texte. Le passage au mode visible se fait en affectant à la propriété Visibility de Grid la valeur Visible, et le passage au mode masqué se fait en affectant à la propriété Visibility de Grid la valeur Hidden.

FIGURE 1.14

x_ruban SelectedIndex=0 FontSize=14 FontFamily=Verdana

Grid.Column=0 Grid.Row=0>

F SmallImageSource=contenu/image/accueil.png>

x_rubrique_quitter Header=Quitter

ImageSource=contenu/image/quitter.png Click=x_rubrique_quitter_Click/>

Header=Accueil >

Infos>

HorizontalAlignment=Center VerticalAlignment=Center ToolTip="Paramètres du rendu

3D Click=x_ong1_btn_infos_Click">

contenu/image/img_infos_camera.png Stretch=None Width=54

Height=54 HorizontalAlignment=Center VerticalAlignment=Center>

Quand la fenêtre de l'application s'affiche (événement Loaded), on fixe explicitement les dimensions du Viewport3D en affectant à sa propriété Width la valeur de sa largeur quand le rendu du contrôle est effectué (propriété ActualWidth), et en affectant à sa propriété Height la valeur de sa hauteur quand le rendu du contrôle est effectué (propriété ActualHeight). Pour afficher le nom donné en XAML au Viewport3D, il faut lui appliquer la méthode GetValue en lui passant en paramètre la propriété de dépendance NameProperty par l'écriture x_vp3d_rendu_3d.GetValue(NameProperty).ToString(). Les dimensions sont obtenues en lisant les propriétés Width et Height.

private void x_fenetre_Loaded(object sender, RoutedEventArgs e) {

x_vp3d_rendu_3d.Width = x_vp3d_rendu_3d.ActualWidth;

x_vp3d_rendu_3d.Height = x_vp3d_rendu_3d.ActualHeight;

}

private void x_ong1_btn_infos_Click(object sender, RoutedEventArgs e) {

x_grid_infos_rendu_3d.Visibility = Visibility.Visible;

x_tbl_grid_rendu_3d.Text = ;

x_tbl_grid_rendu_3d.Text += Viewport3D propriété Name (string) ->

+ x_vp3d_rendu_3d.GetValue(NameProperty).ToString() + RC;

x_tbl_grid_rendu_3d.Text += Viewport3D dimensions relevées ->

+ x_vp3d_rendu_3d.ActualWidth.ToString()

+ par + x_vp3d_rendu_3d.ActualHeight.ToString() + pixels + RC;

x_tbl_grid_rendu_3d.Text += Viewport3D propriétés Width/Height->

+ x_vp3d_rendu_3d.Width.ToString()

+ par + x_vp3d_rendu_3d.Height.ToString() + pixels + RC;

}

Pour fixer à la caméra x_camera le nom x_camera donné en XAML, il faut lui appliquer la méthode SetValue en lui passant en paramètre le nom de la propriété de dépendance NameProperty et la chaîne x_camera. Lors de l'affichage de ses caractéristiques, l'obtention de son nom s'effectue avec la méthode GetValue qui reçoit en paramètre la propriété de dépendance NameProperty. On obtient sa position en lisant le Point3D de sa propriété Position. On obtient sa direction de visée en lisant le Vector3D de sa propriété LookDirection. On obtient son inclinaison en lisant le Vector3D de sa propriété UpDirection. On obtient les distances de près et de loin, de type double, en lisant les propriétés NearPlaneDistance et FarPlaneDistance. On obtient le champ de vision en lisant la propriété FieldOfView de type double.

private void x_fenetre_Loaded(object sender, RoutedEventArgs e) {

x_camera.SetValue(NameProperty, x_camera);

}

private void x_ong1_btn_infos_Click(object sender, RoutedEventArgs e) {

x_tbl_grid_rendu_3d.Text += caméra propriété Name (string) ->

+ x_camera.GetValue(NameProperty).ToString() + RC;

x_tbl_grid_rendu_3d.Text += caméra propriété Position (Point3D) ->

+ MfTexte(x_camera.Position) + RC;

x_tbl_grid_rendu_3d.Text += caméra propriété LookDirection (Vector3D) ->

+ MfTexte(x_camera.LookDirection) + RC;

x_tbl_grid_rendu_3d.Text += caméra propriété UpDirection (Vector3D) ->

+ MfTexte(x_camera.UpDirection) + RC;

x_tbl_grid_rendu_3d.Text += caméra propriété FieldOfView (double) ->

+ x_camera.FieldOfView.ToString(0.00) + RC;

x_tbl_grid_rendu_3d.Text += caméra propriété NearPlaneDistance (double) ->

+ x_camera.NearPlaneDistance.ToString(0.00) + RC;

x_tbl_grid_rendu_3d.Text += caméra propriété FarPlaneDistance (double) ->

+ x_camera.FarPlaneDistance.ToString(0.00) + RC;

}

On s'aide de la méthode MfTexte pour mettre en forme une sortie texte quand l'objet passé en paramètre est de type Point3D et Vector3D.

private string MfTexte(object objet_passe) {

string aff = ;

if (objet_passe.GetType() == typeof(Point3D)) {

Point3D p3d = (Point3D)objet_passe;

aff += ( + p3d.X.ToString(0.00).Replace(',', '.') + ,;

aff += p3d.Y.ToString(0.00).Replace(',', '.') + ,;

aff += p3d.Z.ToString(0.00).Replace(',', '.') + );

}

if (objet_passe.GetType() == typeof(Vector3D)) {

Vector3D v3d = (Vector3D)objet_passe;

aff += ( + v3d.X.ToString(0.00).Replace(',', '.') + ,;

aff += v3d.Y.ToString(0.00).Replace(',', '.') + ,;

aff += v3d.Z.ToString(0.00).Replace(',', '.') + );

}

return aff;

}

2

Définir une surface triangulaire

La solution de projet P02_SurfaceTriangulaire.sln, placée dans le dossier P02_SurfaceTriangulaire, implémente la modélisation d'une facette triangulaire qui représente l'élément surfacique fondamental de tous les maillages. Les facettes triangulaires modélisées auront leurs surfaces peintes avec une couleur unie.

Cette deuxième fiche est consacrée à la modélisation de la facette triangulaire qui représente l'élément surfacique élémentaire de tous les maillages. Nous commencerons dans un premier temps à nous familiariser avec le repère des coordonnées universelles. Puis, dans un second temps, nous verrons comment ajouter un éclairage à la scène pour que les objets soient illuminés. Dans un troisième temps, nous modéliserons un maillage triangulaire avec sa surface extérieure peinte. Et dans un quatrième temps, nous verrons comment modifier les paramètres de la caméra pour obtenir un point de vue différent de la scène 3D.

2.1 - Le repère des coordonnées universelles

Dans un système à 3 dimensions, un point est représenté par ses coordonnées selon les 3 axes X, Y et Z. Dans le repère 3D utilisé par WPF, depuis l’origine O du repère, l’axe X des abscisses positives part vers la droite, l’axe Y des ordonnées positives part vers le haut, et l’axe Z des coordonnées positives part vers l’extérieur et devant. Ces 3 axes peuvent être représentés au moyen des doigts d’une main: le pouce représente l’axe des X, l’index représente l’axe des Y et le majeur représente l’axe des Z. L’axe des X est généralement dirigé vers la droite et l’axe des Y est généralement dirigé vers le haut. Pour la direction de l’axe des Z, WPF utilise le système dit de la main droite (figure 2.1) dans lequel l’axe des Z est dirigé vers l’avant (il sort de l’écran).

FIGURE 2.1

2.2 - L’éclairage de la scène

Dans une scène 3D, les objets 3D ne peuvent être vus que s'il y a un éclairage adéquat pour les illuminer. L’éclairage est géré par des objets dérivés de la classe de base abstraite Light. La figure 2.2 visualise l’arbre d’héritage de la classe Light qui dérive de la classe Model3D. WPF gère l’éclairage par un objet Model3D d’un type particulier, invisible, utilisé pour calculer les couleurs restituées des éléments de la scène. C’est pour cette raison que l’objet Light hérite directement de la classe Model3D.

FIGURE 2.3

La classe abstraite Light possède un ensemble de classes dérivées avec:

la classe DirectionLight qui représente une lumière qui projette son effet dans une direction spécifiée par un Vector3D.

la classe AmbientLight qui représente une lumière ambiante qui applique uniformément de la lumière sur tous les objets, indépendamment de leur forme, de leur positionnement sur la scène et de leur inclinaison.

la classe PointLightBase, qui est une classe de base abstraite, représente un objet lumière comportant une position dans l’espace et projetant sa lumière dans toutes les directions.

La classe abstraite PointLightBase possède comme classes dérivées:

la classe PointLight qui représente une source de lumière qui a une position spécifiée dans l’espace et qui projette sa lumière dans toutes les directions.

la classe SpotLight qui représente une lumière qui projette son effet dans une zone conique selon une direction spécifiée.

Tous ces objets représentant un éclairage, expose la propriété Color qui définit la couleur de l’éclairage. L’objet AmbientLight produit un éclairage uniforme, sans ombre, dont sa position est indéterminée. L’objet DirectionalLight produit un éclairage similaire aux rayons solaires. Les rayons sont parallèles comme s’ils provenaient d’une source très éloignée. Sa position d’éclairage est indéterminée et sa propriété Direction détermine l’orientation des rayons lumineux au moyen d’un vecteur de type Vector3D. Généralement la puissance de l’éclairage directionnel est fixe. La seule façon de l’augmenter consiste à positionner plusieurs objets DirectionLight. Les objets PointLight et SpotLight produisent un éclairage similaire à une lampe d’intérieur qui rayonne autour d’une position donnée. Ces deux objets exposent principalement les propriétés suivantes:

Position qui définit l’emplacement de la source d’éclairage (une position de type Point3D).

Range qui représente la portée maximale de la source d’éclairage; la portée a une valeur infinie par défaut; les zones en dehors de cette portée ne sont pas éclairées (dans le cas d’une valeur finie pour la portée maximale).

ConstantAttenuation qui représente une valeur de constante par laquelle l’intensité de la lumière diminue sur la distance; en agissant comme un facteur de division, la luminosité de la lampe peut être réduite.

LinearAttenuation qui représente une valeur qui spécifie la diminution linéaire de l’intensité de la lumière sur la distance; en agissant comme un facteur multiplicateur de la distance, la lumière peut être réduite.

QuadraticAttenuation qui représente une valeur qui spécifie la diminution de l’effet de la lumière sur la distance, calculée par une opération quadratique; en agissant comme facteur multiplicateur du carré de la distance, la lumière peut être réduite.

Si l’objet PointLight rayonne dans toutes les directions, l’objet SpotLight, quant à lui, réduit son éclairage à un cône, en exposant des propriétés supplémentaires qui sont:

Direction qui définit un Vector3D qui spécifie la direction dans laquelle l’objet SpotLight projette sa lumière.

OuterConeAngle qui définit un angle qui spécifie la proportion d’une projection conique d’un objet SpotLight en dehors de laquelle la lumière n’éclaire pas les objets dans la scène.

InnerConeAngle qui définit un angle qui spécifie la proportion d’une projection conique d’un objet SpotLight dans laquelle la lumière éclaire entièrement les objets dans la scène.

Pour ajouter un éclairage uniforme, sans ombre, avec une couleur d'éclairage qui soit blanche, on écrira en XAML White> par l'ajout d'un modèle 3D de type AmbientLight et en personnalisant la propriété Color à la valeur White. Le code ci-dessous est celui que l'on utilise dans notre exemple:

x_lum_ambiant>

Color=White>

2.3 - Les classes UIElement3D et Model3D

Avant de poursuivre, il faut faire connaissance avec les classes UIElement3D et Model3D pour comprendre comment on réalise un assemblage pour un objet 3D. La classe abstraite UIElement3D est apparue dans le framework .NET 3.5, et elle est une classe de base pour les implémentations au niveau du noyau WPF reposant sur les éléments de WPF et les caractéristiques de présentation de base. Elle est accompagnée de deux classe dérivées (figure 2.3) qui sont ModelUIElement3D et ContainerUIElement3D. Ces deux classes dérivées offrent une alternative intéressante à la classe ModelVisual3D car elles sont plus évoluées sur le plan fonctionnel et aussi plus spécialisées:

la classe abstraite UIElement3D hérite de Visual3D et apporte une gestion de haut niveau de l’interactivité (gestion du focus, support du clavier, du stylet, du toucher et de la souris); son interface est proche de celle de UIElement (classe de base pour les contrôles 2D).

la classe ModelUIElement3D permet d’afficher un modèle défini par un Model3D (soit avec un GeometryModel3D ou soit avec un Model3DGroup) spécifié dans la propriété Model.

la classe ContainerUIElement3D peut contenir d’autres objets Visual3D spécifiés dans la propriété Children.

FIGURE 2.3

Il existe toujours deux techniques pour créer des modèles composites, mais ici en exploitant deux classes différentes:

soit en assemblant des Visual3D au sein d’un ContainerUIElement3D.

soit en assemblant des Model3D au sein d’un Model3DGroup assigné à la propriété Model d’un ModelUIElement3D.

Le code ci-dessous montre un exemple d’ossature de modèle ModelUIElement3D composite, en XAML, regroupant plusieurs objets GeometryModel3D:

Et le code ci-dessous montre un exemple d’ossature de modèle composite, en XAML, regroupant plusieurs ContainerUIElement3D dans la propriété Children d’un objet hôte de type ContainerUIElement3D:

La classe abstraite Model3D fournit des fonctionnalités pour les modèles 3D. Elle représente une description d’objet 3D. Un objet Model3D peut être utilisé pour restituer le visuel d’un objet Visual3D. Comme le montre l’arbre d’héritage de la figure 2.4, les classes concrètes qui dérivent de Model3D sont:

la classe GeometryModel3D qui définit un modèle basé sur une géométrie 3D.

la classe Model3DGroup qui permet l’utilisation de plusieurs modèles Model3D en tant qu’unité.

la classe abstraite Light qui représente un objet Model3D pour définir l’éclairage appliqué à une scène 3D.

FIGURE 2.4

Un objet GeometryModel3D définit un modèle basé sur une géométrie 3D (figure 2.4). Il sert à réaliser un modèle 3D au moyen de ses propriétés:

Geometry qui représente une géométrie 3D.

Material qui représente une matière pour la face avant spécifiée.

BackMaterial qui représente une matière pour la face arrière spécifiée (propriété facultative).

2.4 - Réalisation d’une facette triangulaire

Un objet GeometryModel3D définit un modèle basé sur une géométrie 3D et sa propriété Geometry, qui représente une géométrie 3D, reçoit un objet dérivé de la classe abstraite Geometry3D. La figure 2.5 visualise l’ensemble de ces relations.

FIGURE 2.5

La classe Geometry3D est une classe abstraite qui sert de classe de base pour la géométrie 3D. Les classes qui dérivent de cette classe de base abstraite définissent des formes géométriques 3D. De plus, la classe des objets Geometry3D peut être utilisée pour le test d’atteinte et pour le rendu des données graphiques 3D. Une géométrie 3D contient les données d’un modèle mais ne sait pas s’afficher elle-même. Le seul type de géométrie héritée de la classe abstraite Geometry3D est le type MeshGeometry3D. La figure 2.5 visualise l’arbre d’héritage de la classe Geometry3D. La classe MeshGeometry3D définit le maillage d’un modèle 3D au moyen

Vous avez atteint la fin de cet aperçu. Inscrivez-vous pour en savoir plus !
Page 1 sur 1

Avis

Ce que les gens pensent de Manuel d'apprentissage de la programmation 3D

0
0 évaluations / 0 Avis
Qu'avez-vous pensé ?
Évaluation : 0 sur 5 étoiles

Avis des lecteurs