public static void LoadMesh(this Mesh mesh, VrmLib.Mesh src, VrmLib.Skin skin = null) { mesh.vertices = src.VertexBuffer.Positions.GetSpan <Vector3>().ToArray(); mesh.normals = src.VertexBuffer.Normals?.GetSpan <Vector3>().ToArray(); mesh.uv = src.VertexBuffer.TexCoords?.GetSpan <Vector2>().ToArray(); mesh.colors = src.VertexBuffer.Colors?.GetSpan <Color>().ToArray(); if (src.VertexBuffer.Weights != null && src.VertexBuffer.Joints != null) { var boneWeights = new BoneWeight[mesh.vertexCount]; if (src.VertexBuffer.Weights.Count != mesh.vertexCount || src.VertexBuffer.Joints.Count != mesh.vertexCount) { throw new ArgumentException(); } var weights = src.VertexBuffer.Weights.GetSpan <Vector4>(); var joints = src.VertexBuffer.Joints.GetSpan <VrmLib.SkinJoints>(); if (skin != null) { mesh.bindposes = skin.InverseMatrices.GetSpan <Matrix4x4>().ToArray(); } for (int i = 0; i < weights.Length; ++i) { var w = weights[i]; boneWeights[i].weight0 = w.x; boneWeights[i].weight1 = w.y; boneWeights[i].weight2 = w.z; boneWeights[i].weight3 = w.w; } for (int i = 0; i < joints.Length; ++i) { var j = joints[i]; boneWeights[i].boneIndex0 = j.Joint0; boneWeights[i].boneIndex1 = j.Joint1; boneWeights[i].boneIndex2 = j.Joint2; boneWeights[i].boneIndex3 = j.Joint3; } mesh.boneWeights = boneWeights; } mesh.subMeshCount = src.Submeshes.Count; #if UNITY_2019 var triangles = src.IndexBuffer.GetAsIntArray(); mesh.triangles = triangles; var flags = MeshUpdateFlags.DontRecalculateBounds | MeshUpdateFlags.DontResetBoneBounds; for (int i = 0; i < src.Submeshes.Count; ++i) { var submesh = src.Submeshes[i]; mesh.SetSubMesh(i, new SubMeshDescriptor { indexStart = submesh.Offset, indexCount = submesh.DrawCount, }, flags); } #else var triangles = src.IndexBuffer.GetAsIntList(); for (int i = 0; i < src.Submeshes.Count; ++i) { var submesh = src.Submeshes[i]; mesh.SetTriangles(triangles.GetRange(submesh.Offset, submesh.DrawCount), i); } #endif foreach (var morphTarget in src.MorphTargets) { var positions = morphTarget.VertexBuffer.Positions != null ? morphTarget.VertexBuffer.Positions.GetSpan <Vector3>().ToArray() : new Vector3[mesh.vertexCount] // dummy ; mesh.AddBlendShapeFrame(morphTarget.Name, 100.0f, positions, null, null); mesh.RecalculateBounds(); mesh.RecalculateTangents(); } }
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); }
/// <summary> /// VrmLib.Mesh => UnityEngine.Mesh /// </summary> /// <param name="mesh"></param> /// <param name="src"></param> /// <param name="skin"></param> public static UnityEngine.Mesh LoadSharedMesh(VrmLib.Mesh src, VrmLib.Skin skin = null) { // submesh 方式 var mesh = new UnityEngine.Mesh(); mesh.vertices = src.VertexBuffer.Positions.GetSpan <Vector3>().ToArray(); mesh.normals = src.VertexBuffer.Normals?.GetSpan <Vector3>().ToArray(); mesh.uv = src.VertexBuffer.TexCoords?.GetSpan <Vector2>().ToArray(); mesh.colors = src.VertexBuffer.Colors?.GetSpan <Color>().ToArray(); if (src.VertexBuffer.Weights != null && src.VertexBuffer.Joints != null) { var boneWeights = new BoneWeight[mesh.vertexCount]; if (src.VertexBuffer.Weights.Count != mesh.vertexCount || src.VertexBuffer.Joints.Count != mesh.vertexCount) { throw new ArgumentException(); } var weights = src.VertexBuffer.Weights.GetSpan <Vector4>(); var joints = src.VertexBuffer.Joints.GetSpan <VrmLib.SkinJoints>(); if (skin != null) { mesh.bindposes = skin.InverseMatrices.GetSpan <Matrix4x4>().ToArray(); } for (int i = 0; i < weights.Length; ++i) { var w = weights[i]; boneWeights[i].weight0 = w.x; boneWeights[i].weight1 = w.y; boneWeights[i].weight2 = w.z; boneWeights[i].weight3 = w.w; } for (int i = 0; i < joints.Length; ++i) { var j = joints[i]; boneWeights[i].boneIndex0 = j.Joint0; boneWeights[i].boneIndex1 = j.Joint1; boneWeights[i].boneIndex2 = j.Joint2; boneWeights[i].boneIndex3 = j.Joint3; } mesh.boneWeights = boneWeights; } mesh.subMeshCount = src.Submeshes.Count; var triangles = src.IndexBuffer.GetAsIntList(); for (int i = 0; i < src.Submeshes.Count; ++i) { var submesh = src.Submeshes[i]; mesh.SetTriangles(triangles.GetRange(submesh.Offset, submesh.DrawCount), i); } foreach (var morphTarget in src.MorphTargets) { var positions = morphTarget.VertexBuffer.Positions != null ? morphTarget.VertexBuffer.Positions.GetSpan <Vector3>().ToArray() : new Vector3[mesh.vertexCount] // dummy ; mesh.AddBlendShapeFrame(morphTarget.Name, 100.0f, positions, null, null); } mesh.RecalculateBounds(); mesh.RecalculateTangents(); return(mesh); }