public void ParseCommandLineArguments()
        {
            string[] args = Environment.GetCommandLineArgs();

            if (args.Length > 1)
            {
                try
                {
                    filePath = args[1];
                    ClearVars(true);
                    file = PssgFile.Open(File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read));
                    nodesWorkspace.LoadData(file);
                    texturesWorkspace.LoadData(nodesWorkspace.RootNode);
                    if (texturesWorkspace.Textures.Count > 0)
                    {
                        SelectedTabIndex = 1;
                    }
                    DisplayName = Properties.Resources.AppTitleShort + " - " + Path.GetFileName(filePath);
                }
                catch (Exception excp)
                {
                    // Fail
                    DisplayName = Properties.Resources.AppTitleLong;
                    MessageBox.Show("The program could not open this file!" + Environment.NewLine + Environment.NewLine + excp.Message, "Could Not Open", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
        }
        public void Convert(ModelRoot gltf, PssgFile pssg)
        {
            // Get a list of nodes in the default scene as a flat list
            Dictionary <int, int> nodeBoneIndexMap = new Dictionary <int, int>();
            var rootNode = gltf.DefaultScene.FindNode(n => n.Name.StartsWith("Scene Root"));

            if (rootNode is null)
            {
                throw new InvalidDataException("The default scene must have node name starting with `Scene Root`.");
            }

            // Determine libraries in which to store data
            var nodeLib = pssg.FindNodes("LIBRARY", "type", "NODE").First();
            var rdsLib  = pssg.FindNodes("LIBRARY", "type", "RENDERDATASOURCE").First();
            var ribLib  = pssg.FindNodes("LIBRARY", "type", "RENDERINTERFACEBOUND").First();

            var state = new ImportState(ShaderInputInfo.CreateFromPssg(pssg).ToDictionary(si => si.ShaderGroupId));

            // Clear out the libraries
            nodeLib.RemoveChildNodes(nodeLib.ChildNodes.Where(n => n.Name == "ROOTNODE"));
            rdsLib.RemoveChildNodes(rdsLib.ChildNodes.Where(n => n.Name == "RENDERDATASOURCE"));
            ribLib.RemoveChildNodes(ribLib.ChildNodes.Where(n => n.Name == "DATABLOCK"));

            // Write the scene graph, and collect mesh data
            ConvertSceneNodes(pssg, nodeLib, rootNode, state);
        }
        private void OpenCommand_Execute(object parameter)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();

            openFileDialog.Filter      = "PSSG files|*.pssg|DDS files|*.dds|Xml files|*.xml|All files|*.*";
            openFileDialog.FilterIndex = 1;
            if (!string.IsNullOrEmpty(filePath))
            {
                openFileDialog.FileName         = Path.GetFileNameWithoutExtension(filePath);
                openFileDialog.InitialDirectory = Path.GetDirectoryName(filePath);
            }

            if (openFileDialog.ShowDialog() == true)
            {
                try
                {
                    filePath = openFileDialog.FileName;
                    using (var fs = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        var pssg = PssgFile.Open(fs);
                        LoadPssg(pssg);
                    }
                    DisplayName = Properties.Resources.AppTitleShort + " - " + Path.GetFileName(filePath);
                }
                catch (Exception excp)
                {
                    // Fail
                    DisplayName = Properties.Resources.AppTitleLong;
                    MessageBox.Show("The program could not open this file!" + Environment.NewLine + Environment.NewLine + excp.Message, "Could Not Open", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
        }
        public ModelRoot Convert(PssgFile pssg)
        {
            var sceneBuilder = new SceneBuilder();

            var state = new ExportState();

            // F1 games use lib YYY
            var parent = pssg.FindNodes("LIBRARY", "type", "NODE").FirstOrDefault();

            if (parent is null)
            {
                parent     = pssg.FindNodes("LIBRARY", "type", "YYY").FirstOrDefault();
                state.IsF1 = true;
            }
            if (parent is null)
            {
                throw new InvalidDataException("Could not find library with scene nodes.");
            }

            foreach (var child in parent.ChildNodes)
            {
                CreateNode(sceneBuilder, child, null, state);
            }

            return(sceneBuilder.ToGltf2());
        }
Beispiel #5
0
        public void Convert(ModelRoot gltf, PssgFile pssg)
        {
            // Get a list of nodes in the default scene as a flat list
            Dictionary <int, int> nodeBoneIndexMap = new Dictionary <int, int>();
            var rootNode = gltf.DefaultScene.FindNode(n => n.Name.StartsWith("Scene Root"));

            if (rootNode is null)
            {
                throw new InvalidDataException("The default scene must have node name starting with `Scene Root`.");
            }

            // Determine libraries in which to store data
            var      nodeLib = pssg.FindNodes("LIBRARY", "type", "NODE").FirstOrDefault();
            PssgNode rdsLib; PssgNode ribLib;

            if (nodeLib is not null)
            {
                rdsLib = pssg.FindNodes("LIBRARY", "type", "RENDERDATASOURCE").First();
                ribLib = pssg.FindNodes("LIBRARY", "type", "RENDERINTERFACEBOUND").First();
            }
            else
            {
                // F1 games use YYY, and put almost everything in this lib
                nodeLib = pssg.FindNodes("LIBRARY", "type", "YYY").FirstOrDefault();
                if (nodeLib is null)
                {
                    throw new InvalidDataException("Could not find library with scene nodes.");
                }

                rdsLib = nodeLib;
                ribLib = nodeLib;
            }

            var state = new ImportState(rdsLib, ribLib, ShaderInputInfo.CreateFromPssg(pssg).ToDictionary(si => si.ShaderGroupId));

            // Clear out the libraries
            nodeLib.RemoveChildNodes(nodeLib.ChildNodes.Where(n => n.Name == "ROOTNODE"));
            rdsLib.RemoveChildNodes(rdsLib.ChildNodes.Where(n => n.Name == "RENDERDATASOURCE"));
            ribLib.RemoveChildNodes(ribLib.ChildNodes.Where(n => n.Name == "DATABLOCK"));

            // Write the scene graph, and collect mesh data
            ConvertSceneNodes(pssg, nodeLib, rootNode, state);

            // Seems in Dirt Rally 2.0 there is a bunch of useless data in lib SEGMENTSET
            // lets get rid of it
            var ssLibNode = pssg.FindNodes("LIBRARY", "type", "SEGMENTSET").FirstOrDefault();

            if (ssLibNode is not null)
            {
                ssLibNode.ParentNode?.RemoveChild(ssLibNode);
            }
        }
        private void ClearVars(bool clearPSSG)
        {
            if (file == null)
            {
                return;
            }

            nodesWorkspace.ClearData();
            texturesWorkspace.ClearData();

            DisplayName = Properties.Resources.AppTitleLong;
            if (clearPSSG == true)
            {
                file = null;
            }
        }
Beispiel #7
0
        private static void ConvertMaterial(PssgFile pssg, MaterialBuilder mat, int texCoordSets)
        {
            var shader = pssg.FindNodes("SHADERINSTANCE", "id", mat.Name).FirstOrDefault();

            if (shader is null)
            {
                throw new InvalidDataException($"Could not find shader instance {mat.Name} referenced by the model.");
            }

            var shaderGroupId = shader.Attributes["shaderGroup"].GetValue <string>().Substring(1);
            var sgNode        = shader.File.FindNodes("SHADERGROUP", "id", shaderGroupId).FirstOrDefault();
            var textureInputs = shader.FindNodes("SHADERINPUT", "type", "texture");

            mat.WithMetallicRoughnessShader()
            .WithMetallicRoughness(0.1f, 0.5f)
            .WithBaseColor(new Vector4(1, 1, 1, 1));

            if (texCoordSets > 0)
            {
                mat.UseChannel(KnownChannel.BaseColor).UseTexture()
                .WithPrimaryImage(new MemoryImage(GetDiffuseTexture(sgNode, textureInputs)))
                .WithCoordinateSet(0);
            }

            if (texCoordSets > 1)
            {
                mat.UseChannel(KnownChannel.Occlusion).UseTexture()
                .WithPrimaryImage(new MemoryImage(GetOcclusionTexture(sgNode, textureInputs)))
                .WithCoordinateSet(1);
            }

            if (texCoordSets > 2)
            {
                mat.UseChannel(KnownChannel.Emissive).UseTexture()
                .WithPrimaryImage(new MemoryImage(GetEmissiveTexture(sgNode, textureInputs)))
                .WithCoordinateSet(2);
            }

            if (texCoordSets > 3)
            {
                mat.UseChannel(KnownChannel.Normal).UseTexture()
                .WithPrimaryImage(new MemoryImage(GetNormalTexture(sgNode, textureInputs)))
                .WithCoordinateSet(3);
            }
        }
        private static void ConvertSceneNodes(PssgFile pssg, PssgNode parent, Node gltfNode, ImportState state)
        {
            PssgNode node;

            if (gltfNode.Name.StartsWith("Scene Root", StringComparison.InvariantCulture))
            {
                node = new PssgNode("ROOTNODE", parent.File, parent);
                node.AddAttribute("stopTraversal", 0u);
                node.AddAttribute("nickname", "Scene Root");
                node.AddAttribute("id", "Scene Root");
                parent.ChildNodes.Add(node);
            }
            else if (gltfNode.Mesh is not null)
            {
                _ = CreateRenderNode(parent, gltfNode, state);
                return;
            }
            else
            {
                node = new PssgNode("NODE", parent.File, parent);
                node.AddAttribute("stopTraversal", 0u);
                node.AddAttribute("nickname", gltfNode.Name);
                node.AddAttribute("id", gltfNode.Name);
                parent.ChildNodes.Add(node);
            }

            var transformNode = new PssgNode("TRANSFORM", node.File, node)
            {
                Value = GetTransform(gltfNode.LocalMatrix)
            };

            node.ChildNodes.Add(transformNode);

            var bboxNode = new PssgNode("BOUNDINGBOX", node.File, node)
            {
                Value = GetBoundingBoxData(Vector3.Zero, Vector3.Zero)
            };

            node.ChildNodes.Add(bboxNode);

            foreach (var child in gltfNode.VisualChildren)
            {
                ConvertSceneNodes(pssg, node, child, state);
            }
        }
        public static List <ShaderInputInfo> CreateFromPssg(PssgFile pssg)
        {
            var visitedShaders = new HashSet <string>();
            var inputInfos     = new List <ShaderInputInfo>();

            // Figure out the layout of the vertex data for each shader group by going through rds nodes
            var rdsNodes = pssg.FindNodes("RENDERDATASOURCE");

            foreach (var rdsNode in rdsNodes)
            {
                var info = GetShaderInfo(rdsNode, visitedShaders);
                if (info is not null)
                {
                    inputInfos.Add(info);
                }
            }

            return(inputInfos);
        private static void ConvertSceneNodes(PssgFile pssg, PssgNode parent, Node gltfNode, ImportState state)
        {
            PssgNode node;
            Match    lodMatch;

            if (gltfNode.Name.StartsWith("Scene Root"))
            {
                node = new PssgNode("ROOTNODE", parent.File, parent);
                node.AddAttribute("stopTraversal", 0u);
                node.AddAttribute("nickname", "Scene Root");
                node.AddAttribute("id", "Scene Root");
                parent.ChildNodes.Add(node);
            }
            else if ((lodMatch = state.LodMatcher.Match(gltfNode.Name)).Success)
            {
                var lodNumber = int.Parse(lodMatch.Groups[1].Value);
                node = CreateMatrixPaletteBundleNode(parent, gltfNode, lodNumber, state);
                return;
            }
            else
            {
                node = new PssgNode("NODE", parent.File, parent);
                node.AddAttribute("stopTraversal", 0u);
                node.AddAttribute("nickname", gltfNode.Name);
                node.AddAttribute("id", gltfNode.Name);
                parent.ChildNodes.Add(node);
            }

            var transformNode = new PssgNode("TRANSFORM", node.File, node);

            transformNode.Value = GetTransform(gltfNode.LocalMatrix);
            node.ChildNodes.Add(transformNode);

            var bboxNode = new PssgNode("BOUNDINGBOX", node.File, node);

            bboxNode.Value = GetBoundingBoxData(Vector3.Zero, Vector3.Zero);
            node.ChildNodes.Add(bboxNode);

            foreach (var child in gltfNode.VisualChildren)
            {
                ConvertSceneNodes(pssg, node, child, state);
            }
        }
        private static void ConvertMaterial(PssgFile pssg, MaterialBuilder mat, int texCoordSets)
        {
            var shader = pssg.FindNodes("SHADERINSTANCE", "id", mat.Name).FirstOrDefault();

            if (shader is null)
            {
                throw new InvalidDataException($"Could not find shader instance {mat.Name} referenced by the model.");
            }

            mat.WithMetallicRoughnessShader()
            .WithMetallicRoughness(0.1f, 0.5f)
            .WithBaseColor(new Vector4(1, 1, 1, 1));

            if (texCoordSets > 0)
            {
                mat.UseChannel(KnownChannel.BaseColor).UseTexture()
                .WithPrimaryImage(new MemoryImage(grayImageBytes))
                .WithCoordinateSet(0);
            }

            if (texCoordSets > 1)
            {
                mat.UseChannel(KnownChannel.Occlusion).UseTexture()
                .WithPrimaryImage(new MemoryImage(whiteImageBytes))
                .WithCoordinateSet(1);
            }

            if (texCoordSets > 2)
            {
                mat.UseChannel(KnownChannel.Emissive).UseTexture()
                .WithPrimaryImage(new MemoryImage(blackImageBytes))
                .WithCoordinateSet(2);
            }

            if (texCoordSets > 3)
            {
                mat.UseChannel(KnownChannel.Normal).UseTexture()
                .WithPrimaryImage(new MemoryImage(blackImageBytes))
                .WithCoordinateSet(3);
            }
        }
        public void LoadPssg(PssgFile pssg)
        {
            // if pssg is null, we just want to reload the workspaces
            if (pssg is null)
            {
                ClearVars(false);
            }
            else
            {
                ClearVars(true);
                file = pssg;
            }

            nodesWorkspace.LoadData(file);
            texturesWorkspace.LoadData(nodesWorkspace.RootNode);
            if (texturesWorkspace.Textures.Count > 0)
            {
                SelectedTabIndex = 1;
            }
            _modelsWorkspace.LoadData(file);
        }
        public void ParseCommandLineArguments()
        {
            string[] args = Environment.GetCommandLineArgs();

            if (args.Length > 1)
            {
                try
                {
                    filePath = args[1];
                    using (var fs = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        var pssg = PssgFile.Open(fs);
                        LoadPssg(pssg);
                    }
                    DisplayName = Properties.Resources.AppTitleShort + " - " + Path.GetFileName(filePath);
                }
                catch (Exception excp)
                {
                    // Fail
                    DisplayName = Properties.Resources.AppTitleLong;
                    MessageBox.Show("The program could not open this file!" + Environment.NewLine + Environment.NewLine + excp.Message, "Could Not Open", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
        }
        private void OpenCommand_Execute(object parameter)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();

            openFileDialog.Filter      = "PSSG files|*.pssg|DDS files|*.dds|Xml files|*.xml|All files|*.*";
            openFileDialog.FilterIndex = 1;
            if (!string.IsNullOrEmpty(filePath))
            {
                openFileDialog.FileName         = Path.GetFileNameWithoutExtension(filePath);
                openFileDialog.InitialDirectory = Path.GetDirectoryName(filePath);
            }

            if (openFileDialog.ShowDialog() == true)
            {
                try
                {
                    filePath = openFileDialog.FileName;
                    ClearVars(true);
                    file = Task <PssgFile> .Run(() => { return(PssgFile.Open(File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))); }).Result;

                    nodesWorkspace.LoadData(file);
                    texturesWorkspace.LoadData(nodesWorkspace.RootNode);
                    if (texturesWorkspace.Textures.Count > 0)
                    {
                        SelectedTabIndex = 1;
                    }
                    DisplayName = Properties.Resources.AppTitleShort + " - " + Path.GetFileName(filePath);
                }
                catch (Exception excp)
                {
                    // Fail
                    DisplayName = Properties.Resources.AppTitleLong;
                    MessageBox.Show("The program could not open this file!" + Environment.NewLine + Environment.NewLine + excp.Message, "Could Not Open", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
        }
 public static bool SupportsPssg(PssgFile pssg)
 {
     return(pssg.FindNodes("MATRIXPALETTERENDERINSTANCE").Any() ||
            pssg.FindNodes("MATRIXPALETTEJOINTRENDERINSTANCE").Any());
 }
Beispiel #16
0
 public new static bool SupportsPssg(PssgFile pssg)
 {
     return(pssg.FindNodes("VISIBLERENDERNODE").Any());
 }
Beispiel #17
0
 public override void ClearData()
 {
     _pssg    = null;
     rootNode = null;
     pssgNodes.Clear();
 }
Beispiel #18
0
 public override void LoadData(object data)
 {
     _pssg = (PssgFile)data;
 }
        public static bool SupportsPssg(PssgFile pssg)
        {
            var rsiNodes = pssg.FindNodes("RENDERSTREAMINSTANCE");

            return(rsiNodes.Any() && rsiNodes.First().ParentNode?.Name == "MATRIXPALETTENODE");
        }
 private void NewCommand_Execute(object parameter)
 {
     ClearVars(true);
     file = new PssgFile(PssgFileType.Pssg);
     SaveTag();
 }