Browse Source

Smooth tangents generated by model loader

master
C. J. Howard 4 years ago
parent
commit
6efdf558ba
2 changed files with 34 additions and 12 deletions
  1. +5
    -0
      src/game/states/play-state.cpp
  2. +29
    -12
      src/resources/model-loader.cpp

+ 5
- 0
src/game/states/play-state.cpp View File

@ -212,6 +212,11 @@ void play_state_enter(game_context* ctx)
ctx->camera_system->set_camera(ctx->overworld_camera); ctx->camera_system->set_camera(ctx->overworld_camera);
auto round_eye = round_eye_archetype->create(ecs_registry); auto round_eye = round_eye_archetype->create(ecs_registry);
math::transform<float> eye_xf;
eye_xf.translation = {50, 0, 0};
eye_xf.rotation = math::angle_axis(-math::half_pi<float>, {1, 0, 0});
eye_xf.scale = float3{1, 1, 1} * 50.0f;
ec::set_transform(ecs_registry, round_eye, eye_xf, true);
ctx->overworld_scene->update_tweens(); ctx->overworld_scene->update_tweens();

+ 29
- 12
src/resources/model-loader.cpp View File

@ -206,16 +206,25 @@ model* resource_loader::load(resource_manager* resource_manager, PHYSFS_F
// Calculate faceted tangents and bitangents // Calculate faceted tangents and bitangents
if (has_tangents) if (has_tangents)
{ {
tangents.resize(faces.size());
bitangents.resize(faces.size());
tangents.resize(positions.size());
bitangents.resize(positions.size());
for (std::size_t i = 0; i < positions.size(); ++i)
{
tangents[i] = {0.0f, 0.0f, 0.0f};
bitangents[i] = {0.0f, 0.0f, 0.0f};
}
for (std::size_t i = 0; i < faces.size(); ++i) for (std::size_t i = 0; i < faces.size(); ++i)
{ {
const std::vector<std::size_t>& face = faces[i]; const std::vector<std::size_t>& face = faces[i];
const float3& a = positions[face[0]];
const float3& b = positions[face[3]];
const float3& c = positions[face[6]];
std::size_t ia = face[0];
std::size_t ib = face[3];
std::size_t ic = face[6];
const float3& a = positions[ia];
const float3& b = positions[ib];
const float3& c = positions[ic];
const float2& uva = uvs[face[1]]; const float2& uva = uvs[face[1]];
const float2& uvb = uvs[face[4]]; const float2& uvb = uvs[face[4]];
const float2& uvc = uvs[face[7]]; const float2& uvc = uvs[face[7]];
@ -226,8 +235,15 @@ model* resource_loader::load(resource_manager* resource_manager, PHYSFS_F
float2 uvca = uvc - uva; float2 uvca = uvc - uva;
float f = 1.0f / (uvba.x * uvca.y - uvca.x * uvba.y); float f = 1.0f / (uvba.x * uvca.y - uvca.x * uvba.y);
tangents[i] = math::normalize((ba * uvca.y - ca * uvba.y) * f);
bitangents[i] = math::normalize((ba * -uvca.x + ca * uvba.x) * f);
float3 tangent = (ba * uvca.y - ca * uvba.y) * f;
float3 bitangent = (ba * -uvca.x + ca * uvba.x) * f;
tangents[ia] += tangent;
tangents[ib] += tangent;
tangents[ic] += tangent;
bitangents[ia] += bitangent;
bitangents[ib] += bitangent;
bitangents[ic] += bitangent;
} }
} }
@ -275,13 +291,14 @@ model* resource_loader::load(resource_manager* resource_manager, PHYSFS_F
if (has_tangents) if (has_tangents)
{ {
const float3& normal = normals[face[k - 1]];
float3 tangent = tangents[i];
float3 bitangent = bitangents[i];
const float3& n = normals[face[k - 1]];
const float3& t = tangents[face[k - 3]];
const float3& b = bitangents[face[k - 3]];
// Gram-Schmidt orthogonalize tangent and bitangent // Gram-Schmidt orthogonalize tangent and bitangent
tangent = normalize(tangent - normal * dot(normal, tangent));
bitangent = normalize(bitangent - normal * dot(normal, bitangent));
float3 tangent = math::normalize(t - n * dot(n, t));
tangent = (math::dot(math::cross(n, t), b) < 0.0f) ? -tangent : tangent;
float3 bitangent = math::cross(n, tangent);
*(v++) = tangent.x; *(v++) = tangent.x;
*(v++) = tangent.y; *(v++) = tangent.y;

Loading…
Cancel
Save