source: OniSplit/Motoko/GeometryDaeWriter.cs@ 1194

Last change on this file since 1194 was 1114, checked in by iritscen, 5 years ago

Adding OniSplit source code (v0.9.99.0). Many thanks to Neo for all his work over the years.

File size: 3.9 KB
Line 
1using System;
2using System.Collections.Generic;
3
4namespace Oni.Motoko
5{
6 internal class GeometryDaeWriter
7 {
8 private readonly TextureDaeWriter textureWriter;
9
10 public GeometryDaeWriter(TextureDaeWriter textureWriter)
11 {
12 this.textureWriter = textureWriter;
13 }
14
15 public Dae.Node WriteNode(Geometry geometry, string name)
16 {
17 var daeGeometryInstance = WriteGeometryInstance(geometry, name);
18
19 return new Dae.Node
20 {
21 Name = name,
22 Instances = { daeGeometryInstance }
23 };
24 }
25
26 public Dae.GeometryInstance WriteGeometryInstance(Geometry geometry, string name)
27 {
28 var daeGeometry = WriteGeometry(geometry, name);
29 var daeGeometryInstance = new Dae.GeometryInstance(daeGeometry);
30
31 if (geometry.Texture != null)
32 {
33 var daeMaterial = textureWriter.WriteMaterial(geometry.Texture);
34
35 daeGeometryInstance.Materials.Add(new Dae.MaterialInstance("default", daeMaterial)
36 {
37 Bindings = {
38 new Dae.MaterialBinding(
39 semantic: "diffuse_TEXCOORD",
40 input: daeGeometry.Primitives[0].Inputs.Find(i => i.Semantic == Dae.Semantic.TexCoord))
41 }
42 });
43 }
44
45 return daeGeometryInstance;
46 }
47
48 private Dae.Geometry WriteGeometry(Geometry geometry, string name)
49 {
50 var points = geometry.Points;
51 var normals = geometry.Normals;
52 var texCoords = geometry.TexCoords;
53
54 if (geometry.HasTransform)
55 {
56 points = Vector3.Transform(points, ref geometry.Transform);
57 normals = Vector3.TransformNormal(normals, ref geometry.Transform);
58 }
59
60 int[] pointMap;
61
62 points = WeldPoints(points, out pointMap);
63
64 var positionInput = new Dae.IndexedInput(Dae.Semantic.Position, new Dae.Source(points));
65 var normalInput = new Dae.IndexedInput(Dae.Semantic.Normal, new Dae.Source(normals));
66 var texCoordInput = new Dae.IndexedInput(Dae.Semantic.TexCoord, new Dae.Source(texCoords));
67
68 var primitives = new Dae.MeshPrimitives(Dae.MeshPrimitiveType.Polygons)
69 {
70 MaterialSymbol = "default",
71 Inputs = { positionInput, normalInput, texCoordInput }
72 };
73
74 for (int triangleStart = 0; triangleStart < geometry.Triangles.Length; triangleStart += 3)
75 {
76 primitives.VertexCounts.Add(3);
77
78 for (int i = 0; i < 3; i++)
79 {
80 int index = geometry.Triangles[triangleStart + i];
81
82 positionInput.Indices.Add(pointMap[index]);
83 texCoordInput.Indices.Add(index);
84 normalInput.Indices.Add(index);
85 }
86 }
87
88 return new Dae.Geometry
89 {
90 Name = name,
91 Vertices = { positionInput },
92 Primitives = { primitives }
93 };
94 }
95
96 private static T[] WeldPoints<T>(T[] list, out int[] map)
97 {
98 var indicesMap = new int[list.Length];
99 var index = new Dictionary<T, int>(list.Length);
100 var result = new List<T>(list.Length);
101
102 for (int i = 0; i < indicesMap.Length; i++)
103 {
104 var v = list[i];
105
106 if (!index.TryGetValue(v, out indicesMap[i]))
107 {
108 indicesMap[i] = result.Count;
109 result.Add(v);
110 index.Add(v, indicesMap[i]);
111 }
112 }
113
114 map = indicesMap;
115
116 return result.ToArray();
117 }
118 }
119}
Note: See TracBrowser for help on using the repository browser.