Пример #1
0
        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);
            }
        }
Пример #2
0
        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();
        }