Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

UTILISATION DU MOTEUR 3D OGRE, DU MOTEUR PHYSIQUE NEWTON ET DES SCÈNES OFUSION


Information sur la source

Catégorie :Graphique Source .NET ( DotNet ) Classé sous : moteur, 3d, physique, ogre, newton Niveau : Initié Date de création : 08/08/2008 Date de mise à jour : 12/08/2008 15:08:36 Vu / téléchargé: 4 254 / 180

Note :
Aucune note

Commentaire sur cette source (18)
Ajouter un commentaire et/ou une note

Description

Cliquez pour voir la capture en taille normale
Bonjour

Je vous propose un outil implémentant OGRE et NEWTON sous VB 2008. Pour ce faire, j'ai utilisé les wrappers correspondants Mogre et MogreNewt.

C'est un outil permettant de visualiser une scène exportée depuis 3DS Max avec l'outil oFusion. Il présente sous une interface simple, une fenêtre de rendu 3D incorporée à une forme (Embeded Ogre Window), la gestion des collisions de la caméra (FPS like) ou pas, la possibilité de sélecionner des objets et de jouer avec, de modifier les lumières, leurs couleurs, de jouer avec les ombres...

C'est un premier projet que j'ai réalisé pour prendre en main tous ses outils. Il n'est pas encore parfait, mais est quand même bien avancé, et toutes les fonctions de bases semblent fonctionner (en tout cas chez moi).

Je le met à votre disposition, car je n'ai trouvé aucun exemple en VB quant à l'utilisation de OGRE et Newton, ce qui est bien dommage car se sont vraiment des outils puissants.

J'inclut une scène exemple, pour faire mumuse avec.

Bien sur, si vous voulez aller plus loin, il vous faudra les différents SDK, on peut les trouver sur www.ogre3D.org, http://www.newtondynamics.com/, les wiki : http://www.ogre3d.org/wiki/index.php/Main_Page, http://www.ogre3d.org/wiki/index.php/Mogre_Tutorials...et bien sur, google est mon ami ;o)

Alors voilà, dites moi ce que vous en pensez.

Edit : je viens de commencer à transposer le code dans une classe pour pouvoir le réutiliser de manière simple, j'ai réimplémenté toute la partie chargement affichage et déplacement, il ne reste plus qu'à réimplémenter la gestion de la physique. Quand elle sera terminée, je la déposerais ici, ce qui permettra d'utiliser un moteur 3D puissant en .Net de manière simplissime. (bon, il faudra avoir 3DS MAx quand même...sinon, il faudra voir pour adapter la partie chargement avec les fichiers générés par l'exporter de blender).

Edit 2 : comme promis, la classe est online : http://www.vbfrance.com/codes/CLASSE-UTILISATION-OGRE-NEWTON_47581.aspx
 

Source

  • Imports Mogre
  • Imports MOIS
  • Imports MogreNewt
  • Imports OFusion
  • Imports System.Runtime.InteropServices
  • Public Class frmMain
  • #Region "Déclarations"
  • Private myRoot As Root 'La racine OGRE
  • Private mySceneManager As SceneManager 'Le SceneManager OGRE
  • Private myCamera As Camera 'La caméra
  • Private MyWindow As RenderWindow 'La fenêtre de rendu (ici ce sera une picturebox)
  • Private init As Boolean = True 'Permettra de savoir si on est en cours d'initialisation de l'application
  • Private EnCoursDeSelection = False 'Permettra de savoir si un objet est en cours de sélection
  • Private EnCoursDeTranslation As Boolean = False 'Permettra de savoir si un objet est en cours de translation
  • Private ShowAxes As Boolean = False 'Axe du monde visible ou pas
  • Private TrackObjet As Boolean = False 'Autotracking de la caméra actif ou pas
  • Private RenduEnCours As Boolean = True 'Sert à savoir si on à quitter l'appli pour stopper le rendu
  • Private Scene As OSMScene 'La variable pour le chargement de la scene oFusion
  • Private MyShadowTechnique As Mogre.ShadowTechnique 'Continedra le choix du type d'affichage des ombres
  • 'Variables pour la sélectiond dans la TreeView
  • Private SceneNodeSelected As Mogre.SceneNode 'Contiendra le noeud sélectionné dans le treeview
  • Private MObjectSelected As Mogre.MovableObject 'Contiendra l'objet sélectionnée
  • Private LightSelected As Mogre.Light 'Contiendra la lumière sélectionnée
  • Private NodeAxe As Mogre.SceneNode 'L'axe des objets
  • Private NodeAxeMonde As Mogre.SceneNode 'L'axe du monde
  • 'Déclarations pour Newton
  • Private myWorld As World = Nothing 'Le monde physique
  • Private Gravity As Single = -9.8 'Et oui, on aura un poid...(Sur terre = 9.81m/s²
  • 'La taille du body représentant le corp physique de la caméra
  • 'Ajuster cette valeur en fonction de la scène. A priori, 70 représente un humain d'à peu près 1m80, si mes
  • 'estimations sont juste.
  • Private CamSize As Mogre.Vector3 = New Mogre.Vector3(10, 70, 10)
  • Private CamNode As SceneNode 'Le node de la caméra
  • Private CamViewNode As SceneNode
  • Private CamBody As Body 'Le corps physique de la caméra
  • Private CamColl As CollisionPrimitives.Ellipsoid 'Le type de collision
  • Private NoMovement As Boolean = True
  • Private camera_rotation_x As Single
  • Private camera_rotation_xx As Single
  • Private camera_rotation_y As Mogre.Degree
  • Private y_rotation_cont As Degree
  • Private y_limit_a As Single = 90
  • Private y_limit_b As Single = -90
  • Private InitialCamBodyPos As Mogre.Vector3
  • Private InitialCamBodyOrient As Mogre.Quaternion
  • 'Déclaration pour MOIS
  • Private inputManager As MOIS.InputManager
  • Private inputKeyboard As MOIS.Keyboard = Nothing
  • Private inputMouse As MOIS.Mouse = Nothing
  • 'Translate & rotate scalars
  • Private moving As Boolean
  • #End Region
  • #Region "CONSTANTES"
  • 'Changer ces constantes pour avoir des vitesses de déplacement et/ou de rotation différentes (mode détection de collisions inactif)
  • Const TRANSLATE As Single = 600
  • Const ROTATE As Single = 1
  • #End Region
  • #Region "Procédures & Fonctions"
  • Private Function get_body_position(ByVal bod As Body) As Mogre.Vector3 'retourne la position du body
  • Dim orient As Quaternion
  • Dim pos As Mogre.Vector3
  • bod.GetPositionOrientation(pos, orient)
  • Return pos
  • End Function
  • Private Function get_body_orientation(ByVal bod As Body) As Quaternion ' retourne l'orientation du body
  • Dim orient As Quaternion
  • Dim pos As Mogre.Vector3
  • bod.GetPositionOrientation(pos, orient)
  • Return orient
  • End Function
  • Private Sub camera_force_callback(ByVal Corps As Body)
  • 'Cette procédure est appelée à chaque update du monde physique.
  • 'On y applique la gravité ainsi que la rotation sur l'axe des X
  • If mnuGravite.Checked Then
  • Dim masse As Single
  • Dim inertie As Mogre.Vector3
  • Dim Force As Mogre.Vector3
  • 'on récupère la position et l'orientation du corp passé en paramètre
  • Dim posBody As Mogre.Vector3 = CamBody.Position
  • Dim OrientBody As Quaternion = CamBody.Orientation
  • Corps.GetMassMatrix(masse, inertie) 'on récupère sa masse et son inertie
  • Force = New Mogre.Vector3(0, Gravity * 2000, 0) 'on y applique la gravité, le facteur de multiplication est là pour ajusté la valeur.
  • 'Curieusement, si je ne multiplie pas, on se croirait sur la Lune. Si quelqu'un sait pourquoi, merci de me le dire.
  • Force *= masse
  • Corps.AddForce(Force) 'on applique la force de gravité
  • End If
  • Corps.Omega = New Mogre.Vector3(0, camera_rotation_x, 0) 'pour le déplacement sur X
  • End Sub
  • Private Sub InitOgre()
  • 'Création de la racine OGRE et du SceneManager. Appeler dans le load de la form, le menu Ouvrir et le menu recharger
  • myRoot = New Root("Plugins.cfg", "ogre.cfg", "ogre.log")
  • mySceneManager = myRoot.CreateSceneManager(SceneType.ST_GENERIC)
  • End Sub
  • Private Sub InitTree(ByVal SceneNode As Mogre.SceneNode, ByVal sceneTreeNode As TreeNode)
  • 'Remplissage de la TreeView de sélection des objets
  • 'c'est une fonction récursive
  • 'TODO : classement en ordre alphabétique dans les 3 noeuds principaux
  • Dim NumChildNodes As UShort 'le nombre d'enfants du scenenode passé en paramètre
  • Dim NewNode As TreeNode = New TreeNode 'on crèe un nouveau node dans le treeview qui va recevoir les paramètres à ajouter au treeview
  • Try
  • NumChildNodes = SceneNode.NumChildren 'on récupère le nombre d'enfants du scenenode
  • NewNode.Name = SceneNode.Name 'Son nom
  • NewNode.Text = SceneNode.Name + " (" + NumChildNodes.ToString + " enfants)" 'on concatène le nombre d'enfants au nom pour l'affichage dans le treeview
  • NewNode.Tag = SceneNode 'on met le scenenode dans le tag du noeud de la treeview pour s'en servir lors de la sélection du noeud dans la treeview (cf Treeview_AfterSelect)
  • If SceneNode.Name.ToUpper.Contains("AXE") Then 'si on est sur un scenenode axe, on sort de la procédure car on ne veut pas le faire appraitre dans la treeview
  • Exit Sub
  • End If
  • If SceneNode.Name.ToUpper.Contains("ROOT") Then 'si on est sur root du scenemanager, on ne fait rien, on se contante de lancer le premier niveau de récursivité
  • treeScene.Nodes.Item(0).Text = "Root (" + NumChildNodes.ToString + " enfants)"
  • For i As UShort = 0 To NumChildNodes - 1
  • InitTree(SceneNode.GetChild(i), treeScene.SelectedNode)
  • Next
  • Else 'sinon, on teste le type d'objet et suvant le cas on l'ajoute au noeud du treeview adéquate
  • If SceneNode.GetAttachedObject(SceneNode.Name).MovableType = "Camera" Then
  • 'Cette ligne permet de sélectionner le bon neoud auquel ajouté l'objet
  • treeScene.SelectedNode = treeScene.Nodes.Item(0).Nodes.Item(1)
  • ElseIf SceneNode.GetAttachedObject(SceneNode.Name).MovableType = "Light" Then
  • treeScene.SelectedNode = treeScene.Nodes.Item(0).Nodes.Item(3)
  • ElseIf SceneNode.GetAttachedObject(SceneNode.Name).MovableType = "Entity" Then
  • treeScene.SelectedNode = treeScene.Nodes.Item(0).Nodes.Item(2)
  • End If
  • 'on ajoute le noeud
  • treeScene.SelectedNode.Nodes.Add(NewNode)
  • 'treeScene.SelectedNode = treeScene.Nodes(treeScene.Nodes.Count - 1)
  • If NumChildNodes > 0 Then 'si il y a des nodes enfants, on desend dans le scenenode
  • For i As UShort = 0 To NumChildNodes - 1
  • InitTree(SceneNode.GetChild(i), treeScene.SelectedNode)
  • Next
  • End If
  • End If
  • Catch ex As System.Runtime.InteropServices.SEHException
  • 'en cas d'erreur....on ne fait rien, sinon, des messages apparaissent lors de la création du treeview, on se contente d'un gestionnaire générique pour ne pas planter le programme
  • treeScene.SelectedNode = treeScene.Nodes.Item(0).Nodes.Item(0)
  • 'on ajoute le noeud
  • treeScene.SelectedNode.Nodes.Add(NewNode)
  • If NumChildNodes > 0 Then 'si il y a des nodes enfants, on desend dans le scenenode
  • For i As UShort = 0 To NumChildNodes - 1
  • InitTree(SceneNode.GetChild(i), treeScene.SelectedNode)
  • Next
  • End If
  • End Try
  • End Sub
  • Private Sub InitScene()
  • Try
  • 'On initialise la racine OGRE
  • myRoot.Initialise(False)
  • 'On crè la fenêtre, ici ce sera dans le contrôle picMogre, une picturebox
  • Dim misc As NameValuePairList = New NameValuePairList
  • misc("externalWindowHandle") = picMogre.Handle.ToString
  • Dim const_list As Const_NameValuePairList = misc.ReadOnlyInstance
  • MyWindow = myRoot.CreateRenderWindow("OgreWieport", 0, 0, False, const_list)
  • 'On ajoute un handler qui permettre de récupérer la variable timeSinceLastFrame pour la gestion des déplacements
  • 'AddHandler myRoot.FrameStarted, AddressOf FrameStarted
  • 'On crés le ressource manager avec les ressources choisie dans la boîte de chargement.
  • 'Par défaut, on prend le chemin de la scène
  • ResourceGroupManager.Singleton.AddResourceLocation(System.IO.Path.GetDirectoryName(txtNomScene.Text), "FileSystem", "General")
  • 'On ajoute le répertoires OBJETS de l'application qui contient, entre autre, les axes
  • ResourceGroupManager.Singleton.AddResourceLocation(Application.StartupPath + "\Objets", "FileSystem", "General")
  • 'et on parcourt la listbox de la fenêtre de choix pour ajouter les ressources supplémentaires (répertoires ou fichiers zip)
  • If lstRessources.Items.Count > 0 Then
  • For i As Integer = 0 To lstRessources.Items.Count - 1
  • 'lstTypeRessources contient le type de ressource de la ressource considérée dans lstRessources
  • ResourceGroupManager.Singleton.AddResourceLocation(lstRessources.Items(i), lstTypeRessources.Items(i), "General")
  • Next
  • End If
  • 'Fini, on initialise toutes les ressources
  • ResourceGroupManager.Singleton.InitialiseAllResourceGroups()
  • 'On charge la scène OSM grâce à la dll oFusion
  • Scene = New OSMScene(mySceneManager, MyWindow)
  • Scene.Initialize(txtNomScene.Text)
  • Scene.CreateScene(mySceneManager.RootSceneNode)
  • 'création de la caméra
  • If Scene.CameraList.Count > 0 Then
  • 'Si la scene contient au moins une caméra, on sélectionne la première
  • myCamera = Scene.CameraList(0)
  • Else
  • 'sinon, on en crè une par défaut
  • myCamera = Scene.SceneMgr.CreateCamera("CameraDefaut")
  • myCamera.SetPosition(0, 0, 0)
  • myCamera.SetDirection(0, 0, 0)
  • myCamera.FOVy = CType(1, Mogre.Radian)
  • Dim camNode As SceneNode = mySceneManager.CreateSceneNode("CameraDefaut")
  • camNode.AttachObject(myCamera)
  • Dim CameraTarget As Mogre.SceneNode = mySceneManager.CreateSceneNode("CameraDefaut.target")
  • CameraTarget.SetPosition(1000, 1000, 1000)
  • CameraTarget.SetDirection(0, 0, 0)
  • CameraTarget.SetScale(1, 1, 1)
  • 'On crè le viewport
  • Dim ViewPort As Mogre.Viewport = MyWindow.AddViewport(myCamera)
  • myCamera.AspectRatio = ViewPort.ActualWidth / ViewPort.ActualHeight
  • End If
  • txtFOV.Text = myCamera.FOVy.ValueRadians
  • myCamera.NearClipDistance = 5
  • InitialCamBodyOrient = myCamera.Orientation
  • InitialCamBodyPos = myCamera.Position
  • 'si on a décidé d'activer la gestion des collisions, on initialise Newton
  • If mnuDetectionDeCollision.Checked Then
  • InitNewton()
  • End If
  • 'initialisation de l'inputmanager MOIS
  • InitInputHandler()
  • Catch ex As System.Runtime.InteropServices.SEHException
  • 'en cas d'erreur....
  • If OgreException.IsThrown Then
  • MsgBox(OgreException.LastException.FullDescription, MsgBoxStyle.Critical, _
  • "Exeption OGRE!")
  • Else
  • MsgBox(ex.ToString, "Erreur")
  • End If
  • End Try
  • End Sub
  • Private Sub InitNewton()
  • 'Initialisation de Newton pour la gestion des collision caméras, je n'y suis pas arrivé avec les RayScenQuery...
  • If myWorld Is Nothing Then
  • myWorld = New World 'le monde physique
  • 'et initialisation de sa taille, par défaut elle est de 100 sur chaque axes.
  • myWorld.SetWorldSize(New Mogre.Vector3(-100000, -100000, -100000), New Mogre.Vector3(100000, 100000, 100000))
  • End If
  • Dim cam_mass As Single = 90 'la masse de la caméra
  • 'Création du monde physique pour Newton
  • Dim stat_col As MogreNewt.CollisionPrimitives.TreeCollisionSceneParser = New MogreNewt.CollisionPrimitives.TreeCollisionSceneParser(myWorld)
  • stat_col.ParseScene(mySceneManager.RootSceneNode, False) 'Utilisation du parser de scène Newton, attention, à ce jour (juillet 2008), le parmètre true, au mieux, ne fonctionne pas et au pire plante le programme.
  • 'Création et paramétrage du body pour le monde
  • Dim bod As MogreNewt.Body = New MogreNewt.Body(myWorld, stat_col)
  • stat_col.Dispose()
  • bod.AttachToNode(mySceneManager.RootSceneNode)
  • bod.SetPositionOrientation(New Mogre.Vector3(0.0, 0.0, 0.0), Quaternion.IDENTITY)
  • 'Collision de la caméra
  • Dim PosCam As Mogre.Vector3 = mySceneManager.GetSceneNode(myCamera.Name).Position 'on récupère la position de la caméra
  • Dim OrientCam As Quaternion = mySceneManager.GetSceneNode(myCamera.Name).Orientation 'on récupère l'orientation de la caméra
  • CamNode = mySceneManager.RootSceneNode.CreateChildSceneNode("CamNode") 'on crè un Scennode
  • Me.CamNode.SetScale(Me.CamSize) 'on le met à la taille de la caméra
  • Me.CamColl = New CollisionPrimitives.Ellipsoid(myWorld, Me.CamSize) 'on crè le système de collision
  • Me.CamBody = New Body(myWorld, Me.CamColl) 'on l'applique au body représentant la caméra
  • Me.CamColl.Dispose() 'on libère la collision
  • Me.CamBody.AttachToNode(Me.CamNode) 'et on l'attache au noeud créé précédement
  • 'calcul de l'inertie de la caméra
  • Dim cam_inertia As Mogre.Vector3 = MomentOfInertia.CalcEllipsoidSolid(cam_mass, Me.CamSize)
  • Me.CamBody.SetMassMatrix(cam_mass, cam_inertia)
  • AddHandler Me.CamBody.ForceCallback, AddressOf camera_force_callback 'la fonction appelée lors de l'update du monde physique
  • Me.CamBody.AutoFreeze = False 'Important, sinon, iompossible de déplacer le body...
  • 'Création d'un "UP Vector" pour empécher le body de tourner sur Y
  • Dim uv2 As BasicJoints.UpVector = New BasicJoints.UpVector(myWorld, Me.CamBody, Mogre.Vector3.UNIT_Y)
  • 'Création d'un scenenode 1 unités au dessus du camnode pour y mettre la caméra
  • 'Ca nécessite un peu d'explications :
  • 'Si on met 0 comme valeur sur Y, la caméra est positionnée au centre du body.
  • 'Comme le but est de représenter un être humain, ça ne le fait pas.
  • 'Par contre, la valeur 1 positionne la caméra juste au dessus du body, mais, à contrarion, dans une pièce
  • 'au plafond trop bas, la caméra va passer au dessus du plafond....Pour le moment, je n'ai pas trouvé mieux.
  • Me.CamViewNode = Me.CamNode.CreateChildSceneNode("CamViewNode", New Mogre.Vector3(0, 1, 0)) 'création du scenenode
  • mySceneManager.RootSceneNode.DetachObject(myCamera) 'on détache la caméra du rootscenenode (créé par OSMLoader)
  • Me.CamViewNode.AttachObject(myCamera) 'et on attache la caméra au viewnode
  • CamBody.SetPositionOrientation(PosCam, OrientCam) 'Sert à récupérer la position et orientation initiale de la caméra pour positionner son corp.
  • InitialCamBodyOrient = get_body_orientation(CamBody)
  • InitialCamBodyPos = get_body_position(CamBody)
  • 'CamBody.MaterialGroupID = New MogreNewt.MaterialID(myWorld)
  • MogreNewt.Debugger.Instance.Init(mySceneManager) 'et on initialise le debugger newton.
  • End Sub
  • Private Sub InitInputHandler()
  • 'Définition du mode d'accès de la souris et du handle de fenêtre à gérer. ATTENTION : ce n'est pas le handle du contrôle qui affichera le rendu mais celui de la fenêtre qui le contient
  • Dim param As MOIS.ParamList = New MOIS.ParamList()
  • 'Les 4 premiers paramètres servent à signaler que MOIS ne sera pas le seul à être capable de gérer le clavier et la souris
  • 'ceci permet de disposer du curseur de la souris pour faire autre chose pendant que Ogre rend ses frames
  • param.Insert("w32_mouse", "DISCL_NONEXCLUSIVE")
  • param.Insert("w32_mouse", "DISCL_FOREGROUND")
  • param.Insert("w32_keyboard", "DISCL_NONEXCLUSIVE")
  • param.Insert("w32_keyboard", "DISCL_FOREGROUND")
  • param.Insert("WINDOW", Me.Handle.ToString) 'ici, on passe le handle de notre "top level window" (cf. DirectX et DirectInput)
  • 'Hook de l'input manager à la fenêtre
  • inputManager = MOIS.InputManager.CreateInputSystem(param)
  • If Not inputManager Is Nothing Then
  • 'Creation des device de capture MOIS
  • Try
  • 'Le clavier
  • inputKeyboard = CType(inputManager.CreateInputObject(MOIS.Type.OISKeyboard, False), MOIS.Keyboard)
  • Catch ex As System.Runtime.InteropServices.SEHException
  • 'en cas d'erreur....
  • If OISException.IsThrown Then
  • MsgBox(OISException.LastException.eText, MsgBoxStyle.Critical, _
  • "Exeption OIS!")
  • Else
  • MsgBox(ex.ToString, "Erreur")
  • End If
  • End Try
  • Try
  • 'La souris
  • inputMouse = CType(inputManager.CreateInputObject(MOIS.Type.OISMouse, False), MOIS.Mouse)
  • Catch ex As System.Runtime.InteropServices.SEHException
  • 'en cas d'erreur....
  • If OISException.IsThrown Then
  • MsgBox(OISException.LastException.eText, MsgBoxStyle.Critical, _
  • "Exeption OIS!")
  • Else
  • MsgBox(ex.ToString, "Erreur")
  • End If
  • End Try
  • 'A répéter pour d'autre input, joystick par exemple :
  • '' ''Try
  • '' '' inputJoy = CType(inputManager.CreateInputObject(MOIS.Type.OISJoyStick, False), MOIS.JoyStick)
  • '' ''Catch ex As System.Runtime.InteropServices.SEHException
  • '' '' 'en cas d'erreur....
  • '' '' If OISException.IsThrown Then
  • '' '' MsgBox(OISException.LastException.eText, MsgBoxStyle.Critical, _
  • '' '' "Exeption OIS!")
  • '' '' Else
  • '' '' MsgBox(ex.ToString, "Erreur")
  • '' '' End If
  • '' ''End Try
  • End If
  • ' Et l'évènement qui sera attaché au FrameStarted
  • AddHandler myRoot.FrameStarted, AddressOf FrameStarted
  • End Sub
  • Private Sub DisposeOgre()
  • 'Pemet de nettoyer les instances OGRES en cas de rechargement de la scène ou de l'ouverture d'une nouvelle
  • 'en gros, on réinitialise toutes les instances Ogre
  • SceneNodeSelected = Nothing
  • MObjectSelected = Nothing
  • myCamera = Nothing
  • Scene = Nothing
  • ResourceGroupManager.Singleton.DestroyResourceGroup("General")
  • MyWindow.RemoveAllViewports()
  • MyWindow.Dispose()
  • myRoot.DestroySceneManager(mySceneManager)
  • myRoot.DetachRenderTarget(MyWindow)
  • myRoot.Dispose()
  • MyWindow = Nothing
  • mySceneManager = Nothing
  • End Sub
  • Private Sub DisposeNewton()
  • 'Permet de liberer les instances Newton, mais ça ne marche pas top, à paufiner....
  • 'Ainsi, si on recharge la scène ou si on en charge une autre, tout marche sauf que l'on a pas de mouvement sur X.
  • 'A l'heure qu'il est, je ne sais pas pourquoi
  • RemoveHandler Me.CamBody.ForceCallback, AddressOf camera_force_callback
  • myWorld.DestroyAllBodies()
  • myWorld.Dispose()
  • myWorld = Nothing
  • End Sub
  • Private Sub LoadAxe()
  • 'Permet de charger l'objet Axe et de l'ajouter à la scene
  • Dim Axe01 As Entity 'Sera l'axe afficher sdur les objets
  • Dim AxeMonde As Entity 'Comme son nom l'indique
  • Try
  • Axe01 = mySceneManager.CreateEntity("Axe01", "Axe.mesh") 'on charge l'objet
  • AxeMonde = Axe01.Clone("AxeMonde") 'on le clone pour avoir deux axes séparés
  • 'On crè le node qui contioendra l'axe du monde
  • NodeAxeMonde = mySceneManager.RootSceneNode.CreateChild("AxeMonde")
  • NodeAxeMonde.AttachObject(AxeMonde)
  • NodeAxeMonde.SetPosition(0, 0, 0)
  • NodeAxeMonde.SetScale(1, 1, 1)
  • NodeAxeMonde.SetVisible(False)
  • NodeAxeMonde.ResetToInitialState()
  • 'on fait pareil pour l'axe des objets
  • NodeAxe = mySceneManager.RootSceneNode.CreateChild("Axe01")
  • NodeAxe.AttachObject(Axe01)
  • NodeAxe.SetPosition(0, 0, 0)
  • NodeAxe.SetScale(1, 1, 1)
  • NodeAxe.InheritOrientation = False 'si on ne fait pas ça, l'axe se comporte étrangement lorsque l'objet tourne
  • NodeAxe.InheritScale = False 'Pareil, le scale de l'objet s'ajoute au scale de l'axe
  • NodeAxe.SetVisible(False)
  • Catch ex As System.Runtime.InteropServices.SEHException
  • 'en cas d'erreur....
  • If OgreException.IsThrown Then
  • MsgBox(OgreException.LastException.FullDescription, MsgBoxStyle.Critical, _
  • "Exeption OGRE!")
  • Else
  • MsgBox(ex.ToString, "Erreur")
  • End If
  • End Try
  • End Sub
  • Public Function FrameStarted(ByVal evt As FrameEvent) As Boolean
  • 'Gère les évènements clavier et souris
  • 'le test pour annuler le mouvement de la caméra est mis en externe par rapport
  • 'au test de detection de collision car si on relache la souris avant les touches
  • 'la caméra continue à se déplacer, donc, on annule sa vélocité et sa rotation à la fin de la fonction
  • Dim PasdeMouvement As Boolean = True
  • If moving Then 'Si on a cliqué sur le bouton gauche de la souris, on se déplace dans le monde
  • CaptureFunction() 'on lance la capture clavier/souris par MOIS
  • 'Il y a 2 systèmes de mouvement, avec ou sans détection de collisions
  • If mnuDetectionDeCollision.Checked Then
  • 'Avec
  • 'Le principe est de récupérer l'orientation du corps de la caméra sur l'axe de déplacement choisi
  • 'et de lui affecter une vitesse de déplacement sur cette axe.
  • 'Lorsque l'on arrête le déplacement, on annule la vitesse.
  • Dim direction As Mogre.Vector3
  • If inputKeyboard.IsKeyDown(MOIS.KeyCode.KC_UP) Then
  • direction = get_body_orientation(CamBody) * Mogre.Vector3.NEGATIVE_UNIT_Z
  • CamBody.Velocity = CamBody.Velocity * New Mogre.Vector3(0, 1, 0) + direction * 200 * 2
  • PasdeMouvement = False
  • End If
  • If inputKeyboard.IsKeyDown(MOIS.KeyCode.KC_DOWN) Then
  • direction = get_body_orientation(CamBody) * Mogre.Vector3.UNIT_Z
  • CamBody.Velocity = CamBody.Velocity * New Mogre.Vector3(0, 1, 0) + direction * 200 * 2
  • PasdeMouvement = False
  • End If
  • If inputKeyboard.IsKeyDown(MOIS.KeyCode.KC_LEFT) Then
  • direction = get_body_orientation(CamBody) * Mogre.Vector3.NEGATIVE_UNIT_X
  • CamBody.Velocity = CamBody.Velocity * New Mogre.Vector3(0, 1, 0) + direction * 200 * 2
  • PasdeMouvement = False
  • End If
  • If inputKeyboard.IsKeyDown(MOIS.KeyCode.KC_RIGHT) Then
  • direction = get_body_orientation(CamBody) * Mogre.Vector3.UNIT_X
  • CamBody.Velocity = CamBody.Velocity * New Mogre.Vector3(0, 1, 0) + direction * 200 * 2
  • PasdeMouvement = False
  • End If
  • 'Pour le déplacement sur Y (vertical) on se déplace sur le Y du monde et pas de la caméra
  • 'Donc, pas besoin de récupérer la direction de la caméra
  • If inputKeyboard.IsKeyDown(MOIS.KeyCode.KC_PGUP) Then
  • CamBody.Velocity = New Mogre.Vector3(0, 1000, 0)
  • PasdeMouvement = False
  • End If
  • If inputKeyboard.IsKeyDown(MOIS.KeyCode.KC_PGDOWN) Then
  • CamBody.Velocity = New Mogre.Vector3(0, -1000, 0)
  • PasdeMouvement = False
  • End If
  • 'Pour la rotation de la caméra, on récupère le déplacement de la souris sur X et Y
  • Dim mouseState As MOIS.MouseState_NativePtr = inputMouse.MouseState
  • camera_rotation_x = -mouseState.X.rel * 0.5F
  • If camera_rotation_x <> 0 Then
  • PasdeMouvement = False
  • End If
  • camera_rotation_y = -mouseState.Y.rel * 0.5F
  • 'On travaille sur le camviewnode pour que l'axe de la caméra soit orienté correctement
  • CamViewNode.Pitch(camera_rotation_y)
  • 'Si on atteint un angle de rotation maximale vers le haut ou le bas, on annule la rotation
  • y_rotation_cont += camera_rotation_y
  • If y_rotation_cont > y_limit_a Or y_rotation_cont < y_limit_b Then
  • CamViewNode.Pitch(-camera_rotation_y)
  • y_rotation_cont -= camera_rotation_y
  • End If
  • Else
  • 'Sans
  • 'On applique simplement une translation ou une rotation à la caméra
  • Dim myTranslation As Mogre.Vector3 = Mogre.Vector3.ZERO 'Pour le déplacement de la caméra sur ces axes sans détection de collision
  • myTranslation.z = 0
  • myTranslation.x = 0
  • myTranslation.y = 0
  • If inputKeyboard.IsKeyDown(MOIS.KeyCode.KC_UP) Then
  • myTranslation.z += -TRANSLATE
  • End If
  • If inputKeyboard.IsKeyDown(MOIS.KeyCode.KC_DOWN) Then
  • myTranslation.z += TRANSLATE
  • End If
  • If inputKeyboard.IsKeyDown(MOIS.KeyCode.KC_LEFT) Then
  • myTranslation.x += -TRANSLATE
  • End If
  • If inputKeyboard.IsKeyDown(MOIS.KeyCode.KC_RIGHT) Then
  • myTranslation.x += TRANSLATE
  • End If
  • If inputKeyboard.IsKeyDown(MOIS.KeyCode.KC_PGUP) Then
  • myTranslation.y += TRANSLATE
  • End If
  • If inputKeyboard.IsKeyDown(MOIS.KeyCode.KC_PGDOWN) Then
  • myTranslation.y += -TRANSLATE
  • End If
  • Dim mouseState As MOIS.MouseState_NativePtr = inputMouse.MouseState
  • camera_rotation_x = mouseState.X.rel * -ROTATE
  • camera_rotation_y = mouseState.Y.rel * -ROTATE
  • 'Et on déplace la caméra
  • myCamera.Position += myCamera.Orientation * myTranslation * evt.timeSinceLastFrame
  • myCamera.Yaw(camera_rotation_x * evt.timeSinceLastFrame)
  • myCamera.Pitch(camera_rotation_y) 'si on multiplie par timesincelastframe, le résultat est plus qu'étrange...A voir.
  • End If
  • End If
  • 'C'est ici que l'on annule la vélocité et la rotation de la caméra.
  • If PasdeMouvement And mnuDetectionDeCollision.Checked Then
  • CamBody.Velocity = New Mogre.Vector3(0, 0, 0)
  • camera_rotation_x = 0
  • End If
  • Return RenduEnCours 'tant que l'on ne quitte pas l'appli, on renvoi True.
  • End Function
  • Private Sub CaptureFunction()
  • 'Lance la capture du clavier et de la souris
  • inputKeyboard.Capture()
  • inputMouse.Capture()
  • End Sub
  • Private Sub RemplitGrille()
  • 'Permet de remplir la grille d'infos une fois qu'un objet est sélectionné
  • Dim tab(1) As String
  • Try
  • 'On efface le contenu de la grille
  • grdDetail.Rows.Clear()
  • 'Et on remplit
  • 'La position
  • tab(0) = "Position X"
  • tab(1) = SceneNodeSelected.Position.x.ToString
  • grdDetail.Rows.Add(tab)
  • tab(0) = "Position Y"
  • tab(1) = SceneNodeSelected.Position.y.ToString
  • grdDetail.Rows.Add(tab)
  • tab(0) = "Position Z"
  • tab(1) = SceneNodeSelected.Position.z.ToString
  • grdDetail.Rows.Add(tab)
  • 'L'Orientation
  • tab(0) = "Orientation X"
  • tab(1) = SceneNodeSelected.Orientation.x.ToString
  • grdDetail.Rows.Add(tab)
  • tab(0) = "Orientation Y"
  • tab(1) = SceneNodeSelected.Orientation.y.ToString
  • grdDetail.Rows.Add(tab)
  • tab(0) = "Orientation Z"
  • tab(1) = SceneNodeSelected.Orientation.z.ToString
  • grdDetail.Rows.Add(tab)
  • tab(0) = "Orientation W"
  • tab(1) = SceneNodeSelected.Orientation.w.ToString
  • grdDetail.Rows.Add(tab)
  • 'L'échelle
  • tab(0) = "Echelle X"
  • tab(1) = SceneNodeSelected.GetScale.x.ToString
  • grdDetail.Rows.Add(tab)
  • tab(0) = "Echelle Y"
  • tab(1) = SceneNodeSelected.GetScale.y.ToString
  • grdDetail.Rows.Add(tab)
  • tab(0) = "Echelle Z"
  • tab(1) = SceneNodeSelected.GetScale.z.ToString
  • grdDetail.Rows.Add(tab)
  • 'Les ombres
  • tab(0) = "CastShadows"
  • tab(1) = IIf(MObjectSelected.CastShadows, "Oui", "Non")
  • grdDetail.Rows.Add(tab)
  • 'La visibilité
  • tab(0) = "Visible"
  • tab(1) = IIf(MObjectSelected.Visible, "Oui", "Non")
  • grdDetail.Rows.Add(tab)
  • 'La Bounding box
  • tab(0) = "ShowBoundingBox"
  • tab(1) = IIf(SceneNodeSelected.ShowBoundingBox, "Oui", "Non")
  • grdDetail.Rows.Add(tab)
  • GetPosition()
  • GetOrientation()
  • GetEchelle()
  • Catch ex As Exception
  • End Try
  • End Sub
  • Private Sub GetOrientation()
  • 'Récupère l'orientation de l'objet sélectionné pour l'afficher dans les paramètres de le'objet
  • Try
  • txtOrientationX.Value = SceneNodeSelected.Orientation.x
  • txtOrientationY.Value = SceneNodeSelected.Orientation.y
  • txtOrientationZ.Value = SceneNodeSelected.Orientation.z
  • txtOrientationW.Value = SceneNodeSelected.Orientation.w
  • Catch ex As Exception
  • End Try
  • End Sub
  • Private Sub GetPosition()
  • 'Récupère la position de l'objet sélectionné pour l'afficher dans les paramètres de le'objet
  • Try
  • txtPositionX.Value = SceneNodeSelected.Position.x
  • txtPositionY.Value = SceneNodeSelected.Position.y
  • txtPositionZ.Value = SceneNodeSelected.Position.z
  • Catch ex As Exception
  • End Try
  • End Sub
  • Private Sub GetEchelle()
  • 'Récupère l'échelle de l'objet sélectionné pour l'afficher dans les paramètres de le'objet
  • txtScaleX.Value = SceneNodeSelected.GetScale.x
  • txtScaleY.Value = SceneNodeSelected.GetScale.y
  • txtScaleZ.Value = SceneNodeSelected.GetScale.z
  • End Sub
  • #End Region
  • #Region "Evènements"
  • #Region "Form"
  • Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
  • Me.Hide() 'Cache la fenêtre principale
  • treeScene.Sort() 'trie la treeview, une fois triée, elle le reste même si on la recharge avec de nouvelles données.
  • InitOgre()
  • 'Affichage de la fenêtre de choix de la scène à charger
  • frmViewerload.ShowDialog()
  • If frmViewerload.bValide Then
  • 'Si on a valider le choix.....
  • 'On affiche la form d'attente
  • Cursor = Cursors.WaitCursor 'juste pour la beauté
  • If frmViewerload.chkPhysique.Checked Then
  • mnuDetectionDeCollision.Checked = True
  • mnuGravite.Enabled = True
  • mnuDebugActif.Enabled = True
  • End If
  • 'Affichage de la fenêtre de paramètres OGRES, le cas échéant
  • If frmViewerload.chkOgre.Checked Then
  • If Not myRoot.ShowConfigDialog Then
  • Exit Sub
  • End If
  • Else
  • If Not myRoot.RestoreConfig() Then
  • If Not myRoot.ShowConfigDialog Then
  • Exit Sub
  • End If
  • End If
  • End If
  • frmInfoLoad.Show()
  • frmInfoLoad.Refresh() 'nécessair pour afficher son contenu
  • 'Cette partie permet de remplir les listes locales de la form pour le rechargement de la scène
  • Me.lstRessources.Items.Clear()
  • Me.lstTypeRessources.Items.Clear()
  • Me.txtNomScene = frmViewerload.txtNomscene
  • For i As Integer = 0 To frmViewerload.lstRessources.Items.Count - 1
  • Me.lstRessources.Items.Add(frmViewerload.lstRessources.Items(i))
  • Next
  • For i As Integer = 0 To frmViewerload.lstTypeRessources.Items.Count - 1
  • Me.lstTypeRessources.Items.Add(frmViewerload.lstTypeRessources.Items(i))
  • Next
  • 'Et on initialise la scène
  • Me.InitScene()
  • LoadAxe() 'On ajoute les axes
  • Me.InitTree(mySceneManager.RootSceneNode, Nothing) 'On remplit la treeview
  • frmViewerload.Dispose() 'et on détruit la form de chargement
  • 'On ajoutes la gestion des évèbements aux champs texte
  • AddHandler txtPositionY.ValueChanged, AddressOf Position
  • AddHandler txtPositionZ.ValueChanged, AddressOf Position
  • AddHandler txtScaleY.ValueChanged, AddressOf Echelle
  • AddHandler txtScaleZ.ValueChanged, AddressOf Echelle
  • 'On détruit la form d'attente
  • frmInfoLoad.Hide()
  • frmInfoLoad.Dispose()
  • Cursor = Cursors.Default
  • 'On démarre le timer pour le rendu et la gestion des touches
  • 'timerRendu.Enabled = True
  • init = False 'L'initialisation est terminé, la variable init passe à false
  • Me.Show() 'Tout est fini, on affiche la fenêtre
  • 'myRoot.StartRendering()
  • While RenduEnCours
  • My.Application.DoEvents()
  • 'Affichage des infos de rendu
  • Try
  • lblAvg.Text = "FPS moyennes: " & Mogre.StringConverter.ToString(MyWindow.AverageFPS, 3)
  • lblCurr.Text = "FPS courantes: " & Mogre.StringConverter.ToString(MyWindow.LastFPS, 3)
  • lblBest.Text = "Meilleures FPS: " & Mogre.StringConverter.ToString(MyWindow.BestFPS, 3)
  • lblWorst.Text = "Pires FPS: " & Mogre.StringConverter.ToString(MyWindow.WorstFPS, 3)
  • lblNumTris.Text = "Triangles: " & Mogre.StringConverter.ToString(MyWindow.TriangleCount)
  • lblNumBatches.Text = "Nombre de Batch: " & Mogre.StringConverter.ToString(MyWindow.BatchCount)
  • Catch ex As Exception
  • End Try
  • 'et on rend une frame
  • myRoot.RenderOneFrame()
  • 'Update du monde physique
  • If mnuDetectionDeCollision.Checked Then
  • Dim stepPhysics As Single = 0.1
  • myWorld.Update(stepPhysics)
  • End If
  • If SceneNodeSelected Is Nothing Then
  • 'si un objet est sélectionné ou pas, on active ou désactive le panneau de paramètre
  • grpParamObjet.Enabled = False
  • cmdResetEtat.Enabled = False
  • Else
  • grpParamObjet.Enabled = True
  • cmdResetEtat.Enabled = True
  • End If
  • End While
  • 'Sur des machines rapide, le nombre trop élevé de FPS rend la rotation sur X des plus étrange si la détection de collisions est activée.
  • 'Le renderOneFrame rendant moins de FPS, je l'utilise dans le timer.
  • 'C'est surement une histoire de facteur de multiplication lors de la récupération de camera_rotation_x, mais je n'ai pas trouvé la formule magique.
  • DisposeNewton()
  • If mnuDetectionDeCollision.Checked Then
  • DisposeOgre()
  • End If
  • Else
  • 'Sinon on s'en va
  • Me.Dispose()
  • End If
  • End Sub
  • Private Sub frmMain_Disposed(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Disposed
  • 'On se contente d'arrêter le timer et à positionner la vaiable permettant de stopper le rendu Ogre, le reste des ressources ser libéré par le garbage collector (en tout cas on l'espère ;o) )
  • 'timerRendu.Enabled = False
  • RenduEnCours = False
  • End Sub
  • #End Region
  • #Region "Timer"
  • Private Sub timerRendu_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles timerRendu.Tick
  • ''Affichage des infos de rendu
  • 'Try
  • ' lblAvg.Text = "FPS moyennes: " & Mogre.StringConverter.ToString(MyWindow.AverageFPS, 3)
  • ' lblCurr.Text = "FPS courantes: " & Mogre.StringConverter.ToString(MyWindow.LastFPS, 3)
  • ' lblBest.Text = "Meilleures FPS: " & Mogre.StringConverter.ToString(MyWindow.BestFPS, 3)
  • ' lblWorst.Text = "Pires FPS: " & Mogre.StringConverter.ToString(MyWindow.WorstFPS, 3)
  • ' lblNumTris.Text = "Triangles: " & Mogre.StringConverter.ToString(MyWindow.TriangleCount)
  • ' lblNumBatches.Text = "Nombre de Batch: " & Mogre.StringConverter.ToString(MyWindow.BatchCount)
  • 'Catch ex As Exception
  • 'End Try
  • ''et on rend une frame
  • ''myRoot.RenderOneFrame()
  • ''Update du monde physique
  • 'If mnuDetectionDeCollision.Checked Then
  • ' Dim stepPhysics As Single = 0.1
  • ' myWorld.Update(stepPhysics)
  • 'End If
  • 'If SceneNodeSelected Is Nothing Then
  • ' 'si un objet est sélectionné ou pas, on active ou désactive le panneau de paramètre
  • ' grpParamObjet.Enabled = False
  • ' cmdResetEtat.Enabled = False
  • 'Else
  • ' grpParamObjet.Enabled = True
  • ' cmdResetEtat.Enabled = True
  • 'End If
  • End Sub
  • #End Region
  • #Region "Picture Box (Pour le rendu Ogre et le choix des couleurs de la lumière)"
  • Private Sub picMogre_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles picMogre.MouseDown
  • 'Quand on clique dans la picture box, on active le déplacement si c'est avec le bouton gauche
  • If e.Button = Windows.Forms.MouseButtons.Left Then
  • moving = True
  • Cursor.Hide()
  • End If
  • End Sub
  • Private Sub picMogre_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles picMogre.MouseUp
  • 'Et on désactive le déplacement quand on relache le bouton gauche
  • If e.Button = Windows.Forms.MouseButtons.Left Then
  • moving = False
  • Cursor.Show()
  • End If
  • End Sub
  • Private Sub picSpecular_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles picSpecular.DoubleClick
  • 'On passe les paramètres à la form de sélection des couleurs (la lumière sélectionner et l'action à effectuer)
  • frmColorDialogue.myLight = LightSelected
  • frmColorDialogue.Provenance = "Specular"
  • 'On ouvre la form
  • frmColorDialogue.ShowDialog()
  • 'on la libère
  • frmColorDialogue.Dispose()
  • End Sub
  • Private Sub picDiffuse_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles picDiffuse.DoubleClick
  • 'On passe les paramètres à la form de sélection des couleurs (la lumière sélectionner et l'action à effectuer)
  • frmColorDialogue.myLight = LightSelected
  • frmColorDialogue.Provenance = "Diffuse"
  • 'On ouvre la form
  • frmColorDialogue.ShowDialog()
  • 'on la libère
  • frmColorDialogue.Dispose()
  • End Sub
  • Private Sub picMogre_SizeChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles picMogre.SizeChanged
  • 'Pour redimensionner le vieport de manière correcte quant on redimmensionne la picturebox (du à un resize de la form ou un déplacement des splitter)
  • If Not init Then 'on ne le fait qu'une fois l'initalisation terminée.
  • timerRendu.Enabled = False 'on arrête le timer (on ne va pas rendre pendant que le vieport n'existe plus...)
  • Try
  • 'on récupère le viewport
  • Dim myViewport As Mogre.Viewport = MyWindow.GetViewport(0)
  • 'on récupère la couleur du vieport car elle est perdu à sa destruction
  • Dim CouleurVieport As Mogre.ColourValue = myViewport.BackgroundColour
  • 'On le supprime de la fenêtre de rendu
  • MyWindow.RemoveViewport(myViewport.ZOrder)
  • 'Et on efface la feneêtre de rendu
  • myRoot.DetachRenderTarget(MyWindow)
  • MyWindow.Dispose()
  • MyWindow = Nothing
  • 'On recrè la fenêtre, qui prendra comme dimension la nouvelle taille du contrôle
  • Dim misc As NameValuePairList = New NameValuePairList
  • misc("externalWindowHandle") = picMogre.Handle.ToString
  • Dim const_list As Const_NameValuePairList = misc.ReadOnlyInstance
  • MyWindow = myRoot.CreateRenderWindow("OgreWieport", 0, 0, False, const_list)
  • 'On recrè un viewport avec les nouveaux paramètrex
  • myViewport = MyWindow.AddViewport(myCamera)
  • 'on réaffecte la couleur précédemment sauvegardée
  • myViewport.BackgroundColour = CouleurVieport
  • 'on fixe l'aspect ratio de la caméra
  • myCamera.AspectRatio = myViewport.ActualWidth / myViewport.ActualHeight
  • Catch ex As Exception
  • 'en cas d'erreur....
  • If OgreException.IsThrown Then
  • Try 'parfois ça plante ici car OgreException.LastException n'est pas défini, donc je réimbrique un try
  • MsgBox(OgreException.LastException.FullDescription, MsgBoxStyle.Critical, _
  • "Exeption OGRE!")
  • Catch ex2 As Exception
  • End Try
  • Else
  • MsgBox(ex.ToString, "Erreur")
  • End If
  • End Try
  • timerRendu.Enabled = True 'on redémarre le timer
  • End If
  • End Sub
  • #End Region
  • #Region "Champs texte"
  • Private Sub txtFOV_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtFOV.TextChanged
  • 'Permet de changer l'angle du champ de vision
  • If txtFOV.Text <> "" Then
  • Try
  • myCamera.FOVy = CType(txtFOV.Text, Mogre.Radian)
  • Catch ex As Exception
  • End Try
  • End If
  • End Sub
  • Private Sub Echelle(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtScaleX.ValueChanged
  • 'Appeller par les 3 txtScale, permet de changer le facteur d'échelle de l'objet sélectionné
  • If Not EnCoursDeSelection Then 'nécessaire car si on est en cours de sélection d'un objet, de mauvais paramètres sont appliqués
  • SceneNodeSelected.SetScale(txtScaleX.Value, txtScaleY.Value, txtScaleZ.Value) 'et on applique l'échelle
  • End If
  • End Sub
  • Private Sub Position(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtPositionX.ValueChanged, txtPositionX.Scroll
  • 'Appeller par les 3 txtPosition, permet de changer la position de l'objet sélectionné
  • If Not EnCoursDeSelection And Not EnCoursDeTranslation Then 'nécessaire car si on est en cours de sélection d'un objet, de mauvais paramètres sont appliqués
  • SceneNodeSelected.SetPosition(txtPositionX.Value, txtPositionY.Value, txtPositionZ.Value) 'et on applique la position
  • End If
  • End Sub
  • #End Region
  • #Region "Les menus"
  • Private Sub mnuParamOgre_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuParamOgre.Click
  • 'Montre la fenêtre de configuration OGRE
  • myRoot.ShowConfigDialog()
  • 'Une fois les paramètres modifiés, on recharge la scène
  • mnuRecharger_Click(sender, e)
  • End Sub
  • Private Sub mnuOuvrir_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuOuvrir.Click
  • Me.Hide() 'On cache la fenêtre principale
  • 'Affichage de la fenêtre de choix de la scène à charger
  • frmViewerload.ShowDialog()
  • If frmViewerload.bValide Then
  • 'Si on a valider le choix.....
  • 'On affiche la form d'attente
  • frmInfoLoad.Show()
  • frmInfoLoad.Refresh() 'nécessair pour afficher son contenu
  • Cursor = Cursors.WaitCursor 'juste pour la beauté
  • 'timerRendu.Enabled = False 'on arrête le timer
  • DisposeNewton()
  • DisposeOgre() 'on libère les ressources Ogre
  • 'on reinitialise les checkboxs
  • chkTracking.Checked = False
  • chkAxe.Checked = False
  • 'on vide le treeview et on recrè les 3 noeuds de base
  • treeScene.Nodes.Clear()
  • treeScene.Nodes.Add("Root")
  • treeScene.Nodes.Item(0).Nodes.Add("Autres")
  • treeScene.Nodes.Item(0).Nodes.Add("Cameras")
  • treeScene.Nodes.Item(0).Nodes.Add("Lights")
  • treeScene.Nodes.Item(0).Nodes.Add("Entities")
  • 'on vide les listes héritées de la forme de chargement pour le menu recharger
  • Me.lstRessources.Items.Clear()
  • Me.lstTypeRessources.Items.Clear()
  • Me.txtNomScene = frmViewerload.txtNomscene
  • 'et on les remplit avec les nouvelles valeur
  • For i As Integer = 0 To frmViewerload.lstRessources.Items.Count - 1
  • Me.lstRessources.Items.Add(frmViewerload.lstRessources.Items(i))
  • Next
  • For i As Integer = 0 To frmViewerload.lstTypeRessources.Items.Count - 1
  • Me.lstTypeRessources.Items.Add(frmViewerload.lstTypeRessources.Items(i))
  • Next
  • 'On recrè le scène manager
  • mySceneManager = myRoot.CreateSceneManager(SceneType.ST_GENERIC)
  • If frmViewerload.chkPhysique.Checked Then
  • mnuDetectionDeCollision.Checked = True
  • mnuGravite.Enabled = True
  • mnuDebugActif.Enabled = True
  • End If
  • 'Affichage de la fenêtre de paramètres OGRES, le cas échéant
  • If frmViewerload.chkOgre.Checked Then
  • If Not myRoot.ShowConfigDialog Then
  • Exit Sub
  • End If
  • Else
  • If Not myRoot.RestoreConfig() Then
  • If Not myRoot.ShowConfigDialog Then
  • Exit Sub
  • End If
  • End If
  • End If
  • 'Et on initialise la scène
  • Me.InitScene()
  • LoadAxe() 'On charge les axes
  • Me.InitTree(mySceneManager.RootSceneNode, Nothing) 'on remplit la treeview
  • 'On détruit la form d'attente
  • frmInfoLoad.Hide()
  • frmInfoLoad.Dispose()
  • Cursor = Cursors.Default
  • Me.Show() 'et on réaffiche la fenêtre
  • 'on libère la form de chargement
  • frmViewerload.Dispose()
  • 'On démarre le timer pour le rendu et la gestion des touches
  • 'timerRendu.Enabled = True
  • End If
  • End Sub
  • Private Sub mnuCouleurDuViewport_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuCouleurDuViewport.Click
  • 'on récupère le vieport
  • Dim myViewport As Mogre.Viewport = MyWindow.GetViewport(0)
  • 'pour le passer en paramètre à la fenêtre de choix des couleurs
  • frmColorDialogue.myViewPort = myViewport
  • frmColorDialogue.Provenance = "Viewport"
  • 'on l'affiche
  • frmColorDialogue.ShowDialog()
  • 'et on la libère
  • frmColorDialogue.Dispose()
  • End Sub
  • Private Sub mnuRecharger_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuRecharger.Click
  • 'Permet de recharger la scène en cours
  • Cursor = Cursors.WaitCursor
  • Me.Hide()
  • 'On affiche la form d'attente
  • frmInfoLoad.Show()
  • frmInfoLoad.Refresh() 'nécessair pour afficher son contenu
  • 'on arrête le timer
  • 'timerRendu.Enabled = False
  • 'on détruit nos différentes interfaces
  • DisposeNewton()
  • DisposeOgre()
  • treeScene.Nodes.Clear()
  • treeScene.Nodes.Add("Root")
  • 'on recrè les noeuds de base du treeview
  • treeScene.Nodes.Item(0).Nodes.Add("Autres")
  • treeScene.Nodes.Item(0).Nodes.Add("Cameras")
  • treeScene.Nodes.Item(0).Nodes.Add("Lights")
  • treeScene.Nodes.Item(0).Nodes.Add("Entities")
  • 'on initialise le scenemanager
  • mySceneManager = myRoot.CreateSceneManager(SceneType.ST_GENERIC)
  • 'Et on initialise la scène
  • Me.InitScene()
  • LoadAxe() 'on charge les axes
  • Me.InitTree(mySceneManager.RootSceneNode, Nothing) 'on initialise le treeview
  • 'On détruit la form d'attente
  • frmInfoLoad.Hide()
  • frmInfoLoad.Dispose()
  • Me.Show()
  • Cursor = Cursors.Default
  • 'On démarre le timer pour le rendu et la gestion des touches
  • 'timerRendu.Enabled = True
  • End Sub
  • Private Sub mnuAxeDuMonde_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuAxeDuMonde.Click
  • 'permet de montrer/cacher l'axe du monde
  • If mnuAxeDuMonde.Checked Then
  • NodeAxeMonde.SetVisible(True)
  • Else
  • NodeAxeMonde.SetVisible(False)
  • End If
  • End Sub
  • Private Sub mnuOmbres_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuOmbres.Click
  • 'Permet d'afficher ou pas les ombres on fonction de la technique choisie
  • If mnuOmbres.Checked Then
  • mySceneManager.ShadowTechnique = MyShadowTechnique
  • Else
  • mySceneManager.ShadowTechnique = ShadowTechnique.SHADOWTYPE_NONE
  • End If
  • End Sub
  • Private Sub mnuShadowType_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles mnuShadowType.SelectedIndexChanged
  • 'C'est un menu combbox pour la simple raison que le traitement du choix est simplifié (pas à se paluche les évènements de 6 menu, juste une sélection dans une combo)
  • Select Case mnuShadowType.SelectedIndex
  • Case 0
  • MyShadowTechnique = ShadowTechnique.SHADOWTYPE_STENCIL_MODULATIVE
  • Case 1
  • MyShadowTechnique = ShadowTechnique.SHADOWTYPE_STENCIL_ADDITIVE
  • Case 2
  • MyShadowTechnique = ShadowTechnique.SHADOWTYPE_TEXTURE_MODULATIVE
  • Case 3
  • MyShadowTechnique = ShadowTechnique.SHADOWTYPE_TEXTURE_ADDITIVE
  • Case 4
  • MyShadowTechnique = ShadowTechnique.SHADOWTYPE_TEXTURE_ADDITIVE_INTEGRATED
  • Case 5
  • MyShadowTechnique = ShadowTechnique.SHADOWTYPE_TEXTURE_MODULATIVE_INTEGRATED
  • End Select
  • 'si le menu d'affichage des ombres est coché, on applique directe
  • If mnuOmbres.Checked Then
  • mySceneManager.ShadowTechnique = MyShadowTechnique
  • End If
  • End Sub
  • Private Sub mnuCouleurOmbres_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuCouleurOmbres.Click
  • 'On passe les paramètre à la forme de choix des couleurs
  • frmColorDialogue.mySceneManager = mySceneManager
  • frmColorDialogue.Provenance = "Ombres"
  • 'on l'affiche
  • frmColorDialogue.ShowDialog()
  • 'et on la libère
  • frmColorDialogue.Dispose()
  • End Sub
  • Private Sub mnuLumireAmbiante_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuLumireAmbiante.Click
  • 'On passe les paramètre à la forme de choix des couleurs
  • frmColorDialogue.mySceneManager = mySceneManager
  • frmColorDialogue.Provenance = "Ambiante"
  • 'on l'affiche
  • frmColorDialogue.ShowDialog()
  • 'et on la libère
  • frmColorDialogue.Dispose()
  • End Sub
  • Private Sub mnuDetectionDeCollision_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuDetectionDeCollision.Click
  • mnuOptions.HideDropDown()
  • If mnuDetectionDeCollision.Checked Then
  • mnuGravite.Enabled = True
  • 'mnuGravite.Checked = True
  • mnuDebugActif.Enabled = True
  • mnuRecharger_Click(sender, e)
  • Else
  • mnuGravite.Enabled = False
  • mnuGravite.Checked = False
  • mnuDebugActif.Enabled = False
  • mnuRecharger_Click(sender, e)
  • End If
  • End Sub
  • Private Sub mnuDebugActif_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuDebugActif.Click
  • If mnuDebugActif.Checked Then
  • MogreNewt.Debugger.Instance.ShowLines(myWorld)
  • Else
  • MogreNewt.Debugger.Instance.HideLines()
  • End If
  • End Sub
  • Private Sub mnuHauteurCamera_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles mnuHauteurCamera.TextChanged
  • 'Permet de changer la hauteur de la caméra en temps réel
  • Try
  • If Not init Then
  • Me.CamSize.y = mnuHauteurCamera.Text
  • Me.CamNode.SetScale(Me.CamSize)
  • End If
  • Catch ex As Exception
  • End Try
  • End Sub
  • #End Region
  • #Region "Le treeview"
  • Private Sub treeScene_AfterSelect(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles treeScene.AfterSelect
  • 'si on est pas en cours de chargement de la scène initiale, on traite la sélection du treeview
  • If Not init Then
  • 'on cache le groupe pour la gestion de la lumière
  • grpLumiere.Visible = False
  • 'on est en cours de sélection d'un objet donc :
  • EnCoursDeSelection = True
  • 'chkAxe.Checked = False
  • If Not SceneNodeSelected Is Nothing Then 'si le scenenodeselected précédent n'est pas vide, on cache sa bounding box
  • SceneNodeSelected.ShowBoundingBox = False
  • End If
  • Try
  • Dim tree As TreeView = sender 'on récupère le sender dans un objet typé (plus pratique pour coder
  • SceneNodeSelected = tree.SelectedNode.Tag 'on récupère le scenenode dans le tag du treenode
  • Dim ObjectType As String 'pour le test du type d'objet sélectionné
  • Try
  • MObjectSelected = SceneNodeSelected.GetAttachedObject(tree.SelectedNode.Name) 'on récupère l'objet contenu dans le scenenode
  • Catch
  • End Try
  • If Not e.Node.Text.ToUpper.Contains("ROOT") Then 'si on est pas sur root, alors :
  • Try
  • ObjectType = MObjectSelected.MovableType 'on récupère le type de l'objet
  • Select Case ObjectType
  • Case "Entity" 'si c'est une entity
  • chkTracking.Checked = False
  • chkTracking.Enabled = True
  • grpParamObjet.Enabled = True
  • Case "Camera" 'si c'est une caméra
  • grpParamObjet.Enabled = False
  • myCamera = mySceneManager.GetCamera(MObjectSelected.Name) 'on récupère son nom
  • Dim ViewPort As Mogre.Viewport = MyWindow.GetViewport(0) 'on récupère le premier viewport
  • ViewPort.Camera = myCamera 'et on change de caméra
  • Case "Light" 'si c'est une lumière
  • grpLumiere.Visible = True
  • grpParamObjet.Enabled = True
  • chkTracking.Checked = False
  • chkTracking.Enabled = True
  • LightSelected = MObjectSelected
  • 'on paramètre les picturesbox représentant la couleur de la lumière avec ses couleurs, justement
  • picDiffuse.BackColor = Color.FromArgb(LightSelected.DiffuseColour.GetAsARGB())
  • picSpecular.BackColor = Color.FromArgb(LightSelected.SpecularColour.GetAsARGB())
  • 'et les trackbar pour régler l'atténuation
  • trkRange.Value = LightSelected.AttenuationRange * 100
  • trkConstant.Value = LightSelected.AttenuationConstant * 100
  • trkLinear.Value = LightSelected.AttenuationLinear * 100
  • trkQuadratic.Value = LightSelected.AttenuationQuadric * 100
  • End Select
  • grpParamObjet.Text = "Modifications objet : " + SceneNodeSelected.Name
  • Catch ex As Exception
  • 'si on est en erreur, on désactive tout
  • chkTracking.Checked = False
  • chkTracking.Enabled = True
  • grpLumiere.Visible = False
  • grpParamObjet.Enabled = False
  • End Try
  • Try
  • 'on montre la bounding box de l'objet sélectionné
  • SceneNodeSelected.ShowBoundingBox = True
  • Catch ex As Exception
  • End Try
  • RemplitGrille() 'on remplit la grille de paramètres de l'objet
  • EnCoursDeSelection = False 'la sélection est terminée
  • If ShowAxes Then
  • chkAxe.Checked = True 'si on doit montrer l'axe de l'objet, on le fait
  • End If
  • If TrackObjet Then
  • chkTracking.Checked = True 'si l'autotrackin est actif, alors on le remet
  • End If
  • End If
  • Catch ex As System.Runtime.InteropServices.SEHException
  • 'en cas d'erreur....on ne fait rien de spécial
  • End Try
  • End If
  • End Sub
  • Private Sub treeScene_BeforeSelect(ByVal sender As Object, ByVal e As System.Windows.Forms.TreeViewCancelEventArgs) Handles treeScene.BeforeSelect
  • 'Si l'axe de l'objet est affiché
  • If ShowAxes Then
  • chkAxe.Checked = False 'on va déclencher l'évènement changed de la checkbox
  • End If
  • If TrackObjet Then ' on fait pareil pour l'autotracking
  • chkTracking.Checked = False
  • End If
  • End Sub
  • #End Region
  • #Region "Les check box"
  • Private Sub chkTracking_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkTracking.CheckedChanged
  • 'Permet d'activer/désactiver l'autotracking de l'objet sélectionné par la caméra
  • Try
  • myCamera.SetAutoTracking(False)
  • If chkTracking.Checked Then
  • myCamera.SetAutoTracking(True, SceneNodeSelected)
  • End If
  • Catch ex As Exception
  • End Try
  • End Sub
  • Private Sub chkAxe_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkAxe.CheckedChanged
  • 'Permet de montrer/cacher l'axe de l'objet sélectionné
  • If Not EnCoursDeSelection Then 'si on est pas en cours de sélection de l'objet
  • Try
  • If chkAxe.Checked Then
  • 'Lorsque la case est cochée
  • mySceneManager.RootSceneNode.RemoveChild(NodeAxe) 'on détache l'axe de la racine
  • SceneNodeSelected.AddChild(NodeAxe) 'on l'attache à l'objet sélectionnée
  • NodeAxe.SetPosition(0, 0, 0) 'au centre de ce dernier
  • NodeAxe.SetOrientation(SceneNodeSelected.Orientation.w, SceneNodeSelected.Orientation.x, SceneNodeSelected.Orientation.y, SceneNodeSelected.Orientation.z) 'et avec l'orientation de ce dernier
  • NodeAxe.SetVisible(True) 'et on le montre
  • Else
  • 'lorsque la case est décochée, on cache le Node de l'axe
  • NodeAxe.SetVisible(False)
  • SceneNodeSelected.RemoveChild(NodeAxe) 'on l'enlève de l'objet sélectionné
  • mySceneManager.RootSceneNode.AddChild(NodeAxe) 'et on l'attache à la racine
  • End If
  • Catch
  • 'Juste au cas ou...
  • End Try
  • End If
  • End Sub
  • Private Sub chkAxe_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles chkAxe.Click
  • 'On inverse simplement la variable permettant de savoir si on affiche ou pas l'axe des objets
  • ShowAxes = Not ShowAxes
  • End Sub
  • Private Sub chkTracking_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles chkTracking.Click
  • 'On inverse simplement la variable permettant de savoir si on est en autotracking des objets
  • TrackObjet = Not TrackObjet
  • End Sub
  • #End Region
  • #Region "La grille"
  • Private Sub grdDetail_CellDoubleClick(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles grdDetail.CellDoubleClick
  • 'Lors d'un double clique sur les cellules de la grille, on permet le choix sur boundingbox et visible (les autres valeurs sont modifiée par les champs en entête de la form
  • Dim rectangle As New System.Drawing.Rectangle 'le rectangle correspondant à la cellule sélectionnée
  • Dim Cell As DataGridViewCell = sender.currentcell 'on récupère la cellule sélectionnée
  • Dim Row As DataGridViewRow = sender.rows(Cell.RowIndex) 'la ligne sélectionnée
  • Dim FirstCell As DataGridViewCell = Row.Cells(0) 'La première cellule
  • rectangle = Me.grdDetail.GetCellDisplayRectangle(Cell.ColumnIndex, Cell.RowIndex, True) 'on paramètre le rectangle
  • If Cell.Value = "Oui" Then 'suivant la valeur de la cellule, on paramètre la combobox
  • Me.cboBoolean.SelectedIndex = 0
  • Else
  • Me.cboBoolean.SelectedIndex = 1
  • End If
  • 'on positionne et dimmensionne la combobox pour l'afficher dans la cellule
  • Me.cboBoolean.Top = rectangle.Top
  • Me.cboBoolean.Left = rectangle.Left
  • Me.cboBoolean.Width = rectangle.Width
  • Me.cboBoolean.Height = rectangle.Height
  • Me.cboBoolean.Tag = FirstCell.Value 'pour savoir sur quel paramètre de la grille on travail (cf. cboBoolean.SelectedIndexChanged)
  • 'et on la montre
  • Me.cboBoolean.Visible = True
  • End Sub
  • #End Region
  • #Region "Les Command Buttons"
  • Private Sub cmdSetDirection_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdSetDirection.Click
  • 'Permet de fixer la direction de l'objet en fonction des 3 champs textes
  • SceneNodeSelected.SetDirection(txtDirectionX.Value, txtDirectionY.Value, txtDirectionZ.Value)
  • GetOrientation() 'pour afficher les nouvelles valeurs
  • End Sub
  • Private Sub cmdPitch_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdPitch.Click
  • 'On tourne sur X
  • SceneNodeSelected.Pitch(txtRotationX.Value)
  • 'Si l'axe est affiché, même punition. Réaction bizarre si la vaiable inheritorientation est mise à true.
  • If ShowAxes Then
  • NodeAxe.Pitch(txtRotationX.Value)
  • End If
  • GetOrientation() 'on affiche la nouvelle orientation
  • End Sub
  • Private Sub cmdYAw_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdYAw.Click
  • 'cf. cmdPich_Click sauf que c'est sur Y
  • SceneNodeSelected.Yaw(txtRotationY.Value)
  • If ShowAxes Then
  • NodeAxe.Yaw(txtRotationY.Value)
  • End If
  • GetOrientation()
  • End Sub
  • Private Sub cmdRoll_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdRoll.Click
  • 'cf. cmdPich_Click sauf que c'est sur Z
  • SceneNodeSelected.Roll(txtRotationZ.Value)
  • If ShowAxes Then
  • NodeAxe.Roll(txtRotationZ.Value)
  • End If
  • GetOrientation()
  • End Sub
  • Private Sub cmdResetOrientation_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdResetOrientation.Click
  • 'Permet de mettre l'objet dans sa direction de création, avant toute rotation
  • SceneNodeSelected.ResetOrientation()
  • GetOrientation()
  • End Sub
  • Private Sub cmdSetorientation_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdSetorientation.Click
  • 'Permet de ficer l'orientation de l'objet en fonction des 4 paramètre choisis
  • SceneNodeSelected.SetOrientation(txtOrientationW.Value, txtOrientationX.Value, txtOrientationY.Value, txtOrientationZ.Value)
  • End Sub
  • Private Sub cmdResetEtat_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdResetEtat.Click
  • 'Permet de réinitialiser l'objet à ses conditions d'origine
  • EnCoursDeSelection = True
  • SceneNodeSelected.ResetToInitialState()
  • 'on récupère les nouvelles valeurs pour les afficher
  • GetPosition()
  • GetOrientation()
  • GetEchelle()
  • EnCoursDeSelection = False
  • End Sub
  • Private Sub cmdSetTranslation_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdSetTranslation.Click
  • 'Permet de déplacer l'objet en fonction de l'axe choisi
  • Dim Axe As Mogre.Node.TransformSpace
  • EnCoursDeTranslation = True 'on commence la translation
  • 'On récupère l'axe choisi dans la combobox
  • Select Case cboTransAxe.SelectedIndex
  • Case 0
  • Axe = Node.TransformSpace.TS_LOCAL
  • Case 1
  • Axe = Node.TransformSpace.TS_PARENT
  • Case 2
  • Axe = Node.TransformSpace.TS_WORLD
  • End Select
  • 'et on translate en fonction des paramètres sélectionés
  • SceneNodeSelected.Translate(txtTransX.Value, txtTransY.Value, txtTransZ.Value, Axe)
  • GetPosition() 'on récupère la nouvelle position
  • EnCoursDeTranslation = False 'la translation est terminée
  • End Sub
  • Private Sub cmdReinitCamera_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdReinitCamera.Click
  • 'Pour réinitialiser la caméra à sa position d'origine
  • If mnuDetectionDeCollision.Checked Then
  • CamBody.SetPositionOrientation(InitialCamBodyPos, InitialCamBodyOrient)
  • Else
  • myCamera.SetPosition(InitialCamBodyPos.x, InitialCamBodyPos.y, InitialCamBodyPos.z)
  • myCamera.Orientation = InitialCamBodyOrient
  • End If
  • End Sub
  • #End Region
  • #Region "Les ComboBox"
  • Private Sub cboBoolean_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cboBoolean.SelectedIndexChanged
  • 'Si la combobox est visible, alors on est en tains de choisir l'option
  • If cboBoolean.Visible Then
  • If cboBoolean.Tag = "Visible" Then 'si ça porte sur la visibilité de l'objet
  • If cboBoolean.SelectedIndex = 0 Then
  • MObjectSelected.Visible = True
  • Else
  • MObjectSelected.Visible = False
  • End If
  • ElseIf cboBoolean.Tag = "CastShadows" Then 'sur sa faculté à projeter une ombre
  • If cboBoolean.SelectedIndex = 0 Then
  • MObjectSelected.CastShadows = True
  • Else
  • MObjectSelected.CastShadows = False
  • End If
  • Else 'alors c'est la boundingbox
  • If cboBoolean.SelectedIndex = 0 Then
  • SceneNodeSelected.ShowBoundingBox = True
  • Else
  • SceneNodeSelected.ShowBoundingBox = False
  • End If
  • End If
  • cboBoolean.Visible = False 'on cache la combobox
  • RemplitGrille() 'et on reremplit la grille
  • End If
  • End Sub
  • #End Region
  • #Region "Les trackbars"
  • Private Sub trkRange_ValueChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles trkRange.ValueChanged
  • 'Modification de la portée de la lumière
  • lblRange.Text = trkRange.Value
  • LightSelected.SetAttenuation(trkRange.Value, trkConstant.Value / 100, System.Math.Round(trkLinear.Value / 10000, 5), System.Math.Round(trkQuadratic.Value / 10000, 5))
  • 'Les valeurs sont divisée pour s'accorder au range des paramètres. A affiner, pour voir plus ou moins d'effets
  • End Sub
  • Private Sub trkConstant_ValueChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles trkConstant.ValueChanged
  • 'La constante d'atténuation
  • lblConstant.Text = trkConstant.Value / 100
  • LightSelected.SetAttenuation(trkRange.Value, trkConstant.Value / 100, System.Math.Round(trkLinear.Value / 10000, 5), System.Math.Round(trkQuadratic.Value / 10000, 5))
  • 'Les valeurs sont divisée pour s'accorder au range des paramètres. A affiner, pour voir plus ou moins d'effets
  • End Sub
  • Private Sub trkLinear_ValueChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles trkLinear.ValueChanged
  • 'La linéarité de l'atténuation
  • lblLinear.Text = System.Math.Round(trkLinear.Value / 10000, 5)
  • LightSelected.SetAttenuation(trkRange.Value, trkConstant.Value / 100, System.Math.Round(trkLinear.Value / 10000, 5), System.Math.Round(trkQuadratic.Value / 10000, 5))
  • 'Les valeurs sont divisée pour s'accorder au range des paramètres. A affiner, pour voir plus ou moins d'effets
  • End Sub
  • Private Sub trkQuadratic_ValueChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles trkQuadratic.ValueChanged
  • 'La valeur Quadratic (Pas tout compris là...)
  • lblQuadratic.Text = System.Math.Round(trkQuadratic.Value / 10000, 5)
  • LightSelected.SetAttenuation(trkRange.Value, trkConstant.Value / 100, System.Math.Round(trkLinear.Value / 10000, 5), System.Math.Round(trkQuadratic.Value / 10000, 5))
  • 'Les valeurs sont divisée pour s'accorder au range des paramètres. A affiner, pour voir plus ou moins d'effets
  • End Sub
  • #End Region
  • #End Region
  • End Class
Imports Mogre
Imports MOIS
Imports MogreNewt
Imports OFusion
Imports System.Runtime.InteropServices

Public Class frmMain

#Region "Déclarations"

    Private myRoot As Root 'La racine OGRE
    Private mySceneManager As SceneManager 'Le SceneManager OGRE
    Private myCamera As Camera 'La caméra
    Private MyWindow As RenderWindow 'La fenêtre de rendu (ici ce sera une picturebox)

    Private init As Boolean = True 'Permettra de savoir si on est en cours d'initialisation de l'application
    Private EnCoursDeSelection = False 'Permettra de savoir si un objet est en cours de sélection
    Private EnCoursDeTranslation As Boolean = False 'Permettra de savoir si un objet est en cours de translation
    Private ShowAxes As Boolean = False 'Axe du monde visible ou pas
    Private TrackObjet As Boolean = False 'Autotracking de la caméra actif ou pas
    Private RenduEnCours As Boolean = True 'Sert à savoir si on à quitter l'appli pour stopper le rendu

    Private Scene As OSMScene 'La variable pour le chargement de la scene oFusion
    Private MyShadowTechnique As Mogre.ShadowTechnique 'Continedra le choix du type d'affichage des ombres

    'Variables pour la sélectiond dans la TreeView
    Private SceneNodeSelected As Mogre.SceneNode 'Contiendra le noeud sélectionné dans le treeview
    Private MObjectSelected As Mogre.MovableObject 'Contiendra l'objet sélectionnée
    Private LightSelected As Mogre.Light 'Contiendra la lumière sélectionnée

    Private NodeAxe As Mogre.SceneNode 'L'axe des objets
    Private NodeAxeMonde As Mogre.SceneNode 'L'axe du monde

    'Déclarations pour Newton
    Private myWorld As World = Nothing 'Le monde physique
    Private Gravity As Single = -9.8 'Et oui, on aura un poid...(Sur terre = 9.81m/s²

    'La taille du body représentant le corp physique de la caméra
    'Ajuster cette valeur en fonction de la scène. A priori, 70 représente un humain d'à peu près 1m80, si mes 
    'estimations sont juste.
    Private CamSize As Mogre.Vector3 = New Mogre.Vector3(10, 70, 10)
    Private CamNode As SceneNode 'Le node de la caméra
    Private CamViewNode As SceneNode
    Private CamBody As Body 'Le corps physique de la caméra
    Private CamColl As CollisionPrimitives.Ellipsoid 'Le type de collision
    Private NoMovement As Boolean = True
    Private camera_rotation_x As Single
    Private camera_rotation_xx As Single
    Private camera_rotation_y As Mogre.Degree
    Private y_rotation_cont As Degree
    Private y_limit_a As Single = 90
    Private y_limit_b As Single = -90
    Private InitialCamBodyPos As Mogre.Vector3
    Private InitialCamBodyOrient As Mogre.Quaternion


    'Déclaration pour MOIS
    Private inputManager As MOIS.InputManager
    Private inputKeyboard As MOIS.Keyboard = Nothing
    Private inputMouse As MOIS.Mouse = Nothing

    'Translate & rotate scalars
    Private moving As Boolean

#End Region

#Region "CONSTANTES"

    'Changer ces constantes pour avoir des vitesses de déplacement et/ou de rotation différentes (mode détection de collisions inactif)
    Const TRANSLATE As Single = 600
    Const ROTATE As Single = 1

#End Region

#Region "Procédures & Fonctions"

    Private Function get_body_position(ByVal bod As Body) As Mogre.Vector3 'retourne la position du body 
        Dim orient As Quaternion
        Dim pos As Mogre.Vector3

        bod.GetPositionOrientation(pos, orient)

        Return pos

    End Function

    Private Function get_body_orientation(ByVal bod As Body) As Quaternion  ' retourne l'orientation du body
        Dim orient As Quaternion
        Dim pos As Mogre.Vector3

        bod.GetPositionOrientation(pos, orient)

        Return orient

    End Function

    Private Sub camera_force_callback(ByVal Corps As Body)

        'Cette procédure est appelée à chaque update du monde physique.
        'On y applique la gravité ainsi que la rotation sur l'axe des X

        If mnuGravite.Checked Then
            Dim masse As Single
            Dim inertie As Mogre.Vector3
            Dim Force As Mogre.Vector3

            'on récupère la position et l'orientation du corp passé en paramètre
            Dim posBody As Mogre.Vector3 = CamBody.Position
            Dim OrientBody As Quaternion = CamBody.Orientation
            Corps.GetMassMatrix(masse, inertie) 'on récupère sa masse et son inertie
            Force = New Mogre.Vector3(0, Gravity * 2000, 0) 'on y applique la gravité, le facteur de multiplication est là pour ajusté la valeur.
            'Curieusement, si je ne multiplie pas, on se croirait sur la Lune. Si quelqu'un sait pourquoi, merci de me le dire.
            Force *= masse
            Corps.AddForce(Force) 'on applique la force de gravité

        End If
        Corps.Omega = New Mogre.Vector3(0, camera_rotation_x, 0) 'pour le déplacement sur X

    End Sub

    Private Sub InitOgre()
        'Création de la racine OGRE et du SceneManager. Appeler dans le load de la form, le menu Ouvrir et le menu recharger

        myRoot = New Root("Plugins.cfg", "ogre.cfg", "ogre.log")
        mySceneManager = myRoot.CreateSceneManager(SceneType.ST_GENERIC)

    End Sub

    Private Sub InitTree(ByVal SceneNode As Mogre.SceneNode, ByVal sceneTreeNode As TreeNode)


        'Remplissage de la TreeView de sélection des objets
        'c'est une fonction récursive
        'TODO : classement en ordre alphabétique dans les 3 noeuds principaux

        Dim NumChildNodes As UShort 'le nombre d'enfants du scenenode passé en paramètre
        Dim NewNode As TreeNode = New TreeNode 'on crèe un nouveau node dans le treeview qui va recevoir les paramètres à ajouter au treeview

        Try
            NumChildNodes = SceneNode.NumChildren 'on récupère le nombre d'enfants du scenenode
            NewNode.Name = SceneNode.Name 'Son nom
            NewNode.Text = SceneNode.Name + " (" + NumChildNodes.ToString + " enfants)" 'on concatène le nombre d'enfants au nom pour l'affichage dans le treeview
            NewNode.Tag = SceneNode 'on met le scenenode dans le tag du noeud de la treeview pour s'en servir lors de la sélection du noeud dans la treeview (cf Treeview_AfterSelect)

            If SceneNode.Name.ToUpper.Contains("AXE") Then 'si on est sur un scenenode axe, on sort de la procédure car on ne veut pas le faire appraitre dans la treeview
                Exit Sub
            End If
            If SceneNode.Name.ToUpper.Contains("ROOT") Then 'si on est sur root du scenemanager, on ne fait rien, on se contante de lancer le premier niveau de récursivité
                treeScene.Nodes.Item(0).Text = "Root (" + NumChildNodes.ToString + " enfants)"
                For i As UShort = 0 To NumChildNodes - 1
                    InitTree(SceneNode.GetChild(i), treeScene.SelectedNode)
                Next
            Else 'sinon, on teste le type d'objet et suvant le cas on l'ajoute au noeud du treeview adéquate
                If SceneNode.GetAttachedObject(SceneNode.Name).MovableType = "Camera" Then
                    'Cette ligne permet de sélectionner le bon neoud auquel ajouté l'objet
                    treeScene.SelectedNode = treeScene.Nodes.Item(0).Nodes.Item(1)
                ElseIf SceneNode.GetAttachedObject(SceneNode.Name).MovableType = "Light" Then
                    treeScene.SelectedNode = treeScene.Nodes.Item(0).Nodes.Item(3)
                ElseIf SceneNode.GetAttachedObject(SceneNode.Name).MovableType = "Entity" Then
                    treeScene.SelectedNode = treeScene.Nodes.Item(0).Nodes.Item(2)
                End If

                'on ajoute le noeud
                treeScene.SelectedNode.Nodes.Add(NewNode)

                'treeScene.SelectedNode = treeScene.Nodes(treeScene.Nodes.Count - 1)

                If NumChildNodes > 0 Then 'si il y a des nodes enfants, on desend dans le scenenode
                    For i As UShort = 0 To NumChildNodes - 1
                        InitTree(SceneNode.GetChild(i), treeScene.SelectedNode)
                    Next
                End If

            End If
        Catch ex As System.Runtime.InteropServices.SEHException
            'en cas d'erreur....on ne fait rien, sinon, des messages apparaissent lors de la création du treeview, on se contente d'un gestionnaire générique pour ne pas planter le programme
            treeScene.SelectedNode = treeScene.Nodes.Item(0).Nodes.Item(0)
            'on ajoute le noeud
            treeScene.SelectedNode.Nodes.Add(NewNode)
            If NumChildNodes > 0 Then 'si il y a des nodes enfants, on desend dans le scenenode
                For i As UShort = 0 To NumChildNodes - 1
                    InitTree(SceneNode.GetChild(i), treeScene.SelectedNode)
                Next
            End If
        End Try

    End Sub

    Private Sub InitScene()
        Try
            'On initialise la racine OGRE
            myRoot.Initialise(False)

            'On crè la fenêtre, ici ce sera dans le contrôle picMogre, une picturebox
            Dim misc As NameValuePairList = New NameValuePairList
            misc("externalWindowHandle") = picMogre.Handle.ToString
            Dim const_list As Const_NameValuePairList = misc.ReadOnlyInstance
            MyWindow = myRoot.CreateRenderWindow("OgreWieport", 0, 0, False, const_list)

            'On ajoute un handler qui permettre de récupérer la variable timeSinceLastFrame pour la gestion des déplacements
            'AddHandler myRoot.FrameStarted, AddressOf FrameStarted


            'On crés le ressource manager avec les ressources choisie dans la boîte de chargement.
            'Par défaut, on prend le chemin de la scène
            ResourceGroupManager.Singleton.AddResourceLocation(System.IO.Path.GetDirectoryName(txtNomScene.Text), "FileSystem", "General")

            'On ajoute le répertoires OBJETS de l'application qui contient, entre autre, les axes
            ResourceGroupManager.Singleton.AddResourceLocation(Application.StartupPath + "\Objets", "FileSystem", "General")

            'et on parcourt la listbox de la fenêtre de choix pour ajouter les ressources supplémentaires (répertoires ou fichiers zip)
            If lstRessources.Items.Count > 0 Then
                For i As Integer = 0 To lstRessources.Items.Count - 1
                    'lstTypeRessources contient le type de ressource de la ressource considérée dans lstRessources
                    ResourceGroupManager.Singleton.AddResourceLocation(lstRessources.Items(i), lstTypeRessources.Items(i), "General")
                Next
            End If
            'Fini, on initialise toutes les ressources
            ResourceGroupManager.Singleton.InitialiseAllResourceGroups()

            'On charge la scène OSM grâce à la dll oFusion
            Scene = New OSMScene(mySceneManager, MyWindow)
            Scene.Initialize(txtNomScene.Text)
            Scene.CreateScene(mySceneManager.RootSceneNode)

            'création de la caméra
            If Scene.CameraList.Count > 0 Then
                'Si la scene contient au moins une caméra, on sélectionne la première
                myCamera = Scene.CameraList(0)
            Else
                'sinon, on en crè une par défaut
                myCamera = Scene.SceneMgr.CreateCamera("CameraDefaut")
                myCamera.SetPosition(0, 0, 0)
                myCamera.SetDirection(0, 0, 0)
                myCamera.FOVy = CType(1, Mogre.Radian)
                Dim camNode As SceneNode = mySceneManager.CreateSceneNode("CameraDefaut")
                camNode.AttachObject(myCamera)

                Dim CameraTarget As Mogre.SceneNode = mySceneManager.CreateSceneNode("CameraDefaut.target")
                CameraTarget.SetPosition(1000, 1000, 1000)
                CameraTarget.SetDirection(0, 0, 0)
                CameraTarget.SetScale(1, 1, 1)

                'On crè le viewport
                Dim ViewPort As Mogre.Viewport = MyWindow.AddViewport(myCamera)
                myCamera.AspectRatio = ViewPort.ActualWidth / ViewPort.ActualHeight
            End If
            txtFOV.Text = myCamera.FOVy.ValueRadians
            myCamera.NearClipDistance = 5

            InitialCamBodyOrient = myCamera.Orientation
            InitialCamBodyPos = myCamera.Position

            'si on a décidé d'activer la gestion des collisions, on initialise Newton
            If mnuDetectionDeCollision.Checked Then
                InitNewton()
            End If

            'initialisation de l'inputmanager MOIS
            InitInputHandler()


        Catch ex As System.Runtime.InteropServices.SEHException
            'en cas d'erreur....
            If OgreException.IsThrown Then
                MsgBox(OgreException.LastException.FullDescription, MsgBoxStyle.Critical, _
                     "Exeption OGRE!")
            Else
                MsgBox(ex.ToString, "Erreur")
            End If
        End Try
    End Sub

    Private Sub InitNewton()


        'Initialisation de Newton pour la gestion des collision caméras, je n'y suis pas arrivé avec les RayScenQuery...
        If myWorld Is Nothing Then
            myWorld = New World 'le monde physique
            'et initialisation de sa taille, par défaut elle est de 100 sur chaque axes.
            myWorld.SetWorldSize(New Mogre.Vector3(-100000, -100000, -100000), New Mogre.Vector3(100000, 100000, 100000))
        End If

        Dim cam_mass As Single = 90 'la masse de la caméra


        'Création du monde physique pour Newton

        Dim stat_col As MogreNewt.CollisionPrimitives.TreeCollisionSceneParser = New MogreNewt.CollisionPrimitives.TreeCollisionSceneParser(myWorld)
        stat_col.ParseScene(mySceneManager.RootSceneNode, False) 'Utilisation du parser de scène Newton, attention, à ce jour (juillet 2008), le parmètre true, au mieux, ne fonctionne pas et au pire plante le programme.

        'Création et paramétrage du body pour le monde
        Dim bod As MogreNewt.Body = New MogreNewt.Body(myWorld, stat_col)
        stat_col.Dispose()
        bod.AttachToNode(mySceneManager.RootSceneNode)
        bod.SetPositionOrientation(New Mogre.Vector3(0.0, 0.0, 0.0), Quaternion.IDENTITY)

        'Collision de la caméra
        Dim PosCam As Mogre.Vector3 = mySceneManager.GetSceneNode(myCamera.Name).Position 'on récupère la position de la caméra
        Dim OrientCam As Quaternion = mySceneManager.GetSceneNode(myCamera.Name).Orientation 'on récupère l'orientation de la caméra

        CamNode = mySceneManager.RootSceneNode.CreateChildSceneNode("CamNode") 'on crè un Scennode
        Me.CamNode.SetScale(Me.CamSize) 'on le met à la taille de la caméra
        Me.CamColl = New CollisionPrimitives.Ellipsoid(myWorld, Me.CamSize) 'on crè le système de collision
        Me.CamBody = New Body(myWorld, Me.CamColl) 'on l'applique au body représentant la caméra
        Me.CamColl.Dispose() 'on libère la collision
        Me.CamBody.AttachToNode(Me.CamNode) 'et on l'attache au noeud créé précédement

        'calcul de l'inertie de la caméra
        Dim cam_inertia As Mogre.Vector3 = MomentOfInertia.CalcEllipsoidSolid(cam_mass, Me.CamSize)
        Me.CamBody.SetMassMatrix(cam_mass, cam_inertia)
        AddHandler Me.CamBody.ForceCallback, AddressOf camera_force_callback 'la fonction appelée lors de l'update du monde physique
        Me.CamBody.AutoFreeze = False 'Important, sinon, iompossible de déplacer le body...

        'Création d'un "UP Vector" pour empécher le body de tourner sur Y
        Dim uv2 As BasicJoints.UpVector = New BasicJoints.UpVector(myWorld, Me.CamBody, Mogre.Vector3.UNIT_Y)

        'Création d'un scenenode 1 unités au dessus du camnode pour y mettre la caméra
        'Ca nécessite un peu d'explications :
        'Si on met 0 comme valeur sur Y, la caméra est positionnée au centre du body.
        'Comme le but est de représenter un être humain, ça ne le fait pas.
        'Par contre, la valeur 1 positionne la caméra juste au dessus du body, mais, à contrarion, dans une pièce
        'au plafond trop bas, la caméra va passer au dessus du plafond....Pour le moment, je n'ai pas trouvé mieux.

        Me.CamViewNode = Me.CamNode.CreateChildSceneNode("CamViewNode", New Mogre.Vector3(0, 1, 0)) 'création du scenenode
        mySceneManager.RootSceneNode.DetachObject(myCamera) 'on détache la caméra du rootscenenode (créé par OSMLoader)
        Me.CamViewNode.AttachObject(myCamera) 'et on attache la caméra au viewnode

        CamBody.SetPositionOrientation(PosCam, OrientCam) 'Sert à récupérer la position et orientation initiale de la caméra pour positionner son corp.
        InitialCamBodyOrient = get_body_orientation(CamBody)
        InitialCamBodyPos = get_body_position(CamBody)

        'CamBody.MaterialGroupID = New MogreNewt.MaterialID(myWorld) 

        MogreNewt.Debugger.Instance.Init(mySceneManager) 'et on initialise le debugger newton.

    End Sub

    Private Sub InitInputHandler()

        'Définition du mode d'accès de la souris et du handle de fenêtre à gérer. ATTENTION : ce n'est pas le handle du contrôle qui affichera le rendu mais celui de la fenêtre qui le contient

        Dim param As MOIS.ParamList = New MOIS.ParamList()

        'Les 4 premiers paramètres servent à signaler que MOIS ne sera pas le seul à être capable de gérer le clavier et la souris
        'ceci permet de disposer du curseur de la souris pour faire autre chose pendant que Ogre rend ses frames
        param.Insert("w32_mouse", "DISCL_NONEXCLUSIVE")
        param.Insert("w32_mouse", "DISCL_FOREGROUND")
        param.Insert("w32_keyboard", "DISCL_NONEXCLUSIVE")
        param.Insert("w32_keyboard", "DISCL_FOREGROUND")
        param.Insert("WINDOW", Me.Handle.ToString) 'ici, on passe le handle de notre "top level window" (cf. DirectX et DirectInput)

        'Hook de l'input manager à la fenêtre
        inputManager = MOIS.InputManager.CreateInputSystem(param)
        If Not inputManager Is Nothing Then

            'Creation des device de capture MOIS
            Try
                'Le clavier
                inputKeyboard = CType(inputManager.CreateInputObject(MOIS.Type.OISKeyboard, False), MOIS.Keyboard)
            Catch ex As System.Runtime.InteropServices.SEHException
                'en cas d'erreur....
                If OISException.IsThrown Then
                    MsgBox(OISException.LastException.eText, MsgBoxStyle.Critical, _
                         "Exeption OIS!")
                Else
                    MsgBox(ex.ToString, "Erreur")
                End If
            End Try
            Try
                'La souris
                inputMouse = CType(inputManager.CreateInputObject(MOIS.Type.OISMouse, False), MOIS.Mouse)
            Catch ex As System.Runtime.InteropServices.SEHException
                'en cas d'erreur....
                If OISException.IsThrown Then
                    MsgBox(OISException.LastException.eText, MsgBoxStyle.Critical, _
                         "Exeption OIS!")
                Else
                    MsgBox(ex.ToString, "Erreur")
                End If
            End Try
            'A répéter pour d'autre input, joystick par exemple :
            '' ''Try
            '' ''    inputJoy = CType(inputManager.CreateInputObject(MOIS.Type.OISJoyStick, False), MOIS.JoyStick)
            '' ''Catch ex As System.Runtime.InteropServices.SEHException
            '' ''    'en cas d'erreur....
            '' ''    If OISException.IsThrown Then
            '' ''        MsgBox(OISException.LastException.eText, MsgBoxStyle.Critical, _
            '' ''             "Exeption OIS!")
            '' ''    Else
            '' ''        MsgBox(ex.ToString, "Erreur")
            '' ''    End If
            '' ''End Try
        End If

        ' Et l'évènement qui sera attaché au FrameStarted
        AddHandler myRoot.FrameStarted, AddressOf FrameStarted

    End Sub

    Private Sub DisposeOgre()
        'Pemet de nettoyer les instances OGRES en cas de rechargement de la scène ou de l'ouverture d'une nouvelle
        'en gros, on réinitialise toutes les instances Ogre

        SceneNodeSelected = Nothing
        MObjectSelected = Nothing

        myCamera = Nothing
        Scene = Nothing
        ResourceGroupManager.Singleton.DestroyResourceGroup("General")
        MyWindow.RemoveAllViewports()
        MyWindow.Dispose()
        myRoot.DestroySceneManager(mySceneManager)
        myRoot.DetachRenderTarget(MyWindow)
        myRoot.Dispose()
        MyWindow = Nothing
        mySceneManager = Nothing

    End Sub

    Private Sub DisposeNewton()



        'Permet de liberer les instances Newton, mais ça ne marche pas top, à paufiner....
        'Ainsi, si on recharge la scène ou si on en charge une autre, tout marche sauf que l'on a pas de mouvement sur X.
        'A l'heure qu'il est, je ne sais pas pourquoi

        RemoveHandler Me.CamBody.ForceCallback, AddressOf camera_force_callback
        myWorld.DestroyAllBodies()
        myWorld.Dispose()
        myWorld = Nothing

    End Sub

    Private Sub LoadAxe()
        'Permet de charger l'objet Axe et de l'ajouter à la scene

        Dim Axe01 As Entity 'Sera l'axe afficher sdur les objets
        Dim AxeMonde As Entity 'Comme son nom l'indique


        Try

            Axe01 = mySceneManager.CreateEntity("Axe01", "Axe.mesh") 'on charge l'objet
            AxeMonde = Axe01.Clone("AxeMonde") 'on le clone pour avoir deux axes séparés

            'On crè le node qui contioendra l'axe du monde
            NodeAxeMonde = mySceneManager.RootSceneNode.CreateChild("AxeMonde")
            NodeAxeMonde.AttachObject(AxeMonde)
            NodeAxeMonde.SetPosition(0, 0, 0)
            NodeAxeMonde.SetScale(1, 1, 1)
            NodeAxeMonde.SetVisible(False)
            NodeAxeMonde.ResetToInitialState()

            'on fait pareil pour l'axe des objets
            NodeAxe = mySceneManager.RootSceneNode.CreateChild("Axe01")
            NodeAxe.AttachObject(Axe01)
            NodeAxe.SetPosition(0, 0, 0)
            NodeAxe.SetScale(1, 1, 1)
            NodeAxe.InheritOrientation = False 'si on ne fait pas ça, l'axe se comporte étrangement lorsque l'objet tourne
            NodeAxe.InheritScale = False 'Pareil, le scale de l'objet s'ajoute au scale de l'axe
            NodeAxe.SetVisible(False)

        Catch ex As System.Runtime.InteropServices.SEHException
            'en cas d'erreur....
            If OgreException.IsThrown Then
                MsgBox(OgreException.LastException.FullDescription, MsgBoxStyle.Critical, _
                     "Exeption OGRE!")
            Else
                MsgBox(ex.ToString, "Erreur")
            End If

        End Try


    End Sub

    Public Function FrameStarted(ByVal evt As FrameEvent) As Boolean

        'Gère les évènements clavier et souris


        'le test pour annuler le mouvement de la caméra est mis en externe par rapport
        'au test de detection de collision car si on relache la souris avant les touches
        'la caméra continue à se déplacer, donc, on annule sa vélocité et sa rotation à la fin de la fonction

        Dim PasdeMouvement As Boolean = True

        If moving Then 'Si on a cliqué sur le bouton gauche de la souris, on se déplace dans le monde

            CaptureFunction() 'on lance la capture clavier/souris par MOIS

            'Il y a 2 systèmes de mouvement, avec ou sans détection de collisions
            If mnuDetectionDeCollision.Checked Then
                'Avec

                'Le principe est de récupérer l'orientation du corps de la caméra sur l'axe de déplacement choisi
                'et de lui affecter une vitesse de déplacement sur cette axe.
                'Lorsque l'on arrête le déplacement, on annule la vitesse.

                Dim direction As Mogre.Vector3

                If inputKeyboard.IsKeyDown(MOIS.KeyCode.KC_UP) Then
                    direction = get_body_orientation(CamBody) * Mogre.Vector3.NEGATIVE_UNIT_Z
                    CamBody.Velocity = CamBody.Velocity * New Mogre.Vector3(0, 1, 0) + direction * 200 * 2
                    PasdeMouvement = False
                End If

                If inputKeyboard.IsKeyDown(MOIS.KeyCode.KC_DOWN) Then
                    direction = get_body_orientation(CamBody) * Mogre.Vector3.UNIT_Z
                    CamBody.Velocity = CamBody.Velocity * New Mogre.Vector3(0, 1, 0) + direction * 200 * 2
                    PasdeMouvement = False
                End If

                If inputKeyboard.IsKeyDown(MOIS.KeyCode.KC_LEFT) Then
                    direction = get_body_orientation(CamBody) * Mogre.Vector3.NEGATIVE_UNIT_X
                    CamBody.Velocity = CamBody.Velocity * New Mogre.Vector3(0, 1, 0) + direction * 200 * 2
                    PasdeMouvement = False
                End If

                If inputKeyboard.IsKeyDown(MOIS.KeyCode.KC_RIGHT) Then
                    direction = get_body_orientation(CamBody) * Mogre.Vector3.UNIT_X
                    CamBody.Velocity = CamBody.Velocity * New Mogre.Vector3(0, 1, 0) + direction * 200 * 2
                    PasdeMouvement = False
                End If

                'Pour le déplacement sur Y (vertical) on se déplace sur le Y du monde et pas de la caméra
                'Donc, pas besoin de récupérer la direction de la caméra
                If inputKeyboard.IsKeyDown(MOIS.KeyCode.KC_PGUP) Then
                    CamBody.Velocity = New Mogre.Vector3(0, 1000, 0)
                    PasdeMouvement = False
                End If

                If inputKeyboard.IsKeyDown(MOIS.KeyCode.KC_PGDOWN) Then
                    CamBody.Velocity = New Mogre.Vector3(0, -1000, 0)
                    PasdeMouvement = False
                End If

                'Pour la rotation de la caméra, on récupère le déplacement de la souris sur X et Y
                Dim mouseState As MOIS.MouseState_NativePtr = inputMouse.MouseState

                camera_rotation_x = -mouseState.X.rel * 0.5F
                If camera_rotation_x <> 0 Then
                    PasdeMouvement = False
                End If
                camera_rotation_y = -mouseState.Y.rel * 0.5F

                'On travaille sur le camviewnode pour que l'axe de la caméra soit orienté correctement
                CamViewNode.Pitch(camera_rotation_y)

                'Si on atteint un angle de rotation maximale vers le haut ou le bas, on annule la rotation
                y_rotation_cont += camera_rotation_y
                If y_rotation_cont > y_limit_a Or y_rotation_cont < y_limit_b Then
                    CamViewNode.Pitch(-camera_rotation_y)
                    y_rotation_cont -= camera_rotation_y
                End If

            Else
                'Sans

                'On applique simplement une translation ou une rotation à la caméra

                Dim myTranslation As Mogre.Vector3 = Mogre.Vector3.ZERO 'Pour le déplacement de la caméra sur ces axes sans détection de collision

                myTranslation.z = 0
                myTranslation.x = 0
                myTranslation.y = 0

                If inputKeyboard.IsKeyDown(MOIS.KeyCode.KC_UP) Then
                    myTranslation.z += -TRANSLATE
                End If

                If inputKeyboard.IsKeyDown(MOIS.KeyCode.KC_DOWN) Then
                    myTranslation.z += TRANSLATE
                End If

                If inputKeyboard.IsKeyDown(MOIS.KeyCode.KC_LEFT) Then
                    myTranslation.x += -TRANSLATE
                End If

                If inputKeyboard.IsKeyDown(MOIS.KeyCode.KC_RIGHT) Then
                    myTranslation.x += TRANSLATE
                End If

                If inputKeyboard.IsKeyDown(MOIS.KeyCode.KC_PGUP) Then
                    myTranslation.y += TRANSLATE
                End If

                If inputKeyboard.IsKeyDown(MOIS.KeyCode.KC_PGDOWN) Then
                    myTranslation.y += -TRANSLATE
                End If

                Dim mouseState As MOIS.MouseState_NativePtr = inputMouse.MouseState

                camera_rotation_x = mouseState.X.rel * -ROTATE
                camera_rotation_y = mouseState.Y.rel * -ROTATE


                'Et on déplace la caméra
                myCamera.Position += myCamera.Orientation * myTranslation * evt.timeSinceLastFrame
                myCamera.Yaw(camera_rotation_x * evt.timeSinceLastFrame)
                myCamera.Pitch(camera_rotation_y) 'si on multiplie par timesincelastframe, le résultat est plus qu'étrange...A voir.

            End If

        End If
        'C'est ici que l'on annule la vélocité et la rotation de la caméra.
        If PasdeMouvement And mnuDetectionDeCollision.Checked Then
            CamBody.Velocity = New Mogre.Vector3(0, 0, 0)
            camera_rotation_x = 0
        End If

        Return RenduEnCours 'tant que l'on ne quitte pas l'appli, on renvoi True.

    End Function

    Private Sub CaptureFunction()
        'Lance la capture du clavier et de la souris
        inputKeyboard.Capture()
        inputMouse.Capture()
    End Sub

    Private Sub RemplitGrille()

        'Permet de remplir la grille d'infos une fois qu'un objet est sélectionné

        Dim tab(1) As String
        Try

            'On efface le contenu de la grille  
            grdDetail.Rows.Clear()

            'Et on remplit
            'La position
            tab(0) = "Position X"
            tab(1) = SceneNodeSelected.Position.x.ToString
            grdDetail.Rows.Add(tab)
            tab(0) = "Position Y"
            tab(1) = SceneNodeSelected.Position.y.ToString
            grdDetail.Rows.Add(tab)
            tab(0) = "Position Z"
            tab(1) = SceneNodeSelected.Position.z.ToString
            grdDetail.Rows.Add(tab)

            'L'Orientation
            tab(0) = "Orientation X"
            tab(1) = SceneNodeSelected.Orientation.x.ToString
            grdDetail.Rows.Add(tab)
            tab(0) = "Orientation Y"
            tab(1) = SceneNodeSelected.Orientation.y.ToString
            grdDetail.Rows.Add(tab)
            tab(0) = "Orientation Z"
            tab(1) = SceneNodeSelected.Orientation.z.ToString
            grdDetail.Rows.Add(tab)
            tab(0) = "Orientation W"
            tab(1) = SceneNodeSelected.Orientation.w.ToString
            grdDetail.Rows.Add(tab)

            'L'échelle
            tab(0) = "Echelle X"
            tab(1) = SceneNodeSelected.GetScale.x.ToString
            grdDetail.Rows.Add(tab)
            tab(0) = "Echelle Y"
            tab(1) = SceneNodeSelected.GetScale.y.ToString
            grdDetail.Rows.Add(tab)
            tab(0) = "Echelle Z"
            tab(1) = SceneNodeSelected.GetScale.z.ToString
            grdDetail.Rows.Add(tab)

            'Les ombres
            tab(0) = "CastShadows"
            tab(1) = IIf(MObjectSelected.CastShadows, "Oui", "Non")
            grdDetail.Rows.Add(tab)

            'La visibilité
            tab(0) = "Visible"
            tab(1) = IIf(MObjectSelected.Visible, "Oui", "Non")
            grdDetail.Rows.Add(tab)

            'La Bounding box
            tab(0) = "ShowBoundingBox"
            tab(1) = IIf(SceneNodeSelected.ShowBoundingBox, "Oui", "Non")
            grdDetail.Rows.Add(tab)

            GetPosition()
            GetOrientation()
            GetEchelle()

        Catch ex As Exception

        End Try

    End Sub

    Private Sub GetOrientation()

        'Récupère l'orientation de l'objet sélectionné pour l'afficher dans les paramètres de le'objet
        Try
            txtOrientationX.Value = SceneNodeSelected.Orientation.x
            txtOrientationY.Value = SceneNodeSelected.Orientation.y
            txtOrientationZ.Value = SceneNodeSelected.Orientation.z
            txtOrientationW.Value = SceneNodeSelected.Orientation.w
        Catch ex As Exception

        End Try

    End Sub

    Private Sub GetPosition()

        'Récupère la position de l'objet sélectionné pour l'afficher dans les paramètres de le'objet
        Try
            txtPositionX.Value = SceneNodeSelected.Position.x
            txtPositionY.Value = SceneNodeSelected.Position.y
            txtPositionZ.Value = SceneNodeSelected.Position.z
        Catch ex As Exception

        End Try

    End Sub

    Private Sub GetEchelle()

        'Récupère l'échelle de l'objet sélectionné pour l'afficher dans les paramètres de le'objet
        txtScaleX.Value = SceneNodeSelected.GetScale.x
        txtScaleY.Value = SceneNodeSelected.GetScale.y
        txtScaleZ.Value = SceneNodeSelected.GetScale.z

    End Sub

#End Region

#Region "Evènements"

#Region "Form"

    Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        Me.Hide() 'Cache la fenêtre principale

        treeScene.Sort() 'trie la treeview, une fois triée, elle le reste même si on la recharge avec de nouvelles données.

        InitOgre()


        'Affichage de la fenêtre de choix de la scène à charger
        frmViewerload.ShowDialog()

        If frmViewerload.bValide Then
            'Si on a valider le choix.....
            'On affiche la form d'attente
            Cursor = Cursors.WaitCursor 'juste pour la beauté

            If frmViewerload.chkPhysique.Checked Then
                mnuDetectionDeCollision.Checked = True
                mnuGravite.Enabled = True
                mnuDebugActif.Enabled = True
            End If

            'Affichage de la fenêtre de paramètres OGRES, le cas échéant
            If frmViewerload.chkOgre.Checked Then
                If Not myRoot.ShowConfigDialog Then
                    Exit Sub
                End If
            Else
                If Not myRoot.RestoreConfig() Then
                    If Not myRoot.ShowConfigDialog Then
                        Exit Sub
                    End If
                End If
            End If

            frmInfoLoad.Show()
            frmInfoLoad.Refresh() 'nécessair pour afficher son contenu

            'Cette partie permet de remplir les listes locales de la form pour le rechargement de la scène
            Me.lstRessources.Items.Clear()
            Me.lstTypeRessources.Items.Clear()
            Me.txtNomScene = frmViewerload.txtNomscene
            For i As Integer = 0 To frmViewerload.lstRessources.Items.Count - 1
                Me.lstRessources.Items.Add(frmViewerload.lstRessources.Items(i))
            Next
            For i As Integer = 0 To frmViewerload.lstTypeRessources.Items.Count - 1
                Me.lstTypeRessources.Items.Add(frmViewerload.lstTypeRessources.Items(i))
            Next


            'Et on initialise la scène
            Me.InitScene()
            LoadAxe() 'On ajoute les axes
            Me.InitTree(mySceneManager.RootSceneNode, Nothing) 'On remplit la treeview

            frmViewerload.Dispose() 'et on détruit la form de chargement

            'On ajoutes la gestion des évèbements aux champs texte
            AddHandler txtPositionY.ValueChanged, AddressOf Position
            AddHandler txtPositionZ.ValueChanged, AddressOf Position

            AddHandler txtScaleY.ValueChanged, AddressOf Echelle
            AddHandler txtScaleZ.ValueChanged, AddressOf Echelle

            'On détruit la form d'attente
            frmInfoLoad.Hide()
            frmInfoLoad.Dispose()
            Cursor = Cursors.Default

            'On démarre le timer pour le rendu et la gestion des touches
            'timerRendu.Enabled = True
            init = False 'L'initialisation est terminé, la variable init passe à false

            Me.Show() 'Tout est fini, on affiche la fenêtre

            'myRoot.StartRendering()
            While RenduEnCours
                My.Application.DoEvents()
                'Affichage des infos de rendu
                Try
                    lblAvg.Text = "FPS moyennes: " & Mogre.StringConverter.ToString(MyWindow.AverageFPS, 3)
                    lblCurr.Text = "FPS courantes: " & Mogre.StringConverter.ToString(MyWindow.LastFPS, 3)
                    lblBest.Text = "Meilleures FPS: " & Mogre.StringConverter.ToString(MyWindow.BestFPS, 3)
                    lblWorst.Text = "Pires FPS: " & Mogre.StringConverter.ToString(MyWindow.WorstFPS, 3)
                    lblNumTris.Text = "Triangles: " & Mogre.StringConverter.ToString(MyWindow.TriangleCount)
                    lblNumBatches.Text = "Nombre de Batch: " & Mogre.StringConverter.ToString(MyWindow.BatchCount)
                Catch ex As Exception

                End Try

                'et on rend une frame
                myRoot.RenderOneFrame()

                'Update du monde physique
                If mnuDetectionDeCollision.Checked Then
                    Dim stepPhysics As Single = 0.1
                    myWorld.Update(stepPhysics)
                End If


                If SceneNodeSelected Is Nothing Then
                    'si un objet est sélectionné ou pas, on active ou désactive le panneau de paramètre
                    grpParamObjet.Enabled = False
                    cmdResetEtat.Enabled = False
                Else
                    grpParamObjet.Enabled = True
                    cmdResetEtat.Enabled = True
                End If
            End While
            'Sur des machines rapide, le nombre trop élevé de FPS rend la rotation sur X des plus étrange si la détection de collisions est activée.
            'Le renderOneFrame rendant moins de FPS, je l'utilise dans le timer.
            'C'est surement une histoire de facteur de multiplication lors de la récupération de camera_rotation_x, mais je n'ai pas trouvé la formule magique.
            DisposeNewton()
            If mnuDetectionDeCollision.Checked Then
                DisposeOgre()
            End If
        Else

            'Sinon on s'en va
            Me.Dispose()
        End If

    End Sub

    Private Sub frmMain_Disposed(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Disposed
        'On se contente d'arrêter le timer et à positionner la vaiable permettant de stopper le rendu Ogre, le reste des ressources ser libéré par le garbage collector (en tout cas on l'espère ;o) )
        'timerRendu.Enabled = False
        RenduEnCours = False
    End Sub

#End Region

#Region "Timer"

    Private Sub timerRendu_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles timerRendu.Tick

        ''Affichage des infos de rendu
        'Try
        '    lblAvg.Text = "FPS moyennes: " & Mogre.StringConverter.ToString(MyWindow.AverageFPS, 3)
        '    lblCurr.Text = "FPS courantes: " & Mogre.StringConverter.ToString(MyWindow.LastFPS, 3)
        '    lblBest.Text = "Meilleures FPS: " & Mogre.StringConverter.ToString(MyWindow.BestFPS, 3)
        '    lblWorst.Text = "Pires FPS: " & Mogre.StringConverter.ToString(MyWindow.WorstFPS, 3)
        '    lblNumTris.Text = "Triangles: " & Mogre.StringConverter.ToString(MyWindow.TriangleCount)
        '    lblNumBatches.Text = "Nombre de Batch: " & Mogre.StringConverter.ToString(MyWindow.BatchCount)
        'Catch ex As Exception

        'End Try

        ''et on rend une frame
        ''myRoot.RenderOneFrame()

        ''Update du monde physique
        'If mnuDetectionDeCollision.Checked Then
        '    Dim stepPhysics As Single = 0.1
        '    myWorld.Update(stepPhysics)
        'End If


        'If SceneNodeSelected Is Nothing Then
        '    'si un objet est sélectionné ou pas, on active ou désactive le panneau de paramètre
        '    grpParamObjet.Enabled = False
        '    cmdResetEtat.Enabled = False
        'Else
        '    grpParamObjet.Enabled = True
        '    cmdResetEtat.Enabled = True
        'End If

    End Sub


#End Region

#Region "Picture Box (Pour le rendu Ogre et le choix des couleurs de la lumière)"

    Private Sub picMogre_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles picMogre.MouseDown

        'Quand on clique dans la picture box, on active le déplacement si c'est avec le bouton gauche

        If e.Button = Windows.Forms.MouseButtons.Left Then
            moving = True
            Cursor.Hide()
        End If

    End Sub

    Private Sub picMogre_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles picMogre.MouseUp

        'Et on désactive le déplacement quand on relache le bouton gauche

        If e.Button = Windows.Forms.MouseButtons.Left Then
            moving = False
            Cursor.Show()
        End If
    End Sub

    Private Sub picSpecular_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles picSpecular.DoubleClick

        'On passe les paramètres à la form de sélection des couleurs (la lumière sélectionner et l'action à effectuer)
        frmColorDialogue.myLight = LightSelected
        frmColorDialogue.Provenance = "Specular"

        'On ouvre la form
        frmColorDialogue.ShowDialog()

        'on la libère
        frmColorDialogue.Dispose()

    End Sub

    Private Sub picDiffuse_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles picDiffuse.DoubleClick

        'On passe les paramètres à la form de sélection des couleurs (la lumière sélectionner et l'action à effectuer)
        frmColorDialogue.myLight = LightSelected
        frmColorDialogue.Provenance = "Diffuse"

        'On ouvre la form
        frmColorDialogue.ShowDialog()

        'on la libère
        frmColorDialogue.Dispose()

    End Sub

    Private Sub picMogre_SizeChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles picMogre.SizeChanged

        'Pour redimensionner le vieport de manière correcte quant on redimmensionne la picturebox (du à un resize de la form ou un déplacement des splitter)

        If Not init Then 'on ne le fait qu'une fois l'initalisation terminée.


            timerRendu.Enabled = False 'on arrête le timer (on ne va pas rendre pendant que le vieport n'existe plus...)

            Try

                'on récupère le viewport
                Dim myViewport As Mogre.Viewport = MyWindow.GetViewport(0)

                'on récupère la couleur du vieport car elle est perdu à sa destruction
                Dim CouleurVieport As Mogre.ColourValue = myViewport.BackgroundColour


                'On le supprime de la fenêtre de rendu
                MyWindow.RemoveViewport(myViewport.ZOrder)

                'Et on efface la feneêtre de rendu
                myRoot.DetachRenderTarget(MyWindow)
                MyWindow.Dispose()
                MyWindow = Nothing

                'On recrè la fenêtre, qui prendra comme dimension la nouvelle taille du contrôle
                Dim misc As NameValuePairList = New NameValuePairList
                misc("externalWindowHandle") = picMogre.Handle.ToString
                Dim const_list As Const_NameValuePairList = misc.ReadOnlyInstance
                MyWindow = myRoot.CreateRenderWindow("OgreWieport", 0, 0, False, const_list)

                'On recrè un viewport avec les nouveaux paramètrex
                myViewport = MyWindow.AddViewport(myCamera)
                'on réaffecte la couleur précédemment sauvegardée
                myViewport.BackgroundColour = CouleurVieport
                'on fixe l'aspect ratio de la caméra
                myCamera.AspectRatio = myViewport.ActualWidth / myViewport.ActualHeight

            Catch ex As Exception
                'en cas d'erreur....
                If OgreException.IsThrown Then
                    Try 'parfois ça plante ici car OgreException.LastException n'est pas défini, donc je réimbrique un try
                        MsgBox(OgreException.LastException.FullDescription, MsgBoxStyle.Critical, _
                             "Exeption OGRE!")

                    Catch ex2 As Exception

                    End Try
                Else
                    MsgBox(ex.ToString, "Erreur")
                End If
            End Try

            timerRendu.Enabled = True 'on redémarre le timer 

        End If

    End Sub

#End Region

#Region "Champs texte"

    Private Sub txtFOV_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtFOV.TextChanged
        'Permet de changer l'angle du champ de vision
        If txtFOV.Text <> "" Then
            Try
                myCamera.FOVy = CType(txtFOV.Text, Mogre.Radian)
            Catch ex As Exception

            End Try
        End If
    End Sub

    Private Sub Echelle(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtScaleX.ValueChanged

        'Appeller par les 3 txtScale, permet de changer le facteur d'échelle de l'objet sélectionné
        If Not EnCoursDeSelection Then 'nécessaire car si on est en cours de sélection d'un objet, de mauvais paramètres sont appliqués
            SceneNodeSelected.SetScale(txtScaleX.Value, txtScaleY.Value, txtScaleZ.Value) 'et on applique l'échelle
        End If
    End Sub

    Private Sub Position(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtPositionX.ValueChanged, txtPositionX.Scroll

        'Appeller par les 3 txtPosition, permet de changer la position de l'objet sélectionné

        If Not EnCoursDeSelection And Not EnCoursDeTranslation Then 'nécessaire car si on est en cours de sélection d'un objet, de mauvais paramètres sont appliqués
            SceneNodeSelected.SetPosition(txtPositionX.Value, txtPositionY.Value, txtPositionZ.Value) 'et on applique la position
        End If
    End Sub

#End Region

#Region "Les menus"

    Private Sub mnuParamOgre_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuParamOgre.Click
        'Montre la fenêtre de configuration OGRE
        myRoot.ShowConfigDialog()

        'Une fois les paramètres modifiés, on recharge la scène
        mnuRecharger_Click(sender, e)
    End Sub

    Private Sub mnuOuvrir_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuOuvrir.Click

        Me.Hide() 'On cache la fenêtre principale

        'Affichage de la fenêtre de choix de la scène à charger
        frmViewerload.ShowDialog()

        If frmViewerload.bValide Then
            'Si on a valider le choix.....
            'On affiche la form d'attente
            frmInfoLoad.Show()
            frmInfoLoad.Refresh() 'nécessair pour afficher son contenu
            Cursor = Cursors.WaitCursor 'juste pour la beauté

            'timerRendu.Enabled = False 'on arrête le timer

            DisposeNewton()
            DisposeOgre() 'on libère les ressources Ogre

            'on reinitialise les checkboxs
            chkTracking.Checked = False
            chkAxe.Checked = False

            'on vide le treeview et on recrè les 3 noeuds de base
            treeScene.Nodes.Clear()
            treeScene.Nodes.Add("Root")
            treeScene.Nodes.Item(0).Nodes.Add("Autres")
            treeScene.Nodes.Item(0).Nodes.Add("Cameras")
            treeScene.Nodes.Item(0).Nodes.Add("Lights")
            treeScene.Nodes.Item(0).Nodes.Add("Entities")

            'on vide les listes héritées de la forme de chargement pour le menu recharger
            Me.lstRessources.Items.Clear()
            Me.lstTypeRessources.Items.Clear()
            Me.txtNomScene = frmViewerload.txtNomscene

            'et on les remplit avec les nouvelles valeur
            For i As Integer = 0 To frmViewerload.lstRessources.Items.Count - 1
                Me.lstRessources.Items.Add(frmViewerload.lstRessources.Items(i))
            Next
            For i As Integer = 0 To frmViewerload.lstTypeRessources.Items.Count - 1
                Me.lstTypeRessources.Items.Add(frmViewerload.lstTypeRessources.Items(i))
            Next

            'On recrè le scène manager
            mySceneManager = myRoot.CreateSceneManager(SceneType.ST_GENERIC)

            If frmViewerload.chkPhysique.Checked Then
                mnuDetectionDeCollision.Checked = True
                mnuGravite.Enabled = True
                mnuDebugActif.Enabled = True
            End If


            'Affichage de la fenêtre de paramètres OGRES, le cas échéant
            If frmViewerload.chkOgre.Checked Then
                If Not myRoot.ShowConfigDialog Then
                    Exit Sub
                End If
            Else
                If Not myRoot.RestoreConfig() Then
                    If Not myRoot.ShowConfigDialog Then
                        Exit Sub
                    End If
                End If
            End If

            'Et on initialise la scène
            Me.InitScene()
            LoadAxe() 'On charge les axes
            Me.InitTree(mySceneManager.RootSceneNode, Nothing) 'on remplit la treeview

            'On détruit la form d'attente
            frmInfoLoad.Hide()
            frmInfoLoad.Dispose()
            Cursor = Cursors.Default

            Me.Show() 'et on réaffiche la fenêtre

            'on libère la form de chargement
            frmViewerload.Dispose()

            'On démarre le timer pour le rendu et la gestion des touches
            'timerRendu.Enabled = True

        End If
    End Sub

    Private Sub mnuCouleurDuViewport_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuCouleurDuViewport.Click

        'on récupère le vieport
        Dim myViewport As Mogre.Viewport = MyWindow.GetViewport(0)

        'pour le passer en paramètre à la fenêtre de choix des couleurs
        frmColorDialogue.myViewPort = myViewport
        frmColorDialogue.Provenance = "Viewport"

        'on l'affiche
        frmColorDialogue.ShowDialog()

        'et on la libère
        frmColorDialogue.Dispose()

    End Sub

    Private Sub mnuRecharger_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuRecharger.Click
        'Permet de recharger la scène en cours

        Cursor = Cursors.WaitCursor
        Me.Hide()
        'On affiche la form d'attente
        frmInfoLoad.Show()
        frmInfoLoad.Refresh() 'nécessair pour afficher son contenu

        'on arrête le timer
        'timerRendu.Enabled = False

        'on détruit nos différentes interfaces
        DisposeNewton()
        DisposeOgre()
        treeScene.Nodes.Clear()
        treeScene.Nodes.Add("Root")
        'on recrè les noeuds de base du treeview
        treeScene.Nodes.Item(0).Nodes.Add("Autres")
        treeScene.Nodes.Item(0).Nodes.Add("Cameras")
        treeScene.Nodes.Item(0).Nodes.Add("Lights")
        treeScene.Nodes.Item(0).Nodes.Add("Entities")

        'on initialise le scenemanager
        mySceneManager = myRoot.CreateSceneManager(SceneType.ST_GENERIC)

        'Et on initialise la scène
        Me.InitScene()
        LoadAxe() 'on charge les axes
        Me.InitTree(mySceneManager.RootSceneNode, Nothing) 'on initialise le treeview

        'On détruit la form d'attente
        frmInfoLoad.Hide()
        frmInfoLoad.Dispose()
        Me.Show()
        Cursor = Cursors.Default

        'On démarre le timer pour le rendu et la gestion des touches
        'timerRendu.Enabled = True
    End Sub

    Private Sub mnuAxeDuMonde_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuAxeDuMonde.Click
        'permet de montrer/cacher l'axe du monde

        If mnuAxeDuMonde.Checked Then
            NodeAxeMonde.SetVisible(True)
        Else
            NodeAxeMonde.SetVisible(False)
        End If
    End Sub

    Private Sub mnuOmbres_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuOmbres.Click
        'Permet d'afficher ou pas les ombres on fonction de la technique choisie

        If mnuOmbres.Checked Then
            mySceneManager.ShadowTechnique = MyShadowTechnique
        Else
            mySceneManager.ShadowTechnique = ShadowTechnique.SHADOWTYPE_NONE
        End If
    End Sub

    Private Sub mnuShadowType_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles mnuShadowType.SelectedIndexChanged
        'C'est un menu combbox pour la simple raison que le traitement du choix est simplifié (pas à se paluche les évènements de 6 menu, juste une sélection dans une combo)

        Select Case mnuShadowType.SelectedIndex
            Case 0
                MyShadowTechnique = ShadowTechnique.SHADOWTYPE_STENCIL_MODULATIVE
            Case 1
                MyShadowTechnique = ShadowTechnique.SHADOWTYPE_STENCIL_ADDITIVE
            Case 2
                MyShadowTechnique = ShadowTechnique.SHADOWTYPE_TEXTURE_MODULATIVE
            Case 3
                MyShadowTechnique = ShadowTechnique.SHADOWTYPE_TEXTURE_ADDITIVE
            Case 4
                MyShadowTechnique = ShadowTechnique.SHADOWTYPE_TEXTURE_ADDITIVE_INTEGRATED
            Case 5
                MyShadowTechnique = ShadowTechnique.SHADOWTYPE_TEXTURE_MODULATIVE_INTEGRATED
        End Select

        'si le menu d'affichage des ombres est coché, on applique directe
        If mnuOmbres.Checked Then
            mySceneManager.ShadowTechnique = MyShadowTechnique
        End If
    End Sub

    Private Sub mnuCouleurOmbres_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuCouleurOmbres.Click

        'On passe les paramètre à la forme de choix des couleurs
        frmColorDialogue.mySceneManager = mySceneManager
        frmColorDialogue.Provenance = "Ombres"

        'on l'affiche
        frmColorDialogue.ShowDialog()

        'et on la libère
        frmColorDialogue.Dispose()

    End Sub

    Private Sub mnuLumireAmbiante_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuLumireAmbiante.Click

        'On passe les paramètre à la forme de choix des couleurs
        frmColorDialogue.mySceneManager = mySceneManager
        frmColorDialogue.Provenance = "Ambiante"

        'on l'affiche
        frmColorDialogue.ShowDialog()

        'et on la libère
        frmColorDialogue.Dispose()

    End Sub

    Private Sub mnuDetectionDeCollision_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuDetectionDeCollision.Click
        mnuOptions.HideDropDown()
        If mnuDetectionDeCollision.Checked Then
            mnuGravite.Enabled = True
            'mnuGravite.Checked = True
            mnuDebugActif.Enabled = True
            mnuRecharger_Click(sender, e)
        Else
            mnuGravite.Enabled = False
            mnuGravite.Checked = False
            mnuDebugActif.Enabled = False
            mnuRecharger_Click(sender, e)
        End If
    End Sub

    Private Sub mnuDebugActif_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuDebugActif.Click
        If mnuDebugActif.Checked Then
            MogreNewt.Debugger.Instance.ShowLines(myWorld)
        Else
            MogreNewt.Debugger.Instance.HideLines()
        End If
    End Sub

    Private Sub mnuHauteurCamera_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles mnuHauteurCamera.TextChanged

        'Permet de changer la hauteur de la caméra en temps réel

        Try
            If Not init Then
                Me.CamSize.y = mnuHauteurCamera.Text
                Me.CamNode.SetScale(Me.CamSize)
            End If

        Catch ex As Exception

        End Try

    End Sub

#End Region

#Region "Le treeview"

    Private Sub treeScene_AfterSelect(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles treeScene.AfterSelect

        'si on est pas en cours de chargement de la scène initiale, on traite la sélection du treeview
        If Not init Then

            'on cache le groupe pour la gestion de la lumière
            grpLumiere.Visible = False

            'on est en cours de sélection d'un objet donc : 
            EnCoursDeSelection = True

            'chkAxe.Checked = False

            If Not SceneNodeSelected Is Nothing Then 'si le scenenodeselected précédent n'est pas vide, on cache sa bounding box
                SceneNodeSelected.ShowBoundingBox = False
            End If

            Try
                Dim tree As TreeView = sender 'on récupère le sender dans un objet typé (plus pratique pour coder
                SceneNodeSelected = tree.SelectedNode.Tag 'on récupère le scenenode dans le tag du treenode
                Dim ObjectType As String 'pour le test du type d'objet sélectionné

                Try
                    MObjectSelected = SceneNodeSelected.GetAttachedObject(tree.SelectedNode.Name) 'on récupère l'objet contenu dans le scenenode
                Catch
                End Try

                If Not e.Node.Text.ToUpper.Contains("ROOT") Then 'si on est pas sur root, alors :
                    Try
                        ObjectType = MObjectSelected.MovableType 'on récupère le type de l'objet
                        Select Case ObjectType
                            Case "Entity" 'si c'est une entity 
                                chkTracking.Checked = False
                                chkTracking.Enabled = True
                                grpParamObjet.Enabled = True
                            Case "Camera" 'si c'est une caméra
                                grpParamObjet.Enabled = False
                                myCamera = mySceneManager.GetCamera(MObjectSelected.Name) 'on récupère son nom
                                Dim ViewPort As Mogre.Viewport = MyWindow.GetViewport(0) 'on récupère le premier viewport
                                ViewPort.Camera = myCamera 'et on change de caméra
                            Case "Light" 'si c'est une lumière
                                grpLumiere.Visible = True
                                grpParamObjet.Enabled = True
                                chkTracking.Checked = False
                                chkTracking.Enabled = True
                                LightSelected = MObjectSelected

                                'on paramètre les picturesbox représentant la couleur de la lumière avec ses couleurs, justement
                                picDiffuse.BackColor = Color.FromArgb(LightSelected.DiffuseColour.GetAsARGB())
                                picSpecular.BackColor = Color.FromArgb(LightSelected.SpecularColour.GetAsARGB())
                                'et les trackbar pour régler l'atténuation
                                trkRange.Value = LightSelected.AttenuationRange * 100
                                trkConstant.Value = LightSelected.AttenuationConstant * 100
                                trkLinear.Value = LightSelected.AttenuationLinear * 100
                                trkQuadratic.Value = LightSelected.AttenuationQuadric * 100

                        End Select

                        grpParamObjet.Text = "Modifications objet : " + SceneNodeSelected.Name

                    Catch ex As Exception
                        'si on est en erreur, on désactive tout

                        chkTracking.Checked = False
                        chkTracking.Enabled = True
                        grpLumiere.Visible = False
                        grpParamObjet.Enabled = False

                    End Try

                    Try
                        'on montre la bounding box de l'objet sélectionné
                        SceneNodeSelected.ShowBoundingBox = True
                    Catch ex As Exception
                    End Try

                    RemplitGrille() 'on remplit la grille de paramètres de l'objet
                    EnCoursDeSelection = False 'la sélection est terminée

                    If ShowAxes Then
                        chkAxe.Checked = True 'si on doit montrer l'axe de l'objet, on le fait
                    End If

                    If TrackObjet Then
                        chkTracking.Checked = True 'si l'autotrackin est actif, alors on le remet
                    End If

                End If
            Catch ex As System.Runtime.InteropServices.SEHException
                'en cas d'erreur....on ne fait rien de spécial
            End Try
        End If

    End Sub

    Private Sub treeScene_BeforeSelect(ByVal sender As Object, ByVal e As System.Windows.Forms.TreeViewCancelEventArgs) Handles treeScene.BeforeSelect
        'Si l'axe de l'objet est affiché
        If ShowAxes Then
            chkAxe.Checked = False 'on va déclencher l'évènement changed de la checkbox
        End If
        If TrackObjet Then ' on fait pareil pour l'autotracking
            chkTracking.Checked = False
        End If
    End Sub

#End Region

#Region "Les check box"

    Private Sub chkTracking_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkTracking.CheckedChanged
        'Permet d'activer/désactiver l'autotracking de l'objet sélectionné par la caméra
        Try
            myCamera.SetAutoTracking(False)
            If chkTracking.Checked Then
                myCamera.SetAutoTracking(True, SceneNodeSelected)
            End If
        Catch ex As Exception

        End Try
    End Sub

    Private Sub chkAxe_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkAxe.CheckedChanged
        'Permet de montrer/cacher l'axe de l'objet sélectionné

        If Not EnCoursDeSelection Then 'si on est pas en cours de sélection de l'objet

            Try
                If chkAxe.Checked Then
                    'Lorsque la case est cochée
                    mySceneManager.RootSceneNode.RemoveChild(NodeAxe) 'on détache l'axe de la racine
                    SceneNodeSelected.AddChild(NodeAxe) 'on l'attache à l'objet sélectionnée
                    NodeAxe.SetPosition(0, 0, 0) 'au centre de ce dernier
                    NodeAxe.SetOrientation(SceneNodeSelected.Orientation.w, SceneNodeSelected.Orientation.x, SceneNodeSelected.Orientation.y, SceneNodeSelected.Orientation.z) 'et avec l'orientation de ce dernier
                    NodeAxe.SetVisible(True) 'et on le montre
                Else
                    'lorsque la case est décochée, on cache le Node de l'axe
                    NodeAxe.SetVisible(False)
                    SceneNodeSelected.RemoveChild(NodeAxe) 'on l'enlève de l'objet sélectionné
                    mySceneManager.RootSceneNode.AddChild(NodeAxe) 'et on l'attache à la racine
                End If
            Catch
                'Juste au cas ou...
            End Try

        End If
    End Sub

    Private Sub chkAxe_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles chkAxe.Click
        'On inverse simplement la variable permettant de savoir si on affiche ou pas l'axe des objets
        ShowAxes = Not ShowAxes
    End Sub

    Private Sub chkTracking_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles chkTracking.Click
        'On inverse simplement la variable permettant de savoir si on est en autotracking des objets
        TrackObjet = Not TrackObjet
    End Sub

#End Region

#Region "La grille"

    Private Sub grdDetail_CellDoubleClick(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles grdDetail.CellDoubleClick

        'Lors d'un double clique sur les cellules de la grille, on permet le choix sur boundingbox et visible (les autres valeurs sont modifiée par les champs en entête de la form
        Dim rectangle As New System.Drawing.Rectangle 'le rectangle correspondant à la cellule sélectionnée
        Dim Cell As DataGridViewCell = sender.currentcell 'on récupère la cellule sélectionnée
        Dim Row As DataGridViewRow = sender.rows(Cell.RowIndex) 'la ligne sélectionnée
        Dim FirstCell As DataGridViewCell = Row.Cells(0) 'La première cellule

        rectangle = Me.grdDetail.GetCellDisplayRectangle(Cell.ColumnIndex, Cell.RowIndex, True) 'on paramètre le rectangle
        If Cell.Value = "Oui" Then 'suivant la valeur de la cellule, on paramètre la combobox
            Me.cboBoolean.SelectedIndex = 0
        Else
            Me.cboBoolean.SelectedIndex = 1
        End If

        'on positionne et dimmensionne la combobox pour l'afficher dans la cellule
        Me.cboBoolean.Top = rectangle.Top
        Me.cboBoolean.Left = rectangle.Left
        Me.cboBoolean.Width = rectangle.Width
        Me.cboBoolean.Height = rectangle.Height
        Me.cboBoolean.Tag = FirstCell.Value 'pour savoir sur quel paramètre de la grille on travail (cf. cboBoolean.SelectedIndexChanged)

        'et on la montre
        Me.cboBoolean.Visible = True
    End Sub

#End Region

#Region "Les Command Buttons"

    Private Sub cmdSetDirection_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdSetDirection.Click
        'Permet de fixer la direction de l'objet en fonction des 3 champs textes
        SceneNodeSelected.SetDirection(txtDirectionX.Value, txtDirectionY.Value, txtDirectionZ.Value)
        GetOrientation() 'pour afficher les nouvelles valeurs
    End Sub

    Private Sub cmdPitch_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdPitch.Click
        'On tourne sur X
        SceneNodeSelected.Pitch(txtRotationX.Value)
        'Si l'axe est affiché, même punition. Réaction bizarre si la vaiable inheritorientation est mise à true.
        If ShowAxes Then
            NodeAxe.Pitch(txtRotationX.Value)
        End If
        GetOrientation() 'on affiche la nouvelle orientation
    End Sub

    Private Sub cmdYAw_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdYAw.Click
        'cf. cmdPich_Click sauf que c'est sur Y
        SceneNodeSelected.Yaw(txtRotationY.Value)
        If ShowAxes Then
            NodeAxe.Yaw(txtRotationY.Value)
        End If
        GetOrientation()
    End Sub

    Private Sub cmdRoll_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdRoll.Click
        'cf. cmdPich_Click sauf que c'est sur Z
        SceneNodeSelected.Roll(txtRotationZ.Value)
        If ShowAxes Then
            NodeAxe.Roll(txtRotationZ.Value)
        End If
        GetOrientation()
    End Sub

    Private Sub cmdResetOrientation_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdResetOrientation.Click
        'Permet de mettre l'objet dans sa direction de création, avant toute rotation
        SceneNodeSelected.ResetOrientation()
        GetOrientation()
    End Sub

    Private Sub cmdSetorientation_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdSetorientation.Click
        'Permet de ficer l'orientation de l'objet en fonction des 4 paramètre choisis
        SceneNodeSelected.SetOrientation(txtOrientationW.Value, txtOrientationX.Value, txtOrientationY.Value, txtOrientationZ.Value)
    End Sub

    Private Sub cmdResetEtat_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdResetEtat.Click
        'Permet de réinitialiser l'objet à ses conditions d'origine
        EnCoursDeSelection = True
        SceneNodeSelected.ResetToInitialState()
        'on récupère les nouvelles valeurs pour les afficher
        GetPosition()
        GetOrientation()
        GetEchelle()
        EnCoursDeSelection = False
    End Sub

    Private Sub cmdSetTranslation_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdSetTranslation.Click

        'Permet de déplacer l'objet en fonction de l'axe choisi
        Dim Axe As Mogre.Node.TransformSpace
        EnCoursDeTranslation = True 'on commence la translation

        'On récupère l'axe choisi dans la combobox
        Select Case cboTransAxe.SelectedIndex
            Case 0
                Axe = Node.TransformSpace.TS_LOCAL
            Case 1
                Axe = Node.TransformSpace.TS_PARENT
            Case 2
                Axe = Node.TransformSpace.TS_WORLD
        End Select

        'et on translate en fonction des paramètres sélectionés
        SceneNodeSelected.Translate(txtTransX.Value, txtTransY.Value, txtTransZ.Value, Axe)
        GetPosition() 'on récupère la nouvelle position
        EnCoursDeTranslation = False 'la translation est terminée

    End Sub

    Private Sub cmdReinitCamera_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdReinitCamera.Click
        'Pour réinitialiser la caméra à sa position d'origine
        If mnuDetectionDeCollision.Checked Then
            CamBody.SetPositionOrientation(InitialCamBodyPos, InitialCamBodyOrient)
        Else
            myCamera.SetPosition(InitialCamBodyPos.x, InitialCamBodyPos.y, InitialCamBodyPos.z)
            myCamera.Orientation = InitialCamBodyOrient
        End If
    End Sub

#End Region

#Region "Les ComboBox"

    Private Sub cboBoolean_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cboBoolean.SelectedIndexChanged

        'Si la combobox est visible, alors on est en tains de choisir l'option
        If cboBoolean.Visible Then
            If cboBoolean.Tag = "Visible" Then 'si ça porte sur la visibilité de l'objet
                If cboBoolean.SelectedIndex = 0 Then
                    MObjectSelected.Visible = True
                Else
                    MObjectSelected.Visible = False
                End If
            ElseIf cboBoolean.Tag = "CastShadows" Then 'sur sa faculté à projeter une ombre
                If cboBoolean.SelectedIndex = 0 Then
                    MObjectSelected.CastShadows = True
                Else
                    MObjectSelected.CastShadows = False
                End If
            Else 'alors c'est la boundingbox
                If cboBoolean.SelectedIndex = 0 Then
                    SceneNodeSelected.ShowBoundingBox = True
                Else
                    SceneNodeSelected.ShowBoundingBox = False
                End If
            End If
            cboBoolean.Visible = False 'on cache la combobox
            RemplitGrille() 'et on reremplit la grille
        End If

    End Sub

#End Region

#Region "Les trackbars"

    Private Sub trkRange_ValueChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles trkRange.ValueChanged
        'Modification de la portée de la lumière
        lblRange.Text = trkRange.Value
        LightSelected.SetAttenuation(trkRange.Value, trkConstant.Value / 100, System.Math.Round(trkLinear.Value / 10000, 5), System.Math.Round(trkQuadratic.Value / 10000, 5))
        'Les valeurs sont divisée pour s'accorder au range des paramètres. A affiner, pour voir plus ou moins d'effets
    End Sub

    Private Sub trkConstant_ValueChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles trkConstant.ValueChanged
        'La constante d'atténuation
        lblConstant.Text = trkConstant.Value / 100
        LightSelected.SetAttenuation(trkRange.Value, trkConstant.Value / 100, System.Math.Round(trkLinear.Value / 10000, 5), System.Math.Round(trkQuadratic.Value / 10000, 5))
        'Les valeurs sont divisée pour s'accorder au range des paramètres. A affiner, pour voir plus ou moins d'effets
    End Sub

    Private Sub trkLinear_ValueChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles trkLinear.ValueChanged
        'La linéarité de l'atténuation
        lblLinear.Text = System.Math.Round(trkLinear.Value / 10000, 5)
        LightSelected.SetAttenuation(trkRange.Value, trkConstant.Value / 100, System.Math.Round(trkLinear.Value / 10000, 5), System.Math.Round(trkQuadratic.Value / 10000, 5))
        'Les valeurs sont divisée pour s'accorder au range des paramètres. A affiner, pour voir plus ou moins d'effets
    End Sub

    Private Sub trkQuadratic_ValueChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles trkQuadratic.ValueChanged
        'La valeur Quadratic (Pas tout compris là...)
        lblQuadratic.Text = System.Math.Round(trkQuadratic.Value / 10000, 5)
        LightSelected.SetAttenuation(trkRange.Value, trkConstant.Value / 100, System.Math.Round(trkLinear.Value / 10000, 5), System.Math.Round(trkQuadratic.Value / 10000, 5))
        'Les valeurs sont divisée pour s'accorder au range des paramètres. A affiner, pour voir plus ou moins d'effets
    End Sub

#End Region

#End Region

End Class

Conclusion

Attention, la source ci-dessus n'est pas utilisable tel quel, vous devez télécharger le projet pour celà.
 

Fichier Zip

Pour les "Membres Club", vous pouvez télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip

Historique

08 août 2008 18:20:00 :
Juste un edit de l'entête
08 août 2008 18:55:40 :
Ajout d'une capture
10 août 2008 00:09:27 :
Correction orthographique....
12 août 2008 15:08:37 :
RAS

Commentaires et avis

signaler à un administrateur
Commentaire de gillardg le 08/08/2008 15:46:11

si tu cherches un endroit simple ou déposer un zip :
http://rapidshare.com/

signaler à un administrateur
Commentaire de feanor91 le 08/08/2008 18:08:00

Merci

Mais je connaissais déjà, le souci c'est qu'en free, au bout de 90 jours sans download, le fichier est vir&. Non, là je suis chez moi et je vais l'uploader sur 9Gigas.

signaler à un administrateur
Commentaire de gillardg le 08/08/2008 18:25:45

90 jours sans download

bof c'est viable

signaler à un administrateur
Commentaire de Nix le 08/08/2008 18:30:03 administrateur CS

Voilà, je viens de mettre le zip dans la source (11Mo)

signaler à un administrateur
Commentaire de feanor91 le 08/08/2008 18:46:33

Merci Nix...

A GILLARD : oui, bien sur, mais bon, je parle d'expérience, j'ai galéré comme un fou pour réussir à mettre la main sur un vieux source que j'avais vu sur les forums ogre et qui avais été uploadé via rapidshare mais qui n'y étais plus...Alors je préfère prévenir que guérir.

signaler à un administrateur
Commentaire de gillardg le 13/08/2008 13:26:57

mdr [

pour prévenir =>
une tache automatisée qui download tous les 80 jours

pour guérrir  => toujours faire des backup, ça guérit plein de trucs désagréables

]mdr

signaler à un administrateur
Commentaire de Oackland le 19/01/2009 17:04:03

Salut,

J'espère que tu vas pouvoir m'aider, après le chargement dans visual studio, au lancement du deboggage, j'ai systématiquement ce message :

Le module spécifié est introuvable. (Exception de HRESULT : 0x8007007E)

ceci se produit dès le début du lancement, je ne sais même pas ou est situé l'erreur dans le code.

signaler à un administrateur
Commentaire de feanor91 le 09/03/2009 12:03:10

Bonjour Oakland.

Désolé, mais je ne viens pas très souvent ici, donc, je viens juste de voir ton commentaire.

Ceci étant dit, as-tu résolu ton problème? Et sinon, il me faudrait un peu plus de détails pour comprendre ce qui t'arrive. As tu téléchargé le zip, ou juste copier/coller le code ci-dessus? Si oui, télécharge le zip et recommence car il te faut les dlls contenue dans le fichier pour que ça fonctionne.

signaler à un administrateur
Commentaire de Oackland le 09/03/2009 12:06:56

C'est bon, Feanor91, j'ai trouvé les divers problème que j'avais....
Merci

signaler à un administrateur
Commentaire de tomatomic le 31/03/2009 14:50:51

Bonjour Fenaor91,
Ton code m'interesse énormément mais ton code ne passe pas chez moi, j'ai également l'erreur 'Le module spécifié est introuvable. (Exception de HRESULT : 0x8007007E)' au démarrage de l'application... pourrais-tu me donner un coup de main car là je suis perdu.
Merci d'avance

signaler à un administrateur
Commentaire de feanor91 le 31/03/2009 17:30:42

Hello

Il te faut tout les sdk cités, ainsi que, sans doutes recréer les dépendance pour les différentes librairies (mogre, mogrenewt...), je pense que c'est important de vérifier ça dès le départ. Ton erreur de module est certainement du à ça. En gros, juste le copier coller du code dans vb ne suffit pas.

signaler à un administrateur
Commentaire de tomatomic le 31/03/2009 21:11:49

ben en faite j'ai recréé toutes les dépendances des dlls, soit Mogre,MogreNewt,Mois,OfusionLoader mais erreur tout de meme! En manque t'il un(dll)?

signaler à un administrateur
Commentaire de feanor91 le 31/03/2009 23:16:21

As-tu copiés les dll de ogre dans le dossier? ogremain.dll, ois.dll, de même le répertoire plugins est-il dans le dossier?

Lorsque tu lance en débugant, ça plante où?

signaler à un administrateur
Commentaire de tomatomic le 01/04/2009 14:44:41

oui j'ai bien ogremain.dll,ois.dll dans le dossier debug et le dossier plugins(6 dll's) également dans le dossier debug.
ça plante au déclaration de la frmMain j'arrive même pas à la première instruction...

signaler à un administrateur
Commentaire de feanor91 le 01/04/2009 17:31:33

ALors, là, je ne sais pas. EN plus ça fait un bout que je n'ai pas lancer le truc, il faut que je cherche, déjà voir chez moi si ça marche toujours. Cependant, tout les soucis que j'ai eut avec des exemples de code récupérés ici ou là était du à des problème de chemins pour les différentes ressources. Cherche de ce côté. Pour info, le sdk de ogre rt mogre est installé dans c:\ogresdk.

Par contre, ils ont évolué dans les versions de ogre depuis que ma source est pubbliée. Il est possible que si tu as téléchargé la version la plus récente du SDK, ça soit à cause de ça que ça ne marche pas. Pareil, apparement, les source de mogre ne match pas le SDK de ogre, ils sont en train de bosser sur une nouvelle release de mogre. A suivre sur les forums.

signaler à un administrateur
Commentaire de tomatomic le 01/04/2009 18:51:43

J'ai cherché la 1.4.6, est-ce la bonne version?

signaler à un administrateur
Commentaire de feanor91 le 01/04/2009 19:37:37

non, ça c'est la dernière. Celle avec laquelle j'ai bossé est la 1.4.4 si je ne m'abuse.

signaler à un administrateur
Commentaire de feanor91 le 15/04/2009 15:31:52

Alors TOMATOMIC, tu t'en es sortie? C'était un coup d'un souci de version? Perso, je n'arrive pas trop à comprendre si Mogre à migré sur la version 1.6 ou pas de OGRE, mais bon, je ne suis pas trop chaud pour migrer mon applis (pas celle de ce source, ma vraie appli) dessus car j'ai peur d'avoir des effets de bords indésirables...A voir.

Ajouter un commentaire

Discussions en rapport avec ce code source dans le forum

Moteur 3D [ par FireWave ] Y a t il quelqu'un qui connais où puis-je trouver des sources d'un moteur 3D?MerciFireWave Recherche person pour projet de Moteur 3D sous VB6+DirectX 8 [ par Tellurian ] SalutJe cherche des personnes qui voudraient créé un moteur 3D sous forme de DLL avec VB6 et DirectX 8.J'ai deja créé pa mal de moteur protoype mais l moteur 3d ou librairie graphique? [ par TheWhiteShadow ] encore un problème de nomenclature...enfin ce serait plutôt pour que vous confirmiez:librairie graphique: ensemble de fonctions qui permettent de géné Moteur 3D fait en VB [ par POLARIS ] Salutation &#224; la communaut&#233; 3D de Codes-sources.com Voil&#224; un moteur 3D "NemoX" &#233;veloppe depuis plus de deux ans en VB ce moteur&nbs Moteur 3d - avec gestion des .obj en XML [ par NeO78 ] Salut tout le monde ,Je recherche des personnes intéressées par la création d'un moteur 3d avec chargement et enregistrement des objets sous forme de Moteurs 3D en VB6 ? WebDriver, Ogre, etc... [ par Mutos ] Bonjour à tous,Je recherche les moteurs de rendering 3D utilisables à partir de VB6. J'utilise actuellement WebDriver, de Wild Tangent, qui est rapide moteur 3D isométrique [ par Antony ] Bonjour tout le monde !uhm voilà j'ai un moteur 3d isométrique sous la main et j'aimerais en comprendre son fonctionnement bon je comprends quand meme Moteur graphique TOUT SIMPLE [ par Alain Proviste ] Salut les gens.Bien, je demande votre aide, simple, je veux juste qu'on me guide un tout petit peu parce que j'ai du mal à savoir par où commencer.Sim Tzu3D, Moteur 3D en développement [ par ShadowMaster ] Bonjour, Tzu3D est un moteur 3D, destin&#233; aux amateurs d&#233;sirant produire des jeux 3D en n'ayant aucune connaissance dans le domaine. Mon o [Graphique] Moteur 3D [ par bricaland ] Salutation,Je cherche un moteur 3D soit gratuit soit lors de l'utilisation n'ayant pas de pub (c'est un peu génant quand même) permettant de faire du


Nos sponsors

Sondage...

CalendriCode

Juillet 2009
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
2728293031  

Consulter la suite du CalendriCode

Téléchargements

Logiciels à télécharger sur le même thème :

Comparez les prix Nouvelle version

Photothèque Nouveau !



Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés
Temps d'éxécution de la page : 0,718 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.