diff options
| author | yum <yum.food.vr@gmail.com> | 2025-06-11 18:57:29 -0700 |
|---|---|---|
| committer | yum <yum.food.vr@gmail.com> | 2025-06-11 18:57:29 -0700 |
| commit | 9e5f80c045a648348bdb3b36b8181b928dfbb0ba (patch) | |
| tree | 1fdac58907d851f0ff80a16e76b2dba80d38f957 /Scripts/Editor/DecodeVertexData.cs | |
| parent | 308f5473231c164c407126f8e144543a4ad7d0f6 (diff) | |
Organize scripts
Diffstat (limited to 'Scripts/Editor/DecodeVertexData.cs')
| -rw-r--r-- | Scripts/Editor/DecodeVertexData.cs | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/Scripts/Editor/DecodeVertexData.cs b/Scripts/Editor/DecodeVertexData.cs new file mode 100644 index 0000000..d248773 --- /dev/null +++ b/Scripts/Editor/DecodeVertexData.cs @@ -0,0 +1,213 @@ +using UnityEngine; +using System.Collections.Generic; +using System.Linq; + +public class DecodeVertexVectors : MonoBehaviour +{ + [Header("Display Settings")] + [SerializeField] private int maxVertices = 100; + [SerializeField] private float vectorScale = 0.3f; + + [Header("Edge Visualization")] + [SerializeField] private bool showEdges = true; + [SerializeField] private int edgeSubdivisions = 2; + + [Header("Orientation")] + [SerializeField] private bool showOrientations = true; + [SerializeField] private float orientationScale = 1.0f; + + [Header("UV Channels")] + [SerializeField] private int quaternionXYChannel = 1; + [SerializeField] private int quaternionZWChannel = 2; + + [Header("Colors")] + [SerializeField] private Color vectorColor = new Color(0.5f, 0.8f, 1f); + [SerializeField] private Color correctedVectorColor = new Color(1f, 0.5f, 0.2f); + [SerializeField] private Color forwardColor = Color.blue; + + private void OnDrawGizmos() + { + var meshFilter = GetComponent<MeshFilter>(); + if (!meshFilter || !meshFilter.sharedMesh) return; + + var mesh = meshFilter.sharedMesh; + var vertices = mesh.vertices; + var colors = mesh.colors; + + // Draw vertex vectors from colors + if (colors != null && colors.Length > 0) + { + DrawVertexVectors(mesh, vertices, colors); + } + + // Draw orientations from UVs + if (showOrientations) + { + DrawOrientations(mesh, vertices); + } + } + + void DrawVertexVectors(Mesh mesh, Vector3[] vertices, Color[] colors) + { + Vector2[] uvXY = GetUVData(mesh, quaternionXYChannel); + Vector2[] uvZW = GetUVData(mesh, quaternionZWChannel); + bool hasQuaternions = uvXY != null && uvZW != null; + + int vertexStep = Mathf.Max(1, vertices.Length / maxVertices); + + // Draw vectors at vertices + for (int i = 0; i < vertices.Length; i += vertexStep) + { + if (i >= colors.Length) break; + + Vector3 worldPos = transform.TransformPoint(vertices[i]); + Vector3 decodedVector = DecodeVectorFromColor(colors[i]); + + // Basic vector + Gizmos.color = vectorColor; + DrawVector(worldPos, transform.TransformDirection(decodedVector), vectorScale); + + // Quaternion-corrected vector + if (hasQuaternions && i < uvXY.Length && i < uvZW.Length) + { + Quaternion quat = GetQuaternionFromUV(uvXY[i], uvZW[i]); + Vector3 corrected = quat * decodedVector; + + Gizmos.color = correctedVectorColor; + DrawVector(worldPos, transform.TransformDirection(corrected), vectorScale); + } + } + + // Draw edge interpolations + if (showEdges && edgeSubdivisions > 0) + { + DrawEdgeInterpolations(mesh, vertices, colors, uvXY, uvZW); + } + } + + void DrawEdgeInterpolations(Mesh mesh, Vector3[] vertices, Color[] colors, Vector2[] uvXY, Vector2[] uvZW) + { + var triangles = mesh.triangles; + HashSet<(int, int)> drawnEdges = new HashSet<(int, int)>(); + bool hasQuaternions = uvXY != null && uvZW != null; + + for (int i = 0; i < triangles.Length && drawnEdges.Count < maxVertices/2; i += 3) + { + for (int j = 0; j < 3; j++) + { + int v1 = triangles[i + j]; + int v2 = triangles[i + ((j + 1) % 3)]; + + var edge = v1 < v2 ? (v1, v2) : (v2, v1); + if (!drawnEdges.Add(edge)) continue; + + if (v1 >= vertices.Length || v2 >= vertices.Length || + v1 >= colors.Length || v2 >= colors.Length) continue; + + // Draw subdivisions along edge + for (int k = 1; k < edgeSubdivisions; k++) + { + float t = k / (float)edgeSubdivisions; + Vector3 pos = Vector3.Lerp(vertices[v1], vertices[v2], t); + Color col = Color.Lerp(colors[v1], colors[v2], t); + + Vector3 worldPos = transform.TransformPoint(pos); + Vector3 vec = DecodeVectorFromColor(col); + + // Basic vector + Gizmos.color = vectorColor * 0.7f; // Slightly dimmer for edge points + DrawVector(worldPos, transform.TransformDirection(vec), vectorScale * 0.8f); + + // Quaternion-corrected vector + if (hasQuaternions && v1 < uvXY.Length && v2 < uvXY.Length && + v1 < uvZW.Length && v2 < uvZW.Length) + { + Vector2 interpXY = Vector2.Lerp(uvXY[v1], uvXY[v2], t); + Vector2 interpZW = Vector2.Lerp(uvZW[v1], uvZW[v2], t); + Quaternion interpQuat = GetQuaternionFromUV(interpXY, interpZW); + Vector3 corrected = interpQuat * vec; + + Gizmos.color = correctedVectorColor * 0.7f; // Slightly dimmer for edge points + DrawVector(worldPos, transform.TransformDirection(corrected), vectorScale * 0.8f); + } + } + } + } + } + + void DrawOrientations(Mesh mesh, Vector3[] vertices) + { + Vector2[] uvXY = GetUVData(mesh, quaternionXYChannel); + Vector2[] uvZW = GetUVData(mesh, quaternionZWChannel); + + if (uvXY == null || uvZW == null) return; + + int vertexStep = Mathf.Max(1, vertices.Length / maxVertices); + + for (int i = 0; i < vertices.Length; i += vertexStep) + { + if (i >= uvXY.Length || i >= uvZW.Length) break; + + Vector3 worldPos = transform.TransformPoint(vertices[i]); + Quaternion quat = GetQuaternionFromUV(uvXY[i], uvZW[i]); + + // Draw forward direction + Gizmos.color = forwardColor; + Vector3 forward = transform.TransformDirection(quat * Vector3.forward); + DrawArrow(worldPos, forward, orientationScale); + } + } + + void DrawVector(Vector3 origin, Vector3 direction, float scale) + { + Vector3 end = origin + direction * scale; + Gizmos.DrawLine(origin, end); + Gizmos.DrawSphere(end, 0.02f); + } + + void DrawArrow(Vector3 origin, Vector3 direction, float length) + { + Vector3 end = origin + direction * length; + Gizmos.DrawLine(origin, end); + + // Simple arrowhead + Vector3 right = Vector3.Cross(direction, Vector3.up).normalized; + if (right.magnitude < 0.01f) + right = Vector3.Cross(direction, Vector3.right).normalized; + + Vector3 arrowBack = -direction * length * 0.2f; + Vector3 arrowSide = right * length * 0.1f; + + Gizmos.DrawLine(end, end + arrowBack + arrowSide); + Gizmos.DrawLine(end, end + arrowBack - arrowSide); + } + + Quaternion GetQuaternionFromUV(Vector2 xy, Vector2 zw) + { + return new Quaternion(xy.x, xy.y, zw.x, zw.y).normalized; + } + + Vector3 DecodeVectorFromColor(Color color) + { + return new Vector3( + color.r * 2.0f - 1.0f, + color.g * 2.0f - 1.0f, + color.b * 2.0f - 1.0f) / color.a; + } + + Vector2[] GetUVData(Mesh mesh, int channel) + { + switch (channel) + { + case 0: return mesh.uv; + case 1: return mesh.uv2; + case 2: return mesh.uv3; + case 3: return mesh.uv4; + case 4: return mesh.uv5; + case 5: return mesh.uv6; + case 6: return mesh.uv7; + case 7: return mesh.uv8; + default: return null; + } + } +} |
