Add support for loading PSD files.

Add missing files.
This commit is contained in:
castano
2007-07-02 07:27:23 +00:00
parent b2252fc828
commit 68b0c2697c
7 changed files with 482 additions and 0 deletions

173
src/nvmath/Basis.cpp Normal file
View File

@ -0,0 +1,173 @@
// This code is in the public domain -- castanyo@yahoo.es
#include <nvmath/Basis.h>
using namespace nv;
/// Normalize basis vectors.
void Basis::normalize(float epsilon /*= NV_EPSILON*/)
{
normal = ::normalize(normal, epsilon);
tangent = ::normalize(tangent, epsilon);
bitangent = ::normalize(bitangent, epsilon);
}
/// Gram-Schmidt orthogonalization.
/// @note Works only if the vectors are close to orthogonal.
void Basis::orthonormalize(float epsilon /*= NV_EPSILON*/)
{
// N' = |N|
// T' = |T - (N' dot T) N'|
// B' = |B - (N' dot B) N' - (T' dot B) T'|
normal = ::normalize(normal, epsilon);
tangent -= normal * dot(normal, tangent);
tangent = ::normalize(tangent, epsilon);
bitangent -= normal * dot(normal, bitangent);
bitangent -= tangent * dot(tangent, bitangent);
bitangent = ::normalize(bitangent, epsilon);
}
/// Robust orthonormalization.
/// Returns an orthonormal basis even when the original is degenerate.
void Basis::robustOrthonormalize(float epsilon /*= NV_EPSILON*/)
{
if (length(normal) < epsilon)
{
normal = cross(tangent, bitangent);
if (length(normal) < epsilon)
{
tangent = Vector3(1, 0, 0);
bitangent = Vector3(0, 1, 0);
normal = Vector3(0, 0, 1);
return;
}
}
normal = ::normalize(normal, epsilon);
tangent -= normal * dot(normal, tangent);
bitangent -= normal * dot(normal, bitangent);
if (length(tangent) < epsilon)
{
if (length(bitangent) < epsilon)
{
buildFrameForDirection(normal);
}
else
{
tangent = cross(bitangent, normal);
nvCheck(isNormalized(tangent, epsilon));
}
}
else
{
tangent = ::normalize(tangent, epsilon);
bitangent -= tangent * dot(tangent, bitangent);
if (length(bitangent) < epsilon)
{
bitangent = cross(tangent, normal);
nvCheck(isNormalized(bitangent));
}
else
{
tangent = ::normalize(tangent, epsilon);
}
}
// Check vector lengths.
nvCheck(isNormalized(normal, epsilon));
nvCheck(isNormalized(tangent, epsilon));
nvCheck(isNormalized(bitangent, epsilon));
// Check vector angles.
nvCheck(equal(dot(normal, tangent), 0.0f, epsilon));
nvCheck(equal(dot(normal, bitangent), 0.0f, epsilon));
nvCheck(equal(dot(tangent, bitangent), 0.0f, epsilon));
// Check vector orientation.
const float det = dot(cross(normal, tangent), bitangent);
nvCheck(equal(det, 1.0f, epsilon) || equal(det, -1.0f, epsilon));
}
/// Build an arbitrary frame for the given direction.
void Basis::buildFrameForDirection(Vector3::Arg d)
{
nvCheck(isNormalized(d));
normal = d;
// Choose minimum axis.
if (fabsf(normal.x()) < fabsf(normal.y()) && fabsf(normal.x()) < fabsf(normal.z()))
{
tangent = Vector3(1, 0, 0);
}
else if (fabsf(normal.y()) < fabsf(normal.z()))
{
tangent = Vector3(0, 1, 0);
}
else
{
tangent = Vector3(0, 0, 1);
}
// Ortogonalize
tangent -= normal * dot(normal, tangent);
tangent = ::normalize(tangent);
bitangent = cross(normal, tangent);
}
/*
/// Transform by this basis. (From this basis to object space).
Vector3 Basis::transform(Vector3::Arg v) const
{
Vector3 o = tangent * v.x();
o += bitangent * v.y();
o += normal * v.z();
return o;
}
/// Transform by the transpose. (From object space to this basis).
Vector3 Basis::transformT(Vector3::Arg v)
{
return Vector3(dot(tangent, v), dot(bitangent, v), dot(normal, v));
}
/// Transform by the inverse. (From object space to this basis).
/// @note Uses Kramer's rule so the inverse is not accurate if the basis is ill-conditioned.
Vector3 Basis::transformI(Vector3::Arg v) const
{
const float det = determinant();
nvCheck(!equalf(det, 0.0f));
const float idet = 1.0f / det;
// Rows of the inverse matrix.
Vector3 r0, r1, r2;
r0.x = (bitangent.y() * normal.z() - bitangent.z() * normal.y()) * idet;
r0.y = -(bitangent.x() * normal.z() - bitangent.z() * normal.x()) * idet;
r0.z = (bitangent.x() * normal.y() - bitangent.y() * normal.x()) * idet;
r1.x = -(tangent.y() * normal.z() - tangent.z() * normal.y()) * idet;
r1.y = (tangent.x() * normal.z() - tangent.z() * normal.x()) * idet;
r1.z = -(tangent.x() * normal.y() - tangent.y() * normal.x()) * idet;
r2.x = (tangent.y() * bitangent.z() - tangent.z() * bitangent.y()) * idet;
r2.y = -(tangent.x() * bitangent.z() - tangent.z() * bitangent.x()) * idet;
r2.z = (tangent.x() * bitangent.y() - tangent.y() * bitangent.x()) * idet;
return Vector3(dot(v, r0), dot(v, r1), dot(v, r2));
}
*/

78
src/nvmath/Basis.h Normal file
View File

@ -0,0 +1,78 @@
// This code is in the public domain -- castanyo@yahoo.es
#ifndef NV_MATH_BASIS_H
#define NV_MATH_BASIS_H
#include <nvmath/nvmath.h>
#include <nvmath/Vector.h>
#include <nvmath/Matrix.h>
namespace nv
{
/// Basis class to compute tangent space basis, ortogonalizations and to
/// transform vectors from one space to another.
struct Basis
{
/// Create a null basis.
Basis() : tangent(0, 0, 0), bitangent(0, 0, 0), normal(0, 0, 0) {}
/// Create a basis given three vectors.
Basis(Vector3::Arg n, Vector3::Arg t, Vector3::Arg b) : tangent(t), bitangent(b), normal(n) {}
/// Create a basis with the given tangent vectors and the handness.
Basis(Vector3::Arg n, Vector3::Arg t, float sign)
{
build(n, t, sign);
}
NVMATH_API void normalize(float epsilon = NV_EPSILON);
NVMATH_API void orthonormalize(float epsilon = NV_EPSILON);
NVMATH_API void robustOrthonormalize(float epsilon = NV_EPSILON);
NVMATH_API void buildFrameForDirection(Vector3::Arg d);
/// Calculate the determinant [ F G N ] to obtain the handness of the basis.
float handness() const
{
return determinant() > 0.0f ? 1.0f : -1.0f;
}
/// Build a basis from 2 vectors and a handness flag.
void build(Vector3::Arg n, Vector3::Arg t, float sign)
{
normal = n;
tangent = t;
bitangent = sign * cross(t, n);
}
/// Compute the determinant of this basis.
float determinant() const
{
return
tangent.x() * bitangent.y() * normal.z() - tangent.z() * bitangent.y() * normal.x() +
tangent.y() * bitangent.z() * normal.x() - tangent.y() * bitangent.x() * normal.z() +
tangent.z() * bitangent.x() * normal.y() - tangent.x() * bitangent.z() * normal.y();
}
/*
// Get transform matrix for this basis.
NVMATH_API Matrix matrix() const;
// Transform by this basis. (From this basis to object space).
NVMATH_API Vector3 transform(Vector3::Arg v) const;
// Transform by the transpose. (From object space to this basis).
NVMATH_API Vector3 transformT(Vector3::Arg v);
// Transform by the inverse. (From object space to this basis).
NVMATH_API Vector3 transformI(Vector3::Arg v) const;
*/
Vector3 tangent;
Vector3 bitangent;
Vector3 normal;
};
} // nv namespace
#endif // NV_MATH_BASIS_H