[1114] | 1 | using System;
|
---|
| 2 | using System.Collections.Generic;
|
---|
| 3 | using System.Globalization;
|
---|
| 4 | using System.IO;
|
---|
| 5 |
|
---|
| 6 | namespace Oni.Motoko
|
---|
| 7 | {
|
---|
| 8 | internal class GeometryImporter : Importer
|
---|
| 9 | {
|
---|
| 10 | private readonly bool generateNormals;
|
---|
| 11 | private readonly bool flatNormals;
|
---|
| 12 | private readonly float shellOffset;
|
---|
| 13 | private readonly bool overrideTextureName;
|
---|
| 14 | private string textureName;
|
---|
| 15 |
|
---|
| 16 | public GeometryImporter(string[] args)
|
---|
| 17 | {
|
---|
| 18 | foreach (string arg in args)
|
---|
| 19 | {
|
---|
| 20 | if (arg == "-normals")
|
---|
| 21 | {
|
---|
| 22 | generateNormals = true;
|
---|
| 23 | }
|
---|
| 24 | else if (arg == "-flat")
|
---|
| 25 | {
|
---|
| 26 | flatNormals = true;
|
---|
| 27 | }
|
---|
| 28 | else if (arg == "-cel" || arg.StartsWith("-cel:", StringComparison.Ordinal))
|
---|
| 29 | {
|
---|
| 30 | int i = arg.IndexOf(':');
|
---|
| 31 |
|
---|
| 32 | if (i != -1)
|
---|
| 33 | shellOffset = float.Parse(arg.Substring(i + 1), CultureInfo.InvariantCulture);
|
---|
| 34 | else
|
---|
| 35 | shellOffset = 0.07f;
|
---|
| 36 | }
|
---|
| 37 | else if (arg.StartsWith("-tex:", StringComparison.Ordinal))
|
---|
| 38 | {
|
---|
| 39 | textureName = arg.Substring(5);
|
---|
| 40 | overrideTextureName = true;
|
---|
| 41 | }
|
---|
| 42 | }
|
---|
| 43 | }
|
---|
| 44 |
|
---|
| 45 | public ImporterDescriptor Import(string filePath, ImporterFile importer)
|
---|
| 46 | {
|
---|
| 47 | var scene = Dae.Reader.ReadFile(filePath);
|
---|
| 48 |
|
---|
| 49 | Dae.FaceConverter.Triangulate(scene);
|
---|
| 50 |
|
---|
| 51 | var daeInstances = new List<Dae.GeometryInstance>();
|
---|
| 52 |
|
---|
| 53 | foreach (var node in scene.Nodes)
|
---|
| 54 | {
|
---|
| 55 | var daeInstance = node.GeometryInstances.FirstOrDefault();
|
---|
| 56 |
|
---|
| 57 | if (daeInstance == null || daeInstance.Target == null)
|
---|
| 58 | continue;
|
---|
| 59 |
|
---|
| 60 | daeInstances.Add(daeInstance);
|
---|
| 61 | }
|
---|
| 62 |
|
---|
| 63 | foreach (var daeInstance in daeInstances)
|
---|
| 64 | {
|
---|
| 65 | var daeGeometry = daeInstance.Target;
|
---|
| 66 |
|
---|
| 67 | var geometry = GeometryDaeReader.Read(daeGeometry, generateNormals, flatNormals, shellOffset);
|
---|
| 68 |
|
---|
| 69 | string textureFilePath = null;
|
---|
| 70 |
|
---|
| 71 | if (!overrideTextureName && daeInstance.Materials.Count > 0)
|
---|
| 72 | textureFilePath = ReadMaterial(daeInstance.Materials[0].Target);
|
---|
| 73 |
|
---|
| 74 | geometry.TextureName = Path.GetFileNameWithoutExtension(textureFilePath);
|
---|
| 75 |
|
---|
| 76 | return GeometryDatWriter.Write(geometry, importer);
|
---|
| 77 | }
|
---|
| 78 |
|
---|
| 79 | return null;
|
---|
| 80 | }
|
---|
| 81 |
|
---|
| 82 | public override void Import(string filePath, string outputDirPath)
|
---|
| 83 | {
|
---|
| 84 | var scene = Dae.Reader.ReadFile(filePath);
|
---|
| 85 |
|
---|
| 86 | Dae.FaceConverter.Triangulate(scene);
|
---|
| 87 |
|
---|
| 88 | var daeInstances = new List<Dae.GeometryInstance>();
|
---|
| 89 |
|
---|
| 90 | foreach (var node in scene.Nodes)
|
---|
| 91 | {
|
---|
| 92 | var daeInstance = node.GeometryInstances.FirstOrDefault();
|
---|
| 93 |
|
---|
| 94 | if (daeInstance == null || daeInstance.Target == null)
|
---|
| 95 | continue;
|
---|
| 96 |
|
---|
| 97 | daeInstances.Add(daeInstance);
|
---|
| 98 | }
|
---|
| 99 |
|
---|
| 100 | foreach (var daeInstance in daeInstances)
|
---|
| 101 | {
|
---|
| 102 | var daeGeometry = daeInstance.Target;
|
---|
| 103 |
|
---|
| 104 | var geometry = GeometryDaeReader.Read(daeGeometry, generateNormals, flatNormals, shellOffset);
|
---|
| 105 | geometry.Name = Path.GetFileNameWithoutExtension(filePath);
|
---|
| 106 |
|
---|
| 107 | if (daeInstances.Count > 1)
|
---|
| 108 | geometry.Name += daeGeometry.Name;
|
---|
| 109 |
|
---|
| 110 | string textureFilePath = null;
|
---|
| 111 |
|
---|
| 112 | if (!overrideTextureName && daeInstance.Materials.Count > 0)
|
---|
| 113 | textureFilePath = ReadMaterial(daeInstance.Materials[0].Target);
|
---|
| 114 |
|
---|
| 115 | WriteM3GM(geometry, textureFilePath, outputDirPath);
|
---|
| 116 | }
|
---|
| 117 | }
|
---|
| 118 |
|
---|
| 119 | private void WriteM3GM(Geometry geometry, string textureFilePath, string outputDirPath)
|
---|
| 120 | {
|
---|
| 121 | geometry.Name = MakeInstanceName(TemplateTag.M3GM, geometry.Name);
|
---|
| 122 |
|
---|
| 123 | if (string.IsNullOrEmpty(textureFilePath))
|
---|
| 124 | geometry.TextureName = textureName;
|
---|
| 125 | else
|
---|
| 126 | geometry.TextureName = Path.GetFileNameWithoutExtension(textureFilePath);
|
---|
| 127 |
|
---|
| 128 | BeginImport();
|
---|
| 129 |
|
---|
| 130 | GeometryDatWriter.Write(geometry, ImporterFile);
|
---|
| 131 |
|
---|
| 132 | Write(outputDirPath);
|
---|
| 133 | }
|
---|
| 134 |
|
---|
| 135 | private string ReadMaterial(Dae.Material material)
|
---|
| 136 | {
|
---|
| 137 | if (material == null || material.Effect == null)
|
---|
| 138 | return null;
|
---|
| 139 |
|
---|
| 140 | var texture = material.Effect.Textures.FirstOrDefault(t => t.Channel == Dae.EffectTextureChannel.Diffuse);
|
---|
| 141 |
|
---|
| 142 | if (texture == null)
|
---|
| 143 | return null;
|
---|
| 144 |
|
---|
| 145 | var sampler = texture.Sampler;
|
---|
| 146 |
|
---|
| 147 | if (sampler == null || sampler.Surface == null || sampler.Surface.InitFrom == null || string.IsNullOrEmpty(sampler.Surface.InitFrom.FilePath))
|
---|
| 148 | return null;
|
---|
| 149 |
|
---|
| 150 | return sampler.Surface.InitFrom.FilePath;
|
---|
| 151 | }
|
---|
| 152 | }
|
---|
| 153 | }
|
---|