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);
        }
        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 #3
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);
            }
        }
Beispiel #4
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);
            }
        }
        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 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 static bool SupportsPssg(PssgFile pssg)
 {
     return(pssg.FindNodes("MATRIXPALETTERENDERINSTANCE").Any() ||
            pssg.FindNodes("MATRIXPALETTEJOINTRENDERINSTANCE").Any());
 }
Beispiel #8
0
 public new static bool SupportsPssg(PssgFile pssg)
 {
     return(pssg.FindNodes("VISIBLERENDERNODE").Any());
 }
        public static bool SupportsPssg(PssgFile pssg)
        {
            var rsiNodes = pssg.FindNodes("RENDERSTREAMINSTANCE");

            return(rsiNodes.Any() && rsiNodes.First().ParentNode?.Name == "MATRIXPALETTENODE");
        }