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()); }
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; } }
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()); }
public new static bool SupportsPssg(PssgFile pssg) { return(pssg.FindNodes("VISIBLERENDERNODE").Any()); }
public override void ClearData() { _pssg = null; rootNode = null; pssgNodes.Clear(); }
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(); }