public static void WriteModelData(Stream stream, ModelData modelData, Vector3 scale) { Matrix m = Matrix.CreateScale(scale); EngineBinaryWriter engineBinaryWriter = new EngineBinaryWriter(stream, false); engineBinaryWriter.Write(modelData.Bones.Count); foreach (ModelBoneData current in modelData.Bones) { engineBinaryWriter.Write(current.ParentBoneIndex); engineBinaryWriter.Write(current.Name); engineBinaryWriter.Write((current.ParentBoneIndex < 0) ? (current.Transform * m) : current.Transform); } engineBinaryWriter.Write(modelData.Meshes.Count); foreach (ModelMeshData current2 in modelData.Meshes) { engineBinaryWriter.Write(current2.ParentBoneIndex); engineBinaryWriter.Write(current2.Name); engineBinaryWriter.Write(current2.MeshParts.Count); engineBinaryWriter.Write(current2.BoundingBox); foreach (ModelMeshPartData current3 in current2.MeshParts) { engineBinaryWriter.Write(current3.BuffersDataIndex); engineBinaryWriter.Write(current3.StartIndex); engineBinaryWriter.Write(current3.IndicesCount); engineBinaryWriter.Write(current3.BoundingBox); } } engineBinaryWriter.Write(modelData.Buffers.Count); foreach (ModelBuffersData current4 in modelData.Buffers) { engineBinaryWriter.Write(current4.VertexDeclaration.VertexElements.Count); foreach (VertexElement current5 in current4.VertexDeclaration.VertexElements) { engineBinaryWriter.Write(current5.Offset); engineBinaryWriter.Write((int)current5.Format); engineBinaryWriter.Write(current5.Semantic); } engineBinaryWriter.Write(current4.Vertices.Length); engineBinaryWriter.Write(current4.Vertices); engineBinaryWriter.Write(current4.Indices.Length); engineBinaryWriter.Write(current4.Indices); } }
XElement GetGeometry(ModelData model, ModelMeshData data) { ModelMeshPartData meshPart = data.MeshParts[0]; ModelBoneData boneData = model.Bones[data.ParentBoneIndex]; string meshId = data.Name; var vertexBuffer = model.Buffers[meshPart.BuffersDataIndex]; int count = meshPart.IndicesCount; var vertexDeclaration = vertexBuffer.VertexDeclaration; byte[] original = new byte[count * 32]; using (BinaryReader reader = new BinaryReader(new MemoryStream(vertexBuffer.Indices))) { reader.BaseStream.Position = meshPart.StartIndex * 2; for (int i = 0; i < count; i++) { short index = reader.ReadInt16(); Buffer.BlockCopy(vertexBuffer.Vertices, index * 32, original, i * 32, 32); } } List <Vector3> vertices = new List <Vector3>(); List <Vector3> normals = new List <Vector3>(); float[] textureCord = new float[count * 2]; int[] indexs = new int[count * 3]; using (EngineBinaryReader reader = new EngineBinaryReader(new MemoryStream(original))) { foreach (VertexElement elem in vertexDeclaration.VertexElements) { if (elem.Semantic.StartsWith("POSITION")) { Vector3[] triangle = new Vector3[3]; for (int i = 0; i < count; i++) { reader.BaseStream.Position = vertexDeclaration.VertexStride * i + elem.Offset; var p = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); if (!vertices.Contains(p)) { vertices.Add(p); } var ii = i % 3; triangle[ii] = p; if (ii == 2) { indexs[i * 3 - 6] = vertices.IndexOf(triangle[0]); indexs[i * 3 - 3] = vertices.IndexOf(triangle[2]); indexs[i * 3] = vertices.IndexOf(triangle[1]); } } } else if (elem.Semantic.StartsWith("NORMAL")) { Vector3[] triangle = new Vector3[3]; for (int i = 0; i < count; i++) { reader.BaseStream.Position = vertexDeclaration.VertexStride * i + elem.Offset; var p = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); if (!normals.Contains(p)) { normals.Add(p); } var ii = i % 3; triangle[ii] = p; if (ii == 2) { indexs[i * 3 - 5] = normals.IndexOf(triangle[0]); indexs[i * 3 - 2] = normals.IndexOf(triangle[2]); indexs[i * 3 + 1] = normals.IndexOf(triangle[1]); } } } else if (elem.Semantic.StartsWith("TEXCOORD")) { for (int i = 0; i < count; i++) { reader.BaseStream.Position = vertexDeclaration.VertexStride * i + elem.Offset; textureCord[i * 2] = reader.ReadSingle(); textureCord[i * 2 + 1] = 1f - reader.ReadSingle(); if (i % 3 == 2) { indexs[i * 3 - 4] = i - 2; indexs[i * 3 - 1] = i; indexs[i * 3 + 2] = i - 1; } } } } } XElement positionSource; XElement normalSource; XElement texturecoorSource; XElement vertexSource; XElement meshElem = new XElement( colladaNS + "mesh", positionSource = GetSourceArray( meshId, "-mesh-positions", string.Join(" ", vertices.ConvertAll(v => string.Format("{0} {1} {2}", v.X.ToString("R"), v.Y.ToString("R"), v.Z.ToString("R")))), vertices.Count * 3, 3, XYZParam() ), normalSource = GetSourceArray( meshId, "-mesh-normals", string.Join(" ", normals.ConvertAll(v => string.Format("{0} {1} {2}", v.X.ToString("R"), v.Y.ToString("R"), v.Z.ToString("R")))), normals.Count * 3, 3, XYZParam() ), texturecoorSource = GetSourceArray( meshId, "-mesh-map", string.Join(" ", textureCord.Select(f => f.ToString("R"))), textureCord.Length, 2, STParam() ), vertexSource = new XElement( colladaNS + "vertices", new XAttribute("id", meshId + "-mesh-vertices"), GetInput("POSITION", positionSource) ), new XElement( colladaNS + "triangles", new XAttribute("count", count / 3), GetInput("VERTEX", vertexSource, 0), GetInput("NORMAL", normalSource, 1), GetInput("TEXCOORD", texturecoorSource, 2), new XElement(colladaNS + "p", string.Join(" ", indexs)) ) ); XElement geometry; root.Element(colladaNS + "library_geometries").Add( geometry = new XElement( colladaNS + "geometry", new XAttribute("id", meshId + "-mesh"), new XAttribute("name", meshId), meshElem ) ); return(geometry); }
protected override void OnLoad(EventArgs e) { Random random = new Random(); loader = new Loader(); entities = new List <Entity>(); guiTextures = new List <GuiTexture>(); //********************Player*********************** playerData = OBJLoader.LoadOBJ("Person.obj"); playerModel = loader.LoadToVao(playerData.vertices, playerData.textureCoords, playerData.normals, playerData.indices); playerTextured = new TexturedModel(playerModel, new ModelTexture(loader.LoadTexture("PlayerTexture.png"))); playerEntity = new Player(playerTextured, new Vector3(77.0f, 85.0f, -80.0f), 0.0f, -209.0f, 0.0f, 0.7f); entities.Add(playerEntity); //************************************************* //********************Camera*********************** camera = new Camera(playerEntity); //************************************************* TextMaster.Init(loader, Width, Height); renderer = new MasterRenderer(loader, camera, Width, Height); terrains = new List <Terrain>(); normalMapEntities = new List <Entity>(); lights = new List <Light>(); //*****************Particelle********************** particleTexture = new ParticleTexture(loader.LoadTexture("ParticleAtlas.png"), 4); ParticleMaster.Init(loader, renderer.ProjectionMatrix); particles = new ParticleSystem(50.0f, 25.0f, 0.3f, 4.0f, particleTexture); #region Sistema di particelle avanzato (da fixare) //particles = new ParticleSystem(50.0f, 25.0f, 0.3f, 4.0f, 1.0f); //particles.RandomizeRotation(); //particles.SetDirection(new Vector3(0.0f, 1.0f, 0.0f), 0.1f); //particles.SetLifeError(0.1f); //particles.SetSpeedError(0.4f); //particles.SetScaleError(0.8f); #endregion //************************************************* //*********************Font************************ FontType font = new FontType(loader.LoadFontTexture("FontDistanceField.png"), "FontDistanceField.fnt"); GUIText text = new GUIText("Enacoid text!", 1, font, new Vector2(0.0f, 0.0f), 1.0f, true); //************************************************* //********************TerrainTexture*************** backgroundTexture = new TerrainTexture(loader.LoadTexture("Grassy2.png")); rTexture = new TerrainTexture(loader.LoadTexture("Mud.png")); gTexture = new TerrainTexture(loader.LoadTexture("GrassFlowers.png")); bTexture = new TerrainTexture(loader.LoadTexture("Path.png")); texturePack = new TerrainTexturePack(backgroundTexture, rTexture, gTexture, bTexture); blendMap = new TerrainTexture(loader.LoadTexture("BlendMap.png")); //************************************************* //********************Terreno********************** terrain = new Terrain(0.0f, -1.0f, loader, texturePack, blendMap, "HeightMap.png"); terrains.Add(terrain); //************************************************* //*******************TexturedModel***************** rocks = new TexturedModel(loader.LoadToVao(OBJLoader.LoadOBJ("rocks.obj")), new ModelTexture(loader.LoadTexture("rocks.png"))); ModelTexture fernTextureAtlas = new ModelTexture(loader.LoadTexture("TextureAtlas.png")); fernTextureAtlas.NumberOfRows = 2; TexturedModel fern = new TexturedModel(loader.LoadToVao(OBJLoader.LoadOBJ("fern.obj")), fernTextureAtlas); fern.Texture.hasTransparency = true; TexturedModel bobble = new TexturedModel(loader.LoadToVao(OBJLoader.LoadOBJ("pine.obj")), new ModelTexture(loader.LoadTexture("pine.png"))); bobble.Texture.hasTransparency = true; TexturedModel lamp = new TexturedModel(loader.LoadToVao(OBJLoader.LoadOBJ("lamp.obj")), new ModelTexture(loader.LoadTexture("lamp.png"))); lamp.Texture.useFakeLighting = true; //************************************************* //******************Entità************************* rockEntity = new Entity(rocks, new Vector3(75.0f, terrain.GetHeightOfTerrain(75.0f, -75.0f), -75.0f), 0.0f, 0.0f, 0.0f, 10.0f); entities.Add(rockEntity); bobbleEntity = new Entity(bobble, new Vector3(85.0f, terrain.GetHeightOfTerrain(85.0f, -75.0f), -75.0f), 0.0f, 0.0f, 0.0f, 1.0f); entities.Add(bobbleEntity); lampEntity = new Entity(lamp, new Vector3(65.0f, terrain.GetHeightOfTerrain(65.0f, -75.0f), -75.0f), 0.0f, 0.0f, 0.0f, 1.0f); entities.Add(lampEntity); for (int i = 0; i < 60; i++) { if (i % 3 == 0) { float x = (float)random.NextDouble() * 150; float z = (float)random.NextDouble() * -150; if (!((x > 50 && x < 100) || (z < -50 && z > -100))) { float y = terrain.GetHeightOfTerrain(x, z); entities.Add(new Entity(fern, new Vector3(x, y, z), 0, (float)random.NextDouble() * 360, 0, 0.9f, random.Next(3))); } } if (i % 2 == 0) { float x = (float)random.NextDouble() * 150; float z = (float)random.NextDouble() * -150; if (!((x > 50 && x < 100) || (z < -50 && z > -100))) { float y = terrain.GetHeightOfTerrain(x, z); entities.Add(new Entity(bobble, new Vector3(x, y, z), 0, (float)random.NextDouble() * 360, 0, (float)random.NextDouble() * 0.6f + 0.8f, random.Next(3))); } } } //************************************************* //*******************NormalMapped****************** TexturedModel barrelModel = new TexturedModel(NormalMappedObjLoader.LoadOBJ("Barrel.obj", loader), new ModelTexture(loader.LoadTexture("Barrel.png"))); barrelModel.Texture.shineDamper = 10.0f; barrelModel.Texture.reflectivity = 0.5f; barrelModel.Texture.NormalMap = loader.LoadTexture("BarrelNormal.png"); normalMapEntities.Add(new Entity(barrelModel, new Vector3(163.0f, terrain.GetHeightOfTerrain(163.0f, -67.0f) + 6.5f, -67.0f), 0.0f, 0.0f, 0.0f, 1.0f)); TexturedModel boulderModel = new TexturedModel(NormalMappedObjLoader.LoadOBJ("Boulder.obj", loader), new ModelTexture(loader.LoadTexture("Boulder.png"))); boulderModel.Texture.shineDamper = 5.0f; boulderModel.Texture.reflectivity = 0.3f; boulderModel.Texture.NormalMap = loader.LoadTexture("BoulderNormal.png"); normalMapEntities.Add(new Entity(boulderModel, new Vector3(59.0f, terrain.GetHeightOfTerrain(59, -149) + 6.5f, -149), 0.0f, 0.0f, 0.0f, 1.0f)); ///*******************Luci************************* lights.Add(new Light(new Vector3(199000.0f, 200000.0f, -84000.0f), new Vector3(0.6f, 0.6f, 0.6f))); //************************************************* //********************Acqua************************ waterShader = new WaterShader(); waterFrameBuffers = new WaterFrameBuffer(Width, Height); waterRenderer = new WaterRenderer(loader, waterShader, renderer.ProjectionMatrix, waterFrameBuffers); waters = new List <WaterTile>(); water = new WaterTile(187.0f, -199.0f, terrain.GetHeightOfTerrain(187.0f, -199.0f) + 7.0f); waters.Add(water); //************************************************* mousePicker = new MousePicker(camera, renderer.ProjectionMatrix); //*********************GUIs************************ GuiTexture shadowMap = new GuiTexture(renderer.GetShadowMapTexture(), new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f)); //guiTextures.Add(shadowMap); guiRenderer = new GuiRenderer(loader); //************************************************* base.OnLoad(e); FrameTime = watch.GetCurrentTime(); }
static ModelMeshPartData LoadPolygons(ModelData data, ColladaPolygons polygons) { c__DisplayClass3_0 c__DisplayClass3_ = new c__DisplayClass3_0(); ModelMeshPartData modelMeshPartData = new ModelMeshPartData(); int num = 0; Dictionary <VertexElement, ColladaInput> dictionary = new Dictionary <VertexElement, ColladaInput>(); foreach (ColladaInput current in polygons.Inputs) { string str = (current.Set == 0) ? string.Empty : current.Set.ToString(CultureInfo.InvariantCulture); if (current.Semantic == "POSITION") { dictionary[new VertexElement(num, VertexElementFormat.Vector3, "POSITION" + str)] = current; num += 12; } else if (current.Semantic == "NORMAL") { dictionary[new VertexElement(num, VertexElementFormat.Vector3, "NORMAL" + str)] = current; num += 12; } else if (current.Semantic == "TEXCOORD") { dictionary[new VertexElement(num, VertexElementFormat.Vector2, "TEXCOORD" + str)] = current; num += 8; } else if (current.Semantic == "COLOR") { dictionary[new VertexElement(num, VertexElementFormat.NormalizedByte4, "COLOR" + str)] = current; num += 4; } } c__DisplayClass3_.vertexDeclaration = new VertexDeclaration(dictionary.Keys.ToArray <VertexElement>()); ModelBuffersData modelBuffersData = data.Buffers.FirstOrDefault(new Func <ModelBuffersData, bool>(c__DisplayClass3_.b__0)); if (modelBuffersData == null) { modelBuffersData = new ModelBuffersData(); data.Buffers.Add(modelBuffersData); modelBuffersData.VertexDeclaration = c__DisplayClass3_.vertexDeclaration; } modelMeshPartData.BuffersDataIndex = data.Buffers.IndexOf(modelBuffersData); int num2 = polygons.P.Count / polygons.InputCount; List <int> list = new List <int>(); if (polygons.VCount.Count == 0) { int num3 = 0; for (int i = 0; i < num2 / 3; i++) { list.Add(num3); list.Add(num3 + 2); list.Add(num3 + 1); num3 += 3; } } else { int num4 = 0; foreach (int current2 in polygons.VCount) { if (current2 == 3) { list.Add(num4); list.Add(num4 + 2); list.Add(num4 + 1); num4 += 3; } else { if (current2 != 4) { throw new NotSupportedException("Collada polygons with less than 3 or more than 4 vertices are not supported."); } list.Add(num4); list.Add(num4 + 2); list.Add(num4 + 1); list.Add(num4 + 2); list.Add(num4); list.Add(num4 + 3); num4 += 4; } } } int vertexStride = modelBuffersData.VertexDeclaration.VertexStride; int num5 = modelBuffersData.Vertices.Length; modelBuffersData.Vertices = ExtendArray <byte>(modelBuffersData.Vertices, list.Count * vertexStride); using (BinaryWriter binaryWriter = new BinaryWriter(new MemoryStream(modelBuffersData.Vertices, num5, list.Count * vertexStride))) { bool flag = false; foreach (KeyValuePair <VertexElement, ColladaInput> current3 in dictionary) { VertexElement key = current3.Key; ColladaInput value = current3.Value; if (key.Semantic.StartsWith("POSITION")) { for (int j = 0; j < list.Count; j++) { float[] arg_3EF_0 = value.Source.Accessor.Source.Array; int offset = value.Source.Accessor.Offset; int stride = value.Source.Accessor.Stride; int num6 = polygons.P[list[j] * polygons.InputCount + value.Offset]; binaryWriter.BaseStream.Position = (long)(j * vertexStride + key.Offset); float num7 = arg_3EF_0[offset + stride * num6]; float num8 = arg_3EF_0[offset + stride * num6 + 1]; float num9 = arg_3EF_0[offset + stride * num6 + 2]; modelMeshPartData.BoundingBox = (flag ? BoundingBox.Union(modelMeshPartData.BoundingBox, new Vector3(num7, num8, num9)) : new BoundingBox(num7, num8, num9, num7, num8, num9)); flag = true; binaryWriter.Write(num7); binaryWriter.Write(num8); binaryWriter.Write(num9); } } else if (key.Semantic.StartsWith("NORMAL")) { for (int k = 0; k < list.Count; k++) { float[] arg_51E_0 = value.Source.Accessor.Source.Array; int offset2 = value.Source.Accessor.Offset; int stride2 = value.Source.Accessor.Stride; int num10 = polygons.P[list[k] * polygons.InputCount + value.Offset]; binaryWriter.BaseStream.Position = (long)(k * vertexStride + key.Offset); float num11 = arg_51E_0[offset2 + stride2 * num10]; float num12 = arg_51E_0[offset2 + stride2 * num10 + 1]; float num13 = arg_51E_0[offset2 + stride2 * num10 + 2]; float num14 = 1f / MathUtils.Sqrt(num11 * num11 + num12 * num12 + num13 * num13); binaryWriter.Write(num14 * num11); binaryWriter.Write(num14 * num12); binaryWriter.Write(num14 * num13); } } else if (key.Semantic.StartsWith("TEXCOORD")) { for (int l = 0; l < list.Count; l++) { float[] array = value.Source.Accessor.Source.Array; int offset3 = value.Source.Accessor.Offset; int stride3 = value.Source.Accessor.Stride; int num15 = polygons.P[list[l] * polygons.InputCount + value.Offset]; binaryWriter.BaseStream.Position = (long)(l * vertexStride + key.Offset); binaryWriter.Write(array[offset3 + stride3 * num15]); binaryWriter.Write(1f - array[offset3 + stride3 * num15 + 1]); } } else { if (!key.Semantic.StartsWith("COLOR")) { throw new Exception(); } for (int m = 0; m < list.Count; m++) { float[] array2 = value.Source.Accessor.Source.Array; int offset4 = value.Source.Accessor.Offset; int stride4 = value.Source.Accessor.Stride; int num16 = polygons.P[list[m] * polygons.InputCount + value.Offset]; binaryWriter.BaseStream.Position = (long)(m * vertexStride + key.Offset); Color color = new Color(array2[offset4 + stride4 * num16], array2[offset4 + stride4 * num16 + 1], array2[offset4 + stride4 * num16 + 2], array2[offset4 + stride4 * num16 + 3]); binaryWriter.Write(color.PackedValue); } } } } modelMeshPartData.StartIndex = num5 / vertexStride; modelMeshPartData.IndicesCount = list.Count; return(modelMeshPartData); }
/// <summary> /// Crea un mesh da un file .obj nella cartella Models /// </summary> /// <param name="fileName">Il nome del file</param> /// <returns>Un oggetto di tipo ModelData</returns> public static ModelData LoadOBJ(string fileName) { string line; List <Vertex> vertices = new List <Vertex>(); List <Vector2> textures = new List <Vector2>(); List <Vector3> normals = new List <Vector3>(); List <uint> indices = new List <uint>(); using (StreamReader sr = new StreamReader(path + fileName)) { while (true) { line = sr.ReadLine(); if (line.StartsWith("v ")) { string[] currentLine = line.Split(' '); Vector3 vertex = new Vector3(float.Parse(currentLine[1], CultureInfo.InvariantCulture.NumberFormat), float.Parse(currentLine[2], CultureInfo.InvariantCulture.NumberFormat), float.Parse(currentLine[3], CultureInfo.InvariantCulture.NumberFormat)); Vertex newVertex = new Vertex((uint)Math.Abs(vertices.Count), vertex); vertices.Add(newVertex); } else if (line.StartsWith("vt ")) { string[] currentLine = line.Split(' '); Vector2 texture = new Vector2(float.Parse(currentLine[1], CultureInfo.InvariantCulture.NumberFormat), float.Parse(currentLine[2], CultureInfo.InvariantCulture.NumberFormat)); textures.Add(texture); } else if (line.StartsWith("vn ")) { string[] currentLine = line.Split(' '); Vector3 normal = new Vector3(float.Parse(currentLine[1], CultureInfo.InvariantCulture.NumberFormat), float.Parse(currentLine[2], CultureInfo.InvariantCulture.NumberFormat), float.Parse(currentLine[3], CultureInfo.InvariantCulture.NumberFormat)); normals.Add(normal); } else if (line.StartsWith("f ")) { break; } } while (line != null && line.StartsWith("f ")) { string[] currentLine = line.Split(' '); string[] vertex1 = currentLine[1].Split('/'); string[] vertex2 = currentLine[2].Split('/'); string[] vertex3 = currentLine[3].Split('/'); ProcessVertex(vertex1, vertices, indices); ProcessVertex(vertex2, vertices, indices); ProcessVertex(vertex3, vertices, indices); line = sr.ReadLine(); } } RemoveUnusedVertices(vertices); float[] verticesArray = new float[vertices.Count * 3]; float[] texturesArray = new float[vertices.Count * 2]; float[] normalsArray = new float[vertices.Count * 3]; float furthest = ConvertDataToArrays(vertices, textures, normals, verticesArray, texturesArray, normalsArray); uint[] indicesArray = ConvertIndicesListToArray(indices); ModelData data = new ModelData(verticesArray, texturesArray, normalsArray, indicesArray, furthest); return(data); }
public static void Write(Stream stream, ModelData data, Vector3 scale, bool keepSourceVertexDataInTags = true) { new BinaryWriter(stream).Write(keepSourceVertexDataInTags); ModelDataContentWriter.WriteModelData(stream, data, scale); }