public static ModelData ReadModelData(Stream stream) { EngineBinaryReader engineBinaryReader = new EngineBinaryReader(stream, false); ModelData modelData = new ModelData(); modelData.Bones.Capacity = engineBinaryReader.ReadInt32(); for (int i = 0; i < modelData.Bones.Capacity; i++) { ModelBoneData modelBoneData = new ModelBoneData(); modelData.Bones.Add(modelBoneData); modelBoneData.ParentBoneIndex = engineBinaryReader.ReadInt32(); modelBoneData.Name = engineBinaryReader.ReadString(); modelBoneData.Transform = engineBinaryReader.ReadMatrix(); } modelData.Meshes.Capacity = engineBinaryReader.ReadInt32(); for (int j = 0; j < modelData.Meshes.Capacity; j++) { ModelMeshData modelMeshData = new ModelMeshData(); modelData.Meshes.Add(modelMeshData); modelMeshData.ParentBoneIndex = engineBinaryReader.ReadInt32(); modelMeshData.Name = engineBinaryReader.ReadString(); modelMeshData.MeshParts.Capacity = engineBinaryReader.ReadInt32(); modelMeshData.BoundingBox = engineBinaryReader.ReadBoundingBox(); for (int k = 0; k < modelMeshData.MeshParts.Capacity; k++) { ModelMeshPartData modelMeshPartData = new ModelMeshPartData(); modelMeshData.MeshParts.Add(modelMeshPartData); modelMeshPartData.BuffersDataIndex = engineBinaryReader.ReadInt32(); modelMeshPartData.StartIndex = engineBinaryReader.ReadInt32(); modelMeshPartData.IndicesCount = engineBinaryReader.ReadInt32(); modelMeshPartData.BoundingBox = engineBinaryReader.ReadBoundingBox(); } } modelData.Buffers.Capacity = engineBinaryReader.ReadInt32(); for (int l = 0; l < modelData.Buffers.Capacity; l++) { ModelBuffersData modelBuffersData = new ModelBuffersData(); modelData.Buffers.Add(modelBuffersData); VertexElement[] array = new VertexElement[engineBinaryReader.ReadInt32()]; for (int m = 0; m < array.Length; m++) { array[m] = new VertexElement(engineBinaryReader.ReadInt32(), (VertexElementFormat)engineBinaryReader.ReadInt32(), engineBinaryReader.ReadString()); } modelBuffersData.VertexDeclaration = new VertexDeclaration(array); modelBuffersData.Vertices = engineBinaryReader.ReadBytes(engineBinaryReader.ReadInt32()); modelBuffersData.Indices = engineBinaryReader.ReadBytes(engineBinaryReader.ReadInt32()); } return(modelData); }
static ModelMeshData LoadGeometry(ModelData data, ModelBoneData parentBoneData, ColladaGeometry geometry) { ModelMeshData modelMeshData = new ModelMeshData(); data.Meshes.Add(modelMeshData); modelMeshData.Name = parentBoneData.Name; modelMeshData.ParentBoneIndex = data.Bones.IndexOf(parentBoneData); bool flag = false; foreach (ColladaPolygons current in geometry.Mesh.Polygons) { ModelMeshPartData modelMeshPartData = LoadPolygons(data, current); modelMeshData.MeshParts.Add(modelMeshPartData); modelMeshData.BoundingBox = (flag ? BoundingBox.Union(modelMeshData.BoundingBox, modelMeshPartData.BoundingBox) : modelMeshPartData.BoundingBox); flag = true; } return(modelMeshData); }
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); }
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); }