Advertisement
Old_But_Gold

Untitled

Feb 19th, 2025
5
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.92 KB | None | 0 0
  1. public void CalculateVertexNormals()
  2. {
  3. var world = Transformations.CreateWorldTransform(
  4. Scale,
  5. Matrix4x4.CreateFromYawPitchRoll(Rotation.Y, Rotation.X, Rotation.Z),
  6. Translation);
  7.  
  8. // Создаем обратную транспонированную мировую матрицу для нормалей
  9. var inverseTransposeWorld = Matrix4x4.Transpose(Matrix4x4.Invert(world));
  10.  
  11. // Инициализируем нормали и счетчики нулями
  12. for (int i = 0; i < OriginalVertices.Count; i++)
  13. {
  14. VertexNormals[i] = Vector3.Zero;
  15. Counters[i] = 0;
  16. }
  17.  
  18. // Для каждой грани выполняем фан-трайангуляцию
  19. Parallel.ForEach(Faces, face =>
  20. {
  21. if (face.Vertices.Count < 3)
  22. return;
  23.  
  24. // Фан-трайангуляция: используем первую вершину как базовую и формируем треугольники
  25. for (int j = 1; j < face.Vertices.Count - 1; j++)
  26. {
  27. int idx0 = face.Vertices[0].VertexIndex - 1;
  28. int idx1 = face.Vertices[j].VertexIndex - 1;
  29. int idx2 = face.Vertices[j + 1].VertexIndex - 1;
  30.  
  31. if (idx0 < 0 || idx1 < 0 || idx2 < 0 ||
  32. idx0 >= OriginalVertices.Count || idx1 >= OriginalVertices.Count || idx2 >= OriginalVertices.Count)
  33. continue;
  34.  
  35. // Вычисляем нормаль треугольника в локальном пространстве
  36. var localV0 = OriginalVertices[idx0].AsVector3();
  37. var localV1 = OriginalVertices[idx1].AsVector3();
  38. var localV2 = OriginalVertices[idx2].AsVector3();
  39.  
  40. var edge1 = localV1 - localV0;
  41. var edge2 = localV2 - localV0;
  42.  
  43. var localNormal = Vector3.Normalize(Vector3.Cross(edge1, edge2));
  44.  
  45. // Преобразуем нормаль в мировое пространство с помощью обратной транспонированной матрицы
  46. var worldNormal = Vector3.TransformNormal(localNormal, inverseTransposeWorld);
  47. worldNormal = Vector3.Normalize(worldNormal);
  48.  
  49. // Добавляем нормаль к вершинам треугольника
  50. AddFaceNormalToVertex(idx0, worldNormal);
  51. AddFaceNormalToVertex(idx1, worldNormal);
  52. AddFaceNormalToVertex(idx2, worldNormal);
  53. }
  54. });
  55.  
  56. // Усредняем нормали для каждой вершины
  57. Parallel.For(0, VertexNormals.Length, i =>
  58. {
  59. if (Counters[i] > 0)
  60. {
  61. VertexNormals[i] = Vector3.Normalize(VertexNormals[i] / Counters[i]);
  62. }
  63. });
  64.  
  65. void AddFaceNormalToVertex(int idx, Vector3 normal)
  66. {
  67. VertexNormals[idx] += normal;
  68. Counters[idx]++;
  69. }
  70. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement