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); }
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(); } }
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; }