Расчет касательного и бикасательного векторов при загрузке модели

This commit is contained in:
Ковалев Роман Евгеньевич 2023-02-02 18:57:31 +03:00 committed by R.E. Kovalev
parent 7b0ea8e1c4
commit f50d0d13a3
2 changed files with 51 additions and 0 deletions

View File

@ -11,6 +11,7 @@
#define DEFAULT_MTL_DIR "./"
class GrouptedModel loadOBJtoGroupted(const char* filename, const char* mtl_directory = DEFAULT_MTL_DIR, const char* texture_directory = DEFAULT_MTL_DIR);
void calc_tb(const GLuint* indices, const int indices_count, const glm::vec3* verteces, const glm::vec2* texCords, glm::vec3* tangent, glm::vec3* bitangent);
struct Material
{

View File

@ -274,6 +274,47 @@ inline void hash_combine(std::size_t& seed, const T& v, Rest... rest) {
hash_combine(seed, rest...);
}
// Расчет касательных и бикасательных векторов
void calc_tb(const GLuint* indices, const int indices_count, const glm::vec3* verteces, const glm::vec2* texCords, glm::vec3* tangent, glm::vec3* bitangent)
{
glm::vec2 dTex1, dTex2; // Разница по текстурным координатам
glm::vec3 dPos1, dPos2; // Разница по координатам вершин
float f; // Разность произведений
glm::vec3 tmp; // Для вычислений вектора
for (int i = 0; i < indices_count; i+=3)
{
// Разности векторов
dTex1 = texCords[indices[i+1]] - texCords[indices[i]];
dTex2 = texCords[indices[i+2]] - texCords[indices[i]];
dPos1 = verteces[indices[i+1]] - verteces[indices[i]];
dPos2 = verteces[indices[i+2]] - verteces[indices[i]];
f = dTex1.x * dTex2.y - dTex2.x * dTex1.y;
// Покомпонентное вычисление касательного вектора
tmp.x = (dTex2.y * dPos1.x - dTex1.y * dPos2.x) / f;
tmp.y = (dTex2.y * dPos1.y - dTex1.y * dPos2.y) / f;
tmp.z = (dTex2.y * dPos1.z - dTex1.y * dPos2.z) / f;
// Нормируем значение
tmp = glm::normalize(tmp);
// Добавим вектор в контейнер
tangent[indices[i ]] = tmp; // Для каждого индекса полигона
tangent[indices[i+1]] = tmp; // значение вектора
tangent[indices[i+2]] = tmp; // одинаковое
// Покомпонентное вычисление бикасательного вектора
tmp.x = (-dTex2.x * dPos1.x + dTex1.x * dPos2.x) / f;
tmp.y = (-dTex2.x * dPos1.y + dTex1.x * dPos2.y) / f;
tmp.z = (-dTex2.x * dPos1.z + dTex1.x * dPos2.z) / f;
// Нормируем значение
tmp = glm::normalize(tmp);
// Добавим вектор в контейнер
bitangent[indices[i ]] = tmp; // Для каждого индекса полигона
bitangent[indices[i+1]] = tmp; // значение вектора
bitangent[indices[i+2]] = tmp; // одинаковое
}
}
GrouptedModel loadOBJtoGroupted(const char* filename, const char* mtl_directory, const char* texture_directory)
{
GrouptedModel result;
@ -296,6 +337,7 @@ GrouptedModel loadOBJtoGroupted(const char* filename, const char* mtl_directory,
std::vector<glm::vec3> verteces; // вершины
std::vector<glm::vec3> normals; // нормали
std::vector<glm::vec2> texCords; // текстурные координаты
std::vector<glm::vec3> tangent, bitangent; // касательный и бикасательный веткоры
size_t hash; // Для уникальных вершин
std::map <int, int> uniqueVerteces; // словарь для уникальных вершин: ключ - хеш, значение - индекс вершины
@ -362,10 +404,18 @@ GrouptedModel loadOBJtoGroupted(const char* filename, const char* mtl_directory,
// Изменим размер массивов
tangent.resize(verteces.size());
bitangent.resize(verteces.size());
// Расчет касательных и бикасательных векторов
calc_tb(indices.data(), indices.size(), verteces.data(), texCords.data(), tangent.data(), bitangent.data());
// Загрузка в буферы
model.load_verteces (&verteces[0], verteces.size());
model.load_normals (&normals[0], normals.size());
model.load_texCoords(&texCords[0], texCords.size());
model.load_tangent(&tangent[0], tangent.size());
model.load_bitangent(&bitangent[0], bitangent.size());
// Загрузка индексного буфера
model.load_indices (&indices[0], indices.size());