[1114] | 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 | }
|
---|