Browse Source

WIP: attempt to add morph targets builder.

Vicente Penades 6 years ago
parent
commit
890d39ea99

+ 95 - 0
src/SharpGLTF.Toolkit/Geometry/MorphTargetBuilder.cs

@@ -0,0 +1,95 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+using SharpGLTF.Geometry.VertexTypes;
+
+namespace SharpGLTF.Geometry
+{
+    public class MorphTargetBuilder<TvG>
+        where TvG : struct, IVertexGeometry
+    {
+        #region lifecycle
+        internal MorphTargetBuilder(Func<int, TvG> baseVertexFunc)
+        {
+            _BaseVertexFunc = baseVertexFunc;
+        }
+
+        #endregion
+
+        #region data
+
+        private readonly Func<int, TvG> _BaseVertexFunc;
+
+        private readonly List<Dictionary<int, TvG>> _Targets = new List<Dictionary<int, TvG>>();
+
+        #endregion
+
+        #region properties
+
+        public int Count => _Targets.Count;
+
+        public Boolean AbsoluteMode => true;
+
+        #endregion
+
+        #region API
+
+        public IReadOnlyDictionary<int, TvG> GetTarget(int idx) { return _Targets[idx]; }
+
+        public void SetRelativeVertex(int morphTargetIndex, int vertexIndex, TvG value)
+        {
+            if (AbsoluteMode)
+            {
+                // value = value.ToAbsoluteMorph(_BaseVertexFunc(vertexIndex));
+
+                throw new NotImplementedException();
+            }
+
+            _SetVertex(morphTargetIndex, vertexIndex, value);
+        }
+
+        public void SetAbsoluteVertex(int morphTargetIndex, int vertexIndex, TvG value)
+        {
+            if (!AbsoluteMode)
+            {
+                // value = value.ToRelativeMorph(_BaseVertexFunc(vertexIndex));
+
+                throw new NotImplementedException();
+            }
+
+            _SetVertex(morphTargetIndex, vertexIndex, value);
+        }
+
+        private void _SetVertex(int morphTargetIndex, int vertexIndex, TvG value)
+        {
+            while (_Targets.Count <= morphTargetIndex)
+            {
+                _Targets.Add(new Dictionary<int, TvG>());
+            }
+
+            _Targets[morphTargetIndex][vertexIndex] = value;
+        }
+
+        public void AddAbsoluteVertices<TvM, TvS>(int morphTargetIndex, IReadOnlyDictionary<int, TvG> vertices, Func<VertexBuilder<TvG, TvM, TvS>, VertexBuilder<TvG, TvM, TvS>> vertexTransform)
+            where TvM : struct, IVertexMaterial
+            where TvS : struct, IVertexSkinning
+        {
+            foreach (var kvp in vertices)
+            {
+                if (!AbsoluteMode)
+                {
+                    throw new NotImplementedException();
+                    // TODO: if vertices are in RELATIVE MODE, we must convert them to absolute mode, transform, and back to RELATIVE
+                }
+
+                var v = new VertexBuilder<TvG, TvM, TvS>(kvp.Value, default(TvM), default(TvS));
+                v = vertexTransform(v);
+
+                this.SetAbsoluteVertex(morphTargetIndex, kvp.Key, v.Geometry);
+            }
+        }
+
+        #endregion
+    }
+}

+ 11 - 0
src/SharpGLTF.Toolkit/Geometry/PrimitiveBuilder.cs

@@ -111,6 +111,8 @@ namespace SharpGLTF.Geometry
         {
         {
             this._Mesh = mesh;
             this._Mesh = mesh;
             this._Material = material;
             this._Material = material;
+
+            this._MorphTargets = new MorphTargetBuilder<TvG>( idx => _Vertices[idx].Geometry );
         }
         }
 
 
         #endregion
         #endregion
@@ -123,6 +125,8 @@ namespace SharpGLTF.Geometry
 
 
         private readonly VertexListWrapper _Vertices = new VertexListWrapper();
         private readonly VertexListWrapper _Vertices = new VertexListWrapper();
 
 
+        private readonly MorphTargetBuilder<TvG> _MorphTargets;
+
         #endregion
         #endregion
 
 
         #region properties
         #region properties
@@ -153,6 +157,8 @@ namespace SharpGLTF.Geometry
 
 
         public virtual IReadOnlyList<(int, int, int, int?)> Surfaces => Array.Empty<(int, int, int, int?)>();
         public virtual IReadOnlyList<(int, int, int, int?)> Surfaces => Array.Empty<(int, int, int, int?)>();
 
 
+        public MorphTargetBuilder<TvG> MorphTargets => _MorphTargets;
+
         #endregion
         #endregion
 
 
         #region API
         #region API
@@ -288,6 +294,11 @@ namespace SharpGLTF.Geometry
 
 
                 return;
                 return;
             }
             }
+
+            for (int i = 0; i < primitive._MorphTargets.Count; ++i)
+            {
+                this._MorphTargets.AddAbsoluteVertices<TvM, TvS>(i, primitive._MorphTargets.GetTarget(i), vertexTransform);
+            }
         }
         }
 
 
         public void Validate()
         public void Validate()