This commit is contained in:
CortexCore
2024-03-29 00:58:24 +08:00
parent 967ad8eacf
commit 05315ef4a8
232 changed files with 53368 additions and 8539 deletions

View File

@@ -233,10 +233,10 @@ namespace MagicaCloth2
// チームのセンター姿勢の決定と慣性用の移動量計算
masterJob = tm.CalcCenterAndInertiaAndWind(masterJob);
// パーティクルリセットの適用
// パーティクルの全体慣性およびリセットの適用
masterJob = sm.PreSimulationUpdate(masterJob);
// ■コライダーのローカル姿勢を求める
// ■コライダーのローカル姿勢を求める、および全体慣性とリセットの適用
masterJob = MagicaManager.Collider.PreSimulationUpdate(masterJob);
//-----------------------------------------------------------------

View File

@@ -92,8 +92,6 @@ namespace MagicaCloth2
//=========================================================================================
static volatile bool isPlaying = false;
//static bool isValid = false;
//=========================================================================================
/// <summary>
/// Reload Domain 対策

View File

@@ -33,7 +33,6 @@ namespace MagicaCloth2
{
if (IsPlaying())
{
//Team.globalTimeScale = Mathf.Clamp01(timeScale);
Time.GlobalTimeScale = Mathf.Clamp01(timeScale);
}
}
@@ -47,7 +46,6 @@ namespace MagicaCloth2
{
if (IsPlaying())
{
//return Team.globalTimeScale;
return Time.GlobalTimeScale;
}
else
@@ -166,5 +164,34 @@ namespace MagicaCloth2
PreBuild.UnloadUnusedData();
}
}
/// <summary>
/// MonoBehaviourでのMagicaClothの初期化場所
/// MagicaCloth initialization location in MonoBehaviour.
/// </summary>
public enum InitializationLocation
{
/// <summary>
/// Initialize with MonoBehaviour.Start().
/// (Default)
/// </summary>
Start = 0,
/// <summary>
/// Initialize with MonoBehaviour.Awake().
/// </summary>
Awake = 1,
}
internal static InitializationLocation initializationLocation = InitializationLocation.Start;
/// <summary>
/// MonoBehaviourでのMagicaClothの初期化場所を設定する
/// Setting MagicaCloth initialization location in MonoBehaviour.
/// </summary>
/// <param name="initLocation"></param>
public static void SetInitializationLocation(InitializationLocation initLocation)
{
initializationLocation = initLocation;
}
}
}

View File

@@ -64,6 +64,12 @@ namespace MagicaCloth2
[Range(Define.System.MaxSimulationCountPerFrame_Low, Define.System.MaxSimulationCountPerFrame_Hi)]
public int maxSimulationCountPerFrame = Define.System.DefaultMaxSimulationCountPerFrame;
/// <summary>
/// MonoBehaviourでのMagicaClothの初期化場所。
/// MagicaCloth initialization location in MonoBehaviour.
/// </summary>
public MagicaManager.InitializationLocation initializationLocation = MagicaManager.InitializationLocation.Start;
/// <summary>
/// シミュレーションの更新場所
/// BeforeLateUpdate : LateUpdate()の前に実行します。これはUnity 2D Animationで利用する場合に必要です。
@@ -78,8 +84,7 @@ namespace MagicaCloth2
//=========================================================================================
public void Awake()
{
if (refreshMode == RefreshMode.OnAwake)
Refresh();
Refresh();
}
public void Update()
@@ -108,6 +113,7 @@ namespace MagicaCloth2
MagicaManager.SetSimulationFrequency(simulationFrequency);
MagicaManager.SetMaxSimulationCountPerFrame(maxSimulationCountPerFrame);
MagicaManager.SetInitializationLocation(initializationLocation);
MagicaManager.SetUpdateLocation(updateLocation);
}
else

View File

@@ -90,6 +90,7 @@ namespace MagicaCloth2
public ExNativeArray<float3> oldPositions;
public ExNativeArray<quaternion> oldRotations;
/// <summary>
/// 有効なコライダーデータ数
/// </summary>
@@ -719,6 +720,7 @@ namespace MagicaCloth2
[Unity.Collections.ReadOnly]
public NativeArray<float3> transformScaleArray;
// コライダーごと
public void Execute(int index)
{
var flag = flagArray[index];
@@ -1094,7 +1096,6 @@ namespace MagicaCloth2
}
}
/// <summary>
/// シミュレーション更新後処理
/// </summary>

View File

@@ -540,7 +540,6 @@ namespace MagicaCloth2
[Unity.Collections.WriteOnly]
public NativeArray<float3> velocityPosArray;
public NativeArray<float3> dispPosArray;
[Unity.Collections.WriteOnly]
public NativeArray<float3> velocityArray;
public NativeArray<float3> realVelocityArray;
[Unity.Collections.WriteOnly]
@@ -607,6 +606,7 @@ namespace MagicaCloth2
dispPosArray[pindex] = MathUtility.ShiftPosition(dispPosArray[pindex], prevFrameWorldPosition, cdata.frameComponentShiftVector, cdata.frameComponentShiftRotation);
velocityArray[pindex] = math.mul(cdata.frameComponentShiftRotation, velocityArray[pindex]);
realVelocityArray[pindex] = math.mul(cdata.frameComponentShiftRotation, realVelocityArray[pindex]);
}
}
@@ -1168,6 +1168,7 @@ namespace MagicaCloth2
// 慣性の深さ影響
float inertiaDepth = param.inertiaConstraint.depthInertia * (1.0f - depth * depth); // 二次曲線
//Debug.Log($"[{pindex}] inertiaDepth:{inertiaDepth}");
inertiaVector = math.lerp(inertiaVector, cdata.stepVector, inertiaDepth);
inertiaRotation = math.slerp(inertiaRotation, cdata.stepRotation, inertiaDepth);
@@ -1393,6 +1394,8 @@ namespace MagicaCloth2
if (windMain < 0.01f)
return 0;
//Debug.Log($"windMain:{windMain}");
// 風速係数
float mainRatio = windMain / Define.System.WindBaseSpeed; // 0.0 ~
@@ -1855,8 +1858,6 @@ namespace MagicaCloth2
int vindex = tdata.proxyCommonChunk.startIndex + l_index;
var attr = attributes[vindex];
//if (attr.IsInvalid())
// return;
var pos = positions[vindex];
var rot = rotations[vindex];
@@ -1866,13 +1867,12 @@ namespace MagicaCloth2
// 移動パーティクル
var dpos = oldPosArray[pindex];
#if true
#if !MC2_DISABLE_FUTURE
// 未来予測
// 最終計算位置と実速度から次のステップ位置を予測し、その間のフレーム時間位置を表示位置とする
float3 velocity = realVelocityArray[pindex] * simulationDeltaTime;
float3 fpos = dpos + velocity;
float interval = (tdata.nowUpdateTime + simulationDeltaTime) - tdata.oldTime;
//float t = (tdata.time - tdata.oldTime) / interval;
float t = interval > 0.0f ? (tdata.time - tdata.oldTime) / interval : 0.0f;
fpos = math.lerp(dispPosArray[pindex], fpos, t);
dpos = fpos;

View File

@@ -147,7 +147,7 @@ namespace MagicaCloth2
sb.AppendLine($"MaxSimulationCountPerFrame:{maxSimulationCountPerFrame}");
sb.AppendLine($"GlobalTimeScale:{GlobalTimeScale}");
sb.AppendLine($"SimulationDeltaTime:{SimulationDeltaTime}");
sb.AppendLine($"MaxDeltaTime:{MaxDeltaTime}");
//sb.AppendLine($"MaxDeltaTime:{MaxDeltaTime}");
sb.AppendLine($"SimulationPower:{SimulationPower}");
}
sb.AppendLine();

View File

@@ -34,6 +34,8 @@ namespace MagicaCloth2
public const int Flag_CullingKeep = 12; // カリング時に姿勢を保つ
public const int Flag_Spring = 13; // Spring利用
public const int Flag_SkipWriting = 14; // 書き込み停止(ストップモーション用)
public const int Flag_Anchor = 15; // Inertia anchorを利用中
public const int Flag_AnchorReset = 16; // Inertia anchorの座標リセット
// 以下セルフコリジョン
// !これ以降の順番を変えないこと
@@ -80,6 +82,9 @@ namespace MagicaCloth2
/// </summary>
//public int frequency;
/// <summary>
/// 現在フレームの更新時間
/// </summary>
public float frameDeltaTime;
/// <summary>
@@ -117,11 +122,22 @@ namespace MagicaCloth2
/// </summary>
public float timeScale;
/// <summary>
/// チームの最終計算用タイムスケール(0.0~1.0)
/// グローバルタイムスケールなどを考慮した値
/// </summary>
public float nowTimeScale;
/// <summary>
/// 今回のチーム更新回数(0ならばこのフレームは更新なし)
/// </summary>
public int updateCount;
/// <summary>
/// 今回のチーム更新スキップ回数(1以上ならばシミュレーションスキップが発生)
/// </summary>
public int skipCount;
/// <summary>
/// ステップごとのフレームに対するnowUpdateTime割合
/// これは(frameStartTime ~ time)間でのnowUpdateTimeの割合
@@ -144,7 +160,12 @@ namespace MagicaCloth2
/// <summary>
/// 現在の中心ワールド座標この値はCenterData.nowWorldPositionのコピー
/// </summary>
public float3 centerWorldPosition;
//public float3 centerWorldPosition;
/// <summary>
/// アンカーとして設定されているTransformのインスタンスID(0=なし)
/// </summary>
public int anchorTransformId;
/// <summary>
/// チームスケール
@@ -663,7 +684,7 @@ namespace MagicaCloth2
team.timeScale = 1.0f;
team.initScale = cprocess.clothTransformRecord.scale; // 初期スケール
team.scaleRatio = 1.0f;
team.centerWorldPosition = cprocess.clothTransformRecord.position;
//team.centerWorldPosition = cprocess.clothTransformRecord.position;
team.animationPoseRatio = cprocess.cloth.SerializeData.animationPoseRatio;
var c = teamDataArray.Add(team);
int teamId = c.startIndex;
@@ -1094,12 +1115,14 @@ namespace MagicaCloth2
tdata.timeScale = syncTeamData.timeScale;
tdata.updateCount = syncTeamData.updateCount;
tdata.frameInterpolation = syncTeamData.frameInterpolation;
tdata.skipCount = syncTeamData.skipCount;
//Develop.DebugLog($"Team time sync:{teamId}->{syncCloth.Process.TeamId}");
}
// パラメータ同期
// 同期中は一部のパラメータを連動させる
ref var clothParam = ref GetParametersRef(teamId);
clothParam.inertiaConstraint.anchorInertia = syncCloth.SerializeData.inertiaConstraint.anchorInertia;
clothParam.inertiaConstraint.worldInertia = syncCloth.SerializeData.inertiaConstraint.worldInertia;
clothParam.inertiaConstraint.movementSpeedLimit = syncCloth.SerializeData.inertiaConstraint.movementSpeedLimit.GetValue(-1);
clothParam.inertiaConstraint.rotationSpeedLimit = syncCloth.SerializeData.inertiaConstraint.rotationSpeedLimit.GetValue(-1);
@@ -1111,6 +1134,16 @@ namespace MagicaCloth2
tdata.syncCenterTransformIndex = syncTeamData.centerTransformIndex;
}
// アンカー
var anchorTransform = syncCloth && tdata.syncTeamId > 0 ? syncCloth.SerializeData.inertiaConstraint.anchor : cloth.SerializeData.inertiaConstraint.anchor;
int anchorTransformId = anchorTransform != null ? anchorTransform.GetInstanceID() : 0;
tdata.flag.SetBits(Flag_Anchor, anchorTransformId != 0);
tdata.flag.SetBits(Flag_AnchorReset, anchorTransformId != tdata.anchorTransformId);
tdata.anchorTransformId = anchorTransformId;
ref var cdata = ref GetCenterDataRef(teamId);
cdata.anchorPosition = anchorTransformId != 0 ? anchorTransform.position : float3.zero;
cdata.anchorRotation = anchorTransformId != 0 ? anchorTransform.rotation : quaternion.identity;
// 集計まわり
ref var param = ref GetParametersRef(teamId);
if (param.colliderCollisionConstraint.mode == ColliderCollisionConstraint.Mode.Edge)
@@ -1131,7 +1164,9 @@ namespace MagicaCloth2
float deltaTime = Time.deltaTime;
float fixedDeltaTime = MagicaManager.Time.FixedUpdateCount * Time.fixedDeltaTime;
float unscaledDeltaTime = Time.unscaledDeltaTime;
//Debug.Log($"DeltaTime:{deltaTime}, FixedDeltaTime:{fixedDeltaTime}, fixedUpdateCount:{fixedUpdateCount}");
//Debug.Log($"DeltaTime:{deltaTime}, FixedDeltaTime:{fixedDeltaTime}, simulationDeltaTime:{MagicaManager.Time.SimulationDeltaTime}, maxDeltaTime:{MagicaManager.Time.MaxDeltaTime}");
//Debug.Log($"DeltaTime:{deltaTime}, FixedDeltaTime:{fixedDeltaTime}, simulationDeltaTime:{MagicaManager.Time.SimulationDeltaTime}");
// このJobは即時実行させる
var job = new AlwaysTeamUpdateJob()
@@ -1142,7 +1177,8 @@ namespace MagicaCloth2
unityFrameUnscaledDeltaTime = unscaledDeltaTime,
globalTimeScale = MagicaManager.Time.GlobalTimeScale,
simulationDeltaTime = MagicaManager.Time.SimulationDeltaTime,
maxDeltaTime = MagicaManager.Time.MaxDeltaTime,
//maxDeltaTime = MagicaManager.Time.MaxDeltaTime,
maxSimmulationCountPerFrame = MagicaManager.Time.maxSimulationCountPerFrame,
maxUpdateCount = maxUpdateCount,
teamDataArray = teamDataArray.GetNativeArray(),
@@ -1162,7 +1198,8 @@ namespace MagicaCloth2
public float unityFrameUnscaledDeltaTime;
public float globalTimeScale;
public float simulationDeltaTime;
public float maxDeltaTime;
//public float maxDeltaTime;
public int maxSimmulationCountPerFrame;
public NativeReference<int> maxUpdateCount;
public NativeArray<TeamData> teamDataArray;
@@ -1203,14 +1240,12 @@ namespace MagicaCloth2
// 更新時間
float frameDeltaTime = tdata.IsFixedUpdate ? unityFrameFixedDeltaTime : (tdata.IsUnscaled ? unityFrameUnscaledDeltaTime : unityFrameDeltaTime);
tdata.frameDeltaTime = frameDeltaTime;
// 最大更新時間
float deltaTime = math.min(frameDeltaTime, maxDeltaTime);
float deltaTime = frameDeltaTime;
// タイムスケール
float timeScale = tdata.timeScale * (tdata.IsUnscaled ? 1.0f : globalTimeScale);
timeScale = tdata.flag.IsSet(Flag_Suspend) ? 0.0f : timeScale;
//timeScale = tdata.IsCullingInvisible ? 0.0f : timeScale;
tdata.nowTimeScale = timeScale; // 最終計算用タイムスケール
// 加算時間
float addTime = deltaTime * timeScale; // 今回の加算時間
@@ -1221,7 +1256,20 @@ namespace MagicaCloth2
//Debug.Log($"[{i}] time:{time}, addTime:{addTime}, timeScale:{timeScale}, suspend:{tdata.flag.IsSet(Flag_Suspend)}");
float interval = time - tdata.nowUpdateTime;
tdata.updateCount = (int)(interval / simulationDeltaTime); // 今回の更新回数
// 今回の予定更新回数
int updateCount = (int)(interval / simulationDeltaTime);
// 今回の更新回数(最大更新回数まで)
tdata.updateCount = math.min(updateCount, maxSimmulationCountPerFrame);
// 今回のスキップ回数(最大更新回数超過分)
tdata.skipCount = updateCount - tdata.updateCount;
if (tdata.skipCount > 0)
{
// スキップ発生時はスキップ時間を無かったものとする
time = time - simulationDeltaTime * tdata.skipCount;
}
if (tdata.updateCount > 0 && addTime == 0.0f)
{
@@ -1231,6 +1279,7 @@ namespace MagicaCloth2
// こうなると時間補間関連で0除算が発生して数値が壊れる
// 誤差を修正する
tdata.updateCount = 0;
tdata.skipCount = 0;
tdata.nowUpdateTime = time - simulationDeltaTime + 0.0001f;
}
@@ -1257,7 +1306,7 @@ namespace MagicaCloth2
// 全体の最大実行回数
maxCount = math.max(maxCount, tdata.updateCount);
//Debug.Log($"[{teamId}] updateCount:{tdata.updateCount}, addtime:{addTime}, t.time:{tdata.time}, t.oldtime:{tdata.oldTime}");
//Debug.Log($"[{teamId}] updateCount:{tdata.updateCount}, skipCount:{tdata.skipCount}, addtime:{addTime}, t.time:{tdata.time}, t.oldtime:{tdata.oldTime}, timeScale:{tdata.timeScale}");
}
maxUpdateCount.Value = maxCount;
@@ -1297,6 +1346,8 @@ namespace MagicaCloth2
var job = new CalcCenterAndInertiaAndWindJob()
{
simulationDeltaTime = MagicaManager.Time.SimulationDeltaTime,
teamDataArray = teamDataArray.GetNativeArray(),
centerDataArray = MagicaManager.Team.centerDataArray.GetNativeArray(),
teamWindArray = teamWindArray.GetNativeArray(),
@@ -1323,6 +1374,8 @@ namespace MagicaCloth2
[BurstCompile]
struct CalcCenterAndInertiaAndWindJob : IJobParallelFor
{
public float simulationDeltaTime;
// team
public NativeArray<TeamData> teamDataArray;
public NativeArray<InertiaConstraint.CenterData> centerDataArray;
@@ -1377,6 +1430,8 @@ namespace MagicaCloth2
float3 componentWorldScl = transformScaleArray[centerTransformIndex];
cdata.componentWorldPosition = componentWorldPos;
cdata.componentWorldRotation = componentWorldRot;
float3 oldComponentWorldPosition = cdata.oldComponentWorldPosition;
quaternion oldComponentWorldRotation = cdata.oldComponentWorldRotation;
// コンポーネントスケール倍率
float componentScaleRatio = math.length(componentWorldScl) / math.length(tdata.initScale);
@@ -1419,9 +1474,37 @@ namespace MagicaCloth2
}
var wtol = MathUtility.WorldToLocalMatrix(centerWorldPos, centerWorldRot, centerWorldScl);
// ■アンカー
float3 anchorDeltaVector = 0;
quaternion anchorDeltaRotation = quaternion.identity;
if (tdata.flag.IsSet(Flag_AnchorReset) || tdata.IsReset)
{
cdata.oldAnchorPosition = cdata.anchorPosition;
cdata.oldAnchorRotation = cdata.anchorRotation;
cdata.anchorComponentLocalPosition = MathUtility.InverseTransformPoint(componentWorldPos, cdata.anchorPosition, cdata.anchorRotation, 1);
}
if (tdata.flag.IsSet(Flag_Anchor))
{
// アンカーの移動回転影響
float3 anchorCenterPosition = MathUtility.TransformPoint(cdata.anchorComponentLocalPosition, cdata.anchorPosition, cdata.anchorRotation, 1);
anchorDeltaVector = anchorCenterPosition - oldComponentWorldPosition;
anchorDeltaRotation = MathUtility.FromToRotation(cdata.oldAnchorRotation, cdata.anchorRotation);
// アンカーの影響割合
float anchorRatio = 1.0f - param.inertiaConstraint.anchorInertia;
anchorDeltaVector = math.lerp(float3.zero, anchorDeltaVector, anchorRatio);
anchorDeltaRotation = math.slerp(quaternion.identity, anchorDeltaRotation, anchorRatio);
// 打ち消す
oldComponentWorldPosition += anchorDeltaVector;
oldComponentWorldRotation = math.mul(anchorDeltaRotation, oldComponentWorldRotation);
tdata.flag.SetBits(Flag_InertiaShift, true);
}
// フレーム移動量と速度
float3 frameDeltaVector = componentWorldPos - cdata.oldComponentWorldPosition;
float frameDeltaAngle = MathUtility.Angle(cdata.oldComponentWorldRotation, componentWorldRot);
float3 frameDeltaVector = componentWorldPos - oldComponentWorldPosition;
float frameDeltaAngle = MathUtility.Angle(oldComponentWorldRotation, componentWorldRot);
//Debug.Log($"frameDeltaVector:{frameDeltaVector}, frameDeltaAngle:{frameDeltaAngle}");
// ■テレポート判定(コンポーネント姿勢から判定する)
@@ -1452,6 +1535,8 @@ namespace MagicaCloth2
{
cdata.oldComponentWorldPosition = componentWorldPos;
cdata.oldComponentWorldRotation = componentWorldRot;
oldComponentWorldPosition = componentWorldPos;
oldComponentWorldRotation = componentWorldRot;
cdata.frameWorldPosition = centerWorldPos;
cdata.frameWorldRotation = centerWorldRot;
@@ -1464,8 +1549,7 @@ namespace MagicaCloth2
cdata.nowWorldScale = centerWorldScl;
cdata.oldWorldPosition = centerWorldPos;
cdata.oldWorldRotation = centerWorldRot;
tdata.centerWorldPosition = centerWorldPos;
//tdata.centerWorldPosition = centerWorldPos;
}
else
{
@@ -1475,8 +1559,8 @@ namespace MagicaCloth2
}
// ■ワールド慣性シフト
float3 workOldComponentPosition = cdata.oldComponentWorldPosition;
quaternion workOldComponentRotation = cdata.oldComponentWorldRotation;
float3 workOldComponentPosition = oldComponentWorldPosition;
quaternion workOldComponentRotation = oldComponentWorldRotation;
if (tdata.IsReset)
{
// リセット(なし)
@@ -1485,18 +1569,21 @@ namespace MagicaCloth2
}
else
{
cdata.frameComponentShiftVector = componentWorldPos - cdata.oldComponentWorldPosition;
cdata.frameComponentShiftRotation = MathUtility.FromToRotation(cdata.oldComponentWorldRotation, componentWorldRot);
cdata.frameComponentShiftVector = componentWorldPos - oldComponentWorldPosition;
cdata.frameComponentShiftRotation = MathUtility.FromToRotation(oldComponentWorldRotation, componentWorldRot);
//Debug.Log($"frameComponentShiftVector:{cdata.frameComponentShiftVector}");
float moveShiftRatio = 0.0f;
float rotationShiftRatio = 0.0f;
// ■全体慣性シフト
float movementShift = 1.0f - param.inertiaConstraint.worldInertia; // 同期時は同期先の値が入っている
float rotationShift = 1.0f - param.inertiaConstraint.worldInertia; // 同期時は同期先の値が入っている
// KeepテレポートもしくはCulling時はシフト量100%で実装
bool keep = tdata.IsKeepReset || tdata.IsCullingInvisible;
movementShift = keep ? 1.0f : movementShift;
rotationShift = keep ? 1.0f : rotationShift;
if (movementShift > Define.System.Epsilon || rotationShift > Define.System.Epsilon)
{
// 全体シフトあり
@@ -1530,12 +1617,50 @@ namespace MagicaCloth2
workOldComponentRotation = math.slerp(workOldComponentRotation, componentWorldRot, rotationLimitRatio);
}
// その他の影響
float otherShiftRatio = 0.0f;
// 更新スキップによるシフト
// 更新スキップ時はスキップ時間分ワールド慣性シフトを行う
if (tdata.skipCount > 0)
{
otherShiftRatio = math.lerp(otherShiftRatio, 1.0f, math.saturate((tdata.skipCount * simulationDeltaTime) / (tdata.frameDeltaTime * tdata.nowTimeScale)));
}
// 安定化時間中は慣性を抑える
if (tdata.velocityWeight < 1.0f)
{
otherShiftRatio = math.lerp(otherShiftRatio, 1.0f, 1.0f - tdata.velocityWeight);
}
// タイムスケール
// タイムスケールの影響分ワールド慣性シフトを行う
if (tdata.nowTimeScale < 1.0f)
{
otherShiftRatio = math.lerp(otherShiftRatio, 1.0f, 1.0f - tdata.nowTimeScale);
}
if (otherShiftRatio > 0.0f)
{
tdata.flag.SetBits(Flag_InertiaShift, true);
moveShiftRatio = math.lerp(moveShiftRatio, 1.0f, otherShiftRatio);
workOldComponentPosition = math.lerp(workOldComponentPosition, componentWorldPos, otherShiftRatio);
rotationShiftRatio = math.lerp(rotationShiftRatio, 1.0f, otherShiftRatio);
workOldComponentRotation = math.slerp(workOldComponentRotation, componentWorldRot, otherShiftRatio);
}
// ■慣性シフト最終設定
if (tdata.IsInertiaShift)
{
//Debug.Log($"moveShiftRatio:{moveShiftRatio}, rotationShiftRatio:{rotationShiftRatio}");
cdata.frameComponentShiftVector *= moveShiftRatio;
cdata.frameComponentShiftRotation = math.slerp(quaternion.identity, cdata.frameComponentShiftRotation, rotationShiftRatio);
// アンカーによる打ち消し
cdata.frameComponentShiftVector += anchorDeltaVector;
cdata.frameComponentShiftRotation = math.mul(anchorDeltaRotation, cdata.frameComponentShiftRotation);
cdata.oldFrameWorldPosition = MathUtility.ShiftPosition(cdata.oldFrameWorldPosition, cdata.oldComponentWorldPosition, cdata.frameComponentShiftVector, cdata.frameComponentShiftRotation);
cdata.oldFrameWorldRotation = math.mul(cdata.frameComponentShiftRotation, cdata.oldFrameWorldRotation);
@@ -1552,6 +1677,7 @@ namespace MagicaCloth2
float3 movingVector = componentWorldPos - workOldComponentPosition;
float movingLength = math.length(movingVector);
cdata.frameMovingSpeed = tdata.frameDeltaTime > 0.0f ? movingLength / tdata.frameDeltaTime : 0.0f;
cdata.frameMovingSpeed *= tdata.nowTimeScale > 1e-06f ? 1.0f / tdata.nowTimeScale : 0.0f; // タイムスケール考慮
cdata.frameMovingDirection = movingLength > 1e-06f ? movingVector / movingLength : 0;
//Debug.Log($"frameWorldPosition:{cdata.frameWorldPosition}, framwWorldRotation:{cdata.frameWorldRotation.value}");
@@ -1769,23 +1895,13 @@ namespace MagicaCloth2
cdata.nowWorldRotation = math.normalize(cdata.nowWorldRotation); // 必要
float3 wscl = math.lerp(cdata.oldFrameWorldScale, cdata.frameWorldScale, tdata.frameInterpolation);
cdata.nowWorldScale = wscl;
//cdata.nowLocalToWorldMatrix = MathUtility.LocalToWorldMatrix(cdata.nowWorldPosition, cdata.nowWorldRotation, cdata.nowWorldScale);
// 現在座標はteamDataにもコピーする
tdata.centerWorldPosition = cdata.nowWorldPosition;
// ステップごとの移動量
cdata.stepVector = cdata.nowWorldPosition - cdata.oldWorldPosition;
cdata.stepRotation = MathUtility.FromToRotation(cdata.oldWorldRotation, cdata.nowWorldRotation);
float stepAngle = MathUtility.Angle(cdata.oldWorldRotation, cdata.nowWorldRotation);
// ステップごとの移動速度と回転速度
//float stepMoveSpeed = math.length(cdata.stepVector) / simulationDeltaTime; // 移動速度(m/s)
//float stepAngularVelocity = stepAngle / simulationDeltaTime; // 回転速度(rad/s)
//cdata.angularVelocity = stepAngularVelocity;
// ローカル慣性
//float localInertia = 1.0f - param.inertiaConstraint.localInertia;
float localMovementInertia = 1.0f - param.inertiaConstraint.localInertia;
float localRotationInertia = 1.0f - param.inertiaConstraint.localInertia;
#if true
@@ -1810,7 +1926,7 @@ namespace MagicaCloth2
// 最終慣性
cdata.inertiaVector = math.lerp(float3.zero, cdata.stepVector, localMovementInertia);
cdata.inertiaRotation = math.slerp(quaternion.identity, cdata.stepRotation, localRotationInertia);
//Debug.Log($"Team[{teamId}] stepSpeed:{stepSpeed}, moveInertiaRatio:{moveInertiaRatio}, inertiaVector:{cdata.inertiaVector}, rotationInertiaRatio:{rotationInertiaRatio}");
//Debug.Log($"Team[{teamId}] localMovementInertia:{localMovementInertia}, localRotationInertia:{localRotationInertia}, inertiaVector:{cdata.inertiaVector}, inertiaRotation:{cdata.inertiaRotation}");
// ■遠心力用パラメータ算出
// 今回ステップでの回転速度と回転軸
@@ -1966,8 +2082,16 @@ namespace MagicaCloth2
// 外力クリア
tdata.forceMode = ClothForceMode.None;
tdata.impactForce = 0;
// スキップ
tdata.skipCount = 0;
}
// アンカー
cdata.oldAnchorPosition = cdata.anchorPosition;
cdata.oldAnchorRotation = cdata.anchorRotation;
cdata.anchorComponentLocalPosition = MathUtility.InverseTransformPoint(cdata.componentWorldPosition, cdata.anchorPosition, cdata.anchorRotation, 1);
// フラグリセット
tdata.flag.SetBits(Flag_Reset, false);
tdata.flag.SetBits(Flag_TimeReset, false);
@@ -2099,7 +2223,6 @@ namespace MagicaCloth2
//sb.AppendLine($"ID:{i} [{cprocess.Name}] state:0x{cprocess.GetStateFlag().Value:X}, Flag:0x{tdata.flag.Value:X}, Particle:{tdata.ParticleCount}, Collider:{cprocess.ColliderCapacity} Proxy:{tdata.proxyMeshType}, Mapping:{tdata.MappingCount}");
sb.AppendLine($"ID:{i} [{cprocess.Name}] state:0x{cprocess.GetStateFlag().Value:X}, Flag:0x{tdata.flag.Value:X}, Particle:{tdata.ParticleCount}, Collider:{cprocess.ColliderCapacity} Proxy:{tdata.proxyMeshType}, Mapping:{mappingList.Length}");
sb.AppendLine($" -centerTransformIndex {tdata.centerTransformIndex}");
sb.AppendLine($" -centerWorldPosition {tdata.centerWorldPosition}");
sb.AppendLine($" -initScale {tdata.initScale}");
sb.AppendLine($" -scaleRatio {tdata.scaleRatio}");
sb.AppendLine($" -animationPoseRatio {tdata.animationPoseRatio}");
@@ -2124,16 +2247,11 @@ namespace MagicaCloth2
sb.AppendLine($" -colliderCount {tdata.colliderCount}");
// mapping情報
//var teamMapping = teamMappingIndexArray[i];
//sb.AppendLine($" *Mapping Count {tdata.MappingCount}");
sb.AppendLine($" *Mapping Count {mappingList.Length}");
//if (tdata.MappingCount > 0)
if (mappingList.Length > 0)
{
//for (int j = 0; j < tdata.MappingCount; j++)
for (int j = 0; j < mappingList.Length; j++)
{
//int mid = tdata.mappingDataIndexSet[j];
int mid = mappingList[j];
var mdata = mappingDataArray[mid];
sb.AppendLine($" *Mapping Mid:{mid}, Vertex:{mdata.VertexCount}");