using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using System.Numerics;
using SharpGLTF.Collections;
using SharpGLTF.Geometry.VertexTypes;
namespace SharpGLTF.Geometry
{
///
/// Represents an utility class to help build meshes by adding primitives associated with a given material.
///
/// The material type used by this instance.
///
/// The vertex fragment type with Position, Normal and Tangent.
/// Valid types are:
/// ,
/// ,
/// .
///
///
/// The vertex fragment type with Colors and Texture Coordinates.
/// Valid types are:
/// ,
/// ,
/// ,
/// .
/// .
/// .
///
///
/// The vertex fragment type with Skin Joint Weights.
/// Valid types are:
/// ,
/// ,
/// ,
/// ,
/// .
///
public class MeshBuilder : IMeshBuilder
where TvG : struct, IVertexGeometry
where TvM : struct, IVertexMaterial
where TvS : struct, IVertexSkinning
{
#region lifecycle
public MeshBuilder(string name = null)
{
this.Name = name;
// this is the recomended preprocesor for release/production
_VertexPreprocessor = new VertexPreprocessor();
_VertexPreprocessor.SetSanitizerPreprocessors();
}
#endregion
#region data
private readonly Dictionary<(TMaterial, int), PrimitiveBuilder> _Primitives = new Dictionary<(TMaterial, int), PrimitiveBuilder>();
private VertexPreprocessor _VertexPreprocessor;
#endregion
#region properties
public string Name { get; set; }
public VertexPreprocessor VertexPreprocessor
{
get => _VertexPreprocessor;
set => _VertexPreprocessor = value;
}
public IEnumerable Materials => _Primitives.Keys.Select(item => item.Item1).Distinct();
public IReadOnlyCollection> Primitives => _Primitives.Values;
IReadOnlyCollection> IMeshBuilder.Primitives => _Primitives.Values;
#endregion
#region API
private PrimitiveBuilder _UsePrimitive((TMaterial, int) key)
{
if (!_Primitives.TryGetValue(key, out PrimitiveBuilder primitive))
{
primitive = new PrimitiveBuilder(this, key.Item1, key.Item2);
_Primitives[key] = primitive;
}
return primitive;
}
public PrimitiveBuilder UsePrimitive(TMaterial material, int primitiveVertexCount = 3)
{
Guard.NotNull(material, nameof(material));
Guard.MustBeBetweenOrEqualTo(primitiveVertexCount, 1, 3, nameof(primitiveVertexCount));
return _UsePrimitive((material, primitiveVertexCount));
}
IPrimitiveBuilder IMeshBuilder.UsePrimitive(TMaterial material, int primitiveVertexCount)
{
Guard.NotNull(material, nameof(material));
Guard.MustBeBetweenOrEqualTo(primitiveVertexCount, 1, 3, nameof(primitiveVertexCount));
return _UsePrimitive((material, primitiveVertexCount));
}
public void AddMesh(MeshBuilder mesh, Func materialTransform, Func, VertexBuilder> vertexTransform)
{
if (mesh == null) return;
Guard.NotNull(materialTransform, nameof(materialTransform));
foreach (var p in mesh.Primitives)
{
var materialKey = materialTransform(p.Material);
UsePrimitive(materialKey).AddPrimitive(p, vertexTransform);
}
}
///
/// Transforms all the points of all the
/// of the this using the given lambfa function.
///
/// A lambda function to transform vertices.
public void TransformVertices(Func, VertexBuilder> vertexTransform)
{
foreach (var p in Primitives) p.TransformVertices(vertexTransform);
}
public void Validate()
{
foreach (var p in _Primitives.Values)
{
p.Validate();
}
}
#endregion
}
///
/// Represents an utility class to help build meshes by adding primitives associated with a given material.
///
///
/// The vertex fragment type with Position, Normal and Tangent.
/// Valid types are:
/// ,
/// ,
/// .
///
///
/// The vertex fragment type with Colors and Texture Coordinates.
/// Valid types are:
/// ,
/// ,
/// ,
/// .
/// .
/// .
///
///
/// The vertex fragment type with Skin Joint Weights.
/// Valid types are:
/// ,
/// ,
/// ,
/// ,
/// .
///
public class MeshBuilder : MeshBuilder
where TvG : struct, IVertexGeometry
where TvM : struct, IVertexMaterial
where TvS : struct, IVertexSkinning
{
public MeshBuilder(string name = null)
: base(name) { }
}
///
/// Represents an utility class to help build meshes by adding primitives associated with a given material.
///
///
/// The vertex fragment type with Position, Normal and Tangent.
/// Valid types are:
/// ,
/// ,
/// .
///
///
/// The vertex fragment type with Colors and Texture Coordinates.
/// Valid types are:
/// ,
/// ,
/// ,
/// .
/// .
/// .
///
public class MeshBuilder : MeshBuilder
where TvG : struct, IVertexGeometry
where TvM : struct, IVertexMaterial
{
public MeshBuilder(string name = null)
: base(name) { }
}
///
/// Represents an utility class to help build meshes by adding primitives associated with a given material.
///
///
/// The vertex fragment type with Position, Normal and Tangent.
/// Valid types are:
/// ,
/// ,
/// .
///
public class MeshBuilder : MeshBuilder
where TvG : struct, IVertexGeometry
{
public MeshBuilder(string name = null)
: base(name) { }
}
}