From 28592e73a89d3d9f7ecb04ee8a9a332a1a338f5c Mon Sep 17 00:00:00 2001 From: castano Date: Mon, 28 Feb 2011 09:05:28 +0000 Subject: [PATCH] Add normal transforms and reconstruction. --- src/nvtt/TexImage.cpp | 75 +++++++++++++++++++++++++++++++++++++++++++ src/nvtt/nvtt.h | 7 ++++ 2 files changed, 82 insertions(+) diff --git a/src/nvtt/TexImage.cpp b/src/nvtt/TexImage.cpp index e2ddd5e..00500fe 100644 --- a/src/nvtt/TexImage.cpp +++ b/src/nvtt/TexImage.cpp @@ -1558,6 +1558,81 @@ void TexImage::normalizeNormalMap() nv::normalizeNormalMap(m->image); } +void TexImage::transformNormals(NormalTransform xform) +{ + if (m->image == NULL) return; + + detach(); + + const uint count = m->image->width() * m->image->height(); + for (uint i = 0; i < count; i++) { + float & x = m->image->pixel(i, 0); + float & y = m->image->pixel(i, 1); + float & z = m->image->pixel(i, 2); + Vector3 n(x, y, z); + + n = normalizeSafe(n, Vector3(0.0f), 0.0f); + + if (xform == NormalTransform_Orthographic) { + n.z = 0.0f; + } + else if (xform == NormalTransform_Stereographic) { + n.x = n.x / (1 + n.z); + n.y = n.y / (1 + n.z); + n.z = 0.0f; + } + else if (xform == NormalTransform_Paraboloid) { + float a = (n.x * n.x) + (n.y * n.y); + float b = n.z; + float c = -1.0f; + float discriminant = b * b - 4.0f * a * c; + float t = (-b + sqrtf(discriminant)) / (2.0f * a); + n.x = n.x * t; + n.y = n.y * t; + n.z = 0.0f; + } + + x = n.x; + y = n.y; + z = n.z; + } +} + +void TexImage::reconstructNormals(NormalTransform xform) +{ + if (m->image == NULL) return; + + detach(); + + const uint count = m->image->width() * m->image->height(); + for (uint i = 0; i < count; i++) { + float & x = m->image->pixel(i, 0); + float & y = m->image->pixel(i, 1); + float & z = m->image->pixel(i, 2); + Vector3 n(x, y, z); + + if (xform == NormalTransform_Orthographic) { + n.z = sqrtf(n.x * n.x + n.y * n.y); + } + else if (xform == NormalTransform_Stereographic) { + float denom = 2.0f / (1 + n.x * n.x + n.y * n.y); + n.x *= denom; + n.y *= denom; + n.z = denom - 1; + } + else if (xform == NormalTransform_Paraboloid) { + n.x = n.x; + n.y = n.y; + n.z = 1.0f - nv::clamp(n.x * n.x + n.y * n.y, 0.0f, 1.0f); + n = normalizeSafe(n, Vector3(0.0f), 0.0f); + } + + x = n.x; + y = n.y; + z = n.z; + } +} + void TexImage::flipVertically() { if (m->image == NULL) return; diff --git a/src/nvtt/nvtt.h b/src/nvtt/nvtt.h index 7151638..2530cbc 100644 --- a/src/nvtt/nvtt.h +++ b/src/nvtt/nvtt.h @@ -387,6 +387,11 @@ namespace nvtt // "Compressor" is deprecated. This should have been called "Context" typedef Compressor Context; + enum NormalTransform { + NormalTransform_Orthographic, + NormalTransform_Stereographic, + NormalTransform_Paraboloid, + }; /// A texture mipmap. struct TexImage @@ -465,6 +470,8 @@ namespace nvtt // Normal map transforms. NVTT_API void toNormalMap(float sm, float medium, float big, float large); NVTT_API void normalizeNormalMap(); + NVTT_API void transformNormals(NormalTransform xform); + NVTT_API void reconstructNormals(NormalTransform xform); // Geometric transforms. NVTT_API void flipVertically();