| 1 | using System; | 
 
 
 
 
 | 2 | using System.Collections.Generic; | 
 
 
 
 
 | 3 |  | 
 
 
 
 
 | 4 | namespace 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 | } |