Historique des modifications - Message

Message #2827

Sujet: C# Irrlicht.NET CP 0.8 : loader de modèles DXS


Type Date Auteur Contenu
Création du message 13-08-2007 19:53:31 Aranoth
J'en profite alors pour mettre en ligne un autre code plus récent, mieux commenté.

Il y a pas mal de dépendances, mais il est tout de même assez simple à comprendre.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.IO;
using IrrlichtNETCP;
using IrrlichtNETCP.Inheritable;

namespace AGE
{
	// Mesh loader chargeant le format DXS (DeleD)
	public class DXSMeshLoader : IMeshLoader
	{
		// Chemin des textures
		static public string TexturePath = "";

		// Liste des materiaux
		Dictionary<int, Material> Materials = new Dictionary<int, Material>();

		// Charge le mesh
		public Mesh Load(string file)
		{
			Mesh mesh = new Mesh();

			XML.File xml = new AGE.XML.File(file);
			XML.Node NScene = xml.Root.GetChild(0);

			this.LoadMaterials(NScene.GetChild("materials"));
			this.LoadPrimitives(NScene.GetChild("primitives") , mesh);

			return mesh;
		}

		// Charge les primitives
		void LoadPrimitives(XML.Node NPrimitives , Mesh mesh)
		{
			// Parcours toutes les primitives
			foreach (XML.Node NPrimitive in NPrimitives.Childs)
			{
				// Tag (ex: eau, escaladable, destructible, etc)
				string Tag = NPrimitive.GetChild("tag").Text;

				// Parcours les vertices
				List<Vector3D> VerticesPosition = new List<Vector3D>();
				foreach (XML.Node NVertex in NPrimitive.GetChild("vertices").Childs)
				{
					Vector3D position = new Vector3D();
					position.X = Tools.ValF(NVertex.GetAttribute("x").Value);
					position.Y = Tools.ValF(NVertex.GetAttribute("y").Value);
					position.Z = -Tools.ValF(NVertex.GetAttribute("z").Value);

					VerticesPosition.Add(position);
				}

				// Parcours les polygones
				int OldMaterialID = -1;
				Primitive Primitive = null;
				foreach (XML.Node NPolygon in NPrimitive.GetChild("polygons").Childs)
				{
					// Identifiant du materiau à utiliser
					int MaterialID = Convert.ToInt32(NPolygon.GetAttribute("mid").Value);

					// Changement de matériau
					if (MaterialID != OldMaterialID)
					{
						// Creer une nouvelle primitive
						Primitive = new Primitive();
					}

					// Recupère le materiau dans la liste
					if (Materials.ContainsKey(MaterialID))
						Primitive.Material = Materials[MaterialID];

					// Parcours les vertices
					int VertexNbr = 0;
					foreach (XML.Node NVertex in NPolygon.Childs)
					{
						// Identifiant de la position du vertex
						int VertexID = Convert.ToInt32(NVertex.GetAttribute("vid").Value);
						
						// Coordonnées UV
						float U0 = Tools.ValF(NVertex.GetAttribute("u0").Value);
						float V0 = Tools.ValF(NVertex.GetAttribute("v0").Value);

						float U1 = U0;
						float V1 = V0;
						if (NVertex.GetAttribute("u1") != null && NVertex.GetAttribute("v1") != null)
						{
							U1 = Tools.ValF(NVertex.GetAttribute("u1").Value);
							V1 = Tools.ValF(NVertex.GetAttribute("v1").Value);
						}

						// Position du vertex
						Vector3D Position = VerticesPosition[VertexID];

						// Creer un vertex
						Vertex3DT2 vertex = new Vertex3DT2(Position, new Vector3D(), new Color(255, 255, 255, 255), new Vector2D(U0, V0), new Vector2D(U1, V1));

						Primitive.AddVertex(vertex);
						VertexNbr++;
					}

					// Indices
					int High = VertexNbr - 1;  // High, Low, Center
					int Low = 0;
					int Center = 0;

					int IndexOffset = Primitive.MeshBuffer.VertexCount;
					for (int v = 0; v < VertexNbr - 2; ++v)
					{
						// Calcul les indices
						if ((v & 1) > 0) Center = High - 1;
						else Center = Low + 1;

						// Ajoute les indices
						Primitive.AddIndex(IndexOffset + High);
						Primitive.AddIndex(IndexOffset + Low);
						Primitive.AddIndex(IndexOffset + Center);

						// Retrouve les vertices concernés
						Vertex3DT2 VertexCenter = Primitive.GetVertex(Center);
						Vertex3DT2 VertexLow = Primitive.GetVertex(Low);
						Vertex3DT2 VertexHigh = Primitive.GetVertex(High);

						// Calcul de la normale
						Vector3D Normal = this.GetFaceNormal(VertexHigh.Position, VertexLow.Position, VertexCenter.Position);

						// Corrige les normales des vertices
						VertexCenter.Normal += Normal;
						VertexLow.Normal += Normal;
						VertexHigh.Normal += Normal;

						if ((v & 1) > 0) High--;
						else Low++;
					}

					Primitive.RemadeMeshBuffer();

					// Changement de matériau, c'est donc une nouvelle primitive
					if (MaterialID != OldMaterialID)
					{
						// L'ajoute au mesh
						mesh.AddPrimitive(Primitive);
						OldMaterialID = MaterialID;
					}
				}
			}
		}

		// Charge les matériaux
		void LoadMaterials(XML.Node NMaterials)
		{
			// Parcours toutes les catégories
			foreach (XML.Node NCategory in NMaterials.Childs)
			{
				// Parcours tous les matériaux d'une catégorie
				foreach (XML.Node NMaterial in NCategory.Childs)
				{
					Material Material = new Material();
					Material.Lighting = false;
					int ID = Convert.ToInt32(NMaterial.GetAttribute("id").Value);

					// Parcours les layers du matérial
					foreach (XML.Node NLayer in NMaterial.Childs)
					{
						// Charge le fichier image
						string type = NLayer.GetAttribute("type").Value;
						string file = NLayer.GetChild("texture").GetAttribute("file").Value;

						file = DXSMeshLoader.TexturePath + file;

						if (type == "texture")
							Material.Texture1 = GraphicManager.Instance.Driver.GetTexture(file);
						else if (type == "lightmap")
						{
							// Présence d'une lightmap
							Material.Texture2 = GraphicManager.Instance.Driver.GetTexture(file);
							Material.MaterialType = MaterialType.Lightmap;
						}
					}

					// Ajoute le material à la liste
					Materials.Add(ID, Material);
				}
			}
		}

		// Renvoit la normale d'une face
		Vector3D GetFaceNormal(Vector3D a, Vector3D b, Vector3D c)
		{
			Vector3D o = new Vector3D();

			Vector3D v1 = new Vector3D();
			Vector3D v2 = new Vector3D();
			v1 = a - b;
			v2 = b - c;

			o.X = (v1.Y * v2.Z) - (v1.Z * v2.Y);
			o.Y = (v1.Z * v2.X) - (v1.X * v2.Z);
			o.Z = (v1.X * v2.Y) - (v1.Y * v2.X);

			float dist = (o.X * o.X) + (o.Y * o.Y) + (o.Z * o.Z);

			dist = (float)System.Math.Sqrt(dist);

			if (dist == 0.0f) dist = 0.001f;

			o /= dist;

			return o;
		}
	}
}

Retour

Options Liens officiels Caractéristiques Statistiques Communauté
Préférences cookies
Corrections
irrlicht
irrklang
irredit
irrxml
Propulsé par Django
xhtml 1.0
css 2.1
884 membres
1440 sujets
11337 messages
Dernier membre inscrit: Saidov17
144 invités en ligne
membre en ligne: -
RSS Feed