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