// Magica Cloth 2. // Copyright (c) 2023 MagicaSoft. // https://magicasoft.jp using Unity.Mathematics; using UnityEngine; namespace MagicaCloth2 { public partial class ClothProcess { public ResultCode GenerateStatusCheck() { ResultCode result = new ResultCode(); // スケール値チェック var scl = cloth.transform.lossyScale; if (Mathf.Approximately(scl.x, 0.0f) || Mathf.Approximately(scl.y, 0.0f) || Mathf.Approximately(scl.z, 0.0f)) { // スケール値がゼロ result.SetError(Define.Result.Init_ScaleIsZero); } else if (scl.x < 0.0f || scl.y < 0.0f || scl.z < 0.0f) { // 負のスケール // 負のスケールでの初期化は、事前構築もしくは初期化データありの場合許可する var sdata2 = cloth.GetSerializeData2(); if (sdata2.preBuildData.UsePreBuild() || (sdata2.initData?.HasData() ?? false)) { // ただし許可されるのは一軸フリップのみ int flipCount = (scl.x < 0.0f ? 1 : 0) + (scl.y < 0.0f ? 1 : 0) + (scl.z < 0.0f ? 1 : 0); if (flipCount != 1) { result.SetError(Define.Result.Init_NegativeScale); } } else result.SetError(Define.Result.Init_NegativeScale); } else { float diff1 = Mathf.Abs(1.0f - scl.x / scl.y); float diff2 = Mathf.Abs(1.0f - scl.x / scl.z); const float diffTolerance = 0.01f; // 誤差(1%) if (diff1 > diffTolerance || diff2 > diffTolerance) { // 一様スケールではない result.SetWarning(Define.Result.Init_NonUniformScale); } } return result; } internal bool GenerateInitialization() { result.SetProcess(); // シリアライズデータ(1)の検証 if (cloth.SerializeData.IsValid() == false) { if (cloth.SerializeData.VerificationResult == Define.Result.Empty) result.SetError(Define.Result.CreateCloth_InvalidSerializeData); else result.SetError(cloth.SerializeData.VerificationResult); return false; } cloth.SerializeData.DataValidate(); cloth.serializeData2.DataValidate(); // 初期化実行 Init(); if (result.IsError()) return false; return true; } internal bool GenerateBoneClothSelection() { // セレクションデータの構築 var setupData = boneClothSetupData; int tcnt = setupData.skinBoneCount; // パーティクルトランスフォーム総数 var selectionData = new SelectionData(tcnt); for (int i = 0; i < tcnt; i++) { float3 lpos = math.transform(setupData.initRenderWorldtoLocal, setupData.transformPositions[i]); selectionData.positions[i] = lpos; selectionData.attributes[i] = VertexAttribute.Move; // 移動で初期化 } // 最大接続距離 float maxLength = 0; for (int i = 0; i < tcnt; i++) { int pi = setupData.GetParentTransformIndex(i, true); if (pi >= 0) { float length = math.distance(selectionData.positions[i], selectionData.positions[pi]); maxLength = math.max(maxLength, length); } } selectionData.maxConnectionDistance = maxLength; // ルートを固定に設定 foreach (var rt in cloth.SerializeData.rootBones) { if (rt) { int index = setupData.GetTransformIndexFromId(rt.GetMagicaId()); selectionData.attributes[index] = VertexAttribute.Fixed; } } selectionData.userEdit = true; // 念のため cloth.GetSerializeData2().selectionData = selectionData; return true; } } }