public MeshWrapper([NotNull] IReadOnlyList <SerializedFile> assetFiles, [NotNull] Mesh mesh, [NotNull] TexturedMaterialExtraProperties extraMaterialProperties) { Name = mesh.m_Name; { var subMeshCount = mesh.m_SubMeshes.Length; var subMeshes = new PrettySubMesh[subMeshCount]; uint meshIndexStart = 0; for (var i = 0; i < mesh.m_SubMeshes.Length; i += 1) { var subMesh = mesh.m_SubMeshes[i]; var material = FindMaterialInfo(assetFiles, mesh, i, extraMaterialProperties); var sm = new PrettySubMesh(meshIndexStart, subMesh, material); subMeshes[i] = sm; meshIndexStart += subMesh.indexCount; } SubMeshes = subMeshes; } Indices = mesh.m_Indices.ToArray(); { const int bonePerVertex = 4; var skinCount = mesh.m_Skin.Length; var skins = new BoneInfluence[skinCount][]; for (var i = 0; i < skinCount; i += 1) { var s = new BoneInfluence[bonePerVertex]; skins[i] = s; var w = mesh.m_Skin[i]; for (var j = 0; j < bonePerVertex; j += 1) { BoneInfluence influence; if (w != null) { influence = new BoneInfluence(w, j); } else { influence = null; } s[j] = influence; } } Skin = skins; } BindPose = (Matrix4x4[])mesh.m_BindPose.Clone(); VertexCount = mesh.m_VertexCount; Vertices = ReadVector3Array(mesh.m_Vertices, mesh.m_VertexCount); Normals = ReadVector3Array(mesh.m_Normals); if (mesh.m_Colors != null) { Colors = ReadVector4Array(mesh.m_Colors); } UV1 = ReadVector2Array(mesh.m_UV0); if (mesh.m_Tangents != null) { Tangents = ReadVector3Array(mesh.m_Tangents); } BoneNameHashes = (uint[])mesh.m_BoneNameHashes.Clone(); if (mesh.m_Shapes != null) { Shape = new BlendShapeData(mesh.m_Shapes); } }
private CompositeMesh([NotNull] PrettyMesh[] meshes) { ComponentMeshCount = meshes.Length; { var meshNames = new List <string>(); foreach (var m in meshes) { if (m is CompositeMesh cm) { meshNames.AddRange(cm.Names); } else { meshNames.Add(m.Name); } } Names = meshNames.ToArray(); var sb = new StringBuilder(); sb.Append("Composite mesh of:"); foreach (var name in meshNames) { sb.AppendLine(); sb.Append("\t"); sb.Append(name); } Name = sb.ToString(); } var subMeshList = new List <PrettySubMesh>(); var indexList = new List <uint>(); var skinList = new List <BoneInfluence[]>(); var bindPoseList = new List <Matrix4x4>(); var vertexList = new List <Vector3>(); var normalList = new List <Vector3>(); var colorList = new List <Vector4>(); var uv1List = new List <Vector2>(); // uv2 is the optional secondary UV (highlight etc.) var uv2List = new List <Vector2?>(); var tangentList = new List <Vector3>(); var boneNameHashList = new List <uint>(); var parentMeshIndices = new List <int>(); uint vertexStart = 0; uint indexStart = 0; var boneHashStart = 0; var parentMeshIndex = 0; foreach (var mesh in meshes) { var cm = mesh as CompositeMesh; for (var i = 0; i < mesh.SubMeshes.Length; i++) { var subMesh = mesh.SubMeshes[i]; Debug.Assert(subMesh.Topology == PrimitiveType.Triangles); var newSubMesh = new PrettySubMesh( subMesh.FirstIndex + indexStart, subMesh.IndexCount, subMesh.Topology, subMesh.TriangleCount, subMesh.FirstVertex + vertexStart, subMesh.VertexCount, subMesh.BoundingBox, subMesh.Material); subMeshList.Add(newSubMesh); if (cm != null) { parentMeshIndices.Add(parentMeshIndex + cm.ParentMeshIndices[i]); } else { parentMeshIndices.Add(parentMeshIndex); } } if (cm != null) { parentMeshIndex += cm.Names.Length; } else { ++parentMeshIndex; } foreach (var index in mesh.Indices) { indexList.Add(index + vertexStart); } foreach (var skin in mesh.Skin) { var s = new BoneInfluence[4]; for (var i = 0; i < skin.Length; i++) { var influence = skin[i]; if (influence == null) { break; } var newInfluence = new BoneInfluence(influence.BoneIndex + boneHashStart, influence.Weight); s[i] = newInfluence; } skinList.Add(s); } // Some vertex do not bind to a bone (e.g. 100 vertices & 90 bone influences), // so we have to fill the gap ourselves, or this will influence the meshes // combined after current mesh. if (mesh.Skin.Length < mesh.VertexCount) { var difference = mesh.VertexCount - mesh.Skin.Length; for (var i = 0; i < difference; ++i) { skinList.Add(new BoneInfluence[4]); } } boneNameHashList.AddRange(mesh.BoneNameHashes); bindPoseList.AddRange(mesh.BindPose); vertexList.AddRange(mesh.Vertices); normalList.AddRange(mesh.Normals); if (mesh.Colors != null) { colorList.AddRange(mesh.Colors); } else { for (var i = 0; i < mesh.VertexCount; ++i) { colorList.Add(Vector4.Zero); } } // TODO: counts don't match? if (mesh.Tangents != null) { tangentList.AddRange(mesh.Tangents); } else { for (var i = 0; i < mesh.VertexCount; ++i) { tangentList.Add(Vector3.Zero); } } uv1List.AddRange(mesh.UV1); uv2List.AddRange(mesh.UV2); vertexStart += (uint)mesh.VertexCount; indexStart += (uint)mesh.Indices.Length; boneHashStart += mesh.BoneNameHashes.Length; } VertexCount = (int)vertexStart; var shape = MergeBlendShapes(meshes); Shape = shape; SubMeshes = subMeshList.ToArray(); Indices = indexList.ToArray(); Skin = skinList.ToArray(); BindPose = bindPoseList.ToArray(); Vertices = vertexList.ToArray(); Normals = normalList.ToArray(); Colors = colorList.ToArray(); UV1 = uv1List.ToArray(); UV2 = uv2List.ToArray(); Tangents = tangentList.ToArray(); BoneNameHashes = boneNameHashList.ToArray(); ParentMeshIndices = parentMeshIndices.ToArray(); }