| 1 | using System; | 
 
 
 
 
 | 2 | using System.Collections.Generic; | 
 
 
 
 
 | 3 |  | 
 
 
 
 
 | 4 | namespace Oni.Motoko | 
 
 
 
 
 | 5 | { | 
 
 
 
 
 | 6 | internal static class GeometryDatReader | 
 
 
 
 
 | 7 | { | 
 
 
 
 
 | 8 | public static Geometry Read(InstanceDescriptor m3gm) | 
 
 
 
 
 | 9 | { | 
 
 
 
 
 | 10 | if (m3gm.Template.Tag != TemplateTag.M3GM) | 
 
 
 
 
 | 11 | throw new ArgumentException(string.Format("Invalid instance type {0}", m3gm.Template.Tag), "m3gm"); | 
 
 
 
 
 | 12 |  | 
 
 
 
 
 | 13 | InstanceDescriptor pnta; | 
 
 
 
 
 | 14 | InstanceDescriptor vcra1; | 
 
 
 
 
 | 15 | InstanceDescriptor vcra2; | 
 
 
 
 
 | 16 | InstanceDescriptor txca; | 
 
 
 
 
 | 17 | InstanceDescriptor idxa1; | 
 
 
 
 
 | 18 | InstanceDescriptor idxa2; | 
 
 
 
 
 | 19 | InstanceDescriptor txmp; | 
 
 
 
 
 | 20 |  | 
 
 
 
 
 | 21 | using (var reader = m3gm.OpenRead(4)) | 
 
 
 
 
 | 22 | { | 
 
 
 
 
 | 23 | pnta = reader.ReadInstance(); | 
 
 
 
 
 | 24 | vcra1 = reader.ReadInstance(); | 
 
 
 
 
 | 25 | vcra2 = reader.ReadInstance(); | 
 
 
 
 
 | 26 | txca = reader.ReadInstance(); | 
 
 
 
 
 | 27 | idxa1 = reader.ReadInstance(); | 
 
 
 
 
 | 28 | idxa2 = reader.ReadInstance(); | 
 
 
 
 
 | 29 | txmp = reader.ReadInstance(); | 
 
 
 
 
 | 30 | } | 
 
 
 
 
 | 31 |  | 
 
 
 
 
 | 32 | var geometry = new Geometry { | 
 
 
 
 
 | 33 | Name = m3gm.FullName, | 
 
 
 
 
 | 34 | Texture = txmp | 
 
 
 
 
 | 35 | }; | 
 
 
 
 
 | 36 |  | 
 
 
 
 
 | 37 | Vector3[] faceNormals; | 
 
 
 
 
 | 38 | int[] faceIndices; | 
 
 
 
 
 | 39 | int[] vertexIndices; | 
 
 
 
 
 | 40 |  | 
 
 
 
 
 | 41 | using (var reader = pnta.OpenRead(52)) | 
 
 
 
 
 | 42 | geometry.Points = reader.ReadVector3Array(reader.ReadInt32()); | 
 
 
 
 
 | 43 |  | 
 
 
 
 
 | 44 | using (var reader = vcra1.OpenRead(20)) | 
 
 
 
 
 | 45 | geometry.Normals = reader.ReadVector3Array(reader.ReadInt32()); | 
 
 
 
 
 | 46 |  | 
 
 
 
 
 | 47 | using (var reader = vcra2.OpenRead(20)) | 
 
 
 
 
 | 48 | faceNormals = reader.ReadVector3Array(reader.ReadInt32()); | 
 
 
 
 
 | 49 |  | 
 
 
 
 
 | 50 | using (var reader = txca.OpenRead(20)) | 
 
 
 
 
 | 51 | geometry.TexCoords = reader.ReadVector2Array(reader.ReadInt32()); | 
 
 
 
 
 | 52 |  | 
 
 
 
 
 | 53 | using (var reader = idxa1.OpenRead(20)) | 
 
 
 
 
 | 54 | vertexIndices = reader.ReadInt32Array(reader.ReadInt32()); | 
 
 
 
 
 | 55 |  | 
 
 
 
 
 | 56 | using (var reader = idxa2.OpenRead(20)) | 
 
 
 
 
 | 57 | faceIndices = reader.ReadInt32Array(reader.ReadInt32()); | 
 
 
 
 
 | 58 |  | 
 
 
 
 
 | 59 | geometry.Triangles = ConvertTriangleStripToTriangleList(geometry.Points, vertexIndices, faceNormals, faceIndices); | 
 
 
 
 
 | 60 |  | 
 
 
 
 
 | 61 | return geometry; | 
 
 
 
 
 | 62 | } | 
 
 
 
 
 | 63 |  | 
 
 
 
 
 | 64 | private static int[] ConvertTriangleStripToTriangleList(Vector3[] points, int[] vIndices, Vector3[] fNormals, int[] fIndices) | 
 
 
 
 
 | 65 | { | 
 
 
 
 
 | 66 | var triangles = new List<int>(vIndices.Length * 2); | 
 
 
 
 
 | 67 |  | 
 
 
 
 
 | 68 | var face = new int[3]; | 
 
 
 
 
 | 69 | int faceIndex = 0; | 
 
 
 
 
 | 70 | int order = 0; | 
 
 
 
 
 | 71 |  | 
 
 
 
 
 | 72 | for (int i = 0; i < vIndices.Length; i++) | 
 
 
 
 
 | 73 | { | 
 
 
 
 
 | 74 | if (vIndices[i] < 0) | 
 
 
 
 
 | 75 | { | 
 
 
 
 
 | 76 | face[0] = vIndices[i++] & int.MaxValue; | 
 
 
 
 
 | 77 | face[1] = vIndices[i++]; | 
 
 
 
 
 | 78 | order = 0; | 
 
 
 
 
 | 79 | } | 
 
 
 
 
 | 80 | else | 
 
 
 
 
 | 81 | { | 
 
 
 
 
 | 82 | face[order] = face[2]; | 
 
 
 
 
 | 83 | order ^= 1; | 
 
 
 
 
 | 84 | } | 
 
 
 
 
 | 85 |  | 
 
 
 
 
 | 86 | face[2] = vIndices[i]; | 
 
 
 
 
 | 87 |  | 
 
 
 
 
 | 88 | var v1 = points[face[0]]; | 
 
 
 
 
 | 89 | var v2 = points[face[1]]; | 
 
 
 
 
 | 90 | var v3 = points[face[2]]; | 
 
 
 
 
 | 91 |  | 
 
 
 
 
 | 92 | var faceNormal1 = Vector3.Normalize(fNormals[fIndices[faceIndex]]); | 
 
 
 
 
 | 93 | var faceNormal2 = Vector3.Normalize(Vector3.Cross(v2 - v1, v3 - v1)); | 
 
 
 
 
 | 94 |  | 
 
 
 
 
 | 95 | if (Vector3.Dot(faceNormal1, faceNormal2) < 0.0f) | 
 
 
 
 
 | 96 | { | 
 
 
 
 
 | 97 | triangles.Add(face[2]); | 
 
 
 
 
 | 98 | triangles.Add(face[1]); | 
 
 
 
 
 | 99 | triangles.Add(face[0]); | 
 
 
 
 
 | 100 | } | 
 
 
 
 
 | 101 | else | 
 
 
 
 
 | 102 | { | 
 
 
 
 
 | 103 | triangles.Add(face[0]); | 
 
 
 
 
 | 104 | triangles.Add(face[1]); | 
 
 
 
 
 | 105 | triangles.Add(face[2]); | 
 
 
 
 
 | 106 | } | 
 
 
 
 
 | 107 |  | 
 
 
 
 
 | 108 | faceIndex++; | 
 
 
 
 
 | 109 | } | 
 
 
 
 
 | 110 |  | 
 
 
 
 
 | 111 | return triangles.ToArray(); | 
 
 
 
 
 | 112 | } | 
 
 
 
 
 | 113 | } | 
 
 
 
 
 | 114 | } |