Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public void CalculateVertexNormals()
- {
- var world = Transformations.CreateWorldTransform(
- Scale,
- Matrix4x4.CreateFromYawPitchRoll(Rotation.Y, Rotation.X, Rotation.Z),
- Translation);
- // Создаем обратную транспонированную мировую матрицу для нормалей
- var inverseTransposeWorld = Matrix4x4.Transpose(Matrix4x4.Invert(world));
- // Инициализируем нормали и счетчики нулями
- for (int i = 0; i < OriginalVertices.Count; i++)
- {
- VertexNormals[i] = Vector3.Zero;
- Counters[i] = 0;
- }
- // Для каждой грани выполняем фан-трайангуляцию
- Parallel.ForEach(Faces, face =>
- {
- if (face.Vertices.Count < 3)
- return;
- // Фан-трайангуляция: используем первую вершину как базовую и формируем треугольники
- for (int j = 1; j < face.Vertices.Count - 1; j++)
- {
- int idx0 = face.Vertices[0].VertexIndex - 1;
- int idx1 = face.Vertices[j].VertexIndex - 1;
- int idx2 = face.Vertices[j + 1].VertexIndex - 1;
- if (idx0 < 0 || idx1 < 0 || idx2 < 0 ||
- idx0 >= OriginalVertices.Count || idx1 >= OriginalVertices.Count || idx2 >= OriginalVertices.Count)
- continue;
- // Вычисляем нормаль треугольника в локальном пространстве
- var localV0 = OriginalVertices[idx0].AsVector3();
- var localV1 = OriginalVertices[idx1].AsVector3();
- var localV2 = OriginalVertices[idx2].AsVector3();
- var edge1 = localV1 - localV0;
- var edge2 = localV2 - localV0;
- var localNormal = Vector3.Normalize(Vector3.Cross(edge1, edge2));
- // Преобразуем нормаль в мировое пространство с помощью обратной транспонированной матрицы
- var worldNormal = Vector3.TransformNormal(localNormal, inverseTransposeWorld);
- worldNormal = Vector3.Normalize(worldNormal);
- // Добавляем нормаль к вершинам треугольника
- AddFaceNormalToVertex(idx0, worldNormal);
- AddFaceNormalToVertex(idx1, worldNormal);
- AddFaceNormalToVertex(idx2, worldNormal);
- }
- });
- // Усредняем нормали для каждой вершины
- Parallel.For(0, VertexNormals.Length, i =>
- {
- if (Counters[i] > 0)
- {
- VertexNormals[i] = Vector3.Normalize(VertexNormals[i] / Counters[i]);
- }
- });
- void AddFaceNormalToVertex(int idx, Vector3 normal)
- {
- VertexNormals[idx] += normal;
- Counters[idx]++;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement