private XElement GetGeometry(ModelData model, ModelMeshData data) { ModelMeshPartData modelMeshPartData = data.MeshParts[0]; ModelBoneData modelBoneData = model.Bones[data.ParentBoneIndex]; string name = data.Name; ModelBuffersData modelBuffersData = model.Buffers[modelMeshPartData.BuffersDataIndex]; int indicesCount = modelMeshPartData.IndicesCount; VertexDeclaration vertexDeclaration = modelBuffersData.VertexDeclaration; byte[] array = new byte[indicesCount * 32]; using (BinaryReader binaryReader = new BinaryReader(new MemoryStream(modelBuffersData.Indices))) { binaryReader.BaseStream.Position = (long)(modelMeshPartData.StartIndex * 2); for (int i = 0; i < indicesCount; i++) { short num = binaryReader.ReadInt16(); Buffer.BlockCopy(modelBuffersData.Vertices, (int)(num * 32), array, i * 32, 32); } } List <Vector3> list = new List <Vector3>(); List <Vector3> list2 = new List <Vector3>(); float[] array2 = new float[indicesCount * 2]; int[] array3 = new int[indicesCount * 3]; using (BinaryReader binaryReader = new BinaryReader(new MemoryStream(array))) { foreach (VertexElement vertexElement in vertexDeclaration.VertexElements) { if (vertexElement.Semantic.StartsWith("POSITION")) { Vector3[] array4 = new Vector3[3]; for (int j = 0; j < indicesCount; j++) { binaryReader.BaseStream.Position = (long)(vertexDeclaration.VertexStride * j + vertexElement.Offset); Vector3 vector = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); if (!list.Contains(vector)) { list.Add(vector); } int num2 = j % 3; array4[num2] = vector; if (num2 == 2) { array3[j * 3 - 6] = list.IndexOf(array4[0]); array3[j * 3 - 3] = list.IndexOf(array4[2]); array3[j * 3] = list.IndexOf(array4[1]); } } } else if (vertexElement.Semantic.StartsWith("NORMAL")) { Vector3[] array5 = new Vector3[3]; for (int k = 0; k < indicesCount; k++) { binaryReader.BaseStream.Position = (long)(vertexDeclaration.VertexStride * k + vertexElement.Offset); Vector3 vector2 = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); if (!list2.Contains(vector2)) { list2.Add(vector2); } int num3 = k % 3; array5[num3] = vector2; if (num3 == 2) { array3[k * 3 - 5] = list2.IndexOf(array5[0]); array3[k * 3 - 2] = list2.IndexOf(array5[2]); array3[k * 3 + 1] = list2.IndexOf(array5[1]); } } } else if (vertexElement.Semantic.StartsWith("TEXCOORD")) { for (int l = 0; l < indicesCount; l++) { binaryReader.BaseStream.Position = (long)(vertexDeclaration.VertexStride * l + vertexElement.Offset); array2[l * 2] = binaryReader.ReadSingle(); array2[l * 2 + 1] = 1f - binaryReader.ReadSingle(); if (l % 3 == 2) { array3[l * 3 - 4] = l - 2; array3[l * 3 - 1] = l; array3[l * 3 + 2] = l - 1; } } } } } XName name2 = this.colladaNS + "mesh"; object[] array6 = new object[5]; XElement source = this.GetSourceArray(name, "-mesh-positions", string.Join(" ", list.ConvertAll <string>((Vector3 v) => string.Format("{0} {1} {2}", v.X.ToString("R"), v.Y.ToString("R"), v.Z.ToString("R")))), list.Count * 3, 3, this.XYZParam()); array6[0] = source; XElement source2 = this.GetSourceArray(name, "-mesh-normals", string.Join(" ", list2.ConvertAll <string>((Vector3 v) => string.Format("{0} {1} {2}", v.X.ToString("R"), v.Y.ToString("R"), v.Z.ToString("R")))), list2.Count * 3, 3, this.XYZParam()); array6[1] = source2; XElement source3 = this.GetSourceArray(name, "-mesh-map", string.Join(" ", from f in array2 select f.ToString("R")), array2.Length, 2, this.STParam()); array6[2] = source3; XElement source4 = new XElement(this.colladaNS + "vertices", new object[] { new XAttribute("id", name + "-mesh-vertices"), this.GetInput("POSITION", source) }); array6[3] = source4; array6[4] = new XElement(this.colladaNS + "triangles", new object[] { new XAttribute("count", indicesCount / 3), this.GetInput("VERTEX", source4, 0), this.GetInput("NORMAL", source2, 1), this.GetInput("TEXCOORD", source3, 2), new XElement(this.colladaNS + "p", string.Join <int>(" ", array3)) }); XElement xelement = new XElement(name2, array6); XElement result; this.root.Element(this.colladaNS + "library_geometries").Add(result = new XElement(this.colladaNS + "geometry", new object[] { new XAttribute("id", name + "-mesh"), new XAttribute("name", name), xelement })); return(result); }
public ModelData(Stream stream) { BinaryReader binaryReader = new BinaryReader(stream, Encoding.UTF8); binaryReader.ReadBoolean(); this.Bones.Capacity = binaryReader.ReadInt32(); for (int i = 0; i < this.Bones.Capacity; i++) { ModelBoneData modelBoneData = new ModelBoneData(); this.Bones.Add(modelBoneData); modelBoneData.ParentBoneIndex = binaryReader.ReadInt32(); modelBoneData.Name = binaryReader.ReadString(); modelBoneData.Transform = new Matrix( binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); } this.Meshes.Capacity = binaryReader.ReadInt32(); for (int j = 0; j < this.Meshes.Capacity; j++) { ModelMeshData modelMeshData = new ModelMeshData(); this.Meshes.Add(modelMeshData); modelMeshData.ParentBoneIndex = binaryReader.ReadInt32(); modelMeshData.Name = binaryReader.ReadString(); modelMeshData.MeshParts.Capacity = binaryReader.ReadInt32(); modelMeshData.BoundingBox = new BoundingBox( new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()), new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle())); for (int k = 0; k < modelMeshData.MeshParts.Capacity; k++) { ModelMeshPartData modelMeshPartData = new ModelMeshPartData(); modelMeshData.MeshParts.Add(modelMeshPartData); modelMeshPartData.BuffersDataIndex = binaryReader.ReadInt32(); modelMeshPartData.StartIndex = binaryReader.ReadInt32(); modelMeshPartData.IndicesCount = binaryReader.ReadInt32(); modelMeshPartData.BoundingBox = new BoundingBox( new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()), new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle())); } } this.Buffers.Capacity = binaryReader.ReadInt32(); for (int l = 0; l < this.Buffers.Capacity; l++) { ModelBuffersData modelBuffersData = new ModelBuffersData(); this.Buffers.Add(modelBuffersData); VertexElement[] array = new VertexElement[binaryReader.ReadInt32()]; for (int m = 0; m < array.Length; m++) { array[m] = new VertexElement(binaryReader.ReadInt32(), (VertexElementFormat)binaryReader.ReadInt32(), binaryReader.ReadString()); } modelBuffersData.VertexDeclaration = new VertexDeclaration(array); modelBuffersData.Vertices = binaryReader.ReadBytes(binaryReader.ReadInt32()); modelBuffersData.Indices = binaryReader.ReadBytes(binaryReader.ReadInt32()); } }
private static ModelMeshPartData LoadPolygons(ModelData data, Collada.ColladaPolygons polygons) { ModelMeshPartData modelMeshPartData = new ModelMeshPartData(); int num = 0; Dictionary <VertexElement, Collada.ColladaInput> dictionary = new Dictionary <VertexElement, Collada.ColladaInput>(); foreach (Collada.ColladaInput colladaInput in polygons.Inputs) { string str = (colladaInput.Set == 0) ? string.Empty : colladaInput.Set.ToString(CultureInfo.InvariantCulture); if (colladaInput.Semantic == "POSITION") { dictionary[new VertexElement(num, VertexElementFormat.Vector3, "POSITION" + str)] = colladaInput; num += 12; } else if (colladaInput.Semantic == "NORMAL") { dictionary[new VertexElement(num, VertexElementFormat.Vector3, "NORMAL" + str)] = colladaInput; num += 12; } else if (colladaInput.Semantic == "TEXCOORD") { dictionary[new VertexElement(num, VertexElementFormat.Vector2, "TEXCOORD" + str)] = colladaInput; num += 8; } else if (colladaInput.Semantic == "COLOR") { dictionary[new VertexElement(num, VertexElementFormat.NormalizedByte4, "COLOR" + str)] = colladaInput; num += 4; } } VertexDeclaration vertexDeclaration = new VertexDeclaration(Enumerable.ToArray <VertexElement>(dictionary.Keys)); ModelBuffersData modelBuffersData = Enumerable.FirstOrDefault <ModelBuffersData>(data.Buffers, (ModelBuffersData vd) => vd.VertexDeclaration == vertexDeclaration); if (modelBuffersData == null) { modelBuffersData = new ModelBuffersData(); data.Buffers.Add(modelBuffersData); modelBuffersData.VertexDeclaration = vertexDeclaration; } modelMeshPartData.BuffersDataIndex = data.Buffers.IndexOf(modelBuffersData); int num2 = polygons.P.Count / polygons.Inputs.Count; 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 num5 in polygons.VCount) { if (num5 == 3) { list.Add(num4); list.Add(num4 + 2); list.Add(num4 + 1); num4 += 3; } else { if (num5 != 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 num6 = modelBuffersData.Vertices.Length; modelBuffersData.Vertices = Collada.ExtendArray <byte>(modelBuffersData.Vertices, list.Count * vertexStride); using (BinaryWriter binaryWriter = new BinaryWriter(new MemoryStream(modelBuffersData.Vertices, num6, list.Count * vertexStride))) { bool flag = false; foreach (KeyValuePair <VertexElement, Collada.ColladaInput> keyValuePair in dictionary) { VertexElement key = keyValuePair.Key; Collada.ColladaInput value = keyValuePair.Value; if (key.Semantic.StartsWith("POSITION")) { for (int j = 0; j < list.Count; j++) { float[] array = value.Source.Accessor.Source.Array; int offset = value.Source.Accessor.Offset; int stride = value.Source.Accessor.Stride; int num7 = polygons.P[list[j] * polygons.Inputs.Count + value.Offset]; binaryWriter.BaseStream.Position = (long)(j * vertexStride + key.Offset); float num8 = array[offset + stride * num7]; float num9 = array[offset + stride * num7 + 1]; float num10 = array[offset + stride * num7 + 2]; modelMeshPartData.BoundingBox = (flag ? BoundingBox.Union(modelMeshPartData.BoundingBox, new Vector3(num8, num9, num10)) : new BoundingBox(num8, num9, num10, num8, num9, num10)); flag = true; binaryWriter.Write(num8); binaryWriter.Write(num9); binaryWriter.Write(num10); } } else if (key.Semantic.StartsWith("NORMAL")) { for (int k = 0; k < list.Count; k++) { float[] array2 = value.Source.Accessor.Source.Array; int offset2 = value.Source.Accessor.Offset; int stride2 = value.Source.Accessor.Stride; int num11 = polygons.P[list[k] * polygons.Inputs.Count + value.Offset]; binaryWriter.BaseStream.Position = (long)(k * vertexStride + key.Offset); float num12 = array2[offset2 + stride2 * num11]; float num13 = array2[offset2 + stride2 * num11 + 1]; float num14 = array2[offset2 + stride2 * num11 + 2]; float num15 = 1f / (float)Math.Sqrt(num12 * num12 + num13 * num13 + num14 * num14); binaryWriter.Write(num15 * num12); binaryWriter.Write(num15 * num13); binaryWriter.Write(num15 * num14); } } else if (key.Semantic.StartsWith("TEXCOORD")) { for (int l = 0; l < list.Count; l++) { float[] array3 = value.Source.Accessor.Source.Array; int offset3 = value.Source.Accessor.Offset; int stride3 = value.Source.Accessor.Stride; int num16 = polygons.P[list[l] * polygons.Inputs.Count + value.Offset]; binaryWriter.BaseStream.Position = (long)(l * vertexStride + key.Offset); binaryWriter.Write(array3[offset3 + stride3 * num16]); binaryWriter.Write(1f - array3[offset3 + stride3 * num16 + 1]); } } else { if (!key.Semantic.StartsWith("COLOR")) { throw new Exception(); } for (int m = 0; m < list.Count; m++) { float[] array4 = value.Source.Accessor.Source.Array; int offset4 = value.Source.Accessor.Offset; int stride4 = value.Source.Accessor.Stride; int num17 = polygons.P[list[m] * polygons.Inputs.Count + value.Offset]; binaryWriter.BaseStream.Position = (long)(m * vertexStride + key.Offset); Color color = new Color(array4[offset4 + stride4 * num17], array4[offset4 + stride4 * num17 + 1], array4[offset4 + stride4 * num17 + 2], array4[offset4 + stride4 * num17 + 3]); binaryWriter.Write(color.PackedValue); } } } } modelMeshPartData.StartIndex = num6 / vertexStride; modelMeshPartData.IndicesCount = list.Count; return(modelMeshPartData); }