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