Я пытаюсь экспортировать и загрузить модель из Maya в очень простую настройку iOS OpenGL ES.Для этого я написал ruby obj parser, который в основном берет вершины и нормали и вычисляет их в заголовок C, который я просто включаю.Вывод простого триангулированного единичного куба имеет следующую структуру:
Vertex3D cubeVertices[] = {
{{-0.500000f, -0.500000f, 0.500000f},{0.000000f, 0.000000f, 1.000000f},{0.5f, 0.5f, 0.5f, 1},{{0,1,2},{0,6,7},{0,7,1},{0,6,4},{0,4,2}},5},
{{0.500000f, -0.500000f, 0.500000f},{0.000000f, 0.000000f, 1.000000f},{0.5f, 0.5f, 0.5f, 1},{{1,0,2},{1,2,3},{1,0,7},{1,7,3}},4},
{{-0.500000f, 0.500000f, 0.500000f},{0.000000f, 0.000000f, 1.000000f},{0.5f, 0.5f, 0.5f, 1},{{2,0,1},{2,1,3},{2,3,4},{2,4,0}},4},
{{0.500000f, 0.500000f, 0.500000f},{0.000000f, 0.000000f, 1.000000f},{0.5f, 0.5f, 0.5f, 1},{{3,2,1},{3,2,4},{3,4,5},{3,1,7},{3,7,5}},5},
{{-0.500000f, 0.500000f, -0.500000f},{0.000000f, 1.000000f, 0.000000f},{0.5f, 0.5f, 0.5f, 1},{{4,2,3},{4,3,5},{4,5,6},{4,6,0},{4,0,2}},5},
{{0.500000f, 0.500000f, -0.500000f},{0.000000f, 1.000000f, 0.000000f},{0.5f, 0.5f, 0.5f, 1},{{5,4,3},{5,4,6},{5,6,7},{5,3,7}},4},
{{-0.500000f, -0.500000f, -0.500000f},{0.000000f, 1.000000f, 0.000000f},{0.5f, 0.5f, 0.5f, 1},{{6,4,5},{6,5,7},{6,7,0},{6,0,4}},4},
{{0.500000f, -0.500000f, -0.500000f},{0.000000f, 1.000000f, 0.000000f},{0.5f, 0.5f, 0.5f, 1},{{7,6,5},{7,6,0},{7,0,1},{7,1,3},{7,3,5}},5}
};
GLubyte cubeFaceIndices[] = {
0, 1, 2,
2, 1, 3,
2, 3, 4,
4, 3, 5,
4, 5, 6,
6, 5, 7,
6, 7, 0,
0, 7, 1,
1, 7, 3,
3, 7, 5,
6, 0, 4,
4, 0, 2
};
Определение для Vertex3D:
struct Vertex3D {
vec3 position;
vec3 normal;
vec4 color;
Index3D connected_faces[100];
int connectedFaceCount;
};
typedef struct Vertex3D Vertex3D;
Теперь мне нужно пересчитать нормали вершин, потому что я хочу анимироватьдвижение некоторых вершин.Для этого я просто добавил все индексы связанных вершин в каждую вершину, для этого предназначен индексный массив connected_faces.
Для вычисления я просто вычисляю все нормали граней с перекрестным произведением.Для этого мне нужно всего лишь использовать 3 вершины, хранящиеся в Index3D, загрузить позиции, вычесть первую вершину, чтобы у меня были векторы и вычислить перекрестное произведение.Затем я складываю все перекрестные произведения, которые принадлежат этой вершине, и нормализую вектор, это моя последняя нормальная вершина.
Проблема, с которой я сталкиваюсь, заключается в том, что бывает, что 2 грани, которые будут иметь одинаковыеНормальная грань, например, у триангулированного куба всегда есть 2 треугольника, которые разделяют четырехугольник, и имеют эту нормальную грань в противоположном направлении.Если я добавлю их, чтобы вычислить позже, конечно, их сумма будет нулевым вектором.Я знаю, что это происходит потому, что в некоторых случаях 2 вершины не имеют правильного порядка, это означает, что A следует заменить на B, но я не знаю, какую из них мне нужно перевернуть.
Есть лиматематический способ оценить, в каком направлении идет нормаль, и вычисляю ли я AxB или BxA?Я дважды проверил нормали в Maya, они там просто идеальны.
РЕДАКТИРОВАТЬ: Я заказал соединенные грани сейчас, что прекрасно работает.Я вычисляю нормали следующим образом:
// every vertex
GLsizei vertexCount = sizeof(cubeVertices) / sizeof(Vertex3D);
for (int i = 0; i < vertexCount; i++) {
vec3 newNormal = {0.0f, 0.0f, 0.0f};
// every vertex connected to the current vertex
GLsizei faceCount = cubeVertices[i].connectedFaceCount;
for(int j = 0; j < faceCount; j++){
Index3D index = cubeVertices[i].connected_faces[j];
vec3 vectorA = cubeVertices[index.a].position;
vec3 vectorB = cubeVertices[index.b].position;
vec3 vectorC = cubeVertices[index.c].position;
vec3 vectorNormal = {0.0f, 0.0f, 0.0f};
substractVectors(&vectorB, &vectorA);
substractVectors(&vectorC, &vectorA);
makeNormal(&vectorB, &vectorC, &vectorNormal);
addVectors(&newNormal, &vectorNormal);
}
// set normal for current vertex
normalize(&newNormal);
cubeVertices[i].normal = newNormal;
}
Но теперь у меня проблема в том, что из-за триангуляции у меня иногда есть 2 нормали, указывающие в одном и том же направлении, что не приводит к моему ожидаемому {0.33f, 0.33f, 0.33f} нормали вершин.Это правильное поведение, или есть какой-то другой способ рассчитать это?
Большое спасибо за вашу помощь!