Esempio n. 1
0
        public ModelRoot AddLine(ModelRoot model, IEnumerable <GeoPoint> gpxPointsElevated, Vector4 vector4, float trailWidthMeters)
        {
            var scene = model.UseScene(TERRAIN_SCENE_NAME);
            var rnode = scene.FindNode(n => n.Name == TERRAIN_NODE_NAME);
            var rmesh = rnode.Mesh = FindOrCreateMesh(model, TERRAIN_MESH_NAME);


            var material = model.CreateMaterial("Line")
                           .WithPBRMetallicRoughness(vector4, null, null, 1, 0.1f)
                           .WithDoubleSide(true);


            var triangulation        = _meshService.GenerateTriangleMesh_Line(gpxPointsElevated, trailWidthMeters);
            var indexedTriangulation = new IndexedTriangulation(triangulation.positions, triangulation.indexes);
            var normals = _meshService.ComputeNormals(indexedTriangulation.Positions, indexedTriangulation.Indices);


            // create mesh primitive
            var primitive = rmesh.CreatePrimitive()
                            .WithVertexAccessor("POSITION", indexedTriangulation.Positions)
                            .WithVertexAccessor("NORMAL", normals.ToList())
                            .WithIndicesAccessor(PrimitiveType.TRIANGLES, indexedTriangulation.Indices);

            primitive = primitive.WithMaterial(material);
            return(model);
        }
Esempio n. 2
0
        public ModelRoot AddLine(ModelRoot model, string nodeName, IEnumerable <GeoPoint> gpxPointsElevated, Vector4 color, float trailWidthMeters)
        {
            var scene = model.UseScene(TERRAIN_SCENE_NAME);
            var rnode = scene.FindNode(n => n.Name == nodeName);

            if (rnode == null)
            {
                rnode = scene.CreateNode(nodeName);
            }
            var rmesh = rnode.Mesh = FindOrCreateMesh(model, string.Concat(nodeName, "Mesh"));


            var material = model.CreateMaterial(string.Concat(nodeName, "Material"))
                           .WithPBRMetallicRoughness(color, null, null, 0, 0.9f)
                           .WithDoubleSide(true);

            material.Alpha = SharpGLTF.Schema2.AlphaMode.BLEND;


            var triangulation = _meshService.GenerateTriangleMesh_Line(gpxPointsElevated, trailWidthMeters);
            var normals       = _meshService.ComputeMeshNormals(triangulation.Positions, triangulation.Indices);


            // create mesh primitive
            var primitive = rmesh.CreatePrimitive()
                            .WithVertexAccessor("POSITION", triangulation.Positions)
                            .WithVertexAccessor("NORMAL", normals.ToList())
                            .WithIndicesAccessor(PrimitiveType.TRIANGLES, triangulation.Indices);

            primitive = primitive.WithMaterial(material);
            return(model);
        }
Esempio n. 3
0
        public ModelRoot AddMesh(ModelRoot model, string nodeName, IndexedTriangulation indexedTriangulation, IEnumerable <Vector3> normals, PBRTexture textures, bool doubleSided = true)
        {
            // create a basic scene
            model = model ?? CreateNewModel();
            var rnode = model.LogicalScenes.First()?.FindNode(n => n.Name == nodeName);

            if (rnode == null)
            {
                rnode = model.LogicalScenes.First().CreateNode(nodeName);
            }

            var rmesh = rnode.Mesh = FindOrCreateMesh(model, string.Concat(rnode.Name, "Mesh"));


            var material = model.CreateMaterial(string.Concat(nodeName, "Material"))
                           .WithPBRMetallicRoughness(Vector4.One, textures?.BaseColorTexture?.FilePath, null, 0, 1)
                           .WithDoubleSide(doubleSided);

            if (textures != null && textures.NormalTexture != null)
            {
                material.WithChannelTexture("NORMAL", 0, textures.NormalTexture.FilePath);
            }

            // create mesh primitive
            MeshPrimitive primitive = rmesh.CreatePrimitive();


            if (indexedTriangulation.Colors != null && indexedTriangulation.Colors.Any())
            {
                primitive = primitive.WithVertexAccessor("POSITION", indexedTriangulation.Positions);
                primitive = primitive.WithVertexAccessor("COLOR_0", indexedTriangulation.Colors);
            }
            else
            {
                primitive = primitive.WithVertexAccessor("POSITION", indexedTriangulation.Positions);
            }

            if (normals != null)
            {
                primitive = primitive.WithVertexAccessor("NORMAL", normals.ToList());
            }
            primitive = primitive.WithIndicesAccessor(PrimitiveType.TRIANGLES, indexedTriangulation.Indices);

            if (textures != null && textures.TextureCoordSets == null)
            {
                (Vector3 Min, Vector3 Max)coordBounds = CalculateBounds(indexedTriangulation.Positions);

                textures.TextureCoordSets = indexedTriangulation.Positions.Select(pos => new Vector2(
                                                                                      MathHelper.Map(coordBounds.Min.X, coordBounds.Max.X, 0, 1, pos.X, true)
                                                                                      , MathHelper.Map(coordBounds.Min.Z, coordBounds.Max.Z, 0, 1, pos.Z, true)
                                                                                      ));

                primitive = primitive
                            .WithVertexAccessor("TEXCOORD_0", textures.TextureCoordSets.ToList());
            }

            primitive = primitive.WithMaterial(material);
            return(model);
        }
Esempio n. 4
0
        public ModelRoot AddMesh(ModelRoot model, string nodeName, TriangulationList <Vector3> triangulation, Vector4 color = default, bool doubleSided = true)
        {
            if (color == default || triangulation.HasColors)
            {
                color = Vector4.One;
            }

            var scene = model.UseScene(TERRAIN_SCENE_NAME);
            var rnode = scene.FindNode(n => n.Name == nodeName);

            if (rnode == null)
            {
                rnode = scene.CreateNode(nodeName);
            }
            var rmesh = rnode.Mesh = FindOrCreateMesh(model, string.Concat(nodeName, "Mesh"));


            var material = model.CreateMaterial(string.Concat(nodeName, "Material"))
                           .WithPBRMetallicRoughness(color, null, null, 0, 1f)
                           .WithDoubleSide(doubleSided);

            material.Alpha = (color.W < 1.0 || (triangulation.HasColors && triangulation.Colors.Any(c => c.W < 1.0))) ?
                             SharpGLTF.Schema2.AlphaMode.BLEND
                                : SharpGLTF.Schema2.AlphaMode.OPAQUE;

            // Rotate for glTF compliance
            triangulation.Positions.ToGlTFSpace();

            var normals = _meshService.ComputeMeshNormals(triangulation.Positions, triangulation.Indices);


            // create mesh primitive
            var primitive = rmesh.CreatePrimitive()
                            .WithVertexAccessor("POSITION", triangulation.Positions)
                            .WithVertexAccessor("NORMAL", normals.ToList())
                            .WithIndicesAccessor(PrimitiveType.TRIANGLES, triangulation.Indices);

            if (triangulation.HasColors)
            {
                primitive = primitive.WithVertexAccessor("COLOR_0", triangulation.Colors);
            }

            primitive = primitive.WithMaterial(material);
            return(model);
        }
Esempio n. 5
0
        public void AddGeometryResources(ModelRoot root, IEnumerable <SceneBuilder> srcScenes, SceneBuilderSchema2Settings settings)
        {
            // gather all unique MeshBuilders

            var srcMeshes = srcScenes
                            .SelectMany(item => item.Instances)
                            .Select(item => item.Content?.GetGeometryAsset())
                            .Where(item => item != null)
                            .Distinct()
                            .ToArray();

            // gather all unique MaterialBuilders

            var materialGroups = srcMeshes
                                 .SelectMany(item => item.Primitives)
                                 .Where(item => !Geometry.MeshBuilderToolkit.IsEmpty(item))
                                 .Select(item => item.Material)
                                 .Distinct()
                                 .ToList()
                                 // group by equal content, to reduce material splitting whenever possible.
                                 .GroupBy(item => item, Materials.MaterialBuilder.ContentComparer);

            // create a Schema2.Material for every MaterialBuilder.

            foreach (var mg in materialGroups)
            {
                var val = root.CreateMaterial(mg.Key);
                foreach (var key in mg)
                {
                    _Materials[key] = val;
                }
            }

            // create a Schema2.Mesh for every MeshBuilder.

            var dstMeshes = root.CreateMeshes(mat => _Materials[mat], settings, srcMeshes);

            for (int i = 0; i < srcMeshes.Length; ++i)
            {
                _Meshes[srcMeshes[i]] = dstMeshes[i];
            }

            // TODO: here we could check that every dstMesh has been correctly created.
        }
Esempio n. 6
0
        public ModelRoot AddTerrainMesh(ModelRoot model, Triangulation triangulation, PBRTexture textures)
        {
            // create a basic scene
            model = model ?? CreateNewModel();
            var rnode = model.LogicalScenes.First()?.FindNode(n => n.Name == TERRAIN_NODE_NAME);
            var rmesh = rnode.Mesh = FindOrCreateMesh(model, TERRAIN_MESH_NAME);


            var material = model.CreateMaterial("Default")
                           .WithPBRMetallicRoughness(Vector4.One, textures?.BaseColorTexture?.FilePath, null, 0, 1)
                           .WithDoubleSide(true);

            if (textures != null && textures.NormalTexture != null)
            {
                material.WithChannelTexture("NORMAL", 0, textures.NormalTexture.FilePath);
            }

            var indexedTriangulation = new IndexedTriangulation(triangulation);
            var normals = _meshService.ComputeNormals(indexedTriangulation.Positions, indexedTriangulation.Indices);


            // create mesh primitive
            var primitive = rmesh.CreatePrimitive()
                            .WithVertexAccessor("POSITION", indexedTriangulation.Positions)
                            .WithVertexAccessor("NORMAL", normals.ToList())
                            .WithIndicesAccessor(PrimitiveType.TRIANGLES, indexedTriangulation.Indices);

            if (textures != null && textures.TextureCoordSets == null)
            {
                (Vector3 Min, Vector3 Max)coordBounds = CalculateBounds(indexedTriangulation.Positions);

                textures.TextureCoordSets = indexedTriangulation.Positions.Select(pos => new Vector2(
                                                                                      MathHelper.Map(coordBounds.Min.X, coordBounds.Max.X, 0, 1, pos.X, true)
                                                                                      , MathHelper.Map(coordBounds.Min.Z, coordBounds.Max.Z, 0, 1, pos.Z, true)
                                                                                      ));

                primitive = primitive
                            .WithVertexAccessor("TEXCOORD_0", textures.TextureCoordSets.ToList());
            }

            primitive = primitive.WithMaterial(material);
            return(model);
        }
        private Material GenerateGLTFMaterialFromRenderMaterial(VMaterial renderMaterial, ModelRoot model, string materialName)
        {
            var material = model
                           .CreateMaterial(materialName)
                           .WithDefault();

            renderMaterial.IntParams.TryGetValue("F_TRANSLUCENT", out var isTranslucent);
            material.Alpha = isTranslucent > 0 ? AlphaMode.BLEND : AlphaMode.OPAQUE;

            float metalValue = 0;

            foreach (var floatParam in renderMaterial.FloatParams)
            {
                if (floatParam.Key == "g_flMetalness")
                {
                    metalValue = floatParam.Value;
                }
            }

            // assume non-metallic unless prompted
            material.WithPBRMetallicRoughness(Vector4.One, null, metallicFactor: metalValue);

            foreach (var renderTexture in renderMaterial.TextureParams)
            {
                var texturePath = renderTexture.Value;

                var fileName = Path.GetFileNameWithoutExtension(texturePath);

                ProgressDialog.SetProgress($"Exporting texture: {texturePath}");

                var textureResource = GuiContext.LoadFileByAnyMeansNecessary(texturePath + "_c");

                if (textureResource == null)
                {
                    continue;
                }

                var bitmap = ((ValveResourceFormat.ResourceTypes.Texture)textureResource.DataBlock).GenerateBitmap();

                if (renderTexture.Key == "g_tColor" && material.Alpha == AlphaMode.OPAQUE)
                {
                    // expensive transparency workaround for color maps
                    for (int row = 0; row < bitmap.Width; row++)
                    {
                        for (int col = 0; col < bitmap.Height; col++)
                        {
                            var pixelAt = bitmap.GetPixel(row, col);
                            bitmap.SetPixel(row, col, new SKColor(pixelAt.Red, pixelAt.Green, pixelAt.Blue, 255));
                        }
                    }
                }

                var textureImage = SKImage.FromBitmap(bitmap);
                using var data = textureImage.Encode(SKEncodedImageFormat.Png, 100);

                var image = model.UseImageWithContent(data.ToArray());
                // TODO find a way to change the image's URI to be the image name, right now it turns into (model)_0, (model)_1....
                image.Name = fileName + $"_{model.LogicalImages.Count - 1}";

                var sampler = model.UseTextureSampler(TextureWrapMode.REPEAT, TextureWrapMode.REPEAT, TextureMipMapFilter.NEAREST, TextureInterpolationFilter.DEFAULT);
                sampler.Name = fileName;

                var tex = model.UseTexture(image);
                tex.Name    = fileName + $"_{model.LogicalTextures.Count - 1}";
                tex.Sampler = sampler;

                switch (renderTexture.Key)
                {
                case "g_tColor":

                    material.FindChannel("BaseColor")?.SetTexture(0, tex);

                    var indexTexture = new JsonDictionary()
                    {
                        ["index"] = image.LogicalIndex
                    };
                    var dict = material.TryUseExtrasAsDictionary(true);
                    dict["baseColorTexture"] = indexTexture;

                    break;

                case "g_tNormal":
                    material.FindChannel("Normal")?.SetTexture(0, tex);
                    break;

                case "g_tAmbientOcclusion":
                    material.FindChannel("Occlusion")?.SetTexture(0, tex);
                    break;

                case "g_tEmissive":
                    material.FindChannel("Emissive")?.SetTexture(0, tex);
                    break;

                case "g_tShadowFalloff":
                // example: tongue_gman, materials/default/default_skin_shadowwarp_tga_f2855b6e.vtex
                case "g_tCombinedMasks":
                // example: models/characters/gman/materials/gman_head_mouth_mask_tga_bb35dc38.vtex
                case "g_tDiffuseFalloff":
                // example: materials/default/default_skin_diffusewarp_tga_e58a9ed.vtex
                case "g_tIris":
                // example:
                case "g_tIrisMask":
                // example: models/characters/gman/materials/gman_eye_iris_mask_tga_a5bb4a1e.vtex
                case "g_tTintColor":
                // example: models/characters/lazlo/eyemeniscus_vmat_g_ttintcolor_a00ef19e.vtex
                case "g_tAnisoGloss":
                // example: gordon_beard, models/characters/gordon/materials/gordon_hair_normal_tga_272a44e9.vtex
                case "g_tBentNormal":
                // example: gman_teeth, materials/default/default_skin_shadowwarp_tga_f2855b6e.vtex
                case "g_tFresnelWarp":
                // example: brewmaster_color, materials/default/default_fresnelwarprim_tga_d9279d65.vtex
                case "g_tMasks1":
                // example: brewmaster_color, materials/models/heroes/brewmaster/brewmaster_base_metalnessmask_psd_58eaa40f.vtex
                case "g_tMasks2":
                // example: brewmaster_color,materials/models/heroes/brewmaster/brewmaster_base_specmask_psd_63e9fb90.vtex
                default:
                    Console.WriteLine($"Warning: Unsupported Texture Type {renderTexture.Key}");
                    break;
                }
            }

            return(material);
        }