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 | }
|
---|