113 lines
3.4 KiB
C#

using UnityEngine;
using System.Linq;
using VRMShaders;
namespace UniGLTF.MeshUtility
{
public static class MeshExtensions
{
public static Mesh GetMesh(this Renderer r)
{
if (r is SkinnedMeshRenderer smr)
{
return smr.sharedMesh;
}
if (r is MeshRenderer mr)
{
if (mr.GetComponent<MeshFilter>() is MeshFilter mf)
{
return mf.sharedMesh;
}
}
return null;
}
public static Mesh Copy(this Mesh src, bool copyBlendShape)
{
var dst = new Mesh();
dst.name = src.name + "(copy)";
#if UNITY_2017_3_OR_NEWER
dst.indexFormat = src.indexFormat;
#endif
dst.vertices = src.vertices;
dst.normals = src.normals;
dst.tangents = src.tangents;
dst.colors = src.colors;
dst.uv = src.uv;
dst.uv2 = src.uv2;
dst.uv3 = src.uv3;
dst.uv4 = src.uv4;
dst.boneWeights = src.boneWeights;
dst.bindposes = src.bindposes;
dst.subMeshCount = src.subMeshCount;
for (int i = 0; i < dst.subMeshCount; ++i)
{
dst.SetIndices(src.GetIndices(i), src.GetTopology(i), i);
}
dst.RecalculateBounds();
if (copyBlendShape)
{
var vertices = src.vertices;
var normals = src.normals;
Vector3[] tangents = null;
if (Symbols.VRM_NORMALIZE_BLENDSHAPE_TANGENT)
{
tangents = src.tangents.Select(x => (Vector3)x).ToArray();
}
for (int i = 0; i < src.blendShapeCount; ++i)
{
src.GetBlendShapeFrameVertices(i, 0, vertices, normals, tangents);
dst.AddBlendShapeFrame(
src.GetBlendShapeName(i),
src.GetBlendShapeFrameWeight(i, 0),
vertices,
normals,
tangents
);
}
}
return dst;
}
public static void ApplyRotationAndScale(this Mesh src, Matrix4x4 m, bool removeTranslation = true)
{
if (removeTranslation)
{
m.SetColumn(3, new Vector4(0, 0, 0, 1)); // remove translation
}
src.ApplyMatrix(m);
}
public static void ApplyTranslation(this Mesh src, Vector3 p)
{
var m = Matrix4x4.identity;
m.SetColumn(3, new Vector4(p.x, p.y, p.z, 1));
src.ApplyMatrix(m);
}
public static void ApplyMatrix(this Mesh src, Matrix4x4 m)
{
src.vertices = src.vertices.Select(x => m.MultiplyPoint(x)).ToArray();
if (src.normals != null && src.normals.Length > 0)
{
src.normals = src.normals.Select(x => m.MultiplyVector(x.normalized)).ToArray();
}
if (src.tangents != null && src.tangents.Length > 0)
{
src.tangents = src.tangents.Select(x =>
{
var t = m.MultiplyVector((Vector3)x);
return new Vector4(t.x, t.y, t.z, x.w);
}).ToArray();
}
}
}
}