예제 #1
0
        public ModelMesh CreateMesh(Schema2.Mesh srcMesh, int maxBones = 72)
        {
            if (_Device == null)
            {
                throw new InvalidOperationException();
            }

            var srcPrims = GetValidPrimitives(srcMesh).ToList();

            var dstMesh = new ModelMesh(_Device, Enumerable.Range(0, srcPrims.Count).Select(item => new ModelMeshPart()).ToList());

            dstMesh.Name           = srcMesh.Name;
            dstMesh.BoundingSphere = srcMesh.CreateBoundingSphere();

            var srcNormals = new MeshNormalsFallback(srcMesh);

            var idx = 0;

            foreach (var srcPrim in srcPrims)
            {
                CreateMeshPart(dstMesh.MeshParts[idx++], srcPrim, srcNormals, maxBones);
            }

            return(dstMesh);
        }
예제 #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();
            }
        }
예제 #3
0
        private void CreateMeshPart(ModelMeshPart dstPart, MeshPrimitive srcPart, MeshNormalsFallback normalsFunc, int maxBones)
        {
            var doubleSided = srcPart.Material?.DoubleSided ?? false;

            var srcGeometry = new MeshPrimitiveReader(srcPart, doubleSided, normalsFunc);

            var eff = srcGeometry.IsSkinned ? _MatFactory.UseSkinnedEffect(srcPart.Material) : _MatFactory.UseStaticEffect(srcPart.Material);

            dstPart.Effect = eff;

            var vb = srcGeometry.IsSkinned ? CreateVertexBuffer(srcGeometry.ToXnaSkinned()) : CreateVertexBuffer(srcGeometry.ToXnaStatic());

            dstPart.VertexBuffer = vb;
            dstPart.NumVertices  = srcGeometry.VertexCount;
            dstPart.VertexOffset = 0;

            dstPart.IndexBuffer    = CreateIndexBuffer(srcGeometry.TriangleIndices);
            dstPart.PrimitiveCount = srcGeometry.TriangleIndices.Length;
            dstPart.StartIndex     = 0;
        }