Example #1
0
        private void BuildTextures(OptFile opt)
        {
            this.nullTexture = null;
            this.textures    = null;

            if (opt == null)
            {
                return;
            }

            this.nullTexture = new DiffuseMaterial(Brushes.White);

            this.textures = new Dictionary <string, Material>();

            foreach (var texture in opt.Textures.Values)
            {
                var image = CreateTexture(opt, texture.Name);
                image.Freeze();

                var brush = new ImageBrush(image)
                {
                    ViewportUnits = BrushMappingMode.Absolute,
                    Stretch       = Stretch.Fill,
                    TileMode      = TileMode.Tile,
                    Opacity       = texture.HasAlpha ? 0.999 : 1.0
                };

                brush.Freeze();

                var material = new DiffuseMaterial(brush);
                material.Freeze();

                this.textures.Add(texture.Name, material);
            }
        }
        private void ExecuteNewCommand()
        {
            BusyIndicatorService.Run(dispatcher =>
            {
                bool isEmpty = this.OptModel.File == null ||
                               (string.IsNullOrEmpty(this.OptModel.File.FileName) &&
                                this.OptModel.File.Meshes.Count == 0 &&
                                this.OptModel.File.Textures.Count == 0);

                if (!isEmpty)
                {
                    var message = Messenger.Instance.Notify(new MessageBoxMessage("Creating a new opt will erase the existing one.\nDo you want to continue?", "New opt", MessageBoxButton.YesNo, MessageBoxImage.Warning));

                    if (message.Result != MessageBoxResult.Yes)
                    {
                        return;
                    }
                }

                dispatcher(() => this.OptModel.File = null);

                var opt = new OptFile();

                dispatcher(() => this.OptModel.File = opt);
                dispatcher(() => this.OptModel.UndoStackPush("new"));
            });
        }
        private List <ModelVisual3D> CreateMeshModelWireframe(OptFile opt, int meshIndex, int lodIndex)
        {
            if (opt == null ||
                opt.Meshes.ElementAtOrDefault(meshIndex) == null ||
                opt.Meshes[meshIndex].Lods.ElementAtOrDefault(lodIndex) == null)
            {
                return(new List <ModelVisual3D>());
            }

            var cache = this.Cache;

            if (meshIndex >= cache.meshesWireframes.Length || lodIndex >= cache.meshesWireframes[meshIndex].Length)
            {
                return(new List <ModelVisual3D>());
            }


            return(new List <ModelVisual3D>
            {
                new LinesVisual3D
                {
                    Points = new Point3DCollection(cache.meshesWireframes[meshIndex][lodIndex]),
                    DepthOffset = 0.0001,
                    Color = Colors.White
                }
            });
        }
Example #4
0
        private static ICollection <string> GetTexturesExist(string optName, OptFile opt, List <string> distinctSkins)
        {
            var    texturesExist = new SortedSet <string>();
            string directory     = Path.GetDirectoryName(opt.FileName);

            foreach (string skin in distinctSkins)
            {
                string skinDirectory = $"{directory}\\Skins\\{optName}\\{skin}";

                if (!Directory.Exists(skinDirectory))
                {
                    continue;
                }

                var filesEnum = Directory.EnumerateFiles(skinDirectory)
                                .Select(t => Path.GetFileName(t));

                var filesSet = new SortedSet <string>(filesEnum, StringComparer.OrdinalIgnoreCase);

                foreach (string textureName in opt.Textures.Keys)
                {
                    if (TextureExists(filesSet, textureName, skin) != null)
                    {
                        texturesExist.Add(textureName);
                    }
                }
            }

            return(texturesExist);
        }
        private void ExecuteOpenCommand()
        {
            BusyIndicatorService.Run(dispatcher =>
            {
                string fileName = FileDialogService.GetOpenOptFileName();

                if (fileName == null)
                {
                    return;
                }

                BusyIndicatorService.Notify(string.Concat("Opening ", System.IO.Path.GetFileName(fileName), "..."));

                try
                {
                    dispatcher(() => this.OptModel.File = null);

                    var opt = OptFile.FromFile(fileName);

                    dispatcher(() => this.OptModel.File = opt);
                    dispatcher(() => this.OptModel.UndoStackPush("open " + System.IO.Path.GetFileNameWithoutExtension(fileName)));

                    if (!this.OptModel.IsPlayable)
                    {
                        Messenger.Instance.Notify(new MainViewSelectorMessage("PlayabilityMessages"));
                        Messenger.Instance.Notify(new MessageBoxMessage(fileName + "\n\n" + "This opt will not be fully playable.", "Check Opt Playability", MessageBoxButton.OK, MessageBoxImage.Warning));
                    }
                }
                catch (Exception ex)
                {
                    Messenger.Instance.Notify(new MessageBoxMessage(fileName, ex));
                }
            });
        }
Example #6
0
        private Tuple <OptFile, OptCache> GetOptModel(string name)
        {
            OptFile file;

            if (!this.optFiles.TryGetValue(name, out file))
            {
                string fileName = AppSettings.WorkingDirectory + "FLIGHTMODELS\\" + name + ".opt";

                if (!System.IO.File.Exists(fileName))
                {
                    return(null);
                }

                file = OptFile.FromFile(fileName);
                this.optFiles.Add(name, file);
            }

            OptCache cache;

            if (!this.optCaches.TryGetValue(name, out cache))
            {
                cache = new OptCache(file);
                this.optCaches.Add(name, cache);
            }

            return(new Tuple <OptFile, OptCache>(file, cache));
        }
Example #7
0
        public static int ReadOptFunction([MarshalAs(UnmanagedType.LPStr)] string optFilename)
        {
            if (!File.Exists(optFilename))
            {
                return(0);
            }

            string         optName     = Path.GetFileNameWithoutExtension(optFilename);
            IList <string> objectLines = GetCustomFileLines("Skins");
            IList <string> baseSkins   = XwaHooksConfig.Tokennize(XwaHooksConfig.GetFileKeyValue(objectLines, optName));
            var            baseDefaultSkinDirectory = new DirectoryInfo($"FlightModels\\Skins\\{optName}\\Default");
            bool           baseDefaultSkinExists    = baseDefaultSkinDirectory.Exists && baseDefaultSkinDirectory.EnumerateFiles().Any();
            int            fgCount  = GetFlightgroupsCount(objectLines, optName);
            bool           hasSkins = baseDefaultSkinExists || baseSkins.Count != 0 || fgCount != 0;

            if (hasSkins)
            {
                var opt = OptFile.FromFile(optFilename);
                fgCount = Math.Max(fgCount, opt.MaxTextureVersion);
                UpdateOptFile(optName, opt, objectLines, baseSkins, fgCount);
                opt.Save("temp.opt");
            }

            return(hasSkins ? 1 : 0);
        }
Example #8
0
        public TextureBrowserWindow(Window owner, OptFile optFile)
        {
            InitializeComponent();

            this.Owner       = owner;
            this.DataContext = optFile;
        }
Example #9
0
        public static int ReadOptFunction([MarshalAs(UnmanagedType.LPStr)] string optFilename)
        {
            _tempOptFile     = null;
            _tempOptFileSize = 0;

            if (!File.Exists(optFilename))
            {
                return(0);
            }

            string         optName        = Path.GetFileNameWithoutExtension(optFilename);
            IList <string> objectLines    = GetCustomFileLines("Skins");
            IList <string> baseSkins      = XwaHooksConfig.Tokennize(XwaHooksConfig.GetFileKeyValue(objectLines, optName));
            bool           hasDefaultSkin = GetSkinDirectoryLocatorPath(optName, "Default") != null;
            int            fgCount        = GetFlightgroupsCount(objectLines, optName);
            bool           hasSkins       = hasDefaultSkin || baseSkins.Count != 0 || fgCount != 0;

            if (hasSkins)
            {
                var opt = OptFile.FromFile(optFilename);
                fgCount = Math.Max(fgCount, opt.MaxTextureVersion);
                UpdateOptFile(optName, opt, objectLines, baseSkins, fgCount, hasDefaultSkin);
                //opt.Save("temp.opt", false);

                _tempOptFile     = opt;
                _tempOptFileSize = opt.GetSaveRequiredFileSize(false);
            }

            return(hasSkins ? _tempOptFileSize : 0);
        }
Example #10
0
 public OptCache(OptFile opt)
 {
     this.file = opt;
     this.BuildTextures(opt);
     this.BuildMeshes(opt);
     this.BuildMeshesWireframes(opt);
 }
Example #11
0
        public OptModel()
        {
            this.PlayabilityMessages = new ObservableCollection <PlayabilityMessage>();
            this.UndoStack           = new ObservableCollection <Tuple <string, OptFile> >();

            this.file = new OptFile();
            this.UndoStackPush("new");
        }
        private void ExecuteImportOptCommand()
        {
            BusyIndicatorService.Run(dispatcher =>
            {
                string fileName = FileDialogService.GetOpenOptFileName();

                if (fileName == null)
                {
                    return;
                }

                BusyIndicatorService.Notify(string.Concat("Importing ", System.IO.Path.GetFileName(fileName), "..."));

                var opt = this.OptModel.File;

                try
                {
                    dispatcher(() => this.OptModel.File = null);

                    var import        = OptFile.FromFile(fileName);
                    string importName = System.IO.Path.GetFileNameWithoutExtension(fileName) + "_";

                    foreach (var faceGroup in import.Meshes.SelectMany(t => t.Lods).SelectMany(t => t.FaceGroups))
                    {
                        var textures = faceGroup.Textures.ToList();
                        faceGroup.Textures.Clear();

                        foreach (var texture in textures)
                        {
                            faceGroup.Textures.Add(texture.StartsWith(importName, StringComparison.Ordinal) ? texture : (importName + texture));
                        }
                    }

                    foreach (var texture in import.Textures.Values)
                    {
                        texture.Name = texture.Name.StartsWith(importName, StringComparison.Ordinal) ? texture.Name : (importName + texture.Name);
                    }

                    foreach (var texture in import.Textures.Values)
                    {
                        opt.Textures[texture.Name] = texture;
                    }

                    foreach (var mesh in import.Meshes)
                    {
                        opt.Meshes.Add(mesh);
                    }
                }
                catch (Exception ex)
                {
                    Messenger.Instance.Notify(new MessageBoxMessage(fileName, ex));
                }

                dispatcher(() => this.OptModel.File = opt);
                dispatcher(() => this.OptModel.UndoStackPush("import " + System.IO.Path.GetFileName(fileName)));
            });
        }
Example #13
0
        private static void UpdateOptFile(string optName, OptFile opt, IList <string> objectLines, IList <string> baseSkins, int fgCount)
        {
            List <List <string> > fgSkins       = ReadFgSkins(optName, objectLines, baseSkins, fgCount);
            List <string>         distinctSkins = fgSkins.SelectMany(t => t).Distinct(StringComparer.OrdinalIgnoreCase).ToList();
            ICollection <string>  texturesExist = GetTexturesExist(optName, opt, distinctSkins);

            CreateSwitchTextures(opt, texturesExist, fgSkins);
            UpdateSkins(optName, opt, fgSkins);
        }
        private void ExecuteConvertAllTexturesTo8BppCommand()
        {
            BusyIndicatorService.Run(dispatcher =>
            {
                string fileName = FileDialogService.GetOpenOptFileName();

                if (fileName == null)
                {
                    return;
                }

                string directory = System.IO.Path.GetDirectoryName(fileName);

                BusyIndicatorService.Notify("Converting all textures to 8 bpp...");

                var message = Messenger.Instance.Notify(new MessageBoxMessage(string.Concat("The textures of all OPTs in \"", directory, "\" will be converted to 8 bpp.\nDo you want to continue?"), "Converting textures", MessageBoxButton.YesNo, MessageBoxImage.Warning));

                if (message.Result != MessageBoxResult.Yes)
                {
                    return;
                }

                foreach (string file in System.IO.Directory.GetFiles(directory, "*.opt"))
                {
                    BusyIndicatorService.Notify(string.Concat("Converting ", System.IO.Path.GetFileName(file), " to 8 bpp..."));

                    OptFile opt = null;

                    try
                    {
                        opt = OptFile.FromFile(file);
                    }
                    catch (System.IO.InvalidDataException)
                    {
                        continue;
                    }

                    if (opt.TexturesBitsPerPixel == 8)
                    {
                        continue;
                    }

                    opt.ConvertTextures32To8();
                    opt.Save(opt.FileName);
                }

                BusyIndicatorService.Notify("Converting all textures to 8 bpp completed.");

                Messenger.Instance.Notify(new MessageBoxMessage("Converting all textures to 8 bpp completed.", "Converting textures"));
            });
        }
Example #15
0
        private void Execute_Open(object sender, ExecutedRoutedEventArgs e)
        {
            Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
            dlg.Filter = "Xwa OPT files|*.opt";

            if (dlg.ShowDialog() == true)
            {
                try
                {
                    this.OptFile = OptFile.FromFile(dlg.FileName);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, ex.Source, MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
        }
Example #16
0
        public static unsafe void WriteOptFunction(IntPtr ptr)
        {
            if (ptr == IntPtr.Zero || _tempOptFile == null || _tempOptFileSize == 0)
            {
                _tempOptFile     = null;
                _tempOptFileSize = 0;
                return;
            }

            using (var stream = new UnmanagedMemoryStream((byte *)ptr, _tempOptFileSize, _tempOptFileSize, FileAccess.Write))
            {
                _tempOptFile.Save(stream, false, false);
            }

            _tempOptFile     = null;
            _tempOptFileSize = 0;
        }
Example #17
0
        private static void UpdateSkins(string optName, OptFile opt, List <List <string> > fgSkins)
        {
            opt.Textures.AsParallel().ForAll(texture =>
            {
                int position = texture.Key.IndexOf("_fg_");

                if (position == -1)
                {
                    return;
                }

                string textureName = texture.Key.Substring(0, position);
                int fgIndex        = int.Parse(texture.Key.Substring(position + 4, texture.Key.IndexOf('_', position + 4) - position - 4), CultureInfo.InvariantCulture);
                string directory   = Path.GetDirectoryName(opt.FileName);

                foreach (string skin in fgSkins[fgIndex])
                {
                    string skinDirectory = $"{directory}\\Skins\\{optName}\\{skin}";

                    if (!Directory.Exists(skinDirectory))
                    {
                        continue;
                    }

                    var filesEnum = Directory.EnumerateFiles(skinDirectory)
                                    .Select(t => Path.GetFileName(t));

                    var filesSet = new SortedSet <string>(filesEnum, StringComparer.InvariantCultureIgnoreCase);

                    string filename = TextureExists(filesSet, textureName, skin);

                    if (filename == null)
                    {
                        continue;
                    }

                    CombineTextures(texture.Value, Path.Combine(skinDirectory, filename));
                }

                texture.Value.GenerateMipmaps();
            });
        }
        public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (values.Length < 2 ||
                values[0] == DependencyProperty.UnsetValue ||
                values[1] == DependencyProperty.UnsetValue)
            {
                return(null);
            }

            OptFile optFile = values[1] as OptFile;

            if (optFile == null)
            {
                return(null);
            }

            Texture texture = optFile.Textures.ContainsKey((string)values[0]) ? optFile.Textures[(string)values[0]] : null;

            return(TextureUtils.BuildOptTexture(texture));
        }
Example #19
0
        private static ICollection <string> GetTexturesExist(string optName, OptFile opt, List <string> distinctSkins)
        {
            var texturesExist = new SortedSet <string>();

            foreach (string skin in distinctSkins)
            {
                string path = GetSkinDirectoryLocatorPath(optName, skin);

                if (path == null)
                {
                    continue;
                }

                SortedSet <string> filesSet;

                using (IFileLocator locator = FileLocatorFactory.Create(path))
                {
                    if (locator == null)
                    {
                        continue;
                    }

                    var filesEnum = locator.EnumerateFiles()
                                    .Select(t => Path.GetFileName(t));

                    filesSet = new SortedSet <string>(filesEnum, StringComparer.OrdinalIgnoreCase);
                }

                foreach (string textureName in opt.Textures.Keys)
                {
                    if (TextureExists(filesSet, textureName, skin) != null)
                    {
                        texturesExist.Add(textureName);
                    }
                }
            }

            return(texturesExist);
        }
Example #20
0
        public void XWOpt_Read_TieFighter()
        {
            opt.Read(TieFighter);

            Hardpoint <Vector3> hardpoint = opt.OfType <Hardpoint <Vector3> >().First();

            Assert.That(hardpoint, Is.InstanceOf(typeof(Hardpoint <Vector3>)));
            Assert.That(hardpoint.Location, Is.EqualTo(new Vector3(-17f, -70f, -32f)));

            Assert.That(opt.OfType <Hardpoint <Vector3> >().Count(), Is.EqualTo(2));

            var convertedOpt = new OptFile <Vector2, Vector3>()
            {
                RotateFromOptSpace = new CoordinateSystemConverter <Vector3>(RotateIntoUnitySpace),
                Logger             = msg => TestContext.Out.WriteLine(msg),
            };

            convertedOpt.Read(TieFighter);
            var rotatedHardpoint = convertedOpt.OfType <Hardpoint <Vector3> >().First();

            Assert.That(rotatedHardpoint, Is.InstanceOf(typeof(Hardpoint <Vector3>)));
            Assert.That(rotatedHardpoint.Location, Is.EqualTo(new Vector3(-17f, -32f, 70f)));
        }
Example #21
0
        private static void CreateSwitchTextures(OptFile opt, ICollection <string> texturesExist, List <List <string> > fgSkins, List <int> fgColors)
        {
            int fgCount = fgSkins.Count;

            if (fgCount == 0)
            {
                return;
            }

            var newTextures = new List <Texture>();

            foreach (var texture in opt.Textures)
            {
                if (!texturesExist.Contains(texture.Key))
                {
                    continue;
                }

                foreach (int i in fgColors)
                {
                    texture.Value.Convert8To32();
                    Texture newTexture = texture.Value.Clone();
                    newTexture.Name += "_fg_" + i.ToString(CultureInfo.InvariantCulture) + "_" + string.Join(",", fgSkins[i]);
                    newTextures.Add(newTexture);
                }
            }

            foreach (var newTexture in newTextures)
            {
                opt.Textures.Add(newTexture.Name, newTexture);
            }

            foreach (var mesh in opt.Meshes)
            {
                foreach (var lod in mesh.Lods)
                {
                    foreach (var faceGroup in lod.FaceGroups)
                    {
                        if (faceGroup.Textures.Count == 0)
                        {
                            continue;
                        }

                        string name = faceGroup.Textures[0];

                        if (!texturesExist.Contains(name))
                        {
                            continue;
                        }

                        faceGroup.Textures.Clear();

                        for (int i = 0; i < fgCount; i++)
                        {
                            if (fgColors.Contains(i))
                            {
                                faceGroup.Textures.Add(name + "_fg_" + i.ToString(CultureInfo.InvariantCulture) + "_" + string.Join(",", fgSkins[i]));
                            }
                            else
                            {
                                faceGroup.Textures.Add(name);
                            }
                        }
                    }
                }
            }
        }
Example #22
0
        private static void UpdateSkins(string optName, OptFile opt, List <string> distinctSkins, List <List <string> > fgSkins)
        {
            var locatorsPath = new Dictionary <string, string>(distinctSkins.Count, StringComparer.OrdinalIgnoreCase);
            var filesSets    = new Dictionary <string, SortedSet <string> >(distinctSkins.Count, StringComparer.OrdinalIgnoreCase);

            foreach (string skin in distinctSkins)
            {
                string path = GetSkinDirectoryLocatorPath(optName, skin);
                locatorsPath.Add(skin, path);

                SortedSet <string> filesSet = null;

                if (path != null)
                {
                    using (IFileLocator locator = FileLocatorFactory.Create(path))
                    {
                        if (locator != null)
                        {
                            var filesEnum = locator.EnumerateFiles()
                                            .Select(t => Path.GetFileName(t));

                            filesSet = new SortedSet <string>(filesEnum, StringComparer.OrdinalIgnoreCase);
                        }
                    }
                }

                filesSets.Add(skin, filesSet ?? new SortedSet <string>());
            }

            opt.Textures.AsParallel().ForAll(texture =>
            {
                int position = texture.Key.IndexOf("_fg_");

                if (position == -1)
                {
                    return;
                }

                string textureName = texture.Key.Substring(0, position);
                int fgIndex        = int.Parse(texture.Key.Substring(position + 4, texture.Key.IndexOf('_', position + 4) - position - 4), CultureInfo.InvariantCulture);

                foreach (string skin in fgSkins[fgIndex])
                {
                    string path = locatorsPath[skin];

                    if (path == null)
                    {
                        continue;
                    }

                    string filename = TextureExists(filesSets[skin], textureName, skin);

                    if (filename == null)
                    {
                        continue;
                    }

                    using (IFileLocator locator = FileLocatorFactory.Create(path))
                    {
                        if (locator == null)
                        {
                            continue;
                        }

                        CombineTextures(texture.Value, locator, filename);
                    }
                }

                texture.Value.GenerateMipmaps();
            });
        }
Example #23
0
        public static void OptToObj(OptFile opt, string objPath, bool scale)
        {
            if (opt == null)
            {
                throw new ArgumentNullException("opt");
            }

            string objDirectory = Path.GetDirectoryName(objPath);
            string objName      = Path.GetFileNameWithoutExtension(objPath);

            var objMaterials = new ObjMaterialDictionary();

            foreach (var texture in opt.Textures.Values)
            {
                var material = new ObjMaterial
                {
                    Name = texture.Name,
                    DiffuseMapFileName = string.Format(CultureInfo.InvariantCulture, "{0}.png", texture.Name)
                };

                texture.Save(Path.Combine(objDirectory, material.DiffuseMapFileName));

                if (texture.HasAlpha)
                {
                    material.AlphaMapFileName = string.Format(CultureInfo.InvariantCulture, "{0}_alpha.png", texture.Name);

                    texture.SaveAlphaMap(Path.Combine(objDirectory, material.AlphaMapFileName));
                }

                objMaterials.Add(texture.Name, material);
            }

            objMaterials.Save(Path.ChangeExtension(objPath, "mtl"));

            var distances = opt.Meshes
                            .SelectMany(t => t.Lods)
                            .Select(t => t.Distance)
                            .Distinct()
                            .OrderByDescending(t => t)
                            .ToArray();

            for (int distance = 0; distance < distances.Length; distance++)
            {
                var obj = new ObjFile();

                int objectsIndex        = 0;
                int verticesIndex       = 0;
                int verticesTexIndex    = 0;
                int verticesNormalIndex = 0;

                foreach (var mesh in opt.Meshes)
                {
                    var lod = mesh.Lods.FirstOrDefault(t => t.Distance <= distances[distance]);

                    if (lod == null)
                    {
                        continue;
                    }

                    var objMesh = new ObjMesh(string.Format(CultureInfo.InvariantCulture, "{0}.{1:D3}", mesh.Descriptor.MeshType, objectsIndex));
                    obj.Meshes.Add(objMesh);
                    objectsIndex++;

                    if (scale)
                    {
                        foreach (var v in mesh.Vertices)
                        {
                            obj.Vertices.Add(new ObjVector3(v.X * OptFile.ScaleFactor, v.Z * OptFile.ScaleFactor, v.Y * OptFile.ScaleFactor));
                        }
                    }
                    else
                    {
                        foreach (var v in mesh.Vertices)
                        {
                            obj.Vertices.Add(new ObjVector3(v.X, v.Z, v.Y));
                        }
                    }

                    foreach (var v in mesh.TextureCoordinates)
                    {
                        obj.VertexTexCoords.Add(new ObjVector2(v.U, -v.V));
                    }

                    foreach (var v in mesh.VertexNormals)
                    {
                        obj.VertexNormals.Add(new ObjVector3(v.X, v.Z, v.Y));
                    }

                    foreach (var faceGroup in lod.FaceGroups)
                    {
                        var objFaceGroup = new ObjFaceGroup();

                        if (faceGroup.Textures.Count > 0)
                        {
                            objFaceGroup.MaterialName = faceGroup.Textures[0];
                        }

                        objMesh.FaceGroups.Add(objFaceGroup);

                        foreach (var face in faceGroup.Faces)
                        {
                            if (face.VerticesIndex.D < 0)
                            {
                                objFaceGroup.Faces.Add(new ObjFace()
                                {
                                    VerticesIndex = new ObjIndex(
                                        verticesIndex + face.VerticesIndex.A,
                                        verticesIndex + face.VerticesIndex.B,
                                        verticesIndex + face.VerticesIndex.C
                                        ),

                                    VertexTexCoordsIndex = new ObjIndex(
                                        verticesTexIndex + face.TextureCoordinatesIndex.A,
                                        verticesTexIndex + face.TextureCoordinatesIndex.B,
                                        verticesTexIndex + face.TextureCoordinatesIndex.C),

                                    VertexNormalsIndex = new ObjIndex(
                                        verticesNormalIndex + face.VertexNormalsIndex.A,
                                        verticesNormalIndex + face.VertexNormalsIndex.B,
                                        verticesNormalIndex + face.VertexNormalsIndex.C)
                                });
                            }
                            else
                            {
                                objFaceGroup.Faces.Add(new ObjFace()
                                {
                                    VerticesIndex = new ObjIndex(
                                        verticesIndex + face.VerticesIndex.A,
                                        verticesIndex + face.VerticesIndex.B,
                                        verticesIndex + face.VerticesIndex.C,
                                        verticesIndex + face.VerticesIndex.D
                                        ),

                                    VertexTexCoordsIndex = new ObjIndex(
                                        verticesTexIndex + face.TextureCoordinatesIndex.A,
                                        verticesTexIndex + face.TextureCoordinatesIndex.B,
                                        verticesTexIndex + face.TextureCoordinatesIndex.C,
                                        verticesTexIndex + face.TextureCoordinatesIndex.D),

                                    VertexNormalsIndex = new ObjIndex(
                                        verticesNormalIndex + face.VertexNormalsIndex.A,
                                        verticesNormalIndex + face.VertexNormalsIndex.B,
                                        verticesNormalIndex + face.VertexNormalsIndex.C,
                                        verticesNormalIndex + face.VertexNormalsIndex.D)
                                });
                            }
                        }
                    }

                    verticesIndex       += mesh.Vertices.Count;
                    verticesTexIndex    += mesh.TextureCoordinates.Count;
                    verticesNormalIndex += mesh.VertexNormals.Count;
                }

                obj.Save(Path.Combine(objDirectory, string.Format(CultureInfo.InvariantCulture, "{0}_{1}.obj", objName, distance)), objName);
            }
        }
Example #24
0
        public static OptFile An8ToOpt(string an8Path, bool scale)
        {
            string an8Directory = Path.GetDirectoryName(an8Path);

            var an8 = An8File.FromFile(an8Path);
            var opt = new OptFile();

            foreach (var mesh in an8.Objects
                     .SelectMany(t => t.Components)
                     .SelectMany(t => Converter.EnumMeshes(t)))
            {
                var optMesh = new Mesh();
                opt.Meshes.Add(optMesh);

                if (scale)
                {
                    foreach (var v in mesh.Points)
                    {
                        optMesh.Vertices.Add(new Vector(v.X / OptFile.ScaleFactor, v.Z / OptFile.ScaleFactor, v.Y / OptFile.ScaleFactor));
                    }
                }
                else
                {
                    foreach (var v in mesh.Points)
                    {
                        optMesh.Vertices.Add(new Vector(v.X, v.Z, v.Y));
                    }
                }

                foreach (var v in mesh.TexCoords)
                {
                    optMesh.TextureCoordinates.Add(new TextureCoordinates(v.U, -v.V));
                }

                foreach (var v in mesh.Normals)
                {
                    optMesh.VertexNormals.Add(new Vector(v.X, v.Z, v.Y));
                }

                optMesh.TextureCoordinates.Add(new TextureCoordinates(0, 0));
                optMesh.TextureCoordinates.Add(new TextureCoordinates(1, 0));
                optMesh.TextureCoordinates.Add(new TextureCoordinates(1, 1));
                optMesh.TextureCoordinates.Add(new TextureCoordinates(0, 1));

                var optLod = new MeshLod();
                optMesh.Lods.Add(optLod);

                foreach (var face in mesh.Faces)
                {
                    if (face.PointIndexes.Length < 3)
                    {
                        continue;
                    }

                    bool isQuad = face.PointIndexes.Length > 3;

                    var optFaceGroup = new FaceGroup();
                    optLod.FaceGroups.Add(optFaceGroup);

                    var materialName = mesh.MaterialList.ElementAtOrDefault(face.MaterialIndex);

                    if (!string.IsNullOrEmpty(materialName))
                    {
                        optFaceGroup.Textures.Add(materialName);
                    }

                    Index verticesIndex = new Index(
                        face.PointIndexes[0],
                        face.PointIndexes[1],
                        face.PointIndexes[2],
                        isQuad ? face.PointIndexes[3] : -1);

                    if (verticesIndex.A >= optMesh.Vertices.Count)
                    {
                        verticesIndex.A = 0;
                    }

                    if (verticesIndex.B >= optMesh.Vertices.Count)
                    {
                        verticesIndex.B = 0;
                    }

                    if (verticesIndex.C >= optMesh.Vertices.Count)
                    {
                        verticesIndex.C = 0;
                    }

                    if (verticesIndex.D >= optMesh.Vertices.Count)
                    {
                        verticesIndex.D = 0;
                    }

                    Index textureCoordinatesIndex = new Index(
                        face.TexCoordIndexes[0],
                        face.TexCoordIndexes[1],
                        face.TexCoordIndexes[2],
                        isQuad ? face.TexCoordIndexes[3] : -1);

                    if (textureCoordinatesIndex.A >= optMesh.TextureCoordinates.Count)
                    {
                        textureCoordinatesIndex.A = 0;
                    }

                    if (textureCoordinatesIndex.B >= optMesh.TextureCoordinates.Count)
                    {
                        textureCoordinatesIndex.B = 0;
                    }

                    if (textureCoordinatesIndex.C >= optMesh.TextureCoordinates.Count)
                    {
                        textureCoordinatesIndex.C = 0;
                    }

                    if (textureCoordinatesIndex.D >= optMesh.TextureCoordinates.Count)
                    {
                        textureCoordinatesIndex.D = 0;
                    }

                    Index vertexNormalsIndex = new Index(
                        face.NormalIndexes[0],
                        face.NormalIndexes[1],
                        face.NormalIndexes[2],
                        isQuad ? face.NormalIndexes[3] : -1);

                    if (vertexNormalsIndex.A >= optMesh.VertexNormals.Count)
                    {
                        vertexNormalsIndex.A = 0;
                    }

                    if (vertexNormalsIndex.B >= optMesh.VertexNormals.Count)
                    {
                        vertexNormalsIndex.B = 0;
                    }

                    if (vertexNormalsIndex.C >= optMesh.VertexNormals.Count)
                    {
                        vertexNormalsIndex.C = 0;
                    }

                    if (vertexNormalsIndex.D >= optMesh.VertexNormals.Count)
                    {
                        vertexNormalsIndex.D = 0;
                    }

                    if (textureCoordinatesIndex.A < 0 || textureCoordinatesIndex.B < 0 || textureCoordinatesIndex.C < 0 || (verticesIndex.D >= 0 && textureCoordinatesIndex.D < 0))
                    {
                        textureCoordinatesIndex.A = optMesh.TextureCoordinates.Count - 4;
                        textureCoordinatesIndex.B = optMesh.TextureCoordinates.Count - 3;
                        textureCoordinatesIndex.C = optMesh.TextureCoordinates.Count - 2;
                        textureCoordinatesIndex.D = verticesIndex.D < 0 ? -1 : optMesh.TextureCoordinates.Count - 1;
                    }

                    Vector normal = Vector.Normal(
                        optMesh.Vertices.ElementAtOrDefault(verticesIndex.A),
                        optMesh.Vertices.ElementAtOrDefault(verticesIndex.B),
                        optMesh.Vertices.ElementAtOrDefault(verticesIndex.C));

                    if (vertexNormalsIndex.A < 0 || vertexNormalsIndex.B < 0 || vertexNormalsIndex.C < 0 || (verticesIndex.D >= 0 && vertexNormalsIndex.D < 0))
                    {
                        optMesh.VertexNormals.Add(normal);

                        vertexNormalsIndex.A = optMesh.VertexNormals.Count - 1;
                        vertexNormalsIndex.B = optMesh.VertexNormals.Count - 1;
                        vertexNormalsIndex.C = optMesh.VertexNormals.Count - 1;
                        vertexNormalsIndex.D = verticesIndex.D < 0 ? -1 : optMesh.VertexNormals.Count - 1;
                    }

                    var optFace = new Face()
                    {
                        VerticesIndex           = verticesIndex,
                        TextureCoordinatesIndex = textureCoordinatesIndex,
                        VertexNormalsIndex      = vertexNormalsIndex,
                        Normal = normal
                    };

                    optFaceGroup.Faces.Add(optFace);
                }
            }

            opt.CompactBuffers();
            opt.ComputeHitzones();

            foreach (var material in an8.Materials
                     .Concat(an8.Objects.SelectMany(t => t.Materials))
                     .Where(t => t.FrontSurface != null)
                     .Select(t => new
            {
                Name = t.Name,
                Diffuse = t.FrontSurface.Diffuse,
                Alpha = t.FrontSurface.Alpha
            }))
            {
                Texture texture;

                var an8Texture = material.Diffuse.TextureName != null?
                                 an8.Textures.FirstOrDefault(t => string.Equals(t.Name, material.Diffuse.TextureName, StringComparison.Ordinal)) :
                                     null;

                if (an8Texture == null)
                {
                    byte r = material.Diffuse.Red;
                    byte g = material.Diffuse.Green;
                    byte b = material.Diffuse.Blue;

                    int    width  = 8;
                    int    height = 8;
                    int    length = width * height;
                    byte[] data   = new byte[length * 4];

                    for (int i = 0; i < length; i++)
                    {
                        data[i * 4 + 0] = b;
                        data[i * 4 + 1] = g;
                        data[i * 4 + 2] = r;
                        data[i * 4 + 3] = 255;
                    }

                    texture           = new Texture();
                    texture.Name      = material.Name;
                    texture.Width     = width;
                    texture.Height    = height;
                    texture.ImageData = data;
                }
                else
                {
                    string colorFileName = Path.Combine(an8Directory, Path.GetFileName(an8Texture.Files[0]));

                    texture      = Texture.FromFile(colorFileName);
                    texture.Name = material.Name;
                }

                if (material.Alpha > 0 && material.Alpha < 255)
                {
                    byte alpha = (byte)material.Alpha;

                    int length = texture.Width * texture.Height;

                    byte[] alphaData = new byte[length];
                    var    data      = texture.ImageData;

                    for (int i = 0; i < length; i++)
                    {
                        alphaData[i]    = alpha;
                        data[i * 4 + 3] = alpha;
                    }

                    texture.AlphaData = alphaData;
                }

                opt.Textures.Add(texture.Name, texture);
            }

            opt.GenerateTexturesMipmaps();

            return(opt);
        }
 public OptModel(string fileName)
 {
     this.File     = OptFile.FromFile(fileName);
     this.Cache    = new OptCache(this.File);
     this.SpanSize = this.File.SpanSize;
 }
Example #26
0
        public static void OptToAn8(OptFile opt, string an8Path, bool scale)
        {
            if (opt == null)
            {
                throw new ArgumentNullException("opt");
            }

            string an8Directory = Path.GetDirectoryName(an8Path);
            string an8Name      = Path.GetFileNameWithoutExtension(an8Path);

            foreach (var texture in opt.Textures.Values)
            {
                texture.Save(Path.Combine(an8Directory, string.Concat(texture.Name, ".png")));
            }

            var distances = opt.Meshes
                            .SelectMany(t => t.Lods)
                            .Select(t => t.Distance)
                            .Distinct()
                            .OrderByDescending(t => t)
                            .ToArray();

            for (int distance = 0; distance < distances.Length; distance++)
            {
                var an8 = new An8File();

                foreach (var texture in opt.Textures.Values)
                {
                    var an8Texture = new An8Texture();
                    an8Texture.Name = texture.Name;
                    an8Texture.Files.Add(string.Concat(texture.Name, ".png"));
                    an8.Textures.Add(an8Texture);

                    var an8Material = new An8Material();
                    an8Material.Name                 = texture.Name;
                    an8Material.FrontSurface         = new An8Surface();
                    an8Material.FrontSurface.Diffuse = new An8MaterialColor
                    {
                        TextureName   = texture.Name,
                        TextureParams = new An8TextureParams
                        {
                            AlphaMode = texture.HasAlpha ? An8AlphaMode.Final : An8AlphaMode.None,
                            BlendMode = An8BlendMode.Darken
                        }
                    };

                    an8.Materials.Add(an8Material);
                }

                var an8Object = new An8Object();
                an8Object.Name = Path.GetFileNameWithoutExtension(opt.FileName);
                an8.Objects.Add(an8Object);

                int objectsIndex = 0;

                foreach (var mesh in opt.Meshes)
                {
                    var lod = mesh.Lods.FirstOrDefault(t => t.Distance <= distances[distance]);

                    if (lod == null)
                    {
                        continue;
                    }

                    var an8Mesh = new An8Mesh();
                    an8Mesh.Name = string.Format(CultureInfo.InvariantCulture, "{0}.{1:D3}", mesh.Descriptor.MeshType, objectsIndex);
                    an8Object.Components.Add(an8Mesh);
                    objectsIndex++;

                    foreach (var texture in mesh.Lods
                             .SelectMany(t => t.FaceGroups)
                             .SelectMany(t => t.Textures)
                             .Distinct())
                    {
                        an8Mesh.MaterialList.Add(texture);
                    }

                    if (scale)
                    {
                        foreach (var v in mesh.Vertices)
                        {
                            an8Mesh.Points.Add(new An8Point
                            {
                                X = v.X * OptFile.ScaleFactor,
                                Y = v.Z * OptFile.ScaleFactor,
                                Z = v.Y * OptFile.ScaleFactor
                            });
                        }
                    }
                    else
                    {
                        foreach (var v in mesh.Vertices)
                        {
                            an8Mesh.Points.Add(new An8Point
                            {
                                X = v.X,
                                Y = v.Z,
                                Z = v.Y
                            });
                        }
                    }


                    foreach (var v in mesh.TextureCoordinates)
                    {
                        an8Mesh.TexCoords.Add(new An8TexCoord
                        {
                            U = v.U,
                            V = -v.V
                        });
                    }

                    foreach (var v in mesh.VertexNormals)
                    {
                        an8Mesh.Normals.Add(new An8Point
                        {
                            X = v.X,
                            Y = v.Z,
                            Z = v.Y
                        });
                    }

                    int verticesIndex       = 0;
                    int verticesTexIndex    = 0;
                    int verticesNormalIndex = 0;

                    foreach (var faceGroup in lod.FaceGroups)
                    {
                        int materialIndex = 0;

                        if (faceGroup.Textures.Count > 0)
                        {
                            materialIndex = an8Mesh.MaterialList.IndexOf(faceGroup.Textures[0]);
                        }

                        foreach (var face in faceGroup.Faces)
                        {
                            if (face.VerticesIndex.D < 0)
                            {
                                var an8Face = new An8Face
                                {
                                    MaterialIndex   = materialIndex,
                                    FlatNormalIndex = -1
                                };

                                an8Face.PointIndexes = new int[]
                                {
                                    verticesIndex + face.VerticesIndex.A,
                                    verticesIndex + face.VerticesIndex.B,
                                    verticesIndex + face.VerticesIndex.C
                                };

                                an8Face.TexCoordIndexes = new int[]
                                {
                                    verticesTexIndex + face.TextureCoordinatesIndex.A,
                                    verticesTexIndex + face.TextureCoordinatesIndex.B,
                                    verticesTexIndex + face.TextureCoordinatesIndex.C
                                };

                                an8Face.NormalIndexes = new int[]
                                {
                                    verticesNormalIndex + face.VertexNormalsIndex.A,
                                    verticesNormalIndex + face.VertexNormalsIndex.B,
                                    verticesNormalIndex + face.VertexNormalsIndex.C
                                };

                                an8Mesh.Faces.Add(an8Face);
                            }
                            else
                            {
                                var an8Face = new An8Face
                                {
                                    MaterialIndex   = materialIndex,
                                    FlatNormalIndex = -1
                                };

                                an8Face.PointIndexes = new int[]
                                {
                                    verticesIndex + face.VerticesIndex.A,
                                    verticesIndex + face.VerticesIndex.B,
                                    verticesIndex + face.VerticesIndex.C,
                                    verticesIndex + face.VerticesIndex.D
                                };

                                an8Face.TexCoordIndexes = new int[]
                                {
                                    verticesTexIndex + face.TextureCoordinatesIndex.A,
                                    verticesTexIndex + face.TextureCoordinatesIndex.B,
                                    verticesTexIndex + face.TextureCoordinatesIndex.C,
                                    verticesTexIndex + face.TextureCoordinatesIndex.D
                                };

                                an8Face.NormalIndexes = new int[]
                                {
                                    verticesNormalIndex + face.VertexNormalsIndex.A,
                                    verticesNormalIndex + face.VertexNormalsIndex.B,
                                    verticesNormalIndex + face.VertexNormalsIndex.C,
                                    verticesNormalIndex + face.VertexNormalsIndex.D
                                };

                                an8Mesh.Faces.Add(an8Face);
                            }
                        }
                    }

                    verticesIndex       += mesh.Vertices.Count;
                    verticesTexIndex    += mesh.TextureCoordinates.Count;
                    verticesNormalIndex += mesh.VertexNormals.Count;
                }

                an8.Save(Path.Combine(an8Directory, string.Format(CultureInfo.InvariantCulture, "{0}_{1}.an8", an8Name, distance)));
            }
        }
Example #27
0
 public static void OptToAn8(OptFile opt, string an8Path)
 {
     Converter.OptToAn8(opt, an8Path, true);
 }
Example #28
0
 public TextureBrowserMessage(OptFile optFile)
 {
     this.OptFile = optFile;
 }
        private List <ModelVisual3D> CreateMeshModel(OptFile opt, int meshIndex, int lodIndex, int version)
        {
            if (opt == null ||
                opt.Meshes.ElementAtOrDefault(meshIndex) == null ||
                opt.Meshes[meshIndex].Lods.ElementAtOrDefault(lodIndex) == null)
            {
                return(new List <ModelVisual3D>());
            }

            var cache = this.Cache;

            var mesh = opt.Meshes[meshIndex];
            var lod  = mesh.Lods[lodIndex];

            if (meshIndex >= cache.meshes.Length || lodIndex >= cache.meshes[meshIndex].Length || lod.FaceGroups.Count > cache.meshes[meshIndex][lodIndex].Length)
            {
                return(new List <ModelVisual3D>());
            }

            List <ModelVisual3D> group = new List <ModelVisual3D>();

            for (int faceGroupIndex = 0; faceGroupIndex < lod.FaceGroups.Count; faceGroupIndex++)
            {
                var faceGroup = lod.FaceGroups[faceGroupIndex];

                Material texture = null;
                bool     alpha   = false;

                if (faceGroup.Textures.Count != 0)
                {
                    int currentVersion = version;

                    if (version < 0 || version >= faceGroup.Textures.Count)
                    {
                        currentVersion = faceGroup.Textures.Count - 1;
                    }

                    string textureName = faceGroup.Textures[currentVersion];

                    if (cache.textures.ContainsKey(textureName))
                    {
                        texture = cache.textures[textureName];
                        alpha   = opt.Textures[textureName].HasAlpha;
                    }
                }

                var geometries = cache.meshes[meshIndex][lodIndex][faceGroupIndex];

                if (alpha)
                {
                    for (int i = 1; i < geometries.Length; i++)
                    {
                        GeometryModel3D model = new GeometryModel3D
                        {
                            Geometry     = geometries[i],
                            Material     = texture ?? cache.nullTexture,
                            BackMaterial = texture ?? cache.nullTexture
                        };

                        model.Freeze();

                        group.Add(new ModelVisual3D()
                        {
                            Content = model
                        });

                        this.ModelToMeshLodFace.Add(model, new MeshLodFace(opt.Meshes[meshIndex], opt.Meshes[meshIndex].Lods[lodIndex], faceGroup));
                    }
                }
                else
                {
                    GeometryModel3D model = new GeometryModel3D
                    {
                        Geometry = geometries[0],
                        Material = texture ?? cache.nullTexture
                    };

                    model.Freeze();

                    group.Add(new ModelVisual3D()
                    {
                        Content = model
                    });

                    this.ModelToMeshLodFace.Add(model, new MeshLodFace(opt.Meshes[meshIndex], opt.Meshes[meshIndex].Lods[lodIndex], faceGroup));
                }
            }

            return(group);
        }
        private static void ContentChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            var opt = (OptVisual3D)obj;

            switch (args.Property.Name)
            {
            case "FileName":
                opt.File = null;

                if (!string.IsNullOrEmpty(opt.FileName))
                {
                    try
                    {
                        opt.File = OptFile.FromFile(opt.FileName);
                    }
                    catch (InvalidDataException)
                    {
                    }
                }

                break;

            case "File":
                opt.Cache = null;

                if (opt.File != null)
                {
                    opt.Cache = new OptCache(opt.File);
                }

                break;

            case "Cache":
            case "Mesh":
            case "Lod":
            case "Distance":
            case "Version":
            case "IsSolid":
            case "IsWireframe":
                if (opt.Distance == null)
                {
                    opt.LoadOpt(opt.Mesh, opt.Lod, opt.Version);
                }
                else
                {
                    opt.LoadOpt(opt.Mesh, opt.Distance.Value, opt.Version);
                }

                break;
            }

            opt.Changed?.Invoke(opt, EventArgs.Empty);

            switch (args.Property.Name)
            {
            case "Cache":
            case "Mesh":
            case "Lod":
            case "Distance":
                opt.ModelChanged?.Invoke(opt, EventArgs.Empty);
                break;

            case "Version":
            case "IsSolid":
            case "IsWireframe":
                opt.AppearanceChanged?.Invoke(opt, EventArgs.Empty);
                break;
            }
        }