|
@@ -27,6 +27,8 @@ namespace SharpGLTF.Geometry
|
|
|
/// </summary>
|
|
/// </summary>
|
|
|
IReadOnlyList<IVertexBuilder> Vertices { get; }
|
|
IReadOnlyList<IVertexBuilder> Vertices { get; }
|
|
|
|
|
|
|
|
|
|
+ IMorphTargetReader MorphTargets { get; }
|
|
|
|
|
+
|
|
|
/// <summary>
|
|
/// <summary>
|
|
|
/// Gets the indices of all points, given that <see cref="VerticesPerPrimitive"/> is 1.
|
|
/// Gets the indices of all points, given that <see cref="VerticesPerPrimitive"/> is 1.
|
|
|
/// </summary>
|
|
/// </summary>
|
|
@@ -61,6 +63,8 @@ namespace SharpGLTF.Geometry
|
|
|
/// </summary>
|
|
/// </summary>
|
|
|
Type VertexType { get; }
|
|
Type VertexType { get; }
|
|
|
|
|
|
|
|
|
|
+ void SetVertexDisplacement(int morphTargetIndex, int vertexIndex, IVertexGeometry vertex);
|
|
|
|
|
+
|
|
|
int AddPoint(IVertexBuilder a);
|
|
int AddPoint(IVertexBuilder a);
|
|
|
|
|
|
|
|
(int, int) AddLine(IVertexBuilder a, IVertexBuilder b);
|
|
(int, int) AddLine(IVertexBuilder a, IVertexBuilder b);
|
|
@@ -159,22 +163,23 @@ namespace SharpGLTF.Geometry
|
|
|
|
|
|
|
|
public MorphTargetBuilder<TvG> MorphTargets => _MorphTargets;
|
|
public MorphTargetBuilder<TvG> MorphTargets => _MorphTargets;
|
|
|
|
|
|
|
|
|
|
+ IMorphTargetReader IPrimitiveReader<TMaterial>.MorphTargets => _MorphTargets;
|
|
|
|
|
+
|
|
|
#endregion
|
|
#endregion
|
|
|
|
|
|
|
|
#region API
|
|
#region API
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
|
- /// Checks if <paramref name="v"/> is a compatible vertex and casts it, or converts it if it is not.
|
|
|
|
|
|
|
+ /// Checks if <paramref name="vertex"/> is a compatible vertex and casts it, or converts it if it is not.
|
|
|
/// </summary>
|
|
/// </summary>
|
|
|
- /// <param name="v">Any vertex</param>
|
|
|
|
|
|
|
+ /// <param name="vertex">Any vertex</param>
|
|
|
/// <returns>A vertex compatible with this primitive.</returns>
|
|
/// <returns>A vertex compatible with this primitive.</returns>
|
|
|
- private static VertexBuilder<TvG, TvM, TvS> ConvertVertex(IVertexBuilder v)
|
|
|
|
|
|
|
+ private static VertexBuilder<TvG, TvM, TvS> ConvertVertex(IVertexBuilder vertex)
|
|
|
{
|
|
{
|
|
|
- Guard.NotNull(v, nameof(v));
|
|
|
|
|
|
|
+ Guard.NotNull(vertex, nameof(vertex));
|
|
|
|
|
|
|
|
- var vv = v.ConvertTo<TvG, TvM, TvS>();
|
|
|
|
|
-
|
|
|
|
|
- System.Diagnostics.Debug.Assert(vv.Position == v.GetGeometry().GetPosition());
|
|
|
|
|
|
|
+ var vv = vertex.ConvertTo<TvG, TvM, TvS>();
|
|
|
|
|
+ System.Diagnostics.Debug.Assert(vv.Position == vertex.GetGeometry().GetPosition());
|
|
|
|
|
|
|
|
return vv;
|
|
return vv;
|
|
|
}
|
|
}
|
|
@@ -194,6 +199,16 @@ namespace SharpGLTF.Geometry
|
|
|
return _Vertices.Use(vertex);
|
|
return _Vertices.Use(vertex);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ void IPrimitiveBuilder.SetVertexDisplacement(int morphTargetIndex, int vertexIndex, IVertexGeometry vertex)
|
|
|
|
|
+ {
|
|
|
|
|
+ Guard.NotNull(vertex, nameof(vertex));
|
|
|
|
|
+
|
|
|
|
|
+ var v = vertex.ConvertToGeometry<TvG>();
|
|
|
|
|
+ System.Diagnostics.Debug.Assert(v.GetPosition() == vertex.GetPosition());
|
|
|
|
|
+
|
|
|
|
|
+ this._MorphTargets.SetVertexDisplacement(morphTargetIndex, vertexIndex, v);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
/// <summary>
|
|
/// <summary>
|
|
|
/// Adds a point.
|
|
/// Adds a point.
|
|
|
/// </summary>
|
|
/// </summary>
|
|
@@ -244,74 +259,88 @@ namespace SharpGLTF.Geometry
|
|
|
return AddQuadrangle(ConvertVertex(a), ConvertVertex(b), ConvertVertex(c), ConvertVertex(d));
|
|
return AddQuadrangle(ConvertVertex(a), ConvertVertex(b), ConvertVertex(c), ConvertVertex(d));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- internal void AddPrimitive(PrimitiveBuilder<TMaterial, TvG, TvM, TvS> primitive, Func<VertexBuilder<TvG, TvM, TvS>, VertexBuilder<TvG, TvM, TvS>> vertexTransform)
|
|
|
|
|
|
|
+ public void Validate()
|
|
|
|
|
+ {
|
|
|
|
|
+ foreach (var v in _Vertices)
|
|
|
|
|
+ {
|
|
|
|
|
+ v.Validate();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public void TransformVertices(Func<VertexBuilder<TvG, TvM, TvS>, VertexBuilder<TvG, TvM, TvS>> vertexTransformFunc)
|
|
|
|
|
+ {
|
|
|
|
|
+ _Vertices.TransformVertices(vertexTransformFunc);
|
|
|
|
|
+
|
|
|
|
|
+ TvG geoFunc(TvG g) => vertexTransformFunc(new VertexBuilder<TvG, TvM, TvS>(g, default, default(TvS))).Geometry;
|
|
|
|
|
+
|
|
|
|
|
+ _MorphTargets.TransformVertices(geoFunc);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ internal void AddPrimitive(PrimitiveBuilder<TMaterial, TvG, TvM, TvS> primitive, Func<VertexBuilder<TvG, TvM, TvS>, VertexBuilder<TvG, TvM, TvS>> vertexTransformFunc)
|
|
|
{
|
|
{
|
|
|
if (primitive == null) return;
|
|
if (primitive == null) return;
|
|
|
|
|
|
|
|
|
|
+ // vertex-vertex map so we can know where to set the morph targets.
|
|
|
|
|
+ var vmap = new Dictionary<int, int>();
|
|
|
|
|
+
|
|
|
if (this.VerticesPerPrimitive == 1)
|
|
if (this.VerticesPerPrimitive == 1)
|
|
|
{
|
|
{
|
|
|
foreach (var p in primitive.Points)
|
|
foreach (var p in primitive.Points)
|
|
|
{
|
|
{
|
|
|
- var a = vertexTransform(primitive.Vertices[p]);
|
|
|
|
|
|
|
+ var a = vertexTransformFunc(primitive.Vertices[p]);
|
|
|
|
|
|
|
|
- AddPoint(a);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ var idx = AddPoint(a);
|
|
|
|
|
|
|
|
- return;
|
|
|
|
|
|
|
+ vmap[p] = idx;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (this.VerticesPerPrimitive == 2)
|
|
if (this.VerticesPerPrimitive == 2)
|
|
|
{
|
|
{
|
|
|
foreach (var l in primitive.Lines)
|
|
foreach (var l in primitive.Lines)
|
|
|
{
|
|
{
|
|
|
- var a = vertexTransform(primitive.Vertices[l.Item1]);
|
|
|
|
|
- var b = vertexTransform(primitive.Vertices[l.Item2]);
|
|
|
|
|
|
|
+ var a = vertexTransformFunc(primitive.Vertices[l.Item1]);
|
|
|
|
|
+ var b = vertexTransformFunc(primitive.Vertices[l.Item2]);
|
|
|
|
|
|
|
|
- AddLine(a, b);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ var indices = AddLine(a, b);
|
|
|
|
|
|
|
|
- return;
|
|
|
|
|
|
|
+ vmap[l.Item1] = indices.Item1;
|
|
|
|
|
+ vmap[l.Item2] = indices.Item2;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (this.VerticesPerPrimitive == 3)
|
|
if (this.VerticesPerPrimitive == 3)
|
|
|
{
|
|
{
|
|
|
foreach (var s in primitive.Surfaces)
|
|
foreach (var s in primitive.Surfaces)
|
|
|
{
|
|
{
|
|
|
- var a = vertexTransform(primitive.Vertices[s.Item1]);
|
|
|
|
|
- var b = vertexTransform(primitive.Vertices[s.Item2]);
|
|
|
|
|
- var c = vertexTransform(primitive.Vertices[s.Item3]);
|
|
|
|
|
|
|
+ var a = vertexTransformFunc(primitive.Vertices[s.Item1]);
|
|
|
|
|
+ var b = vertexTransformFunc(primitive.Vertices[s.Item2]);
|
|
|
|
|
+ var c = vertexTransformFunc(primitive.Vertices[s.Item3]);
|
|
|
|
|
|
|
|
if (s.Item4.HasValue)
|
|
if (s.Item4.HasValue)
|
|
|
{
|
|
{
|
|
|
- var d = vertexTransform(primitive.Vertices[s.Item4.Value]);
|
|
|
|
|
- AddQuadrangle(a, b, c, d);
|
|
|
|
|
|
|
+ var d = vertexTransformFunc(primitive.Vertices[s.Item4.Value]);
|
|
|
|
|
+ var indices = AddQuadrangle(a, b, c, d);
|
|
|
|
|
+
|
|
|
|
|
+ vmap[s.Item1] = indices.Item1;
|
|
|
|
|
+ vmap[s.Item2] = indices.Item2;
|
|
|
|
|
+ vmap[s.Item3] = indices.Item3;
|
|
|
|
|
+ vmap[s.Item4.Value] = indices.Item4;
|
|
|
}
|
|
}
|
|
|
else
|
|
else
|
|
|
{
|
|
{
|
|
|
- AddTriangle(a, b, c);
|
|
|
|
|
|
|
+ var indices = AddTriangle(a, b, c);
|
|
|
|
|
+
|
|
|
|
|
+ vmap[s.Item1] = indices.Item1;
|
|
|
|
|
+ vmap[s.Item2] = indices.Item2;
|
|
|
|
|
+ vmap[s.Item3] = indices.Item3;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- return;
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- for (int i = 0; i < primitive._MorphTargets.Count; ++i)
|
|
|
|
|
- {
|
|
|
|
|
- this._MorphTargets.AddAbsoluteVertices<TvM, TvS>(i, primitive._MorphTargets.GetTarget(i), vertexTransform);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ TvG geoFunc(TvG g) => vertexTransformFunc(new VertexBuilder<TvG, TvM, TvS>(g, default, default(TvS))).Geometry;
|
|
|
|
|
|
|
|
- public void Validate()
|
|
|
|
|
- {
|
|
|
|
|
- foreach (var v in _Vertices)
|
|
|
|
|
- {
|
|
|
|
|
- v.Validate();
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public void TransformVertices(Func<VertexBuilder<TvG, TvM, TvS>, VertexBuilder<TvG, TvM, TvS>> transformFunc)
|
|
|
|
|
- {
|
|
|
|
|
- _Vertices.TransformVertices(transformFunc);
|
|
|
|
|
|
|
+ _MorphTargets.SetMorphTargets(primitive._MorphTargets, vmap, geoFunc);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
#endregion
|
|
@@ -365,7 +394,7 @@ namespace SharpGLTF.Geometry
|
|
|
{
|
|
{
|
|
|
throw new NotSupportedException("Quadrangles are not supported for this primitive");
|
|
throw new NotSupportedException("Quadrangles are not supported for this primitive");
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
#endregion
|
|
#endregion
|
|
|
|
|
|
|
|
#region helper types
|
|
#region helper types
|