public void Capture(Mesh mesh, Cloth cloth, MeshBuffer mbuf, AlembicRecorderSettings settings)
            {
                if (mesh == null || cloth == null)
                {
                    mbuf.Clear();
                    return;
                }

                if (remap.Count != mesh.vertexCount)
                {
                    GenerateRemapIndices(mesh, mbuf);
                }

                // capture cloth points and normals
                vertices.Assign(cloth.vertices);
                if (numRemappedVertices != vertices.Count)
                {
                    Debug.LogWarning("numRemappedVertices != vertices.Count");
                    return;
                }

                if (settings.MeshNormals)
                {
                    normals.Assign(cloth.normals);
                }
                else
                {
                    normals.Clear();
                }

                // apply root bone transform
                if (rootBone != null)
                {
                    var mat = Matrix4x4.TRS(rootBone.localPosition, rootBone.localRotation, Vector3.one);
                    NativeMethods.aeApplyMatrixP(vertices, vertices.Count, ref mat);
                    NativeMethods.aeApplyMatrixV(normals, normals.Count, ref mat);
                }

                // remap vertices and normals
                for (int vi = 0; vi < remap.Count; ++vi)
                {
                    mbuf.points[vi] = vertices[remap[vi]];
                }
                if (normals.Count > 0)
                {
                    mbuf.normals.ResizeDiscard(remap.Count);
                    for (int vi = 0; vi < remap.Count; ++vi)
                    {
                        mbuf.normals[vi] = normals[remap[vi]];
                    }
                }

                // capture other components
                if (settings.MeshUV0)
                {
                    mbuf.uv0.LockList(ls => mesh.GetUVs(0, ls));
                }
                else
                {
                    mbuf.uv0.Clear();
                }

                if (settings.MeshUV1)
                {
                    mbuf.uv1.LockList(ls => mesh.GetUVs(1, ls));
                }
                else
                {
                    mbuf.uv1.Clear();
                }

                if (settings.MeshColors)
                {
                    mbuf.colors.LockList(ls => mesh.GetColors(ls));
                }
                else
                {
                    mbuf.colors.Clear();
                }
            }
            public void Capture(Mesh mesh, Matrix4x4 world2local,
                                bool captureNormals, bool captureUV0, bool captureUV1, bool captureColors)
            {
                if (mesh == null)
                {
                    Clear();
                    return;
                }

                if (world2local != Matrix4x4.identity)
                {
                    var verts = new List <Vector3>();
                    mesh.GetVertices(verts);
                    for (var i = 0; i < verts.Count; ++i)
                    {
                        var v = verts[i];
                        verts[i] = world2local.MultiplyPoint(v);
                    }

                    points.Assign(verts);
                }
                else
                {
                    points.LockList(ls => mesh.GetVertices(ls));
                }


                if (captureNormals)
                {
                    if (world2local != Matrix4x4.identity)
                    {
                        var meshNormals = new List <Vector3>();
                        mesh.GetNormals(meshNormals);
                        for (var i = 0; i < meshNormals.Count; ++i)
                        {
                            var n = meshNormals[i];
                            meshNormals[i] = world2local.MultiplyVector(n);
                        }
                        normals.Assign(meshNormals);
                    }
                    else
                    {
                        normals.LockList(ls => mesh.GetNormals(ls));
                    }
                }
                else
                {
                    normals.Clear();
                }

                if (captureUV0)
                {
                    uv0.LockList(ls => mesh.GetUVs(0, ls));
                }
                else
                {
                    uv0.Clear();
                }

                if (captureUV1)
                {
                    uv1.LockList(ls => mesh.GetUVs(1, ls));
                }
                else
                {
                    uv1.Clear();
                }

                if (captureColors)
                {
                    colors.LockList(ls => mesh.GetColors(ls));
                }
                else
                {
                    colors.Clear();
                }


                int submeshCount = mesh.subMeshCount;

                submeshData.Resize(submeshCount);
                if (submeshIndices.Count > submeshCount)
                {
                    submeshIndices.RemoveRange(submeshCount, submeshIndices.Count - submeshCount);
                }
                while (submeshIndices.Count < submeshCount)
                {
                    submeshIndices.Add(new PinnedList <int>());
                }
                for (int smi = 0; smi < submeshCount; ++smi)
                {
                    var indices = submeshIndices[smi];
                    indices.LockList(l => { mesh.GetIndices(l, smi); });

                    aeSubmeshData smd = new aeSubmeshData();
                    switch (mesh.GetTopology(smi))
                    {
                    case MeshTopology.Triangles: smd.topology = aeTopology.Triangles; break;

                    case MeshTopology.Lines: smd.topology = aeTopology.Lines; break;

                    case MeshTopology.Quads: smd.topology = aeTopology.Quads; break;

                    default: smd.topology = aeTopology.Points; break;
                    }
                    smd.indexes      = indices;
                    smd.indexCount   = indices.Count;
                    submeshData[smi] = smd;
                }
            }