public void SetStreamedVertices(IPrimitiveReader <TMaterial> srcPrim, PackedEncoding vertexEncoding)
        {
            Guard.NotNull(srcPrim, nameof(srcPrim));

            var attributeNames = VertexTypes.VertexUtils
                                 .GetVertexAttributes(srcPrim.Vertices[0], srcPrim.Vertices.Count, vertexEncoding)
                                 .Select(item => item.Name)
                                 .ToList();

            var vAccessors = new List <MACCESSOR>();

            GuardAll.MustBeEqualTo(vAccessors.Select(item => item.Attribute.ByteOffset), 0, nameof(vAccessors));
            GuardAll.MustBeEqualTo(vAccessors.Select(item => item.Attribute.ByteStride), 0, nameof(vAccessors));

            foreach (var an in attributeNames)
            {
                var vAccessor = VertexTypes.VertexUtils.CreateVertexMemoryAccessor(srcPrim.Vertices, an, vertexEncoding);
                if (vAccessor == null)
                {
                    continue;
                }

                vAccessors.Add(vAccessor);
            }

            _VertexAccessors = vAccessors.ToArray();

            MACCESSOR.SanitizeVertexAttributes(_VertexAccessors);
        }
        public void SetMorphTargets(IPrimitiveReader <TMaterial> srcPrim, PackedEncoding vertexEncodings, ISet <string> morphTargetAttributes)
        {
            bool hasPositions = _VertexAccessors.Any(item => item.Attribute.Name == "POSITION");
            bool hasNormals   = _VertexAccessors.Any(item => item.Attribute.Name == "NORMAL");
            bool hasTangents  = _VertexAccessors.Any(item => item.Attribute.Name == "TANGENT");

            bool hasColors0 = _VertexAccessors.Any(item => item.Attribute.Name == "COLOR_0");
            bool hasColors1 = _VertexAccessors.Any(item => item.Attribute.Name == "COLOR_1");

            bool hasTexCoords0 = _VertexAccessors.Any(item => item.Attribute.Name == "TEXCOORD_0");
            bool hasTexCoords1 = _VertexAccessors.Any(item => item.Attribute.Name == "TEXCOORD_1");
            bool hasTexCoords2 = _VertexAccessors.Any(item => item.Attribute.Name == "TEXCOORD_2");
            bool hasTexCoords3 = _VertexAccessors.Any(item => item.Attribute.Name == "TEXCOORD_3");

            for (int i = 0; i < srcPrim.MorphTargets.Count; ++i)
            {
                var(pAccessor, nAccessor, tAccessor, c0Accessor, c1Accessor, uv0Accessor, uv1Accessor, uv2Accessor, uv3Accessor) = srcPrim._GetMorphTargetAccessors(i, vertexEncodings, morphTargetAttributes);

                if (!hasPositions)
                {
                    pAccessor = null;
                }
                if (!hasNormals)
                {
                    nAccessor = null;
                }
                if (!hasTangents)
                {
                    tAccessor = null;
                }
                if (!hasColors0)
                {
                    c0Accessor = null;
                }
                if (!hasColors1)
                {
                    c1Accessor = null;
                }
                if (!hasTexCoords0)
                {
                    uv0Accessor = null;
                }
                if (!hasTexCoords1)
                {
                    uv1Accessor = null;
                }
                if (!hasTexCoords2)
                {
                    uv2Accessor = null;
                }
                if (!hasTexCoords3)
                {
                    uv3Accessor = null;
                }

                AddMorphTarget(pAccessor, nAccessor, tAccessor, c0Accessor, c1Accessor, uv0Accessor, uv1Accessor, uv2Accessor, uv3Accessor);
            }
        }
        /// <summary>
        /// Converts a collection of <see cref="IMeshBuilder{TMaterial}"/> meshes into a collection of <see cref="PackedMeshBuilder{TMaterial}"/> meshes,
        /// ensuring that the resources are shared across all meshes.
        /// </summary>
        /// <param name="meshBuilders">A collection of <see cref="IMeshBuilder{TMaterial}"/> meshes.</param>
        /// <param name="settings">Mesh packaging settings.</param>
        /// <returns>A collectio of <see cref="PackedMeshBuilder{TMaterial}"/> meshes.</returns>
        internal static IEnumerable <PackedMeshBuilder <TMaterial> > CreatePackedMeshes(IEnumerable <IMeshBuilder <TMaterial> > meshBuilders, Scenes.SceneBuilderSchema2Settings settings)
        {
            try
            {
                foreach (var m in meshBuilders)
                {
                    m.Validate();
                }
            }
            catch (Exception ex)
            {
                throw new ArgumentException(ex.Message, nameof(meshBuilders), ex);
            }

            var vertexEncodings = new PackedEncoding();

            vertexEncodings.JointsEncoding  = meshBuilders.GetOptimalJointEncoding();
            vertexEncodings.WeightsEncoding = settings.CompactVertexWeights ? EncodingType.UNSIGNED_SHORT : EncodingType.FLOAT;

            var indexEncoding = meshBuilders.GetOptimalIndexEncoding();

            foreach (var srcMesh in meshBuilders)
            {
                var dstMesh = new PackedMeshBuilder <TMaterial>(srcMesh.Name);

                foreach (var srcPrim in srcMesh.Primitives)
                {
                    if (srcPrim.Vertices.Count == 0)
                    {
                        continue;
                    }

                    var dstPrim = dstMesh.AddPrimitive(srcPrim.Material, srcPrim.VerticesPerPrimitive);

                    bool useStrided = settings.UseStridedBuffers;
                    if (srcPrim.MorphTargets.Count > 0)
                    {
                        useStrided = false;                                 // if the primitive has morphing, it is better not to use strided vertex buffers.
                    }
                    if (useStrided)
                    {
                        dstPrim.SetStridedVertices(srcPrim, vertexEncodings);
                    }
                    else
                    {
                        dstPrim.SetStreamedVertices(srcPrim, vertexEncodings);
                    }

                    dstPrim.SetIndices(srcPrim, indexEncoding);
                    dstPrim.SetMorphTargets(srcPrim, vertexEncodings);
                }

                yield return(dstMesh);
            }
        }
        public void SetStridedVertices(IPrimitiveReader <TMaterial> srcPrim, PackedEncoding vertexEncoding)
        {
            Guard.NotNull(srcPrim, nameof(srcPrim));

            var vAccessors = VertexTypes.VertexUtils.CreateVertexMemoryAccessors(srcPrim.Vertices, vertexEncoding);

            Guard.NotNull(vAccessors, nameof(srcPrim));

            _StridedVertexType = srcPrim.VertexType;
            _VertexAccessors   = vAccessors;
        }
示例#5
0
        public static void _GatherMorphTargetAttributes <TMaterial>(this IPrimitiveReader <TMaterial> srcPrim, HashSet <string> attributes)
        {
            var vertexEncodings = new PackedEncoding();

            vertexEncodings.ColorEncoding = EncodingType.FLOAT;

            for (int i = 0; i < srcPrim.MorphTargets.Count; ++i)
            {
                var accessors = srcPrim._GetMorphTargetAccessors(i, vertexEncodings, new HashSet <string>());

                if (accessors.Pos != null)
                {
                    attributes.Add("POSITIONDELTA");
                }
                if (accessors.Nrm != null)
                {
                    attributes.Add("NORMALDELTA");
                }
                if (accessors.Tgt != null)
                {
                    attributes.Add("TANGENTDELTA");
                }

                if (accessors.Col0 != null)
                {
                    attributes.Add("COLOR_0DELTA");
                }
                if (accessors.Col1 != null)
                {
                    attributes.Add("COLOR_1DELTA");
                }

                if (accessors.Tuv0 != null)
                {
                    attributes.Add("TEXCOORD_0DELTA");
                }
                if (accessors.Tuv1 != null)
                {
                    attributes.Add("TEXCOORD_1DELTA");
                }
                if (accessors.Tuv2 != null)
                {
                    attributes.Add("TEXCOORD_2DELTA");
                }
                if (accessors.Tuv3 != null)
                {
                    attributes.Add("TEXCOORD_3DELTA");
                }
            }
        }
示例#6
0
        public void SetMorphTargets(IPrimitiveReader <TMaterial> srcPrim, PackedEncoding vertexEncodings)
        {
            bool hasPositions = _VertexAccessors.Any(item => item.Attribute.Name == "POSITION");
            bool hasNormals   = _VertexAccessors.Any(item => item.Attribute.Name == "NORMAL");
            bool hasTangents  = _VertexAccessors.Any(item => item.Attribute.Name == "TANGENT");

            if (!hasPositions)
            {
                throw new InvalidOperationException("Set vertices before morph targets.");
            }

            for (int i = 0; i < srcPrim.MorphTargets.Count; ++i)
            {
                var mtv = srcPrim.MorphTargets[i].GetMorphTargetVertices(srcPrim.Vertices.Count);

                var pAccessor = VertexTypes.VertexUtils.CreateVertexMemoryAccessor(mtv, "POSITIONDELTA", vertexEncodings);

                var nAccessor = !hasNormals ? null : VertexTypes.VertexUtils.CreateVertexMemoryAccessor(mtv, "NORMALDELTA", vertexEncodings);

                var tAccessor = !hasTangents ? null : VertexTypes.VertexUtils.CreateVertexMemoryAccessor(mtv, "TANGENTDELTA", vertexEncodings);

                AddMorphTarget(pAccessor, nAccessor, tAccessor);
            }
        }
示例#7
0
 public static (MACCESSOR Pos, MACCESSOR Nrm, MACCESSOR Tgt, MACCESSOR Col0, MACCESSOR Col1, MACCESSOR Tuv0, MACCESSOR Tuv1, MACCESSOR Tuv2, MACCESSOR Tuv3) _GetMorphTargetAccessors <TMaterial>(this IPrimitiveReader <TMaterial> srcPrim, int morphTargetIdx, PackedEncoding vertexEncodings, ISet <string> requiredAttributes)
 {
示例#8
0
        /// <summary>
        /// Converts a collection of <see cref="IMeshBuilder{TMaterial}"/> meshes into a collection of <see cref="PackedMeshBuilder{TMaterial}"/> meshes,
        /// ensuring that the resources are shared across all meshes.
        /// </summary>
        /// <param name="meshBuilders">A collection of <see cref="IMeshBuilder{TMaterial}"/> meshes.</param>
        /// <param name="settings">Mesh packaging settings.</param>
        /// <returns>A collectio of <see cref="PackedMeshBuilder{TMaterial}"/> meshes.</returns>
        internal static IEnumerable <PackedMeshBuilder <TMaterial> > CreatePackedMeshes(IEnumerable <IMeshBuilder <TMaterial> > meshBuilders, Scenes.SceneBuilderSchema2Settings settings)
        {
            try
            {
                foreach (var m in meshBuilders)
                {
                    m.Validate();
                }
            }
            catch (Exception ex)
            {
                throw new ArgumentException(ex.Message, nameof(meshBuilders), ex);
            }

            var vertexEncodings = new PackedEncoding();

            vertexEncodings.JointsEncoding  = meshBuilders.GetOptimalJointEncoding();
            vertexEncodings.WeightsEncoding = settings.CompactVertexWeights ? EncodingType.UNSIGNED_SHORT : EncodingType.FLOAT;

            var indexEncoding = meshBuilders.GetOptimalIndexEncoding();

            foreach (var srcMesh in meshBuilders)
            {
                // Gather all the primitives of the mesh

                var srcPrims = srcMesh
                               .Primitives
                               .Where(item => item.Vertices.Count > 0)
                               .ToList();

                // identify morph target attributes in use

                var morphTargetsAttributes = new HashSet <string>();

                foreach (var srcPrim in srcPrims)
                {
                    srcPrim._GatherMorphTargetAttributes(morphTargetsAttributes);
                }

                // adjust vertex encoding

                if (morphTargetsAttributes.Count > 0)
                {
                    // if any primitive has morph targets, it is better not to use strided vertex buffers.
                    settings.UseStridedBuffers = false;
                }

                bool hasColorMorph = morphTargetsAttributes.Contains("COLOR_0DELTA") ||
                                     morphTargetsAttributes.Contains("COLOR_1DELTA") ||
                                     morphTargetsAttributes.Contains("COLOR_2DELTA") ||
                                     morphTargetsAttributes.Contains("COLOR_3DELTA");

                // if any primitive has color morphing, we need to ensure the vertex
                // color attribute encoding is FLOAT to allow negative delta values.

                vertexEncodings.ColorEncoding = hasColorMorph
                    ? EncodingType.FLOAT
                    : (EncodingType?)null;

                // Create a packed mesh

                var dstMesh = new PackedMeshBuilder <TMaterial>(srcMesh.Name, srcMesh.Extras);

                foreach (var srcPrim in srcPrims)
                {
                    var dstPrim = dstMesh.AddPrimitive(srcPrim.Material, srcPrim.VerticesPerPrimitive);

                    if (settings.UseStridedBuffers)
                    {
                        dstPrim.SetStridedVertices(srcPrim, vertexEncodings);
                    }
                    else
                    {
                        dstPrim.SetStreamedVertices(srcPrim, vertexEncodings);
                    }

                    dstPrim.SetIndices(srcPrim, indexEncoding);

                    if (morphTargetsAttributes.Count > 0)
                    {
                        dstPrim.SetMorphTargets(srcPrim, vertexEncodings, morphTargetsAttributes);
                    }
                }

                yield return(dstMesh);
            }
        }