private (PrimitiveTopology, IEnumerable <int>) TransformPrimitive(MeshPrimitive primitive)
        {
            switch (primitive.DrawPrimitiveType)
            {
            case PrimitiveType.TRIANGLES:
                return(PrimitiveTopology.TriangleList,
                       primitive.GetTriangleIndices().SelectMany(_ => new[] { _.Item1, _.Item2, _.Item3 }));

            case PrimitiveType.TRIANGLE_STRIP:
                return(PrimitiveTopology.TriangleList,
                       primitive.GetTriangleIndices().SelectMany(_ => new[] { _.Item1, _.Item2, _.Item3 }));

            case PrimitiveType.TRIANGLE_FAN:
                return(PrimitiveTopology.TriangleList,
                       primitive.GetTriangleIndices().SelectMany(_ => new[] { _.Item1, _.Item2, _.Item3 }));

            case PrimitiveType.POINTS:
                return(PrimitiveTopology.PointList, primitive.GetPointIndices());

            case PrimitiveType.LINES:
                return(PrimitiveTopology.LineList,
                       primitive.GetLineIndices().SelectMany(_ => new[] { _.Item1, _.Item2 }));

            case PrimitiveType.LINE_STRIP:
                return(PrimitiveTopology.LineList,
                       primitive.GetLineIndices().SelectMany(_ => new[] { _.Item1, _.Item2 }));

            case PrimitiveType.LINE_LOOP:
                return(PrimitiveTopology.LineList,
                       primitive.GetLineIndices().SelectMany(_ => new[] { _.Item1, _.Item2 }));

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
Beispiel #2
0
        public MeshPrimitiveReader(MeshPrimitive srcPrim, bool doubleSided, MeshNormalsFallback fallbackNormals)
        {
            _Positions = srcPrim.GetVertexAccessor("POSITION")?.AsVector3Array();
            _Normals   = srcPrim.GetVertexAccessor("NORMAL")?.AsVector3Array();

            if (_Normals == null)
            {
                _Normals = new XYZ[_Positions.Count];

                for (int i = 0; i < _Normals.Count; ++i)
                {
                    _Normals[i] = fallbackNormals.GetNormal(_Positions[i]);
                }
            }

            _Color0    = srcPrim.GetVertexAccessor("COLOR_0")?.AsColorArray();
            _TexCoord0 = srcPrim.GetVertexAccessor("TEXCOORD_0")?.AsVector2Array();

            _Joints0  = srcPrim.GetVertexAccessor("JOINTS_0")?.AsVector4Array();
            _Joints1  = srcPrim.GetVertexAccessor("JOINTS_1")?.AsVector4Array();
            _Weights0 = srcPrim.GetVertexAccessor("WEIGHTS_0")?.AsVector4Array();
            _Weights1 = srcPrim.GetVertexAccessor("WEIGHTS_1")?.AsVector4Array();

            if (_Joints0 == null || _Weights0 == null)
            {
                _Joints0 = _Joints1 = _Weights0 = _Weights1 = null;
            }
            if (_Joints1 == null || _Weights1 == null)
            {
                _Joints1 = _Weights1 = null;
            }

            if (_Weights0 != null)
            {
                _Weights0 = _Weights0.ToArray(); // isolate memory to prevent overwriting source glTF.

                for (int i = 0; i < _Weights0.Count; ++i)
                {
                    var r = XYZW.Dot(_Weights0[i], XYZW.One);
                    _Weights0[i] /= r;
                }
            }

            if (doubleSided) // Monogame's effect material does not support double sided materials, so we simulate it by adding reverse faces
            {
                var front = srcPrim.GetTriangleIndices();
                var back  = front.Select(item => (item.A, item.C, item.B));
                _Triangles = front.Concat(back).ToArray();
            }
            else
            {
                _Triangles = srcPrim.GetTriangleIndices().ToArray();
            }
        }