using System; using System.Collections.Generic; using System.IO; using Oni.Imaging; namespace Oni.Motoko { internal class TextureDaeWriter { private readonly string outputDirPath; private readonly Dictionary materials = new Dictionary(); public TextureDaeWriter(string outputDirPath) { this.outputDirPath = outputDirPath; } public Dae.Material WriteMaterial(InstanceDescriptor txmp) { Dae.Material material; if (!materials.TryGetValue(txmp, out material)) { material = CreateMaterial(txmp); materials.Add(txmp, material); } return material; } private Dae.Material CreateMaterial(InstanceDescriptor txmp) { var texture = TextureDatReader.Read(txmp); var imageFilePath = Utils.CleanupTextureName(txmp.Name) + ".tga"; imageFilePath = Path.Combine("images", imageFilePath); TgaWriter.Write(texture.Surfaces[0], Path.Combine(outputDirPath, imageFilePath)); string name = TextureNameToId(txmp); var image = new Dae.Image { FilePath = "./" + imageFilePath.Replace('\\', '/'), Name = name }; var effectSurface = new Dae.EffectSurface(image); var effectSampler = new Dae.EffectSampler(effectSurface) { WrapS = texture.WrapU ? Dae.EffectSamplerWrap.Wrap : Dae.EffectSamplerWrap.None, WrapT = texture.WrapV ? Dae.EffectSamplerWrap.Wrap : Dae.EffectSamplerWrap.None }; var effectTexture = new Dae.EffectTexture(effectSampler, "diffuse_TEXCOORD"); var effect = new Dae.Effect { Name = name, DiffuseValue = effectTexture, TransparentValue = texture.HasAlpha ? effectTexture : null, Parameters = { new Dae.EffectParameter("surface", effectSurface), new Dae.EffectParameter("sampler", effectSampler) } }; var material = new Dae.Material { Name = name, Effect = effect }; return material; } private static string TextureNameToId(InstanceDescriptor txmp) { string name = Utils.CleanupTextureName(txmp.Name); if (name.StartsWith("Iteration", StringComparison.Ordinal)) { // // HACK: discard Iteration_NNN_ prefixes to avoid truncation of material // names in Blender. // name = name.Substring(9); if (char.IsDigit(name[0]) && char.IsDigit(name[1]) && char.IsDigit(name[2]) && name[3] == '_') name = name.Substring(4); } return name; } } }