BITFALL/Assets/Plugins/MagicaCloth2/Scripts/Editor/Cloth/ClothEditorUtility.cs

1042 lines
42 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Magica Cloth 2.
// Copyright (c) 2023 MagicaSoft.
// https://magicasoft.jp
using System.Collections.Generic;
using Unity.Collections;
using Unity.Mathematics;
using UnityEditor;
using UnityEngine;
namespace MagicaCloth2
{
/// <summary>
/// クロスコンポーネントのギズモ表示
/// </summary>
public static class ClothEditorUtility
{
public static readonly Color MovePointColor = new Color(0.8f, 0.8f, 0.8f, 0.8f);
//public static readonly Color MovePointColor = Color.white;
public static readonly Color FixedPointColor = new Color(1.0f, 0.0f, 0.0f, 0.8f);
public static readonly Color InvalidPointColor = new Color(0.0f, 0.0f, 0.0f, 0.8f);
public static readonly Color AngleLimitConeColor = new Color(0.0f, 0.349f, 0.725f, 0.325f);
public static readonly Color AngleLimitWireColor = new Color(0.0f, 0.843f, 1.0f, 0.313f);
public static readonly Color BaseTriangleColor = new Color(204 / 255f, 153 / 255f, 255 / 255f);
public static readonly Color BaseLineColor = new Color(153 / 255f, 204 / 255f, 255 / 255f);
public static readonly Color TriangleColor = new Color(1.0f, 0.0f, 0.8f, 1f);
public static readonly Color LineColor = Color.cyan;
public static readonly Color SkininngLine = Color.yellow;
/// <summary>
/// クロスペイント時のギズモ表示設定
/// </summary>
internal static readonly ClothDebugSettings PaintSettings = new ClothDebugSettings()
{
enable = true,
position = false,
collider = false,
//basicShape = true,
animatedShape = true,
};
//=========================================================================================
static List<Vector3> positionBuffer0 = new List<Vector3>(1024);
static List<Vector3> positionBuffer1 = new List<Vector3>(1024);
static List<Vector3> positionBuffer2 = new List<Vector3>(1024);
static List<int> segmentBuffer0 = new List<int>(2048);
static List<int> segmentBuffer1 = new List<int>(2048);
static List<int> segmentBuffer2 = new List<int>(2048);
//=========================================================================================
/// <summary>
/// 編集時のクロスデータの表示すべてHandlesクラスで描画
/// </summary>
/// <param name="editMesh"></param>
/// <param name="drawSettings"></param>
public static void DrawClothEditor(VirtualMesh editMesh, ClothDebugSettings drawSettings, ClothSerializeData serializeData, bool selected, bool direction, bool paint)
{
if (editMesh == null || editMesh.IsSuccess == false)
return;
if (drawSettings.enable == false || serializeData == null)
return;
// シーンカメラ
var scam = SceneView.currentDrawingSceneView?.camera;
if (scam == null)
return;
var crot = scam.transform.rotation;
// 座標空間に合わせる
var t = editMesh.GetCenterTransform();
if (t == null)
return;
Handles.zTest = drawSettings.ztest ? UnityEngine.Rendering.CompareFunction.LessEqual : UnityEngine.Rendering.CompareFunction.Always;
Handles.lighting = true;
Handles.matrix = t.localToWorldMatrix;
// シーンカメラ回転をローカル空間へ変換する
crot = Quaternion.Inverse(t.rotation) * crot;
int vcnt = editMesh.VertexCount;
float worldToLocalScale = 1.0f / t.lossyScale.x;
float drawPointSize = drawSettings.GetPointSize() * worldToLocalScale;
float drawLineSize = drawSettings.GetLineSize() * worldToLocalScale;
float3 cdir = crot * Vector3.forward; // ローカルカメラ方向
float colorScale = selected ? 1.0f : 0.5f;
// position
if (drawSettings.position || drawSettings.animatedPosition)
{
using var pointList = new NativeList<ClothPainter.Point>(vcnt, Allocator.TempJob);
for (int i = 0; i < vcnt; i++)
{
if (drawSettings.CheckParticleDrawing(i) == false)
continue;
var point = new ClothPainter.Point()
{
vindex = i,
};
pointList.AddNoResize(point);
}
if (pointList.Length > 0)
{
// カメラ距離でソート
ClothPainter.CalcPointCameraDistance(editMesh.localPositions.GetNativeArray(), 0, t.localToWorldMatrix, scam.transform.position, pointList);
// 描画
int cnt = pointList.Length;
for (int i = 0; i < cnt; i++)
{
var p = pointList[i];
var attr = editMesh.attributes[p.vindex];
var col = InvalidPointColor;
if (attr.IsFixed()) col = FixedPointColor;
else if (attr.IsMove()) col = MovePointColor;
GizmoUtility.SetColor(col * colorScale, true);
// radius
float depth = editMesh.vertexDepths[p.vindex];
float radius = serializeData.radius.Evaluate(depth);
radius *= worldToLocalScale;
var pos = editMesh.localPositions[p.vindex];
GizmoUtility.DrawSphere(pos, drawSettings.CheckRadiusDrawing() ? radius : drawPointSize, true);
}
}
}
// animated shape / shape
if (drawSettings.animatedShape || drawSettings.shape)
{
positionBuffer0.Clear();
segmentBuffer0.Clear();
for (int i = 0; i < vcnt; i++)
{
positionBuffer0.Add(editMesh.localPositions[i]);
}
GizmoUtility.SetColor(drawSettings.animatedShape ? BaseTriangleColor : TriangleColor, true);
int tcnt = editMesh.TriangleCount;
for (int i = 0; i < tcnt; i++)
{
if (drawSettings.CheckTriangleDrawing(i) == false)
continue;
int3 tri = editMesh.triangles[i];
// 方向性
if (direction)
{
var tn = MathUtility.TriangleNormal(editMesh.localPositions[tri.x], editMesh.localPositions[tri.y], editMesh.localPositions[tri.z]);
if (math.dot(tn, cdir) >= 0.0f)
continue;
}
segmentBuffer0.Add(tri.x);
segmentBuffer0.Add(tri.y);
segmentBuffer0.Add(tri.y);
segmentBuffer0.Add(tri.z);
segmentBuffer0.Add(tri.z);
segmentBuffer0.Add(tri.x);
}
Handles.DrawLines(positionBuffer0.ToArray(), segmentBuffer0.ToArray());
segmentBuffer0.Clear();
GizmoUtility.SetColor((drawSettings.animatedShape ? BaseLineColor : LineColor) * colorScale, true);
int lcnt = editMesh.LineCount;
for (int i = 0; i < lcnt; i++)
{
int2 line = editMesh.lines[i];
segmentBuffer0.Add(line.x);
segmentBuffer0.Add(line.y);
}
Handles.DrawLines(positionBuffer0.ToArray(), segmentBuffer0.ToArray());
}
// base line
if (drawSettings.baseLine && editMesh.BaseLineCount > 0)
{
GizmoUtility.SetColor(new Color(1.0f, 0.27f, 0.0f) * colorScale, true);
int bcnt = editMesh.BaseLineCount;
for (int i = 0; i < bcnt; i++)
{
int dstart = editMesh.baseLineStartDataIndices[i];
int dcnt = editMesh.baseLineDataCounts[i];
for (int j = 1; j < dcnt; j++)
{
int vindex = editMesh.baseLineData[dstart + j];
int pindex = editMesh.vertexParentIndices[vindex];
if (pindex >= 0)
{
var pos = editMesh.localPositions[vindex];
var ppos = editMesh.localPositions[pindex];
GizmoUtility.DrawLine(pos, ppos, true);
}
}
}
}
// axis
if (drawSettings.axis != ClothDebugSettings.DebugAxis.None || drawSettings.animatedAxis != ClothDebugSettings.DebugAxis.None)
{
positionBuffer0.Clear();
positionBuffer1.Clear();
positionBuffer2.Clear();
segmentBuffer0.Clear();
segmentBuffer1.Clear();
segmentBuffer2.Clear();
for (int i = 0; i < vcnt; i++)
{
if (drawSettings.CheckParticleDrawing(i) == false)
continue;
var pos = editMesh.localPositions[i];
var rot = MathUtility.ToRotation(editMesh.localNormals[i], editMesh.localTangents[i]);
// 基準軸の変換用ローカル回転
float len = drawLineSize;
// 基準軸
bool xaxis = false, yaxis = false, zaxis = false;
if (drawSettings.axis == ClothDebugSettings.DebugAxis.Normal || drawSettings.animatedAxis == ClothDebugSettings.DebugAxis.Normal)
{
switch (serializeData.normalAxis)
{
case ClothNormalAxis.Right:
case ClothNormalAxis.InverseRight:
xaxis = true;
break;
case ClothNormalAxis.Up:
case ClothNormalAxis.InverseUp:
yaxis = true;
break;
case ClothNormalAxis.Forward:
case ClothNormalAxis.InverseForward:
zaxis = true;
break;
}
}
if (drawSettings.axis == ClothDebugSettings.DebugAxis.All || drawSettings.animatedAxis == ClothDebugSettings.DebugAxis.All)
{
xaxis = yaxis = zaxis = true;
}
if (xaxis)
{
int index = positionBuffer0.Count;
positionBuffer0.Add(pos);
positionBuffer0.Add(pos + MathUtility.ToBinormal(rot) * len);
segmentBuffer0.Add(index);
segmentBuffer0.Add(index + 1);
}
if (yaxis)
{
int index = positionBuffer1.Count;
positionBuffer1.Add(pos);
positionBuffer1.Add(pos + MathUtility.ToNormal(rot) * len);
segmentBuffer1.Add(index);
segmentBuffer1.Add(index + 1);
}
if (zaxis)
{
int index = positionBuffer2.Count;
positionBuffer2.Add(pos);
positionBuffer2.Add(pos + MathUtility.ToTangent(rot) * len);
segmentBuffer2.Add(index);
segmentBuffer2.Add(index + 1);
}
}
if (positionBuffer0.Count > 0)
{
Handles.color = Color.red * colorScale;
Handles.DrawLines(positionBuffer0.ToArray(), segmentBuffer0.ToArray());
}
if (positionBuffer1.Count > 0)
{
Handles.color = Color.green * colorScale;
Handles.DrawLines(positionBuffer1.ToArray(), segmentBuffer1.ToArray());
}
if (positionBuffer2.Count > 0)
{
Handles.color = Color.blue * colorScale;
Handles.DrawLines(positionBuffer2.ToArray(), segmentBuffer2.ToArray());
}
}
// depth
if (drawSettings.depth)
{
for (int i = 0; i < vcnt; i++)
{
if (drawSettings.CheckParticleDrawing(i) == false)
continue;
var pos = editMesh.localPositions[i];
var depth = editMesh.vertexDepths[i];
if (depth > 0.0f)
Handles.Label(pos, $"{depth:0.##}");
}
}
#if MC2_DEBUG
// number
else if (drawSettings.particleNumber || drawSettings.localNumber)
{
for (int i = 0; i < vcnt; i++)
{
if (drawSettings.CheckParticleDrawing(i) == false)
continue;
var pos = editMesh.localPositions[i];
Handles.Label(pos, i.ToString());
}
}
// attribute
else if (drawSettings.attribute)
{
for (int i = 0; i < vcnt; i++)
{
if (drawSettings.CheckParticleDrawing(i) == false)
continue;
var pos = editMesh.localPositions[i];
var attr = editMesh.attributes[i];
Handles.Label(pos, $"0x{attr.Value:X2}");
}
}
// triangle number
else if (drawSettings.triangleNumber)
{
int tcnt = editMesh.TriangleCount;
for (int i = 0; i < tcnt; i++)
{
if (drawSettings.CheckTriangleDrawing(i) == false)
continue;
int3 tri = editMesh.triangles[i];
var pos1 = editMesh.localPositions[tri.x];
var pos2 = editMesh.localPositions[tri.y];
var pos3 = editMesh.localPositions[tri.z];
var cen = MathUtility.TriangleCenter(pos1, pos2, pos3);
Handles.Label(cen, i.ToString());
}
}
#endif
// inertia center
if (paint == false && editMesh.CenterFixedPointCount > 0)
{
float3 pos = 0;
int ccnt = editMesh.CenterFixedPointCount;
for (int i = 0; i < ccnt; i++)
{
pos += editMesh.localPositions[editMesh.centerFixedList[i]];
}
pos /= ccnt;
GizmoUtility.SetColor(Color.magenta * colorScale, true);
GizmoUtility.DrawSphere(pos, drawSettings.GetInertiaCenterRadius() * worldToLocalScale, true);
}
Handles.matrix = Matrix4x4.identity;
// custom skinning bone
if (paint == false)
{
Handles.color = SkininngLine * colorScale;
var boneList = serializeData.customSkinningSetting.skinningBones;
for (int i = 0; i < boneList.Count - 1; i++)
{
var bone1 = boneList[i];
if (bone1 == null)
continue;
for (int j = i + 1; j < boneList.Count; j++)
{
var bone2 = boneList[j];
if (bone2 == null)
continue;
if (bone1.parent == bone2 || bone2.parent == bone1)
{
Handles.DrawLine(bone1.position, bone2.position);
}
}
}
}
}
/// <summary>
/// 実行時のクロスデータの表示すべてHandlesクラスで描画
/// </summary>
/// <param name="cprocess"></param>
/// <param name="drawSettings"></param>
public static void DrawClothRuntime(ClothProcess cprocess, ClothDebugSettings drawSettings, bool selected)
{
if (cprocess == null || cprocess.IsValid() == false)
return;
if (drawSettings.enable == false)
return;
if (MagicaManager.Team == null)
return;
if (MagicaManager.Team.ContainsTeamData(cprocess.TeamId) == false)
return;
// プロキシメッシュ
var proxyMesh = cprocess.ProxyMesh;
if (proxyMesh == null || proxyMesh.IsSuccess == false)
return;
// シーンカメラ
var scam = SceneView.currentDrawingSceneView?.camera;
if (scam == null)
return;
var crot = scam.transform.rotation;
// チームデータ
var tdata = MagicaManager.Team.GetTeamData(cprocess.TeamId);
var cdata = MagicaManager.Team.centerDataArray[cprocess.TeamId];
int pcnt = tdata.ParticleCount;
int pstart = tdata.particleChunk.startIndex;
int vstart = tdata.proxyCommonChunk.startIndex;
float drawPointSize = drawSettings.GetPointSize();
float drawLineSize = drawSettings.GetLineSize();
// 座標空間に合わせる
var t = cprocess.cloth.ClothTransform;
if (t == null)
return;
Handles.zTest = drawSettings.ztest ? UnityEngine.Rendering.CompareFunction.LessEqual : UnityEngine.Rendering.CompareFunction.Always;
Handles.matrix = Matrix4x4.identity;
float colorScale = selected ? 1 : 0.5f;
var sim = MagicaManager.Simulation;
var vm = MagicaManager.VMesh;
// 座標参照先
var positionArray = drawSettings.IsReferOldPos() ? sim.oldPosArray : sim.dispPosArray;
// position
if (drawSettings.position)
{
using var pointList = new NativeList<ClothPainter.Point>(pcnt, Allocator.TempJob);
for (int i = 0; i < pcnt; i++)
{
if (drawSettings.CheckParticleDrawing(i) == false)
continue;
var point = new ClothPainter.Point()
{
vindex = i,
};
pointList.AddNoResize(point);
}
if (pointList.Length > 0)
{
// カメラ距離でソート
ClothPainter.CalcPointCameraDistance(positionArray.GetNativeArray(), pstart, float4x4.identity, scam.transform.position, pointList);
// 描画
int cnt = pointList.Length;
for (int i = 0; i < cnt; i++)
{
var p = pointList[i];
int pindex = pstart + p.vindex;
int cvindex = tdata.proxyCommonChunk.startIndex + p.vindex;
var attr = vm.attributes[cvindex];
var col = InvalidPointColor;
if (attr.IsFixed()) col = FixedPointColor;
else if (attr.IsMove()) col = MovePointColor;
GizmoUtility.SetColor(col * colorScale, true);
// radius
float depth = vm.vertexDepths[cvindex];
float radius = cprocess.parameters.radiusCurveData.EvaluateCurve(depth);
radius *= tdata.scaleRatio;
var pos = positionArray[pindex];
GizmoUtility.DrawSphere(pos, drawSettings.CheckRadiusDrawing() ? radius : drawPointSize, true);
}
}
}
// rotation axis / area
if (drawSettings.axis != ClothDebugSettings.DebugAxis.None)
{
positionBuffer0.Clear();
positionBuffer1.Clear();
positionBuffer2.Clear();
segmentBuffer0.Clear();
segmentBuffer1.Clear();
segmentBuffer2.Clear();
for (int i = 0; i < pcnt; i++)
{
if (drawSettings.CheckParticleDrawing(i) == false)
continue;
int pindex = pstart + i;
int cvindex = tdata.proxyCommonChunk.startIndex + i;
var pos = positionArray[pindex];
var rot = vm.rotations[cvindex]; // 計算済みの前フレームの最終姿勢
float len = drawLineSize;
// 基準軸
bool xaxis = false, yaxis = false, zaxis = false;
if (drawSettings.axis == ClothDebugSettings.DebugAxis.Normal)
{
switch (cprocess.parameters.normalAxis)
{
case ClothNormalAxis.Right:
case ClothNormalAxis.InverseRight:
xaxis = true;
break;
case ClothNormalAxis.Up:
case ClothNormalAxis.InverseUp:
yaxis = true;
break;
case ClothNormalAxis.Forward:
case ClothNormalAxis.InverseForward:
zaxis = true;
break;
}
}
if (drawSettings.axis == ClothDebugSettings.DebugAxis.All)
{
xaxis = yaxis = zaxis = true;
}
if (xaxis)
{
int index = positionBuffer0.Count;
positionBuffer0.Add(pos);
positionBuffer0.Add(pos + MathUtility.ToBinormal(rot) * len);
segmentBuffer0.Add(index);
segmentBuffer0.Add(index + 1);
}
if (yaxis)
{
int index = positionBuffer1.Count;
positionBuffer1.Add(pos);
positionBuffer1.Add(pos + MathUtility.ToNormal(rot) * len);
segmentBuffer1.Add(index);
segmentBuffer1.Add(index + 1);
}
if (zaxis)
{
int index = positionBuffer2.Count;
positionBuffer2.Add(pos);
positionBuffer2.Add(pos + MathUtility.ToTangent(rot) * len);
segmentBuffer2.Add(index);
segmentBuffer2.Add(index + 1);
}
}
if (positionBuffer0.Count > 0)
{
Handles.color = Color.red * colorScale;
Handles.DrawLines(positionBuffer0.ToArray(), segmentBuffer0.ToArray());
}
if (positionBuffer1.Count > 0)
{
Handles.color = Color.green * colorScale;
Handles.DrawLines(positionBuffer1.ToArray(), segmentBuffer1.ToArray());
}
if (positionBuffer2.Count > 0)
{
Handles.color = Color.blue * colorScale;
Handles.DrawLines(positionBuffer2.ToArray(), segmentBuffer2.ToArray());
}
}
#if MC2_DEBUG
// collision normal
if (drawSettings.collisionNormal)
{
GizmoUtility.SetColor(Color.yellow * colorScale, true);
for (int i = 0; i < pcnt; i++)
{
if (drawSettings.CheckParticleDrawing(i) == false)
continue;
int pindex = pstart + i;
var pos = positionArray[pindex];
float3 cn = sim.collisionNormalArray[pindex];
if (math.lengthsq(cn) > 1e-06f)
{
GizmoUtility.DrawLine(pos, pos + cn * drawPointSize, true);
}
}
}
#endif
// animated shape
if (drawSettings.animatedShape)
{
positionBuffer0.Clear();
segmentBuffer0.Clear();
for (int i = 0; i < pcnt; i++)
{
positionBuffer0.Add(sim.basePosArray[pstart + i]);
//positionBuffer0.Add(sim.stepBasicPositionBuffer[pstart + i]);
}
GizmoUtility.SetColor(BaseTriangleColor, true);
int tcnt = tdata.proxyTriangleChunk.dataLength;
for (int i = 0; i < tcnt; i++)
{
if (drawSettings.CheckTriangleDrawing(i) == false)
continue;
int tindex = tdata.proxyTriangleChunk.startIndex + i;
int3 tri = vm.triangles[tindex];
//int3 vtri = tri + tdata.proxyCommonChunk.startIndex;
//if (vm.attributes[vtri.x].IsInvalid() || vm.attributes[vtri.y].IsInvalid() || vm.attributes[vtri.z].IsInvalid())
// continue;
segmentBuffer0.Add(tri.x);
segmentBuffer0.Add(tri.y);
segmentBuffer0.Add(tri.y);
segmentBuffer0.Add(tri.z);
segmentBuffer0.Add(tri.z);
segmentBuffer0.Add(tri.x);
}
Handles.DrawLines(positionBuffer0.ToArray(), segmentBuffer0.ToArray());
segmentBuffer0.Clear();
GizmoUtility.SetColor(BaseLineColor * colorScale, true);
int lcnt = proxyMesh.LineCount;
for (int i = 0; i < lcnt; i++)
{
int2 line = proxyMesh.lines[i];
segmentBuffer0.Add(line.x);
segmentBuffer0.Add(line.y);
}
Handles.DrawLines(positionBuffer0.ToArray(), segmentBuffer0.ToArray());
}
// shape
if (drawSettings.shape)
{
positionBuffer0.Clear();
segmentBuffer0.Clear();
for (int i = 0; i < pcnt; i++)
{
positionBuffer0.Add(positionArray[pstart + i]);
}
GizmoUtility.SetColor(TriangleColor * colorScale, true);
int tcnt = tdata.proxyTriangleChunk.dataLength;
for (int i = 0; i < tcnt; i++)
{
if (drawSettings.CheckTriangleDrawing(i) == false)
continue;
int tindex = tdata.proxyTriangleChunk.startIndex + i;
int3 tri = vm.triangles[tindex];
segmentBuffer0.Add(tri.x);
segmentBuffer0.Add(tri.y);
segmentBuffer0.Add(tri.y);
segmentBuffer0.Add(tri.z);
segmentBuffer0.Add(tri.z);
segmentBuffer0.Add(tri.x);
}
Handles.DrawLines(positionBuffer0.ToArray(), segmentBuffer0.ToArray());
segmentBuffer0.Clear();
GizmoUtility.SetColor(LineColor * colorScale, true);
int lcnt = proxyMesh.LineCount;
for (int i = 0; i < lcnt; i++)
{
int2 line = proxyMesh.lines[i];
segmentBuffer0.Add(line.x);
segmentBuffer0.Add(line.y);
}
Handles.DrawLines(positionBuffer0.ToArray(), segmentBuffer0.ToArray());
}
// base line
if (drawSettings.baseLine && proxyMesh.BaseLineCount > 0)
{
GizmoUtility.SetColor(new Color(1.0f, 0.27f, 0.0f) * colorScale, true);
int bcnt = proxyMesh.BaseLineCount;
for (int i = 0; i < bcnt; i++)
{
int dstart = proxyMesh.baseLineStartDataIndices[i];
int dcnt = proxyMesh.baseLineDataCounts[i];
for (int j = 1; j < dcnt; j++)
{
int vindex = proxyMesh.baseLineData[dstart + j];
int pindex = proxyMesh.vertexParentIndices[vindex];
if (pindex >= 0)
{
var pos = positionArray[pstart + vindex];
var ppos = positionArray[pstart + pindex];
GizmoUtility.DrawLine(pos, ppos, true);
}
}
}
}
// animated position
if (drawSettings.animatedPosition)
{
for (int i = 0; i < pcnt; i++)
{
if (drawSettings.CheckParticleDrawing(i) == false)
continue;
int pindex = tdata.particleChunk.startIndex + i;
//int cvindex = tdata.proxyCommonChunk.startIndex + i;
//var attr = vm.attributes[cvindex];
//if (attr.IsInvalid())
// continue;
var pos = sim.basePosArray[pindex];
//var pos = sim.stepBasicPositionBuffer[pindex];
GizmoUtility.SetColor(Color.cyan * colorScale, true);
GizmoUtility.DrawSphere(pos, drawPointSize, true);
}
}
// animated axis
if (drawSettings.animatedAxis != ClothDebugSettings.DebugAxis.None)
{
float size = drawLineSize;
positionBuffer0.Clear();
positionBuffer1.Clear();
positionBuffer2.Clear();
segmentBuffer0.Clear();
segmentBuffer1.Clear();
segmentBuffer2.Clear();
for (int i = 0; i < pcnt; i++)
{
if (drawSettings.CheckParticleDrawing(i) == false)
continue;
int pindex = tdata.particleChunk.startIndex + i;
int cvindex = tdata.proxyCommonChunk.startIndex + i;
//var attr = vm.attributes[cvindex];
//if (attr.IsInvalid())
// continue;
var pos = sim.basePosArray[pindex];
var rot = sim.baseRotArray[pindex];
//var pos = sim.stepBasicPositionBuffer[pindex];
//var rot = sim.stepBasicRotationBuffer[pindex];
// 基準軸
bool xaxis = false, yaxis = false, zaxis = false;
if (drawSettings.animatedAxis == ClothDebugSettings.DebugAxis.Normal)
{
switch (cprocess.parameters.normalAxis)
{
case ClothNormalAxis.Right:
case ClothNormalAxis.InverseRight:
xaxis = true;
break;
case ClothNormalAxis.Up:
case ClothNormalAxis.InverseUp:
yaxis = true;
break;
case ClothNormalAxis.Forward:
case ClothNormalAxis.InverseForward:
zaxis = true;
break;
}
}
if (drawSettings.animatedAxis == ClothDebugSettings.DebugAxis.All)
{
xaxis = yaxis = zaxis = true;
}
if (xaxis)
{
int index = positionBuffer0.Count;
positionBuffer0.Add(pos);
positionBuffer0.Add(pos + MathUtility.ToBinormal(rot) * size);
segmentBuffer0.Add(index);
segmentBuffer0.Add(index + 1);
}
if (yaxis)
{
int index = positionBuffer1.Count;
positionBuffer1.Add(pos);
positionBuffer1.Add(pos + MathUtility.ToNormal(rot) * size);
segmentBuffer1.Add(index);
segmentBuffer1.Add(index + 1);
}
if (zaxis)
{
int index = positionBuffer2.Count;
positionBuffer2.Add(pos);
positionBuffer2.Add(pos + MathUtility.ToTangent(rot) * size);
segmentBuffer2.Add(index);
segmentBuffer2.Add(index + 1);
}
}
if (positionBuffer0.Count > 0)
{
Handles.color = Color.red * colorScale;
Handles.DrawLines(positionBuffer0.ToArray(), segmentBuffer0.ToArray());
}
if (positionBuffer1.Count > 0)
{
Handles.color = Color.green * colorScale;
Handles.DrawLines(positionBuffer1.ToArray(), segmentBuffer1.ToArray());
}
if (positionBuffer2.Count > 0)
{
Handles.color = Color.blue * colorScale;
Handles.DrawLines(positionBuffer2.ToArray(), segmentBuffer2.ToArray());
}
}
#if false
// distance constraint
//for (int k = 0; k < DistanceConstraint.TypeCount; k++)
{
//bool drawFlag = false;
//switch (k)
//{
// case DistanceConstraint.Type_Vertical: drawFlag = drawSettings.verticalDistanceConstraint; break;
// case DistanceConstraint.Type_Horizontal: drawFlag = drawSettings.horizontalDistanceConstraint; break;
//}
//if (drawFlag == false)
// continue;
var distanceConstraint = sim.distanceConstraint;
//var nData = distanceConstraint.nativeData[k];
var sc = tdata.distanceStartChunk;
var dc = tdata.distanceDataChunk;
if (sc.IsValid)
{
//var col = Color.black;
//switch (k)
//{
// case DistanceConstraint.Type_Vertical:
// col = Color.yellow;
// break;
// case DistanceConstraint.Type_Horizontal:
// col = Color.red;
// break;
//}
//GizmoUtility.SetColor(col * colorScale, true);
positionBuffer0.Clear();
segmentBuffer0.Clear();
for (int i = 0; i < pcnt; i++)
{
positionBuffer0.Add(positionArray[pstart + i]);
}
for (int i = 0; i < pcnt; i++)
{
if (drawSettings.CheckParticleDrawing(i) == false)
continue;
int cindex = sc.startIndex + i;
var pack = distanceConstraint.indexArray[cindex];
DataUtility.Unpack10_22(pack, out int dcnt, out int dstart);
if (dcnt > 0)
{
for (int j = 0; j < dcnt; j++)
{
int targetIndex = distanceConstraint.dataArray[dc.startIndex + dstart + j];
segmentBuffer0.Add(i);
segmentBuffer0.Add(targetIndex);
}
}
}
Handles.DrawLines(positionBuffer0.ToArray(), segmentBuffer0.ToArray());
}
}
#endif
// depth
if (drawSettings.depth)
{
for (int i = 0; i < pcnt; i++)
{
if (drawSettings.CheckParticleDrawing(i) == false)
continue;
int pindex = tdata.particleChunk.startIndex + i;
int cvindex = tdata.proxyCommonChunk.startIndex + i;
var pos = positionArray[pindex];
var depth = vm.vertexDepths[cvindex];
Handles.Label(pos, $"{depth:0.##}");
}
}
#if MC2_DEBUG
// number
else if (drawSettings.particleNumber || drawSettings.localNumber)
{
for (int i = 0; i < pcnt; i++)
{
//if (drawSettings.CheckParticleDrawing(i) == false)
// continue;
int pindex = tdata.particleChunk.startIndex + i;
var pos = positionArray[pindex];
if (drawSettings.particleNumber && drawSettings.CheckParticleDrawing(pindex))
Handles.Label(pos, pindex.ToString());
else if (drawSettings.localNumber && drawSettings.CheckParticleDrawing(i))
Handles.Label(pos, i.ToString());
}
}
// attribute
else if (drawSettings.attribute)
{
for (int i = 0; i < pcnt; i++)
{
if (drawSettings.CheckParticleDrawing(i) == false)
continue;
int pindex = tdata.particleChunk.startIndex + i;
int cvindex = tdata.proxyCommonChunk.startIndex + i;
var pos = positionArray[pindex];
var attr = vm.attributes[cvindex];
Handles.Label(pos, $"0x{attr.Value:X2}");
}
}
// friction
else if (drawSettings.friction)
{
for (int i = 0; i < pcnt; i++)
{
if (drawSettings.CheckParticleDrawing(i) == false)
continue;
int pindex = tdata.particleChunk.startIndex + i;
int cvindex = tdata.proxyCommonChunk.startIndex + i;
var pos = positionArray[pindex];
var friction = sim.frictionArray[pindex];
if (friction > 1e-06f)
Handles.Label(pos, $"{friction:0.##}");
}
}
// static friction
else if (drawSettings.staticFriction)
{
for (int i = 0; i < pcnt; i++)
{
if (drawSettings.CheckParticleDrawing(i) == false)
continue;
int pindex = tdata.particleChunk.startIndex + i;
int cvindex = tdata.proxyCommonChunk.startIndex + i;
var pos = positionArray[pindex];
var friction = sim.staticFrictionArray[pindex];
if (friction > 1e-06f)
Handles.Label(pos, $"{friction:0.##}");
}
}
// triangle number
else if (drawSettings.triangleNumber)
{
int tcnt = tdata.proxyTriangleChunk.dataLength;
for (int i = 0; i < tcnt; i++)
{
if (drawSettings.CheckTriangleDrawing(i) == false)
continue;
int tindex = tdata.proxyTriangleChunk.startIndex + i;
int3 tri = vm.triangles[tindex];
var pos1 = positionArray[pstart + tri.x];
var pos2 = positionArray[pstart + tri.y];
var pos3 = positionArray[pstart + tri.z];
var cen = MathUtility.TriangleCenter(pos1, pos2, pos3);
Handles.Label(cen, i.ToString());
}
}
#endif
// 空間を戻す
Handles.matrix = Matrix4x4.identity;
// 以下はワールド
// custom skinning bone
{
Handles.color = SkininngLine * colorScale;
var boneList = cprocess.cloth.SerializeData.customSkinningSetting.skinningBones;
for (int i = 0; i < boneList.Count - 1; i++)
{
var bone1 = boneList[i];
if (bone1 == null)
continue;
for (int j = i + 1; j < boneList.Count; j++)
{
var bone2 = boneList[j];
if (bone2 == null)
continue;
if (bone1.parent == bone2 || bone2.parent == bone1)
{
Handles.DrawLine(bone1.position, bone2.position);
}
}
}
}
// inertia center
{
var pos = cdata.nowWorldPosition;
var rot = cdata.nowWorldRotation;
GizmoUtility.SetColor(Color.magenta * colorScale, true);
GizmoUtility.DrawSphere(pos, drawSettings.GetInertiaCenterRadius(), true);
GizmoUtility.DrawCross(pos, rot, drawSettings.GetInertiaCenterRadius() * 2.0f, true);
}
#if MC2_DEBUG
// cell cube
//if (drawSettings.cellCube)
//{
// GizmoUtility.SetColor(Color.black * colorScale, true);
// GizmoUtility.DrawWireCube(tdata.cubeWorldCenter, Quaternion.identity, Vector3.one * tdata.cubeSize, true);
//}
#endif
}
}
}