Open Inventor
Partie 1

WB01624_.gif (281 octets) RETOUR

Introduction

Open Inventor : couche objet ajoutée à OpenGL pour faciliter la modélisation des scènes à afficher.

Open Inventor : librairie d'objets et de méthodes utilisables pour créer des applications graphiques 3D interactives.

La boite à outils d'Inventor inclut :

(1) des primitives de gestion de base de données de scène composée d'objets (forme, propriétés, groupe et moteur),

(2) un ensemble de noeuds qui autorisent la création de groupes de noeuds prédéfinis,

(3) des manipulateurs interactifs (boite de manipulation et trackball) qui sont des objets présents dans la scène que l'utilisateur peut manipuler interactivement,

(4) la librairie de composants Inventor Xt (visualiseur, éditeur de matériau, éditeur de lumière,...) qui donne accès à des fonctions d'interface de haut niveau.

Open Inventor a été utilisé par SGI comme base pour les spécifications de VRML.

La base de données Inventor

noeud : bloc de construction élémentaire utilisé pour créer une base de données 3D Inventor.

Chaque noeud contient de l'information (matériau de surface, description de forme, transformation géométrique, lumière, caméra,...).

Graphes de scène : scène constituée d'un assemblage de noeuds constitué en graphe.

Base de donnée Inventor : assemblage de plusieurs graphes de scène constituant ainsi une scène globale.

Opérations peuvant être réalisées sur un graphe de scène :

  • rendu,
  • sélection,
  • recherche,
  • calcul de boite englobante,
  • écriture vers un fichier (fichier iv).

Les noeuds peuvent être classés en :

  • noeuds de forme (sphère, cube, cylindre,...),
  • noeuds de propriété (matériau, éclairage, texture,...),
  • noeuds de groupe (séparateur, niveau de détail,...).

Primitives plus spéciales : les moteurs et les senseurs.

Moteur : objet pouvant être connecté à d'autres objets utilisé pour réaliser des animations ou imposer des contraintes inter-objets

Senseur : objet destiné à détecter un changement dans la base de données et à appeller alors une fonction

Manipulateurs

Manipulateur : noeud d'un type spécial destiné à réagir à des événements de l'interface utilisateur et pouvant être édité directement par l'utilisateur.

Exemple : la boite de saisie est une boite englobante munie de poignées aux coins et aux faces.

La librairie de composants d'Inventor

Intégration et support avec le système X-Window:

  • fenêtre de rendu,
  • fonctions réalisant la boucle principale d'affichage et les initialisations (aux)
  • traduction des événements X-Window en événements Inventor
  • éditeurs (matériau, source lumineuse,...)
  • visualiseurs (trajectoire, ...)

L'arbre de classes d'Inventor

Toutes les classes d'Inventor font partie d'un arbre de classes dérivant de la classe SoBase.

Il est possible de dériver soit même de nouvelles classes de toute classe existante.

Exemples

Création d'une fenêtre où une scène sera rendue.

Construction du graphe de scène (un cône) par création de noeuds propriété et forme et leur combinaison en groupes.

#include <Inventor/Xt/SoXt.h>
#include <Inventor/Xt/SoXtRenderArea.h>
#include <Inventor/nodes/SoCone.h>
#include <Inventor/nodes/
          SoDirectionalLight.h>
#include <Inventor/nodes/SoMaterial.h>
#include <Inventor/nodes/
          SoPerspectiveCamera.h>
#include <Inventor/nodes/SoSeparator.h>

main(int , char **argv)
{ Widget myWindow = SoXt::init(argv[0]);
  if (myWindow == NULL)
    exit(1);
  SoSeparator *root = new SoSeparator;
  SoPerspectiveCamera *myCamera =
      new SoPerspectiveCamera;
  SoMaterial *myMaterial = new SoMaterial;
  root->ref();
  root->addChild(myCamera);
  root->addChild(new SoDirectionalLight);
  myMaterial->diffuseColor.setValue(1.0,
                                    0.0,
                                    0.0);
  root->addChild(myMaterial);
  root->addChild(new SoCone);
  SoXtRenderArea *RenderArea =
      new SoXtRenderArea(myWindow);
  myCamera->viewAll(root,
      RenderArea->getViewportRegion());
  RenderArea->setSceneGraph(root);
  RenderArea->setTitle("Hello Cone");
  RenderArea->show();
  SoXt::show(myWindow);
  SoXt::mainLoop();
}

Utilisation d'un moteur pour faire tourner le cône

#include <Inventor/Xt/SoXt.h>
#include <Inventor/Xt/SoXtRenderArea.h>
#include <Inventor/engines/SoElapsedTime.h>
#include <Inventor/nodes/SoCone.h>
#include <Inventor/nodes/
          SoDirectionalLight.h>
#include <Inventor/nodes/SoMaterial.h>
#include <Inventor/nodes/
          SoPerspectiveCamera.h>
#include <Inventor/nodes/SoRotationXYZ.h>
#include <Inventor/nodes/SoSeparator.h>

main(int , char **argv)
{ Widget myWindow = SoXt::init(argv[0]);
  if ( myWindow == NULL )
    exit(1);
  SoSeparator *root = new SoSeparator;
  root->ref();
  SoPerspectiveCamera *myCamera =
      new SoPerspectiveCamera;
  root->addChild(myCamera);
  root->addChild(new SoDirectionalLight);
  SoRotationXYZ *myRotXYZ = new SoRotationXYZ;
  root->addChild(myRotXYZ);
  SoMaterial *myMaterial = new SoMaterial;
  myMaterial->diffuseColor.setValue(1.0,
                                    0.0,
                                    0.0);
  root->addChild(myMaterial);
  root->addChild(new SoCone);
  myRotXYZ->axis = SoRotationXYZ::X;
  SoElapsedTime *myCounter
                = new SoElapsedTime;
  myRotXYZ->angle.connectFrom(&myCounter->
                              timeOut);
  SoXtRenderArea *RenderArea =
      new SoXtRenderArea(myWindow);
  myCamera->viewAll(root,
      RenderArea->getViewportRegion());
  RenderArea->setSceneGraph(root);
  RenderArea->setTitle("Moteur de rotation");
  RenderArea->show();
  SoXt::show(myWindow);
  SoXt::mainLoop();
}

Addition d'un manipulateur trackball

#include <Inventor/Xt/SoXt.h>
#include <Inventor/Xt/SoXtRenderArea.h>
#include <Inventor/manips/SoTrackballManip.h>
#include <Inventor/nodes/SoCone.h>
#include <Inventor/nodes/
          SoDirectionalLight.h>
#include <Inventor/nodes/SoMaterial.h>
#include <Inventor/nodes/
          SoPerspectiveCamera.h>
#include <Inventor/nodes/SoSeparator.h>

main(int , char **argv)
{ Widget myWindow = SoXt::init(argv[0]);
  if (myWindow == NULL)
    exit(1);
  SoSeparator *root = new SoSeparator;
  root->ref();
  SoPerspectiveCamera *myCamera =
      new SoPerspectiveCamera;
  root->addChild(myCamera);
  root->addChild(new SoDirectionalLight);
  root->addChild(new SoTrackballManip);
  SoMaterial *myMaterial = new SoMaterial;
  myMaterial->diffuseColor.setValue(1.0,
                                    0.0,
                                    0.0);
  root->addChild(myMaterial);
  root->addChild(new SoCone);
  SoXtRenderArea *RenderArea =
      new SoXtRenderArea(myWindow);
  myCamera->viewAll(root,
      RenderArea->getViewportRegion());
  RenderArea->setSceneGraph(root);
  RenderArea->setTitle("Trackball");
  RenderArea->show();
  SoXt::show(myWindow);
  SoXt::mainLoop();
}

Utilisation d'une fenêtre de rendu avec zones de contrôle pour des rotations et des agrandissements

#include <Inventor/Xt/SoXt.h>
#include <Inventor/Xt/viewers/
          SoXtExaminerViewer.h>
#include <Inventor/nodes/SoCone.h>
#include <Inventor/nodes/SoDirectionalLight.h>
#include <Inventor/nodes/SoMaterial.h>
#include <Inventor/nodes/SoPerspectiveCamera.h>
#include <Inventor/nodes/SoSeparator.h>

main(int,char **argv)
{ SoXtExaminerViewer *myViewer ;
  Widget myWindow = SoXt::init(argv[0]);
  if (myWindow == NULL)
    exit(1);
  SoSeparator *root = new SoSeparator;
  root->ref();
  SoMaterial *myMaterial = new SoMaterial;
  myMaterial->diffuseColor.setValue(1.0,
                                    0.0,
                                    0.0);
  root->addChild(myMaterial);
  root->addChild(new SoCone);
  myViewer = new SoXtExaminerViewer(myWindow);
  myViewer->setSceneGraph(root);
  myViewer->setTitle("Examiner Viewer");
  myViewer->show();
  SoXt::show(myWindow);
  SoXt::mainLoop();
}

Conventions de syntaxe

Les types basiques commencent par Sb.

Nom

Rôle

SbBool

Booléen (TRUE ou FALSE)

SbBoxnx

Boite 2D ou 3D orthogonale aux axes

SbColor

Couleur RVB

SbCylinder

Cylindre

SbLine

Ligne 3D

SbMatrix

Matrice 4x4

SbName

Chaîne de caractères

SbPList

Liste de pointeurs (void *)

SbPlane

Plan 3D

SbRotation

Rotation 3D autour d'un axe arbitraire

SbSphere

Sphère

SbString

Chaîne de caractères

SbTime

Temps

SbVecnx

Vecteurs 2D et 3D (points et directions)

SbViewportRegion

Région active dans la fenêtre d'affichage

SbViewVolume

Volume de visualisation

Toutes les autres classes sont préfixées avec les lettres So (SoCone, SoMaterial, SoTransform,...).

Les noms de méthode et de variable commencent par une minuscule. Chaque mot dans un nom commence par une majuscule (getNormal(), setSceneGraph(),...).

Les énumérations sont en majuscules (FILLED, PER_PART).

Un fichier d'inclusion correspond à chaque classe.

Les noeuds et les groupes

La base de données de scène

La base de données de scène contient les informations concernant une ou plus scènes 3D.

Elle est appelée SoDB.

La méthode la plus importante associée à SoDB est SoDB::init(). Il s'agit de la première opération à réaliser (SoXt::init() si on utilise la component library pour programmer sous X). Elle réalise l'initialisation de la base de donnée de scène.

Les graphes de scène

Graphe de scène : composition de un ou plusieurs noeuds représentant individuellement un objet géométrique, une propriété ou un noeud de groupe.

Une hiérarchie de noeuds est créée par additions de noeuds en tant que fils de noeud de groupe avec pour résultat la constitution d'un graphe.

Les noeuds

Création

Utilisation de l'opérateur C++ new

SoSphere *sphere = new SoSphere;

Pas de delete

Types de noeuds :

  • Noeud de forme -> représentation d'objets géométriques 3D

  • Noeud propriété -> représentation de l'apparence et d'autres propriétés qualitatives d'une scène

  • Noeuds de groupe -> Container renfermant une collection de noeuds

Un noeud est composé d'un ensemble de données appelées champs qui le décrivent.

Exemple

Noeud

Champs

SoCoordinate3

point

SoMaterial

ambientColor
diffuseColor
specularColor
emissiveColor
shininess
transparency

Chaque noeud implante ses propres modes d'action.

Réalisation d'une action particulière sur une scène

-> instanciation de la classe de cette action

-> application au noeud racine du graphe de scène

Exécution d'une action

-> parcours du graphe de scène de la racine aux feuilles et de gauche à la droite (préordre)

Exécution d'une action

-> gestion d'un état courant (collection de paramètres) :

paramètres de l'état courant

transformation géométrique courante

composants du matériau courant

style de dessin courant

modèle d'illumination courant

police de caractères courante

coordonnées courantes

normales courantes

lumières courantes

spécifications de visualisation courante

Durant le parcours du graphe de scène, les noeuds peuvent modifier cet état courant.

Création de groupes

Utilisation de la classe SoGroup

Utilisation de la méthode addchild()

Combinaison d'un noeud transform, d'un noeud material et d'un noeud sphere pour constituer un groupe "tête" pour un objet de type robot :

SoGroup head = new SoGroup;

head->addChild(transform); 
head->addChild(material); 
head->addChild(sphere);
  • void addChild(SoNode *fils)

Ajoute un noeud à la fin de la liste des fils d'un groupe.

fils : noeud insèrer

  • void insertChild(SoNode *fils,int indexe)

Insère un noeud en position indexe.

fils : noeud insèrer

indexe : position d'insertion

Les noeuds d'un groupe sont indexés à partir de 0.

Lors du parcours d'un graphe de scène, les noeuds sont évalués dans l'ordre de leurs indexes.

Les séparateurs

Le noeud SoSeparator (sous-classe de SoGroup) permet d'isoler les effets de certains noeuds d'un groupe par rapport aux autres.

Avant de traiter ses fils, le noeud SoSeparator sauvegarde l'état courant et le restaure après traitement.

SoTransform *xf1 = new SoTransform;
xf1->translation.setValue(0.0, 3.0, 0.0);

SoMaterial *bronze = new SoMaterial;
bronze->ambientColor.setValue(.33,.22,.27);
bronze->diffuseColor.setValue(.78,.57,.11);
bronze->specularColor.setValue(.99,.94,.81);
bronze->shininess = .28;

SoCylinder *myCylinder = new SoCylinder;
myCylinder->radius = 2.5;
myCylinder->height = 6;

SoSeparator *body = new SoSeparator;
body->addChild(xf1);
body->addChild(bronze);
body->addChild(myCylinder);

SoTransform *xf2 = new SoTransform;
xf2->translation.setValue(0,7.5,0);
xf2->scaleFactor.setValue(1.5,1.5,1.5);

SoMaterial *silver = new SoMaterial;
silver->ambientColor.setValue(.2,.2,.2);
silver->diffuseColor.setValue(.6,.6,.6);
silver->specularColor.setValue(.5,.5,.5);
silver->shininess = .5;

SoSphere *mySphere = new SoSphere;

SoSeparator *head = new SoSeparator;
head->addChild(xf2);
head->addChild(silver);
head->addChild(mySphere);

SoSeparator *robot = new SoSeparator;
robot->addChild(body);
robot->addChild(head);

L'instanciation multiple

Un même noeud peut être ajouté à plusieurs groupes

-> il possède plusieurs parents.

Tout changement du noeud fils sera répercuté sur chacune de ses instances.

Exemple : création d'un robot avec deux instanciations d'une jambe

SoCube *thigh = new SoCube;     
thigh->width = 1.2;
thigh->height = 2.2;
thigh->depth = 1.1;
SoTransform *calfTransform = new SoTransform;
calfTransform->translation.setValue(0,-2.25,0.0);
SoCube *calf = new SoCube;
calf->width = 1;
calf->height = 2.2;
calf->depth = 1;
SoTransform *footTransform = new SoTransform;
footTransform->translation.setValue(0,-2,.5);
SoCube *foot = new SoCube;
foot->width = 0.8;
foot->height = 0.8;
foot->depth = 2;
SoGroup *leg = new SoGroup;      
leg->addChild(thigh);
leg->addChild(calfTransform);
leg->addChild(calf);
leg->addChild(footTransform);
leg->addChild(foot);

SoTransform *leftTransform = new SoTransform;
leftTransform->translation = SbVec3f(1,-4.25,0);
SoSeparator *leftLeg = new SoSeparator;   
leftLeg->addChild(leftTransform);
leftLeg->addChild(leg);
SoTransform *rightTransform = new SoTransform;
rightTransform->translation.setValue(-1,-4.25,0);
SoSeparator *rightLeg = new SoSeparator;   
rightLeg->addChild(rightTransform);
rightLeg->addChild(leg);

SoTransform *bodyTransform = new SoTransform;
bodyTransform->translation.setValue(0.0,3.0,0.0);
SoMaterial *bronze = new SoMaterial;
bronze->ambientColor.setValue(.33,.22,.27);
bronze->diffuseColor.setValue(.78,.57,.11);
bronze->specularColor.setValue(.99,.94,.81);
bronze->shininess = .28;
SoCylinder *bodyCylinder = new SoCylinder;
bodyCylinder->radius = 2.5;
bodyCylinder->height = 6;
SoSeparator *body = new SoSeparator;
body->addChild(bodyTransform);
body->addChild(bronze);
body->addChild(bodyCylinder);
body->addChild(leftLeg);
body->addChild(rightLeg);
SoTransform *headTransform = new SoTransform;
headTransform->translation.setValue(0,7.5,0);
headTransform->scaleFactor.setValue(1.5,1.5,1.5);
SoMaterial *silver = new SoMaterial;
silver->ambientColor.setValue(.2,.2,.2);
silver->diffuseColor.setValue(.6,.6,.6);
silver->specularColor.setValue(.5,.5,.5);
silver->shininess = .5;
SoSphere *headSphere = new SoSphere;
SoSeparator *head = new SoSeparator;
head->addChild(headTransform);
head->addChild(silver);
head->addChild(headSphere);
SoSeparator *robot = new SoSeparator;
robot->addChild(body);
robot->addChild(head);

Les champs

Les champs d'un noeud créé sont automatiquement initialisés.

La syntaxe pour affecter une valeur à un champ dépend :

  • du type de champ,

  • du fait que ce champ soit un champ simple ou multiple.

Exemple

SoDrawStyle *d = new SoDrawStyle;
d->style.setValue(SoDrawStyle::LINES) ;
d->lineWidth.setValue(3) ;
d->linePattern.setValue(0xf0f0);
  • Long, float et short

Affectation

SoOrthographicCamera *cam = new SoOrthographicCamera;
cam->height.setValue(1.);

Lecture

float result = cam->height.getValue();
  • Vecteurs

Affectation

SoTransform *xform = new SoTransform;
SbVec3f vector;
vector.setValue(2.5, 3.5, 0.0);
xform->translation.setValue(vector);

SoTransform *xform = new SoTransform;
xform->translation.setValue(SbVec3f(2.5,3.5,0.0));

SoTransform *xform = new SoTransform;
float x = 2.5, y = 3.5, z = 0.0;
xform->translation.setValue(x, y, z);

SoTransform *xform = new SoTransform;
float floatArray[3];
floatArray[0] = 2.5;
floatArray[1] = 3.5;
floatArray[2] = 0.0;
xform->translation.setValue(floatArray);

Lecture

SbVec3f t = xform->translation.getValue();
  • Champs à valeur multiple

Allocation de la zone mémoire destinée à contenir les valeurs.

Affectation et allocation

noeud->champ.setValues(starting index,
                       number of values,
                       pointer to array of values);

SoMaterial *mtl;
float vals[3];
vals[0] = 0.2;
vals[1] = 0.5;
vals[2] = 0.9;
mtl->transparency.setValues(0, 3, vals);

Lecture

f = mtl->transparency[13];

Insertion

float newValues[2];
newValues[0] = 0.1;
newValues[1] = 0.2;

mtl->transparency.insertSpace(10,2);
mtl->transparency.setValues(10,2,newValues);

Nombre de valeurs

mtl->transparency.getNum()

Suppression de valeurs

mtl->transparency.deleteValues(8,2);

Ignore flag

Permet de rendre un champ inactif.

SoMaterial *bronze = new SoMaterial;

bronze->ambientColor.setValue(.33, .22, .27);
bronze->diffuseColor.setValue(.78, .57, .11);
bronze->specularColor.setIgnored(TRUE);
bronze->shininess = .28;

bronze->specularColor.setIgnored(FALSE);

if (bronze->specularColor.isIgnored()) {
   printf("Yes, specular is ignored\n");
}

Les caméras et les lumières

Les caméras

Un noeud caméra génère une image de tout ce qui est défini après lui dans le graphe de scène.

Les noeuds caméra sont dérivés de la classe SoCamera.

Champ de SoCamera

Rôle

viewportMapping (SoSFEnum)

traitement quand l'aspect ratio de la caméra est différent de celui du viewport

position (SoSFVec3f)

Position

orientation (SoSFRotation)

Orientation de la direction de visée

aspectRatio (SoSFFloat)

Rapport entre la largeur et la hauteur de visualisation

nearDistance (SoSFFloat)

Distance entre la caméra et le plan de clipping proche

farDistance (SoSFFloat)

Distance entre la caméra et le plan de clipping éloigné

focalDistance (SoSFFloat)

Distance entre la caméra et le point de focalisation

Actions réalisées lors de la rencontre d'un noeud caméra

  • Placement de la caméra (position et orientation)

  • Création d'un volume de visualisation (à 6 plans)

  • Définition de la projection de ce volume 3D en une image 2D mappée sur l'écran

  • Rendu du reste du graphe de scène avec cette projection

SoPerspectiveCamera

Sous-classe de SoCamera permettant la visualisation en perspective telle que celle réalisée par l'oeil humain.

Un champ supplémentaire : heightAngle (SoSFFloat) : angle vertical du volume de visualisation de la caméra (pyramide tronquée)

SoOrthographicCamera

Sous-classe de SoCamera permettant la visualisation en projection orthographique (parallèle).

Un champ supplémentaire : height (SoSFFloat) : hauteur du volume de visualisation de la caméra (parallélépipède rectangle)

Visualisation écran de l'image générée

Un viewport est une zone rectangulaire où est affichée une image calculée.

Par défaut, le viewport a la même dimension que la fenêtre d'affichage. (SoXtRenderArea).

Le champ viewportMapping de SoCamera permet d'indiquer comment mapper la projection de la caméra dans le viewport quand leurs deux aspects ratio différent.

valeur de viewportMapping

Conséquence

CROP_VIEWPORT_FILL_FRAME

Ajuste le viewport à la caméra

CROP_VIEWPORT_LINE_FRAME

"

CROP_VIEWPORT_NO_FRAME

"

ADJUST_CAMERA

Ajuste la caméra au viewport

LEAVE_ALONE

Pas de modification -> l'image de la caméra est distordue.

Exemple

Trois caméra sont définies :

  • c1 : orthographique, visualisation de toute la scène

  • c2 : perspective, visualisation de toute la scène

  • c3 : perspective, modification de la position du centre de projection

#include <Inventor/SbLinear.h>
#include <Inventor/SoDB.h>
#include <Inventor/SoInput.h>
#include <Inventor/Xt/SoXt.h>
#include <Inventor/Xt/SoXtRenderArea.h>
#include <Inventor/nodes/SoBlinker.h>
#include <Inventor/nodes/SoDirectionalLight.h>
#include <Inventor/nodes/SoMaterial.h>
#include <Inventor/nodes/SoOrthographicCamera.h>
#include <Inventor/nodes/SoPerspectiveCamera.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoTransform.h>

main(int, char **argv)
{
Widget myWindow = SoXt::init(argv[0]);
  if (myWindow == NULL) 
    exit(1);
  SoSeparator *root = new SoSeparator;
  root->ref();
  SoBlinker *myBlinker = new SoBlinker;
  root->addChild(myBlinker);
  SoOrthographicCamera *c1 =
      new SoOrthographicCamera;
  SoPerspectiveCamera *c2 =
      new SoPerspectiveCamera;
  SoPerspectiveCamera *c3 =
      new SoPerspectiveCamera;
  myBlinker->addChild(c1);
  myBlinker->addChild(c2);
  myBlinker->addChild(c3);
  root->addChild(new SoDirectionalLight);
  SoInput myInput;
  if (! myInput.openFile("parkbench.iv")) 
    return 1;
  SoSeparator *fileContents =
      SoDB::readAll(&myInput);
  if (fileContents == NULL) 
    return 1;
  SoMaterial *myMaterial = new SoMaterial;
  myMaterial->diffuseColor.setValue(0.8,0.23,
                                    0.03);
  root->addChild(myMaterial);
  root->addChild(fileContents);
  SoXtRenderArea *RenderArea =
      new SoXtRenderArea(myWindow);
  SbViewportRegion myRg(RenderArea->getSize());
  c1->viewAll(root,myRg);
  c2->viewAll(root,myRg);
  c3->viewAll(root,myRg);
  SbVec3f initialPos; 
  initialPos = c3->position.getValue();
  float x,y,z;
  initialPos.getValue(x,y,z);
  c3->position.setValue(x+x/2.,y+y/2.,z+z/4.);
  RenderArea->setSceneGraph(root);
  RenderArea->setTitle("Cameras");
  RenderArea->show();
  SoXt::show(myWindow);
  SoXt::mainLoop();
}

Les lumières

Toutes les lumières sont dérivées de la classe SoLight.

Champ de SoLight

Rôle

on (SoSFBool)

Indique si la lumière est allumée

intensity (SoSFFloat)

Puissance de la source lumineuse

color (SoSFColor)

Couleur de la lumière émise

Trois sous-classes dérivent de SoLight :

SoPointLight

Définition d'une lumière ponctuelle émettant uniformément dans toutes les directions.

Un champ supplémentaire :

  • location (SoSFVec3f) : position

SoDirectionalLight

Définition d'une lumière émettant uniformément dans une direction particulière.

Un champ supplémentaire :

  • direction (SoSFVec3f) : direction des rayons lumineux

SoSpotLight

Définition d'une lumière ponctuelle émettant dans une direction privilégiée définissant un cône d'illumination.

Quatre champs supplémentaires :

  • location (SoSFVec3f) : position

  • direction (SoSFVec3f) : direction privilégiée

  • dropOffRate (SoSFFloat) : vitesse avec laquelle l'illumination décroît en s'éloignant de la direction privilégiée

  • cutOffRate (SoSFFloat) : angle (avec la direction privilégiée) au delà duquel l'illumination est égale à 0

Exemple

#include <Inventor/SoDB.h>
#include <Inventor/Xt/SoXt.h>
#include <Inventor/Xt/viewers/SoXtExaminerViewer.h>
#include <Inventor/nodes/SoCone.h>
#include <Inventor/nodes/SoDirectionalLight.h>
#include <Inventor/nodes/SoMaterial.h>
#include <Inventor/nodes/SoPointLight.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoShuttle.h>
#include <Inventor/nodes/SoTransformSeparator.h>

main(int,char **argv)
{ Widget myWindow = SoXt::init(argv[0]);
  if (myWindow == NULL) 
    exit(1);
  SoSeparator *root = new SoSeparator;
  root->ref();
  SoDirectionalLight *myDirLight =
      new SoDirectionalLight;
  myDirLight->direction.setValue(0,-1,-1);
  myDirLight->color.setValue(1,0,0);
  root->addChild(myDirLight);
  SoTransformSeparator *sep =
      new SoTransformSeparator;
  root->addChild(sep);
  SoShuttle *myShuttle = new SoShuttle;
  sep->addChild(myShuttle);
  myShuttle->translation0.setValue(-2,-1,3);
  myShuttle->translation1.setValue( 1, 2,-3);
  SoPointLight *myPointLight = new SoPointLight;
  sep->addChild(myPointLight);
  myPointLight->color.setValue(0,1,0);
  root->addChild(new SoCone);
  SoXtExaminerViewer *v =
      new SoXtExaminerViewer(myWindow);
  v->setSceneGraph(root);
  v->setTitle("Lights");
  v->setHeadlight(FALSE);
  v->show();
  SoXt::show(myWindow);
  SoXt::mainLoop();
}

Suite