Beispiel #1
0
        private static VrmLib.MeshGroup CreateMesh(Mesh mesh, Renderer renderer, Dictionary <Material, VrmLib.Material> materials)
        {
            var meshGroup = new VrmLib.MeshGroup(mesh.name);
            var vrmMesh   = new VrmLib.Mesh();

            vrmMesh.VertexBuffer = new VrmLib.VertexBuffer();
            vrmMesh.VertexBuffer.Add(VrmLib.VertexBuffer.PositionKey, ToBufferAccessor(mesh.vertices));

            if (mesh.boneWeights.Length == mesh.vertexCount)
            {
                vrmMesh.VertexBuffer.Add(
                    VrmLib.VertexBuffer.WeightKey,
                    ToBufferAccessor(mesh.boneWeights.Select(x =>
                                                             new Vector4(x.weight0, x.weight1, x.weight2, x.weight3)).ToArray()
                                     ));
                vrmMesh.VertexBuffer.Add(
                    VrmLib.VertexBuffer.JointKey,
                    ToBufferAccessor(mesh.boneWeights.Select(x =>
                                                             new VrmLib.SkinJoints((ushort)x.boneIndex0, (ushort)x.boneIndex1, (ushort)x.boneIndex2, (ushort)x.boneIndex3)).ToArray()
                                     ));
            }
            if (mesh.uv.Length == mesh.vertexCount)
            {
                vrmMesh.VertexBuffer.Add(VrmLib.VertexBuffer.TexCoordKey, ToBufferAccessor(mesh.uv));
            }
            if (mesh.normals.Length == mesh.vertexCount)
            {
                vrmMesh.VertexBuffer.Add(VrmLib.VertexBuffer.NormalKey, ToBufferAccessor(mesh.normals));
            }
            if (mesh.colors.Length == mesh.vertexCount)
            {
                vrmMesh.VertexBuffer.Add(VrmLib.VertexBuffer.ColorKey, ToBufferAccessor(mesh.colors));
            }
            vrmMesh.IndexBuffer = ToBufferAccessor(mesh.triangles);

            int offset = 0;

            for (int i = 0; i < mesh.subMeshCount; i++)
            {
                var subMesh = mesh.GetSubMesh(i);
                try
                {
                    vrmMesh.Submeshes.Add(new VrmLib.Submesh(offset, subMesh.indexCount, materials[renderer.sharedMaterials[i]]));
                }
                catch (Exception ex)
                {
                    Debug.LogError(ex);
                }

                offset += subMesh.indexCount;
            }

            for (int i = 0; i < mesh.blendShapeCount; i++)
            {
                var blendShapeVertices = mesh.vertices;
                var usePosition        = blendShapeVertices != null && blendShapeVertices.Length > 0;

                var blendShapeNormals = mesh.normals;
                var useNormal         = usePosition && blendShapeNormals != null && blendShapeNormals.Length == blendShapeVertices.Length;
                // var useNormal = usePosition && blendShapeNormals != null && blendShapeNormals.Length == blendShapeVertices.Length && !exportOnlyBlendShapePosition;

                var blendShapeTangents = mesh.tangents.Select(y => (Vector3)y).ToArray();
                //var useTangent = usePosition && blendShapeTangents != null && blendShapeTangents.Length == blendShapeVertices.Length;
                // var useTangent = false;

                var frameCount = mesh.GetBlendShapeFrameCount(i);
                mesh.GetBlendShapeFrameVertices(i, frameCount - 1, blendShapeVertices, blendShapeNormals, null);

                if (usePosition)
                {
                    var morphTarget = new VrmLib.MorphTarget(mesh.GetBlendShapeName(i));
                    morphTarget.VertexBuffer = new VrmLib.VertexBuffer();
                    morphTarget.VertexBuffer.Add(VrmLib.VertexBuffer.PositionKey, ToBufferAccessor(blendShapeVertices));
                    vrmMesh.MorphTargets.Add(morphTarget);
                }
            }

            meshGroup.Meshes.Add(vrmMesh);
            return(meshGroup);
        }
        public static UnityEngine.Mesh LoadDivided(VrmLib.MeshGroup src)
        {
            var dst = new UnityEngine.Mesh();

            //
            // vertices
            //
            var vertexCount = src.Meshes.Sum(x => x.VertexBuffer.Count);
            var positions   = new List <Vector3>(vertexCount);
            var normals     = new List <Vector3>(vertexCount);
            var uv          = new List <Vector2>(vertexCount);
            var boneWeights = new List <BoneWeight>(vertexCount);

            for (int meshIndex = 0; meshIndex < src.Meshes.Count; ++meshIndex)
            {
                var mesh = src.Meshes[meshIndex];
                positions.AddRange(mesh.VertexBuffer.Positions.GetSpan <Vector3>());
                normals.AddRange(mesh.VertexBuffer.Normals.GetSpan <Vector3>());
                uv.AddRange(mesh.VertexBuffer.TexCoords.GetSpan <Vector2>());
                if (src.Skin != null)
                {
                    var j = mesh.VertexBuffer.Joints.GetSpan <VrmLib.SkinJoints>();
                    var w = mesh.VertexBuffer.Weights.GetSpan <Vector4>();
                    for (int i = 0; i < mesh.VertexBuffer.Count; ++i)
                    {
                        var jj = j[i];
                        var ww = w[i];
                        boneWeights.Add(new BoneWeight
                        {
                            boneIndex0 = jj.Joint0,
                            boneIndex1 = jj.Joint1,
                            boneIndex2 = jj.Joint2,
                            boneIndex3 = jj.Joint3,
                            weight0    = ww.x,
                            weight1    = ww.y,
                            weight2    = ww.z,
                            weight3    = ww.w,
                        });
                    }
                }
            }

            dst.name     = src.Name;
            dst.vertices = positions.ToArray();
            dst.normals  = normals.ToArray();
            dst.uv       = uv.ToArray();
            if (src.Skin != null)
            {
                dst.boneWeights = boneWeights.ToArray();
            }

            //
            // skin
            //
            if (src.Skin != null)
            {
                dst.bindposes = src.Skin.InverseMatrices.GetSpan <Matrix4x4>().ToArray();
            }

            //
            // triangles
            //
            dst.subMeshCount = src.Meshes.Count;
            var offset = 0;

            for (int meshIndex = 0; meshIndex < src.Meshes.Count; ++meshIndex)
            {
                var mesh    = src.Meshes[meshIndex];
                var indices = mesh.IndexBuffer.GetAsIntArray().Select(x => offset + x).ToArray();
                dst.SetTriangles(indices, meshIndex);
                offset += mesh.VertexBuffer.Count;
            }

            dst.RecalculateBounds();
            dst.RecalculateTangents();

            //
            // blendshape
            //
            var blendShapeCount = src.Meshes[0].MorphTargets.Count;

            for (int i = 0; i < blendShapeCount; ++i)
            {
                positions.Clear();
                normals.Clear();
                var name = src.Meshes[0].MorphTargets[i].Name;
                for (int meshIndex = 0; meshIndex < src.Meshes.Count; ++meshIndex)
                {
                    var morphTarget = src.Meshes[meshIndex].MorphTargets[i];
                    positions.AddRange(morphTarget.VertexBuffer.Positions.GetSpan <Vector3>());
                    if (morphTarget.VertexBuffer.Normals != null)
                    {
                        normals.AddRange(morphTarget.VertexBuffer.Normals.GetSpan <Vector3>());
                    }
                    else
                    {
                        // fill zero
                        normals.AddRange(Enumerable.Range(0, morphTarget.VertexBuffer.Count).Select(x => Vector3.zero));
                    }
                }
                dst.AddBlendShapeFrame(name, 100.0f, positions.ToArray(), normals.ToArray(), null);
            }

            return(dst);
        }