From 777cd5ea3fcde4add3edd215cfe25b74afcaba30 Mon Sep 17 00:00:00 2001 From: ww-rm Date: Sun, 13 Apr 2025 00:19:02 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=83=A8=E5=88=86=E8=B0=83?= =?UTF-8?q?=E8=AF=95=E6=B8=B2=E6=9F=93=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SpineViewer/Controls/SpinePreviewPanel.cs | 4 +- .../SpineObject/SpineObject21.cs | 154 ++++++++++++++- .../SpineObject/SpineObject36.cs | 183 ++++++++++++++++- .../SpineObject/SpineObject37.cs | 183 ++++++++++++++++- .../SpineObject/SpineObject38.cs | 185 +++++++++++++++++- .../SpineObject/SpineObject40.cs | 185 +++++++++++++++++- .../SpineObject/SpineObject41.cs | 185 +++++++++++++++++- .../SpineObject/Spineobject42.cs | 185 +++++++++++++++++- SpineViewer/Spine/SpineObject.cs | 91 ++++++++- .../Spine/SpineView/SpineDebugProperty.cs | 42 +++- 10 files changed, 1314 insertions(+), 83 deletions(-) diff --git a/SpineViewer/Controls/SpinePreviewPanel.cs b/SpineViewer/Controls/SpinePreviewPanel.cs index 9214275..829a298 100644 --- a/SpineViewer/Controls/SpinePreviewPanel.cs +++ b/SpineViewer/Controls/SpinePreviewPanel.cs @@ -389,9 +389,9 @@ namespace SpineViewer.Controls if (RenderSelectedOnly && !spine.IsSelected) continue; - spine.IsDebug = true; + spine.EnableDebug = true; renderWindow.Draw(spine); - spine.IsDebug = false; + spine.EnableDebug = false; } } } diff --git a/SpineViewer/Spine/Implementations/SpineObject/SpineObject21.cs b/SpineViewer/Spine/Implementations/SpineObject/SpineObject21.cs index a666056..509bf11 100644 --- a/SpineViewer/Spine/Implementations/SpineObject/SpineObject21.cs +++ b/SpineViewer/Spine/Implementations/SpineObject/SpineObject21.cs @@ -381,18 +381,152 @@ namespace SpineViewer.Spine.Implementations.SpineObject lineVertices.Clear(); rectLineVertices.Clear(); - // 调试包围盒 - if (debugBounds) + if (debugRegions) { - var b = bounds; - var v = new SFML.Graphics.Vertex() { Color = BoundsColor }; - v.Position = new(b.Left, b.Top); lineVertices.Append(v); - v.Position = new(b.Right, b.Top); lineVertices.Append(v); lineVertices.Append(v); - v.Position = new(b.Right, b.Bottom); lineVertices.Append(v); lineVertices.Append(v); - v.Position = new(b.Left, b.Bottom); lineVertices.Append(v); lineVertices.Append(v); - v.Position = new(b.Left, b.Top); lineVertices.Append(v); + SFML.Graphics.Vertex vt = new() { Color = AttachmentLineColor }; + foreach (var slot in skeleton.Slots) + { + if (slot.Attachment is RegionAttachment regionAttachment) + { + regionAttachment.ComputeWorldVertices(slot.Bone, worldVerticesBuffer); + + vt.Position.X = worldVerticesBuffer[0]; + vt.Position.Y = worldVerticesBuffer[1]; + lineVertices.Append(vt); + + vt.Position.X = worldVerticesBuffer[2]; + vt.Position.Y = worldVerticesBuffer[3]; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = worldVerticesBuffer[4]; + vt.Position.Y = worldVerticesBuffer[5]; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = worldVerticesBuffer[6]; + vt.Position.Y = worldVerticesBuffer[7]; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = worldVerticesBuffer[0]; + vt.Position.Y = worldVerticesBuffer[1]; + lineVertices.Append(vt); + } + } } + if (debugMeshes) + { + SFML.Graphics.Vertex vt = new() { Color = MeshLineColor }; + foreach (var slot in skeleton.Slots) + { + if (slot.Attachment is MeshAttachment meshAttachment) + { + if (meshAttachment.Vertices.Length > worldVerticesBuffer.Length) + worldVerticesBuffer = new float[meshAttachment.Vertices.Length * 2]; + + meshAttachment.ComputeWorldVertices(slot, worldVerticesBuffer); + + var triangleIndices = meshAttachment.Triangles; + for (int i = 0; i < triangleIndices.Length; i += 3) + { + var idx0 = triangleIndices[i] * 2; + var idx1 = triangleIndices[i + 1] * 2; + var idx2 = triangleIndices[i + 2] * 2; + + vt.Position.X = worldVerticesBuffer[idx0]; + vt.Position.Y = worldVerticesBuffer[idx0 + 1]; + lineVertices.Append(vt); + + vt.Position.X = worldVerticesBuffer[idx1]; + vt.Position.Y = worldVerticesBuffer[idx1 + 1]; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = worldVerticesBuffer[idx2]; + vt.Position.Y = worldVerticesBuffer[idx2 + 1]; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = worldVerticesBuffer[idx0]; + vt.Position.Y = worldVerticesBuffer[idx0 + 1]; + lineVertices.Append(vt); + } + } + } + } + + if (debugMeshHulls) + { + SFML.Graphics.Vertex vt = new() { Color = AttachmentLineColor }; + foreach (var slot in skeleton.Slots) + { + if (slot.Attachment is MeshAttachment meshAttachment) + { + if (meshAttachment.Vertices.Length > worldVerticesBuffer.Length) + worldVerticesBuffer = new float[meshAttachment.Vertices.Length * 2]; + + meshAttachment.ComputeWorldVertices(slot, worldVerticesBuffer); + + var hullLength = (meshAttachment.HullLength >> 1) << 1; + + if (debugMeshHulls && hullLength > 2) + { + vt.Position.X = worldVerticesBuffer[0]; + vt.Position.Y = worldVerticesBuffer[1]; + lineVertices.Append(vt); + + for (int i = 2; i < hullLength; i += 2) + { + vt.Position.X = worldVerticesBuffer[i]; + vt.Position.Y = worldVerticesBuffer[i + 1]; + lineVertices.Append(vt); + lineVertices.Append(vt); + } + + vt.Position.X = worldVerticesBuffer[0]; + vt.Position.Y = worldVerticesBuffer[1]; + lineVertices.Append(vt); + } + } + } + } + + if (debugBoundingBoxes) + { + throw new NotImplementedException(); + } + + if (debugPaths) + { + throw new NotImplementedException(); + } + + if (debugClippings) { } // 没有剪裁附件 + + if (debugBounds) + { + var vt = new SFML.Graphics.Vertex() { Color = BoundsColor }; + var b = bounds; + + vt.Position.X = b.Left; + vt.Position.Y = b.Top; + lineVertices.Append(vt); + + vt.Position.X = b.Right; + vt.Position.Y = b.Top; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = b.Right; + vt.Position.Y = b.Bottom; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = b.Left; + vt.Position.Y = b.Bottom; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = b.Left; + vt.Position.Y = b.Top; + lineVertices.Append(vt); + } + + // 骨骼线放最后画 if (debugBones) { var width = scale; @@ -408,7 +542,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject target.Draw(lineVertices); target.Draw(rectLineVertices); - // 骨骼的点最后画, 层级处于上面 + // 骨骼的点最后画, 层级处于骨骼线上面 if (debugBones) { var radius = scale; diff --git a/SpineViewer/Spine/Implementations/SpineObject/SpineObject36.cs b/SpineViewer/Spine/Implementations/SpineObject/SpineObject36.cs index 94550cf..b33ccae 100644 --- a/SpineViewer/Spine/Implementations/SpineObject/SpineObject36.cs +++ b/SpineViewer/Spine/Implementations/SpineObject/SpineObject36.cs @@ -338,18 +338,181 @@ namespace SpineViewer.Spine.Implementations.SpineObject lineVertices.Clear(); rectLineVertices.Clear(); - // 调试包围盒 - if (debugBounds) + if (debugRegions) { - var b = bounds; - var v = new SFML.Graphics.Vertex() { Color = BoundsColor }; - v.Position = new(b.Left, b.Top); lineVertices.Append(v); - v.Position = new(b.Right, b.Top); lineVertices.Append(v); lineVertices.Append(v); - v.Position = new(b.Right, b.Bottom); lineVertices.Append(v); lineVertices.Append(v); - v.Position = new(b.Left, b.Bottom); lineVertices.Append(v); lineVertices.Append(v); - v.Position = new(b.Left, b.Top); lineVertices.Append(v); + SFML.Graphics.Vertex vt = new() { Color = AttachmentLineColor }; + foreach (var slot in skeleton.Slots) + { + if (slot.Attachment is RegionAttachment regionAttachment) + { + regionAttachment.ComputeWorldVertices(slot.Bone, worldVerticesBuffer, 0); + + vt.Position.X = worldVerticesBuffer[0]; + vt.Position.Y = worldVerticesBuffer[1]; + lineVertices.Append(vt); + + vt.Position.X = worldVerticesBuffer[2]; + vt.Position.Y = worldVerticesBuffer[3]; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = worldVerticesBuffer[4]; + vt.Position.Y = worldVerticesBuffer[5]; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = worldVerticesBuffer[6]; + vt.Position.Y = worldVerticesBuffer[7]; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = worldVerticesBuffer[0]; + vt.Position.Y = worldVerticesBuffer[1]; + lineVertices.Append(vt); + } + } } + if (debugMeshes) + { + SFML.Graphics.Vertex vt = new() { Color = MeshLineColor }; + foreach (var slot in skeleton.Slots) + { + if (slot.Attachment is MeshAttachment meshAttachment) + { + if (meshAttachment.WorldVerticesLength > worldVerticesBuffer.Length) + worldVerticesBuffer = new float[meshAttachment.WorldVerticesLength * 2]; + + meshAttachment.ComputeWorldVertices(slot, worldVerticesBuffer); + + var triangleIndices = meshAttachment.Triangles; + for (int i = 0; i < triangleIndices.Length; i += 3) + { + var idx0 = triangleIndices[i] * 2; + var idx1 = triangleIndices[i + 1] * 2; + var idx2 = triangleIndices[i + 2] * 2; + + vt.Position.X = worldVerticesBuffer[idx0]; + vt.Position.Y = worldVerticesBuffer[idx0 + 1]; + lineVertices.Append(vt); + + vt.Position.X = worldVerticesBuffer[idx1]; + vt.Position.Y = worldVerticesBuffer[idx1 + 1]; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = worldVerticesBuffer[idx2]; + vt.Position.Y = worldVerticesBuffer[idx2 + 1]; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = worldVerticesBuffer[idx0]; + vt.Position.Y = worldVerticesBuffer[idx0 + 1]; + lineVertices.Append(vt); + } + } + } + } + + if (debugMeshHulls) + { + SFML.Graphics.Vertex vt = new() { Color = AttachmentLineColor }; + foreach (var slot in skeleton.Slots) + { + if (slot.Attachment is MeshAttachment meshAttachment) + { + if (meshAttachment.WorldVerticesLength > worldVerticesBuffer.Length) + worldVerticesBuffer = new float[meshAttachment.WorldVerticesLength * 2]; + + meshAttachment.ComputeWorldVertices(slot, worldVerticesBuffer); + + var hullLength = (meshAttachment.HullLength >> 1) << 1; + + if (debugMeshHulls && hullLength > 2) + { + vt.Position.X = worldVerticesBuffer[0]; + vt.Position.Y = worldVerticesBuffer[1]; + lineVertices.Append(vt); + + for (int i = 2; i < hullLength; i += 2) + { + vt.Position.X = worldVerticesBuffer[i]; + vt.Position.Y = worldVerticesBuffer[i + 1]; + lineVertices.Append(vt); + lineVertices.Append(vt); + } + + vt.Position.X = worldVerticesBuffer[0]; + vt.Position.Y = worldVerticesBuffer[1]; + lineVertices.Append(vt); + } + } + } + } + + if (debugBoundingBoxes) + { + throw new NotImplementedException(); + } + + if (debugPaths) + { + throw new NotImplementedException(); + } + + if (debugClippings) + { + SFML.Graphics.Vertex vt = new() { Color = ClippingLineColor }; + foreach (var slot in skeleton.Slots) + { + if (slot.Attachment is ClippingAttachment clippingAttachment) + { + if (clippingAttachment.WorldVerticesLength > worldVerticesBuffer.Length) + worldVerticesBuffer = worldVerticesBuffer = new float[clippingAttachment.WorldVerticesLength * 2]; + + clippingAttachment.ComputeWorldVertices(slot, worldVerticesBuffer); + + vt.Position.X = worldVerticesBuffer[0]; + vt.Position.Y = worldVerticesBuffer[1]; + lineVertices.Append(vt); + + for (int i = 2; i < clippingAttachment.WorldVerticesLength; i += 2) + { + vt.Position.X = worldVerticesBuffer[i]; + vt.Position.Y = worldVerticesBuffer[i + 1]; + lineVertices.Append(vt); + lineVertices.Append(vt); + } + + vt.Position.X = worldVerticesBuffer[0]; + vt.Position.Y = worldVerticesBuffer[1]; + lineVertices.Append(vt); + } + } + } + + if (debugBounds) + { + var vt = new SFML.Graphics.Vertex() { Color = BoundsColor }; + var b = bounds; + + vt.Position.X = b.Left; + vt.Position.Y = b.Top; + lineVertices.Append(vt); + + vt.Position.X = b.Right; + vt.Position.Y = b.Top; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = b.Right; + vt.Position.Y = b.Bottom; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = b.Left; + vt.Position.Y = b.Bottom; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = b.Left; + vt.Position.Y = b.Top; + lineVertices.Append(vt); + } + + // 骨骼线放最后画 if (debugBones) { var width = scale; @@ -365,7 +528,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject target.Draw(lineVertices); target.Draw(rectLineVertices); - // 骨骼的点最后画, 层级处于上面 + // 骨骼的点最后画, 层级处于骨骼线上面 if (debugBones) { var radius = scale; diff --git a/SpineViewer/Spine/Implementations/SpineObject/SpineObject37.cs b/SpineViewer/Spine/Implementations/SpineObject/SpineObject37.cs index 0ac774b..3538fcb 100644 --- a/SpineViewer/Spine/Implementations/SpineObject/SpineObject37.cs +++ b/SpineViewer/Spine/Implementations/SpineObject/SpineObject37.cs @@ -310,18 +310,181 @@ namespace SpineViewer.Spine.Implementations.SpineObject lineVertices.Clear(); rectLineVertices.Clear(); - // 调试包围盒 - if (debugBounds) + if (debugRegions) { - var b = bounds; - var v = new SFML.Graphics.Vertex() { Color = BoundsColor }; - v.Position = new(b.Left, b.Top); lineVertices.Append(v); - v.Position = new(b.Right, b.Top); lineVertices.Append(v); lineVertices.Append(v); - v.Position = new(b.Right, b.Bottom); lineVertices.Append(v); lineVertices.Append(v); - v.Position = new(b.Left, b.Bottom); lineVertices.Append(v); lineVertices.Append(v); - v.Position = new(b.Left, b.Top); lineVertices.Append(v); + SFML.Graphics.Vertex vt = new() { Color = AttachmentLineColor }; + foreach (var slot in skeleton.Slots) + { + if (slot.Attachment is RegionAttachment regionAttachment) + { + regionAttachment.ComputeWorldVertices(slot.Bone, worldVerticesBuffer, 0); + + vt.Position.X = worldVerticesBuffer[0]; + vt.Position.Y = worldVerticesBuffer[1]; + lineVertices.Append(vt); + + vt.Position.X = worldVerticesBuffer[2]; + vt.Position.Y = worldVerticesBuffer[3]; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = worldVerticesBuffer[4]; + vt.Position.Y = worldVerticesBuffer[5]; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = worldVerticesBuffer[6]; + vt.Position.Y = worldVerticesBuffer[7]; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = worldVerticesBuffer[0]; + vt.Position.Y = worldVerticesBuffer[1]; + lineVertices.Append(vt); + } + } } + if (debugMeshes) + { + SFML.Graphics.Vertex vt = new() { Color = MeshLineColor }; + foreach (var slot in skeleton.Slots) + { + if (slot.Attachment is MeshAttachment meshAttachment) + { + if (meshAttachment.WorldVerticesLength > worldVerticesBuffer.Length) + worldVerticesBuffer = new float[meshAttachment.WorldVerticesLength * 2]; + + meshAttachment.ComputeWorldVertices(slot, worldVerticesBuffer); + + var triangleIndices = meshAttachment.Triangles; + for (int i = 0; i < triangleIndices.Length; i += 3) + { + var idx0 = triangleIndices[i] * 2; + var idx1 = triangleIndices[i + 1] * 2; + var idx2 = triangleIndices[i + 2] * 2; + + vt.Position.X = worldVerticesBuffer[idx0]; + vt.Position.Y = worldVerticesBuffer[idx0 + 1]; + lineVertices.Append(vt); + + vt.Position.X = worldVerticesBuffer[idx1]; + vt.Position.Y = worldVerticesBuffer[idx1 + 1]; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = worldVerticesBuffer[idx2]; + vt.Position.Y = worldVerticesBuffer[idx2 + 1]; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = worldVerticesBuffer[idx0]; + vt.Position.Y = worldVerticesBuffer[idx0 + 1]; + lineVertices.Append(vt); + } + } + } + } + + if (debugMeshHulls) + { + SFML.Graphics.Vertex vt = new() { Color = AttachmentLineColor }; + foreach (var slot in skeleton.Slots) + { + if (slot.Attachment is MeshAttachment meshAttachment) + { + if (meshAttachment.WorldVerticesLength > worldVerticesBuffer.Length) + worldVerticesBuffer = new float[meshAttachment.WorldVerticesLength * 2]; + + meshAttachment.ComputeWorldVertices(slot, worldVerticesBuffer); + + var hullLength = (meshAttachment.HullLength >> 1) << 1; + + if (debugMeshHulls && hullLength > 2) + { + vt.Position.X = worldVerticesBuffer[0]; + vt.Position.Y = worldVerticesBuffer[1]; + lineVertices.Append(vt); + + for (int i = 2; i < hullLength; i += 2) + { + vt.Position.X = worldVerticesBuffer[i]; + vt.Position.Y = worldVerticesBuffer[i + 1]; + lineVertices.Append(vt); + lineVertices.Append(vt); + } + + vt.Position.X = worldVerticesBuffer[0]; + vt.Position.Y = worldVerticesBuffer[1]; + lineVertices.Append(vt); + } + } + } + } + + if (debugBoundingBoxes) + { + throw new NotImplementedException(); + } + + if (debugPaths) + { + throw new NotImplementedException(); + } + + if (debugClippings) + { + SFML.Graphics.Vertex vt = new() { Color = ClippingLineColor }; + foreach (var slot in skeleton.Slots) + { + if (slot.Attachment is ClippingAttachment clippingAttachment) + { + if (clippingAttachment.WorldVerticesLength > worldVerticesBuffer.Length) + worldVerticesBuffer = worldVerticesBuffer = new float[clippingAttachment.WorldVerticesLength * 2]; + + clippingAttachment.ComputeWorldVertices(slot, worldVerticesBuffer); + + vt.Position.X = worldVerticesBuffer[0]; + vt.Position.Y = worldVerticesBuffer[1]; + lineVertices.Append(vt); + + for (int i = 2; i < clippingAttachment.WorldVerticesLength; i += 2) + { + vt.Position.X = worldVerticesBuffer[i]; + vt.Position.Y = worldVerticesBuffer[i + 1]; + lineVertices.Append(vt); + lineVertices.Append(vt); + } + + vt.Position.X = worldVerticesBuffer[0]; + vt.Position.Y = worldVerticesBuffer[1]; + lineVertices.Append(vt); + } + } + } + + if (debugBounds) + { + var vt = new SFML.Graphics.Vertex() { Color = BoundsColor }; + var b = bounds; + + vt.Position.X = b.Left; + vt.Position.Y = b.Top; + lineVertices.Append(vt); + + vt.Position.X = b.Right; + vt.Position.Y = b.Top; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = b.Right; + vt.Position.Y = b.Bottom; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = b.Left; + vt.Position.Y = b.Bottom; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = b.Left; + vt.Position.Y = b.Top; + lineVertices.Append(vt); + } + + // 骨骼线放最后画 if (debugBones) { var width = scale; @@ -337,7 +500,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject target.Draw(lineVertices); target.Draw(rectLineVertices); - // 骨骼的点最后画, 层级处于上面 + // 骨骼的点最后画, 层级处于骨骼线上面 if (debugBones) { var radius = scale; diff --git a/SpineViewer/Spine/Implementations/SpineObject/SpineObject38.cs b/SpineViewer/Spine/Implementations/SpineObject/SpineObject38.cs index 30f58a0..78f4ac8 100644 --- a/SpineViewer/Spine/Implementations/SpineObject/SpineObject38.cs +++ b/SpineViewer/Spine/Implementations/SpineObject/SpineObject38.cs @@ -318,23 +318,187 @@ namespace SpineViewer.Spine.Implementations.SpineObject lineVertices.Clear(); rectLineVertices.Clear(); - // 调试包围盒 - if (debugBounds) + if (debugRegions) { - var b = bounds; - var v = new SFML.Graphics.Vertex() { Color = BoundsColor }; - v.Position = new(b.Left, b.Top); lineVertices.Append(v); - v.Position = new(b.Right, b.Top); lineVertices.Append(v); lineVertices.Append(v); - v.Position = new(b.Right, b.Bottom); lineVertices.Append(v); lineVertices.Append(v); - v.Position = new(b.Left, b.Bottom); lineVertices.Append(v); lineVertices.Append(v); - v.Position = new(b.Left, b.Top); lineVertices.Append(v); + SFML.Graphics.Vertex vt = new() { Color = AttachmentLineColor }; + foreach (var slot in skeleton.Slots) + { + if (slot.Bone.Active && slot.Attachment is RegionAttachment regionAttachment) + { + regionAttachment.ComputeWorldVertices(slot.Bone, worldVerticesBuffer, 0); + + vt.Position.X = worldVerticesBuffer[0]; + vt.Position.Y = worldVerticesBuffer[1]; + lineVertices.Append(vt); + + vt.Position.X = worldVerticesBuffer[2]; + vt.Position.Y = worldVerticesBuffer[3]; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = worldVerticesBuffer[4]; + vt.Position.Y = worldVerticesBuffer[5]; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = worldVerticesBuffer[6]; + vt.Position.Y = worldVerticesBuffer[7]; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = worldVerticesBuffer[0]; + vt.Position.Y = worldVerticesBuffer[1]; + lineVertices.Append(vt); + } + } } + if (debugMeshes) + { + SFML.Graphics.Vertex vt = new() { Color = MeshLineColor }; + foreach (var slot in skeleton.Slots) + { + if (slot.Bone.Active && slot.Attachment is MeshAttachment meshAttachment) + { + if (meshAttachment.WorldVerticesLength > worldVerticesBuffer.Length) + worldVerticesBuffer = new float[meshAttachment.WorldVerticesLength * 2]; + + meshAttachment.ComputeWorldVertices(slot, worldVerticesBuffer); + + var triangleIndices = meshAttachment.Triangles; + for (int i = 0; i < triangleIndices.Length; i += 3) + { + var idx0 = triangleIndices[i] * 2; + var idx1 = triangleIndices[i + 1] * 2; + var idx2 = triangleIndices[i + 2] * 2; + + vt.Position.X = worldVerticesBuffer[idx0]; + vt.Position.Y = worldVerticesBuffer[idx0 + 1]; + lineVertices.Append(vt); + + vt.Position.X = worldVerticesBuffer[idx1]; + vt.Position.Y = worldVerticesBuffer[idx1 + 1]; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = worldVerticesBuffer[idx2]; + vt.Position.Y = worldVerticesBuffer[idx2 + 1]; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = worldVerticesBuffer[idx0]; + vt.Position.Y = worldVerticesBuffer[idx0 + 1]; + lineVertices.Append(vt); + } + } + } + } + + if (debugMeshHulls) + { + SFML.Graphics.Vertex vt = new() { Color = AttachmentLineColor }; + foreach (var slot in skeleton.Slots) + { + if (slot.Bone.Active && slot.Attachment is MeshAttachment meshAttachment) + { + if (meshAttachment.WorldVerticesLength > worldVerticesBuffer.Length) + worldVerticesBuffer = new float[meshAttachment.WorldVerticesLength * 2]; + + meshAttachment.ComputeWorldVertices(slot, worldVerticesBuffer); + + var hullLength = (meshAttachment.HullLength >> 1) << 1; + + if (debugMeshHulls && hullLength > 2) + { + vt.Position.X = worldVerticesBuffer[0]; + vt.Position.Y = worldVerticesBuffer[1]; + lineVertices.Append(vt); + + for (int i = 2; i < hullLength; i += 2) + { + vt.Position.X = worldVerticesBuffer[i]; + vt.Position.Y = worldVerticesBuffer[i + 1]; + lineVertices.Append(vt); + lineVertices.Append(vt); + } + + vt.Position.X = worldVerticesBuffer[0]; + vt.Position.Y = worldVerticesBuffer[1]; + lineVertices.Append(vt); + } + } + } + } + + if (debugBoundingBoxes) + { + throw new NotImplementedException(); + } + + if (debugPaths) + { + throw new NotImplementedException(); + } + + if (debugClippings) + { + SFML.Graphics.Vertex vt = new() { Color = ClippingLineColor }; + foreach (var slot in skeleton.Slots) + { + if (slot.Bone.Active && slot.Attachment is ClippingAttachment clippingAttachment) + { + if (clippingAttachment.WorldVerticesLength > worldVerticesBuffer.Length) + worldVerticesBuffer = worldVerticesBuffer = new float[clippingAttachment.WorldVerticesLength * 2]; + + clippingAttachment.ComputeWorldVertices(slot, worldVerticesBuffer); + + vt.Position.X = worldVerticesBuffer[0]; + vt.Position.Y = worldVerticesBuffer[1]; + lineVertices.Append(vt); + + for (int i = 2; i < clippingAttachment.WorldVerticesLength; i += 2) + { + vt.Position.X = worldVerticesBuffer[i]; + vt.Position.Y = worldVerticesBuffer[i + 1]; + lineVertices.Append(vt); + lineVertices.Append(vt); + } + + vt.Position.X = worldVerticesBuffer[0]; + vt.Position.Y = worldVerticesBuffer[1]; + lineVertices.Append(vt); + } + } + } + + if (debugBounds) + { + var vt = new SFML.Graphics.Vertex() { Color = BoundsColor }; + var b = bounds; + + vt.Position.X = b.Left; + vt.Position.Y = b.Top; + lineVertices.Append(vt); + + vt.Position.X = b.Right; + vt.Position.Y = b.Top; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = b.Right; + vt.Position.Y = b.Bottom; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = b.Left; + vt.Position.Y = b.Bottom; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = b.Left; + vt.Position.Y = b.Top; + lineVertices.Append(vt); + } + + // 骨骼线放最后画 if (debugBones) { var width = scale; foreach (var bone in skeleton.Bones) { + if (!bone.Active) continue; var boneLength = bone.Data.Length; var p1 = new SFML.System.Vector2f(bone.WorldX, bone.WorldY); var p2 = new SFML.System.Vector2f(bone.WorldX + boneLength * bone.A, bone.WorldY + boneLength * bone.C); @@ -345,12 +509,13 @@ namespace SpineViewer.Spine.Implementations.SpineObject target.Draw(lineVertices); target.Draw(rectLineVertices); - // 骨骼的点最后画, 层级处于上面 + // 骨骼的点最后画, 层级处于骨骼线上面 if (debugBones) { var radius = scale; foreach (var bone in skeleton.Bones) { + if (!bone.Active) continue; DrawCirclePoint(target, new(bone.WorldX, bone.WorldY), BonePointColor, radius); } } diff --git a/SpineViewer/Spine/Implementations/SpineObject/SpineObject40.cs b/SpineViewer/Spine/Implementations/SpineObject/SpineObject40.cs index 2042e41..0b4b667 100644 --- a/SpineViewer/Spine/Implementations/SpineObject/SpineObject40.cs +++ b/SpineViewer/Spine/Implementations/SpineObject/SpineObject40.cs @@ -314,23 +314,187 @@ namespace SpineViewer.Spine.Implementations.SpineObject lineVertices.Clear(); rectLineVertices.Clear(); - // 调试包围盒 - if (debugBounds) + if (debugRegions) { - var b = bounds; - var v = new SFML.Graphics.Vertex() { Color = BoundsColor }; - v.Position = new(b.Left, b.Top); lineVertices.Append(v); - v.Position = new(b.Right, b.Top); lineVertices.Append(v); lineVertices.Append(v); - v.Position = new(b.Right, b.Bottom); lineVertices.Append(v); lineVertices.Append(v); - v.Position = new(b.Left, b.Bottom); lineVertices.Append(v); lineVertices.Append(v); - v.Position = new(b.Left, b.Top); lineVertices.Append(v); + SFML.Graphics.Vertex vt = new() { Color = AttachmentLineColor }; + foreach (var slot in skeleton.Slots) + { + if (slot.Bone.Active && slot.Attachment is RegionAttachment regionAttachment) + { + regionAttachment.ComputeWorldVertices(slot.Bone, worldVerticesBuffer, 0); + + vt.Position.X = worldVerticesBuffer[0]; + vt.Position.Y = worldVerticesBuffer[1]; + lineVertices.Append(vt); + + vt.Position.X = worldVerticesBuffer[2]; + vt.Position.Y = worldVerticesBuffer[3]; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = worldVerticesBuffer[4]; + vt.Position.Y = worldVerticesBuffer[5]; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = worldVerticesBuffer[6]; + vt.Position.Y = worldVerticesBuffer[7]; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = worldVerticesBuffer[0]; + vt.Position.Y = worldVerticesBuffer[1]; + lineVertices.Append(vt); + } + } } + if (debugMeshes) + { + SFML.Graphics.Vertex vt = new() { Color = MeshLineColor }; + foreach (var slot in skeleton.Slots) + { + if (slot.Bone.Active && slot.Attachment is MeshAttachment meshAttachment) + { + if (meshAttachment.WorldVerticesLength > worldVerticesBuffer.Length) + worldVerticesBuffer = new float[meshAttachment.WorldVerticesLength * 2]; + + meshAttachment.ComputeWorldVertices(slot, worldVerticesBuffer); + + var triangleIndices = meshAttachment.Triangles; + for (int i = 0; i < triangleIndices.Length; i += 3) + { + var idx0 = triangleIndices[i] * 2; + var idx1 = triangleIndices[i + 1] * 2; + var idx2 = triangleIndices[i + 2] * 2; + + vt.Position.X = worldVerticesBuffer[idx0]; + vt.Position.Y = worldVerticesBuffer[idx0 + 1]; + lineVertices.Append(vt); + + vt.Position.X = worldVerticesBuffer[idx1]; + vt.Position.Y = worldVerticesBuffer[idx1 + 1]; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = worldVerticesBuffer[idx2]; + vt.Position.Y = worldVerticesBuffer[idx2 + 1]; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = worldVerticesBuffer[idx0]; + vt.Position.Y = worldVerticesBuffer[idx0 + 1]; + lineVertices.Append(vt); + } + } + } + } + + if (debugMeshHulls) + { + SFML.Graphics.Vertex vt = new() { Color = AttachmentLineColor }; + foreach (var slot in skeleton.Slots) + { + if (slot.Bone.Active && slot.Attachment is MeshAttachment meshAttachment) + { + if (meshAttachment.WorldVerticesLength > worldVerticesBuffer.Length) + worldVerticesBuffer = new float[meshAttachment.WorldVerticesLength * 2]; + + meshAttachment.ComputeWorldVertices(slot, worldVerticesBuffer); + + var hullLength = (meshAttachment.HullLength >> 1) << 1; + + if (debugMeshHulls && hullLength > 2) + { + vt.Position.X = worldVerticesBuffer[0]; + vt.Position.Y = worldVerticesBuffer[1]; + lineVertices.Append(vt); + + for (int i = 2; i < hullLength; i += 2) + { + vt.Position.X = worldVerticesBuffer[i]; + vt.Position.Y = worldVerticesBuffer[i + 1]; + lineVertices.Append(vt); + lineVertices.Append(vt); + } + + vt.Position.X = worldVerticesBuffer[0]; + vt.Position.Y = worldVerticesBuffer[1]; + lineVertices.Append(vt); + } + } + } + } + + if (debugBoundingBoxes) + { + throw new NotImplementedException(); + } + + if (debugPaths) + { + throw new NotImplementedException(); + } + + if (debugClippings) + { + SFML.Graphics.Vertex vt = new() { Color = ClippingLineColor }; + foreach (var slot in skeleton.Slots) + { + if (slot.Bone.Active && slot.Attachment is ClippingAttachment clippingAttachment) + { + if (clippingAttachment.WorldVerticesLength > worldVerticesBuffer.Length) + worldVerticesBuffer = worldVerticesBuffer = new float[clippingAttachment.WorldVerticesLength * 2]; + + clippingAttachment.ComputeWorldVertices(slot, worldVerticesBuffer); + + vt.Position.X = worldVerticesBuffer[0]; + vt.Position.Y = worldVerticesBuffer[1]; + lineVertices.Append(vt); + + for (int i = 2; i < clippingAttachment.WorldVerticesLength; i += 2) + { + vt.Position.X = worldVerticesBuffer[i]; + vt.Position.Y = worldVerticesBuffer[i + 1]; + lineVertices.Append(vt); + lineVertices.Append(vt); + } + + vt.Position.X = worldVerticesBuffer[0]; + vt.Position.Y = worldVerticesBuffer[1]; + lineVertices.Append(vt); + } + } + } + + if (debugBounds) + { + var vt = new SFML.Graphics.Vertex() { Color = BoundsColor }; + var b = bounds; + + vt.Position.X = b.Left; + vt.Position.Y = b.Top; + lineVertices.Append(vt); + + vt.Position.X = b.Right; + vt.Position.Y = b.Top; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = b.Right; + vt.Position.Y = b.Bottom; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = b.Left; + vt.Position.Y = b.Bottom; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = b.Left; + vt.Position.Y = b.Top; + lineVertices.Append(vt); + } + + // 骨骼线放最后画 if (debugBones) { var width = scale; foreach (var bone in skeleton.Bones) { + if (!bone.Active) continue; var boneLength = bone.Data.Length; var p1 = new SFML.System.Vector2f(bone.WorldX, bone.WorldY); var p2 = new SFML.System.Vector2f(bone.WorldX + boneLength * bone.A, bone.WorldY + boneLength * bone.C); @@ -341,12 +505,13 @@ namespace SpineViewer.Spine.Implementations.SpineObject target.Draw(lineVertices); target.Draw(rectLineVertices); - // 骨骼的点最后画, 层级处于上面 + // 骨骼的点最后画, 层级处于骨骼线上面 if (debugBones) { var radius = scale; foreach (var bone in skeleton.Bones) { + if (!bone.Active) continue; DrawCirclePoint(target, new(bone.WorldX, bone.WorldY), BonePointColor, radius); } } diff --git a/SpineViewer/Spine/Implementations/SpineObject/SpineObject41.cs b/SpineViewer/Spine/Implementations/SpineObject/SpineObject41.cs index 1a26296..df5cadc 100644 --- a/SpineViewer/Spine/Implementations/SpineObject/SpineObject41.cs +++ b/SpineViewer/Spine/Implementations/SpineObject/SpineObject41.cs @@ -314,23 +314,187 @@ namespace SpineViewer.Spine.Implementations.SpineObject lineVertices.Clear(); rectLineVertices.Clear(); - // 调试包围盒 - if (debugBounds) + if (debugRegions) { - var b = bounds; - var v = new SFML.Graphics.Vertex() { Color = BoundsColor }; - v.Position = new(b.Left, b.Top); lineVertices.Append(v); - v.Position = new(b.Right, b.Top); lineVertices.Append(v); lineVertices.Append(v); - v.Position = new(b.Right, b.Bottom); lineVertices.Append(v); lineVertices.Append(v); - v.Position = new(b.Left, b.Bottom); lineVertices.Append(v); lineVertices.Append(v); - v.Position = new(b.Left, b.Top); lineVertices.Append(v); + SFML.Graphics.Vertex vt = new() { Color = AttachmentLineColor }; + foreach (var slot in skeleton.Slots) + { + if (slot.Bone.Active && slot.Attachment is RegionAttachment regionAttachment) + { + regionAttachment.ComputeWorldVertices(slot, worldVerticesBuffer, 0); + + vt.Position.X = worldVerticesBuffer[0]; + vt.Position.Y = worldVerticesBuffer[1]; + lineVertices.Append(vt); + + vt.Position.X = worldVerticesBuffer[2]; + vt.Position.Y = worldVerticesBuffer[3]; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = worldVerticesBuffer[4]; + vt.Position.Y = worldVerticesBuffer[5]; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = worldVerticesBuffer[6]; + vt.Position.Y = worldVerticesBuffer[7]; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = worldVerticesBuffer[0]; + vt.Position.Y = worldVerticesBuffer[1]; + lineVertices.Append(vt); + } + } } + if (debugMeshes) + { + SFML.Graphics.Vertex vt = new() { Color = MeshLineColor }; + foreach (var slot in skeleton.Slots) + { + if (slot.Bone.Active && slot.Attachment is MeshAttachment meshAttachment) + { + if (meshAttachment.WorldVerticesLength > worldVerticesBuffer.Length) + worldVerticesBuffer = new float[meshAttachment.WorldVerticesLength * 2]; + + meshAttachment.ComputeWorldVertices(slot, worldVerticesBuffer); + + var triangleIndices = meshAttachment.Triangles; + for (int i = 0; i < triangleIndices.Length; i += 3) + { + var idx0 = triangleIndices[i] * 2; + var idx1 = triangleIndices[i + 1] * 2; + var idx2 = triangleIndices[i + 2] * 2; + + vt.Position.X = worldVerticesBuffer[idx0]; + vt.Position.Y = worldVerticesBuffer[idx0 + 1]; + lineVertices.Append(vt); + + vt.Position.X = worldVerticesBuffer[idx1]; + vt.Position.Y = worldVerticesBuffer[idx1 + 1]; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = worldVerticesBuffer[idx2]; + vt.Position.Y = worldVerticesBuffer[idx2 + 1]; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = worldVerticesBuffer[idx0]; + vt.Position.Y = worldVerticesBuffer[idx0 + 1]; + lineVertices.Append(vt); + } + } + } + } + + if (debugMeshHulls) + { + SFML.Graphics.Vertex vt = new() { Color = AttachmentLineColor }; + foreach (var slot in skeleton.Slots) + { + if (slot.Bone.Active && slot.Attachment is MeshAttachment meshAttachment) + { + if (meshAttachment.WorldVerticesLength > worldVerticesBuffer.Length) + worldVerticesBuffer = new float[meshAttachment.WorldVerticesLength * 2]; + + meshAttachment.ComputeWorldVertices(slot, worldVerticesBuffer); + + var hullLength = (meshAttachment.HullLength >> 1) << 1; + + if (debugMeshHulls && hullLength > 2) + { + vt.Position.X = worldVerticesBuffer[0]; + vt.Position.Y = worldVerticesBuffer[1]; + lineVertices.Append(vt); + + for (int i = 2; i < hullLength; i += 2) + { + vt.Position.X = worldVerticesBuffer[i]; + vt.Position.Y = worldVerticesBuffer[i + 1]; + lineVertices.Append(vt); + lineVertices.Append(vt); + } + + vt.Position.X = worldVerticesBuffer[0]; + vt.Position.Y = worldVerticesBuffer[1]; + lineVertices.Append(vt); + } + } + } + } + + if (debugBoundingBoxes) + { + throw new NotImplementedException(); + } + + if (debugPaths) + { + throw new NotImplementedException(); + } + + if (debugClippings) + { + SFML.Graphics.Vertex vt = new() { Color = ClippingLineColor }; + foreach (var slot in skeleton.Slots) + { + if (slot.Bone.Active && slot.Attachment is ClippingAttachment clippingAttachment) + { + if (clippingAttachment.WorldVerticesLength > worldVerticesBuffer.Length) + worldVerticesBuffer = worldVerticesBuffer = new float[clippingAttachment.WorldVerticesLength * 2]; + + clippingAttachment.ComputeWorldVertices(slot, worldVerticesBuffer); + + vt.Position.X = worldVerticesBuffer[0]; + vt.Position.Y = worldVerticesBuffer[1]; + lineVertices.Append(vt); + + for (int i = 2; i < clippingAttachment.WorldVerticesLength; i += 2) + { + vt.Position.X = worldVerticesBuffer[i]; + vt.Position.Y = worldVerticesBuffer[i + 1]; + lineVertices.Append(vt); + lineVertices.Append(vt); + } + + vt.Position.X = worldVerticesBuffer[0]; + vt.Position.Y = worldVerticesBuffer[1]; + lineVertices.Append(vt); + } + } + } + + if (debugBounds) + { + var vt = new SFML.Graphics.Vertex() { Color = BoundsColor }; + var b = bounds; + + vt.Position.X = b.Left; + vt.Position.Y = b.Top; + lineVertices.Append(vt); + + vt.Position.X = b.Right; + vt.Position.Y = b.Top; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = b.Right; + vt.Position.Y = b.Bottom; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = b.Left; + vt.Position.Y = b.Bottom; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = b.Left; + vt.Position.Y = b.Top; + lineVertices.Append(vt); + } + + // 骨骼线放最后画 if (debugBones) { var width = scale; foreach (var bone in skeleton.Bones) { + if (!bone.Active) continue; var boneLength = bone.Data.Length; var p1 = new SFML.System.Vector2f(bone.WorldX, bone.WorldY); var p2 = new SFML.System.Vector2f(bone.WorldX + boneLength * bone.A, bone.WorldY + boneLength * bone.C); @@ -341,12 +505,13 @@ namespace SpineViewer.Spine.Implementations.SpineObject target.Draw(lineVertices); target.Draw(rectLineVertices); - // 骨骼的点最后画, 层级处于上面 + // 骨骼的点最后画, 层级处于骨骼线上面 if (debugBones) { var radius = scale; foreach (var bone in skeleton.Bones) { + if (!bone.Active) continue; DrawCirclePoint(target, new(bone.WorldX, bone.WorldY), BonePointColor, radius); } } diff --git a/SpineViewer/Spine/Implementations/SpineObject/Spineobject42.cs b/SpineViewer/Spine/Implementations/SpineObject/Spineobject42.cs index f694a0d..135b64d 100644 --- a/SpineViewer/Spine/Implementations/SpineObject/Spineobject42.cs +++ b/SpineViewer/Spine/Implementations/SpineObject/Spineobject42.cs @@ -314,23 +314,187 @@ namespace SpineViewer.Spine.Implementations.SpineObject lineVertices.Clear(); rectLineVertices.Clear(); - // 调试包围盒 - if (debugBounds) + if (debugRegions) { - var b = bounds; - var v = new SFML.Graphics.Vertex() { Color = BoundsColor }; - v.Position = new(b.Left, b.Top); lineVertices.Append(v); - v.Position = new(b.Right, b.Top); lineVertices.Append(v); lineVertices.Append(v); - v.Position = new(b.Right, b.Bottom); lineVertices.Append(v); lineVertices.Append(v); - v.Position = new(b.Left, b.Bottom); lineVertices.Append(v); lineVertices.Append(v); - v.Position = new(b.Left, b.Top); lineVertices.Append(v); + SFML.Graphics.Vertex vt = new() { Color = AttachmentLineColor }; + foreach (var slot in skeleton.Slots) + { + if (slot.Bone.Active && slot.Attachment is RegionAttachment regionAttachment) + { + regionAttachment.ComputeWorldVertices(slot, worldVerticesBuffer, 0); + + vt.Position.X = worldVerticesBuffer[0]; + vt.Position.Y = worldVerticesBuffer[1]; + lineVertices.Append(vt); + + vt.Position.X = worldVerticesBuffer[2]; + vt.Position.Y = worldVerticesBuffer[3]; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = worldVerticesBuffer[4]; + vt.Position.Y = worldVerticesBuffer[5]; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = worldVerticesBuffer[6]; + vt.Position.Y = worldVerticesBuffer[7]; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = worldVerticesBuffer[0]; + vt.Position.Y = worldVerticesBuffer[1]; + lineVertices.Append(vt); + } + } } + if (debugMeshes) + { + SFML.Graphics.Vertex vt = new() { Color = MeshLineColor }; + foreach (var slot in skeleton.Slots) + { + if (slot.Bone.Active && slot.Attachment is MeshAttachment meshAttachment) + { + if (meshAttachment.WorldVerticesLength > worldVerticesBuffer.Length) + worldVerticesBuffer = new float[meshAttachment.WorldVerticesLength * 2]; + + meshAttachment.ComputeWorldVertices(slot, worldVerticesBuffer); + + var triangleIndices = meshAttachment.Triangles; + for (int i = 0; i < triangleIndices.Length; i += 3) + { + var idx0 = triangleIndices[i] * 2; + var idx1 = triangleIndices[i + 1] * 2; + var idx2 = triangleIndices[i + 2] * 2; + + vt.Position.X = worldVerticesBuffer[idx0]; + vt.Position.Y = worldVerticesBuffer[idx0 + 1]; + lineVertices.Append(vt); + + vt.Position.X = worldVerticesBuffer[idx1]; + vt.Position.Y = worldVerticesBuffer[idx1 + 1]; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = worldVerticesBuffer[idx2]; + vt.Position.Y = worldVerticesBuffer[idx2 + 1]; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = worldVerticesBuffer[idx0]; + vt.Position.Y = worldVerticesBuffer[idx0 + 1]; + lineVertices.Append(vt); + } + } + } + } + + if (debugMeshHulls) + { + SFML.Graphics.Vertex vt = new() { Color = AttachmentLineColor }; + foreach (var slot in skeleton.Slots) + { + if (slot.Bone.Active && slot.Attachment is MeshAttachment meshAttachment) + { + if (meshAttachment.WorldVerticesLength > worldVerticesBuffer.Length) + worldVerticesBuffer = new float[meshAttachment.WorldVerticesLength * 2]; + + meshAttachment.ComputeWorldVertices(slot, worldVerticesBuffer); + + var hullLength = (meshAttachment.HullLength >> 1) << 1; + + if (debugMeshHulls && hullLength > 2) + { + vt.Position.X = worldVerticesBuffer[0]; + vt.Position.Y = worldVerticesBuffer[1]; + lineVertices.Append(vt); + + for (int i = 2; i < hullLength; i += 2) + { + vt.Position.X = worldVerticesBuffer[i]; + vt.Position.Y = worldVerticesBuffer[i + 1]; + lineVertices.Append(vt); + lineVertices.Append(vt); + } + + vt.Position.X = worldVerticesBuffer[0]; + vt.Position.Y = worldVerticesBuffer[1]; + lineVertices.Append(vt); + } + } + } + } + + if (debugBoundingBoxes) + { + throw new NotImplementedException(); + } + + if (debugPaths) + { + throw new NotImplementedException(); + } + + if (debugClippings) + { + SFML.Graphics.Vertex vt = new() { Color = ClippingLineColor }; + foreach (var slot in skeleton.Slots) + { + if (slot.Bone.Active && slot.Attachment is ClippingAttachment clippingAttachment) + { + if (clippingAttachment.WorldVerticesLength > worldVerticesBuffer.Length) + worldVerticesBuffer = worldVerticesBuffer = new float[clippingAttachment.WorldVerticesLength * 2]; + + clippingAttachment.ComputeWorldVertices(slot, worldVerticesBuffer); + + vt.Position.X = worldVerticesBuffer[0]; + vt.Position.Y = worldVerticesBuffer[1]; + lineVertices.Append(vt); + + for (int i = 2; i < clippingAttachment.WorldVerticesLength; i += 2) + { + vt.Position.X = worldVerticesBuffer[i]; + vt.Position.Y = worldVerticesBuffer[i + 1]; + lineVertices.Append(vt); + lineVertices.Append(vt); + } + + vt.Position.X = worldVerticesBuffer[0]; + vt.Position.Y = worldVerticesBuffer[1]; + lineVertices.Append(vt); + } + } + } + + if (debugBounds) + { + var vt = new SFML.Graphics.Vertex() { Color = BoundsColor }; + var b = bounds; + + vt.Position.X = b.Left; + vt.Position.Y = b.Top; + lineVertices.Append(vt); + + vt.Position.X = b.Right; + vt.Position.Y = b.Top; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = b.Right; + vt.Position.Y = b.Bottom; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = b.Left; + vt.Position.Y = b.Bottom; + lineVertices.Append(vt); lineVertices.Append(vt); + + vt.Position.X = b.Left; + vt.Position.Y = b.Top; + lineVertices.Append(vt); + } + + // 骨骼线放最后画 if (debugBones) { var width = scale; foreach (var bone in skeleton.Bones) { + if (!bone.Active) continue; var boneLength = bone.Data.Length; var p1 = new SFML.System.Vector2f(bone.WorldX, bone.WorldY); var p2 = new SFML.System.Vector2f(bone.WorldX + boneLength * bone.A, bone.WorldY + boneLength * bone.C); @@ -341,12 +505,13 @@ namespace SpineViewer.Spine.Implementations.SpineObject target.Draw(lineVertices); target.Draw(rectLineVertices); - // 骨骼的点最后画, 层级处于上面 + // 骨骼的点最后画, 层级处于骨骼线上面 if (debugBones) { var radius = scale; foreach (var bone in skeleton.Bones) { + if (!bone.Active) continue; DrawCirclePoint(target, new(bone.WorldX, bone.WorldY), BonePointColor, radius); } } diff --git a/SpineViewer/Spine/SpineObject.cs b/SpineViewer/Spine/SpineObject.cs index 5c4c2b7..b53efe7 100644 --- a/SpineViewer/Spine/SpineObject.cs +++ b/SpineViewer/Spine/SpineObject.cs @@ -232,14 +232,14 @@ namespace SpineViewer.Spine protected bool isSelected = false; /// - /// 显示调试 + /// 启用渲染调试 /// - public bool IsDebug + public bool EnableDebug { - get { lock (_lock) return isDebug; } - set { lock (_lock) { isDebug = value; update(0); } } + get { lock (_lock) return enableDebug; } + set { lock (_lock) { enableDebug = value; update(0); } } } - private bool isDebug = false; + private bool enableDebug = false; /// /// 显示纹理 @@ -269,7 +269,67 @@ namespace SpineViewer.Spine get { lock (_lock) return debugBones; } set { lock (_lock) { debugBones = value; update(0); } } } - protected bool debugBones = true; + protected bool debugBones = false; + + /// + /// 显示区域附件边框 + /// + public bool DebugRegions + { + get { lock (_lock) return debugRegions; } + set { lock (_lock) { debugRegions = value; update(0); } } + } + protected bool debugRegions = false; + + /// + /// 显示网格附件边框线 + /// + public bool DebugMeshHulls + { + get { lock (_lock) return debugMeshHulls; } + set { lock (_lock) { debugMeshHulls = value; update(0); } } + } + protected bool debugMeshHulls = false; + + /// + /// 显示网格附件网格线 + /// + public bool DebugMeshes + { + get { lock (_lock) return debugMeshes; } + set { lock (_lock) { debugMeshes = value; update(0); } } + } + protected bool debugMeshes = false; + + /// + /// 显示碰撞盒附件边框线 + /// + public bool DebugBoundingBoxes + { + get { lock (_lock) return debugBoundingBoxes; } + set { lock (_lock) { debugBoundingBoxes = value; update(0); } } + } + protected bool debugBoundingBoxes = false; + + /// + /// 显示路径附件网格线 + /// + public bool DebugPaths + { + get { lock (_lock) return debugPaths; } + set { lock (_lock) { debugPaths = value; update(0); } } + } + protected bool debugPaths = false; + + /// + /// 显示剪裁附件网格线 + /// + public bool DebugClippings + { + get { lock (_lock) return debugClippings; } + set { lock (_lock) { debugClippings = value; update(0); } } + } + protected bool debugClippings = false; /// /// 获取已加载的皮肤列表快照, 允许出现重复值 @@ -400,6 +460,21 @@ namespace SpineViewer.Spine /// protected static readonly SFML.Graphics.Color BoneLineColor = new(255, 0, 0); + /// + /// 网格线颜色 + /// + protected static readonly SFML.Graphics.Color MeshLineColor = new(255, 163, 0, 128); + + /// + /// 附件边框线颜色 + /// + protected static readonly SFML.Graphics.Color AttachmentLineColor = new(0, 0, 255, 128); + + /// + /// 剪裁附件边框线颜色 + /// + protected static readonly SFML.Graphics.Color ClippingLineColor = new(204, 0, 0); + /// /// spine 顶点坐标缓冲区 /// @@ -468,14 +543,14 @@ namespace SpineViewer.Spine { lock (_lock) { - if (!isDebug) + if (!enableDebug) { draw(target, states); } else { if (debugTexture) draw(target, states); - debugDraw(target); + if (isSelected) debugDraw(target); } } } diff --git a/SpineViewer/Spine/SpineView/SpineDebugProperty.cs b/SpineViewer/Spine/SpineView/SpineDebugProperty.cs index c56db9d..d54dfde 100644 --- a/SpineViewer/Spine/SpineView/SpineDebugProperty.cs +++ b/SpineViewer/Spine/SpineView/SpineDebugProperty.cs @@ -19,19 +19,55 @@ namespace SpineViewer.Spine.SpineView /// /// 显示纹理 /// - [DisplayName("纹理")] + [DisplayName("Texture")] public bool DebugTexture { get => Spine.DebugTexture; set => Spine.DebugTexture = value; } /// /// 显示包围盒 /// - [DisplayName("包围盒")] + [DisplayName("Bounds")] public bool DebugBounds { get => Spine.DebugBounds; set => Spine.DebugBounds = value; } /// /// 显示骨骼 /// - [DisplayName("骨架")] + [DisplayName("Bones")] public bool DebugBones { get => Spine.DebugBones; set => Spine.DebugBones = value; } + + /// + /// 显示区域附件边框线 + /// + [DisplayName("Regions")] + public bool DebugRegions { get => Spine.DebugRegions; set => Spine.DebugRegions = value; } + + /// + /// 显示网格附件边框线 + /// + [DisplayName("MeshHulls")] + public bool DebugMeshHulls { get => Spine.DebugMeshHulls; set => Spine.DebugMeshHulls = value; } + + /// + /// 显示网格附件网格线 + /// + [DisplayName("Meshes")] + public bool DebugMeshes { get => Spine.DebugMeshes; set => Spine.DebugMeshes = value; } + + ///// + ///// 显示碰撞盒附件边框线 + ///// + //[DisplayName("BoudingBoxes")] + //public bool DebugBoundingBoxes { get => Spine.DebugBoundingBoxes; set => Spine.DebugBoundingBoxes = value; } + + ///// + ///// 显示路径附件网格线 + ///// + //[DisplayName("Paths")] + //public bool DebugPaths { get => Spine.DebugPaths; set => Spine.DebugPaths = value; } + + /// + /// 显示剪裁附件网格线 + /// + [DisplayName("Clippings")] + public bool DebugClippings { get => Spine.DebugClippings; set => Spine.DebugClippings = value; } } }