// Magica Cloth. // Copyright (c) MagicaSoft, 2020-2022. // https://magicasoft.jp using System.Collections.Generic; using UnityEngine; namespace MagicaReductionMesh { /// /// リダクションメッシュ /// ・複数のメッシュを1つにマージ /// ・リダクション機能 /// ・加工後のメッシュデータ取得 /// public class ReductionMesh { /// /// 結合頂点ウエイト計算方式 /// public enum ReductionWeightMode { /// /// 共有頂点からの距離によるウエイト付(従来方式) /// Distance = 0, /// /// 共有頂点に属するメッシュ頂点ウエイトの平均値 /// Average = 1, /// /// 共有頂点からの距離によりウエイト(改良版) /// DistanceAverage = 2, } public ReductionWeightMode WeightMode { get; set; } = ReductionWeightMode.Distance; //========================================================================================= private MeshData meshData = new MeshData(); private ReductionData reductionData = new ReductionData(); private DebugData debugData = new DebugData(); //========================================================================================= public MeshData MeshData { get { meshData.SetParent(this); return meshData; } } public ReductionData ReductionData { get { reductionData.SetParent(this); return reductionData; } } public DebugData DebugData { get { debugData.SetParent(this); return debugData; } } //========================================================================================= /// /// メッシュを追加する /// 登録したメッシュインデックスを返す /// /// /// /// public int AddMesh(bool isSkinning, Mesh mesh, List bones, Matrix4x4[] bindPoseList, BoneWeight[] boneWeightList) { return MeshData.AddMesh(isSkinning, mesh, bones, bindPoseList, boneWeightList); } /// /// メッシュを追加する /// 登録したメッシュインデックスを返す(-1=エラー) /// /// public int AddMesh(Renderer ren) { if (ren == null) { Debug.LogError("Renderer is NUll!"); return -1; } if (ren is SkinnedMeshRenderer) { var sren = ren as SkinnedMeshRenderer; return MeshData.AddMesh(true, sren.sharedMesh, new List(sren.bones), sren.sharedMesh.bindposes, sren.sharedMesh.boneWeights); } else { var mfilter = ren.GetComponent(); var bones = new List(); bones.Add(ren.transform); return MeshData.AddMesh(false, mfilter.sharedMesh, bones, null, null); } } /// /// メッシュを追加する /// 登録したメッシュインデックスを返す /// /// /// /// /// /// /// public int AddMesh(Transform root, List posList, List norList = null, List tanList = null, List uvList = null, List triangleList = null) { return MeshData.AddMesh(root, posList, norList, tanList, uvList, triangleList); } /// /// リダクション実行 /// /// 重複頂点のマージ距離(0.0f=実行しない) /// 周辺頂点のマージ距離(0.0f=実行しない) /// ポリゴン接続のマージ距離(0.0f=実行しない) public void Reduction(float zeroRadius, float radius, float polygonLength, bool createTetra) { // ゼロ距離頂点をマージする if (zeroRadius > 0.0f) ReductionData.ReductionZeroDistance(zeroRadius); // 範囲内の頂点をマージする if (radius > 0.0f) ReductionData.ReductionRadius(radius); // ポリゴン接続から範囲内の頂点をマージする if (polygonLength > 0.0f) ReductionData.ReductionPolygonLink(polygonLength); // メッシュデータ更新 MeshData.UpdateMeshData(createTetra); // 未使用ボーンの削除 ReductionData.ReductionBone(); } /// /// 最終メッシュデータを計算して返す /// 子頂点の親頂点に対するスキニングが不要な場合は(weightLength=0)に設定します。 /// /// メッシュの基準トランスフォーム(この姿勢を元にローカル座標変換される) public FinalData GetFinalData(Transform root) { return MeshData.GetFinalData(root); } } }