Files
nvidia-texture-tools/src/nvtt/bc6h/arvo/Vec3.h
2010-05-29 02:47:57 +00:00

518 lines
18 KiB
C++
Executable File

/***************************************************************************
* Vec3.h *
* *
* Basic operations on 3-dimensional vectors. This special case is useful *
* because many operations are performed inline. *
* *
* HISTORY *
* Name Date Description *
* *
* arvo 10/27/94 Reorganized (removed Col & Row distinction). *
* arvo 06/14/93 Initial coding. *
* *
*--------------------------------------------------------------------------*
* Copyright (C) 1994, James Arvo *
* *
* This program is free software; you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the *
* Free Software Foundation. See http://www.fsf.org/copyleft/gpl.html *
* *
* This program is distributed in the hope that it will be useful, but *
* WITHOUT EXPRESS OR IMPLIED WARRANTY of merchantability or fitness for *
* any particular purpose. See the GNU General Public License for more *
* details. *
* *
***************************************************************************/
#ifndef __VEC3_INCLUDED__
#define __VEC3_INCLUDED__
#include <math.h>
#include <iostream>
#include "Vec2.h"
namespace ArvoMath {
class Vec3 {
public:
Vec3( float c = 0.0 ) { x = c; y = c; z = c; }
Vec3( float a, float b, float c ) { x = a; y = b; z = c; }
Vec3( const Vec3 &A ) { x = A.X(); y = A.Y(); z = A.Z(); }
void operator=( float c ) { x = c; y = c; z = c; }
void operator=( const Vec3 &A ) { x = A.X(); y = A.Y(); z = A.Z(); }
void operator=( const Vec2 &A ) { x = A.X(); y = A.Y(); z = 0.0; }
~Vec3() {}
float X() const { return x; }
float Y() const { return y; }
float Z() const { return z; }
float & X() { return x; }
float & Y() { return y; }
float & Z() { return z; }
float operator[]( int i ) const { return *( &x + i ); }
float & operator[]( int i ) { return *( &x + i ); }
private:
float x, y, z;
};
//class Mat3x3 {
//public:
// inline Mat3x3( );
// Mat3x3( const Mat3x3 &M ) { *this = M; }
// Mat3x3( const Vec3 &, const Vec3 &, const Vec3 & ); // Three columns.
// ~Mat3x3( ) {}
// float operator()( int i, int j ) const { return m[i][j]; }
// float & operator()( int i, int j ) { return m[i][j]; }
// Mat3x3 & operator=( float );
// Mat3x3 & operator=( const Mat3x3 & );
// inline void ScaleRows( float, float, float );
// inline void ScaleCols( float, float, float );
// void Col( int n, const Vec3 & );
// const float *Base() const { return &(m[0][0]); }
//private:
// float m[3][3];
//};
//class Mat4x4 {
//public:
// Mat4x4( );
// Mat4x4( const Mat4x4 &M ) { *this = M; }
// Mat4x4( const Mat3x3 &M ) ;
// ~Mat4x4( ) {}
// float operator()( int i, int j ) const { return m[i][j]; }
// float & operator()( int i, int j ) { return m[i][j]; }
// Mat4x4 & operator=( float );
// Mat4x4 & operator=( const Mat4x4 & );
// void Row( int i, int j, const Vec3 & );
// void Col( int i, int j, const Vec3 & );
// void ScaleRows( float, float, float, float );
// void ScaleCols( float, float, float, float );
// const float *Base() const { return &(m[0][0]); }
//private:
// float m[4][4];
//};
//==========================================
//=== External operators ===
//==========================================
//extern Vec3 operator * ( const Mat4x4 &, const Vec3 & );
//extern Vec3 operator * ( const Vec3 &, const Mat4x4 & );
//extern Mat3x3 operator * ( float , const Mat3x3 & );
//extern Mat3x3 operator * ( const Mat3x3 &, float );
//extern Mat3x3 operator / ( const Mat3x3 &, double );
//extern Mat3x3 & operator *=( Mat3x3 &, float );
//extern Mat3x3 & operator *=( Mat3x3 &, const Mat3x3 & );
//extern Mat3x3 operator * ( const Mat3x3 &, const Mat3x3 & );
//extern Mat3x3 operator + ( const Mat3x3 &, const Mat3x3 & );
//extern Mat3x3 & operator +=( Mat3x3 &, const Mat3x3 & );
//extern Mat3x3 operator - ( const Mat3x3 &, const Mat3x3 & );
//extern Mat3x3 & operator -=( Mat3x3 &, const Mat3x3 & );
//extern Mat4x4 operator * ( float , const Mat4x4 & );
//extern Mat4x4 operator * ( const Mat4x4 &, float );
//extern Mat4x4 operator / ( const Mat4x4 &, float );
//extern Mat4x4 & operator *=( Mat4x4 &, float );
//extern Mat4x4 operator * ( const Mat4x4 &, const Mat4x4 & );
//extern Mat4x4 operator + ( const Mat4x4 &, const Mat4x4 & );
//extern Mat4x4 & operator +=( Mat4x4 &, const Mat4x4 & );
//extern Mat4x4 operator - ( const Mat4x4 &, const Mat4x4 & );
//extern Mat4x4 & operator -=( Mat4x4 &, const Mat4x4 & );
//==========================================
//=== Miscellaneous external functions ===
//==========================================
//extern Vec3 OrthogonalTo( const Vec3 & ); // A vector orthogonal to that given.
//extern Vec3 Min ( const Vec3 &, const Vec3 & );
//extern Vec3 Max ( const Vec3 &, const Vec3 & );
//extern double Angle ( const Vec3 &, const Vec3 & );
//extern int Orthonormal ( Vec3 &, Vec3 & );
//extern int Orthonormal ( Vec3 &, Vec3 &, Vec3 & );
//extern float Trace ( const Mat3x3 & );
//extern float Normalize ( Vec3 & );
//extern float Norm1 ( const Mat3x3 & );
//extern float SupNorm ( const Mat3x3 & );
//extern double Determinant ( const Mat3x3 & );
//extern Mat3x3 Transp ( const Mat3x3 & );
//extern Mat3x3 Householder ( const Vec3 &, const Vec3 & );
//extern Mat3x3 Householder ( const Vec3 & );
//extern Mat3x3 Rotation3x3 ( float, float, float ); // Values in [0,1].
//extern Mat3x3 Inverse ( const Mat3x3 & );
//extern Mat3x3 Diag3x3 ( const Vec3 & );
//extern Mat3x3 Diag3x3 ( float, float, float );
//extern Mat3x3 Rotation3x3 ( const Vec3 &Axis, float angle );
//extern Mat4x4 Rotation4x4 ( const Vec3 &Axis, const Vec3 &Origin, float angle );
//==========================================
//=== Norm-related functions ===
//==========================================
inline double LenSqr ( const Vec3 &A ) { return Sqr(A[0]) + Sqr(A[1]) + Sqr(A[2]); }
inline double Len ( const Vec3 &A ) { return Sqrt( LenSqr( A ) ); }
inline double Norm1 ( const Vec3 &A ) { return Abs(A[0]) + Abs(A[1]) + Abs(A[2]); }
inline double Norm2 ( const Vec3 &A ) { return Len( A ); }
inline float SupNorm( const Vec3 &A ) { return MaxAbs( A[0], A[1], A[2] ); }
//==========================================
//=== Addition ===
//==========================================
inline Vec3 operator+( const Vec3 &A, const Vec3 &B )
{
return Vec3( A.X() + B.X(), A.Y() + B.Y(), A.Z() + B.Z() );
}
inline Vec3& operator+=( Vec3 &A, const Vec3 &B )
{
A.X() += B.X();
A.Y() += B.Y();
A.Z() += B.Z();
return A;
}
//==========================================
//=== Subtraction ===
//==========================================
inline Vec3 operator-( const Vec3 &A, const Vec3 &B )
{
return Vec3( A.X() - B.X(), A.Y() - B.Y(), A.Z() - B.Z() );
}
inline Vec3 operator-( const Vec3 &A )
{
return Vec3( -A.X(), -A.Y(), -A.Z() );
}
inline Vec3& operator-=( Vec3 &A, const Vec3 &B )
{
A.X() -= B.X();
A.Y() -= B.Y();
A.Z() -= B.Z();
return A;
}
//==========================================
//=== Multiplication ===
//==========================================
inline Vec3 operator*( float a, const Vec3 &x )
{
return Vec3( a * x.X(), a * x.Y(), a * x.Z() );
}
inline Vec3 operator*( const Vec3 &x, float a )
{
return Vec3( a * x.X(), a * x.Y(), a * x.Z() );
}
inline float operator*( const Vec3 &A, const Vec3 &B ) // Inner product.
{
return A.X() * B.X() + A.Y() * B.Y() + A.Z() * B.Z();
}
inline Vec3& operator*=( Vec3 &A, float a )
{
A.X() *= a;
A.Y() *= a;
A.Z() *= a;
return A;
}
//inline Vec3& operator*=( Vec3 &A, const Mat3x3 &M ) // A = M * A
//{
// float x = M(0,0) * A.X() + M(0,1) * A.Y() + M(0,2) * A.Z();
// float y = M(1,0) * A.X() + M(1,1) * A.Y() + M(1,2) * A.Z();
// float z = M(2,0) * A.X() + M(2,1) * A.Y() + M(2,2) * A.Z();
// A.X() = x;
// A.Y() = y;
// A.Z() = z;
// return A;
//}
//inline Vec3& operator*=( Vec3 &A, const Mat4x4 &M ) // A = M * A
//{
// float x = M(0,0) * A.X() + M(0,1) * A.Y() + M(0,2) * A.Z() + M(0,3);
// float y = M(1,0) * A.X() + M(1,1) * A.Y() + M(1,2) * A.Z() + M(1,3);
// float z = M(2,0) * A.X() + M(2,1) * A.Y() + M(2,2) * A.Z() + M(2,3);
// A.X() = x;
// A.Y() = y;
// A.Z() = z;
// return A;
//}
//==========================================
//=== Division ===
//==========================================
inline Vec3 operator/( const Vec3 &A, double c )
{
double t = 1.0 / c;
return Vec3( A.X() * t, A.Y() * t, A.Z() * t );
}
inline Vec3& operator/=( Vec3 &A, double a )
{
A.X() /= a;
A.Y() /= a;
A.Z() /= a;
return A;
}
inline Vec3 operator/( const Vec3 &A, const Vec3 &B ) // Remove component parallel to B.
{
Vec3 C; // Cumbersome due to compiler falure.
double x = LenSqr( B );
if( x > 0.0 ) C = A - B * (( A * B ) / x); else C = A;
return C;
}
inline void operator/=( Vec3 &A, const Vec3 &B ) // Remove component parallel to B.
{
double x = LenSqr( B );
if( x > 0.0 ) A -= B * (( A * B ) / x);
}
//==========================================
//=== Miscellaneous ===
//==========================================
inline float operator|( const Vec3 &A, const Vec3 &B ) // Inner product.
{
return A * B;
}
inline Vec3 Unit( const Vec3 &A )
{
double d = LenSqr( A );
return d > 0.0 ? A / sqrt(d) : Vec3(0,0,0);
}
inline Vec3 Unit( float x, float y, float z )
{
return Unit( Vec3( x, y, z ) );
}
inline Vec3 Ortho( const Vec3 &A, const Vec3 &B )
{
return Unit( A / B );
}
inline int operator==( const Vec3 &A, float x )
{
return (A[0] == x) && (A[1] == x) && (A[2] == x);
}
inline Vec3 operator^( const Vec3 &A, const Vec3 &B )
{
return Vec3(
A.Y() * B.Z() - A.Z() * B.Y(),
A.Z() * B.X() - A.X() * B.Z(),
A.X() * B.Y() - A.Y() * B.X() );
}
inline double dist( const Vec3 &A, const Vec3 &B )
{
return Len( A - B );
}
inline double Dihedral( const Vec3 &A, const Vec3 &B, const Vec3 &C )
{
return ArcCos( Unit( A ^ B ) * Unit( C ^ B ) );
}
inline Vec3 operator>>( const Vec3 &A, const Vec3 &B ) // Project A onto B.
{
Vec3 C;
double x = LenSqr( B );
if( x > 0.0 ) C = B * (( A * B ) / x);
return C;
}
inline Vec3 operator<<( const Vec3 &A, const Vec3 &B ) // Project B onto A.
{
return B >> A;
}
inline double Triple( const Vec3 &A, const Vec3 &B, const Vec3 &C )
{
return ( A ^ B ) * C;
}
//==========================================
//=== Operations involving Matrices ===
//==========================================
//inline Mat3x3 Outer( const Vec3 &A, const Vec3 &B ) // Outer product.
//{
// Mat3x3 C;
// C(0,0) = A.X() * B.X();
// C(0,1) = A.X() * B.Y();
// C(0,2) = A.X() * B.Z();
// C(1,0) = A.Y() * B.X();
// C(1,1) = A.Y() * B.Y();
// C(1,2) = A.Y() * B.Z();
// C(2,0) = A.Z() * B.X();
// C(2,1) = A.Z() * B.Y();
// C(2,2) = A.Z() * B.Z();
// return C;
//}
//inline Vec3 operator*( const Mat3x3 &M, const Vec3 &A )
//{
// return Vec3(
// M(0,0) * A[0] + M(0,1) * A[1] + M(0,2) * A[2],
// M(1,0) * A[0] + M(1,1) * A[1] + M(1,2) * A[2],
// M(2,0) * A[0] + M(2,1) * A[1] + M(2,2) * A[2]);
//}
//inline Vec3 operator*( const Vec3 &A, const Mat3x3 &M )
//{
// return Vec3(
// A[0] * M(0,0) + A[1] * M(1,0) + A[2] * M(2,0),
// A[0] * M(0,1) + A[1] * M(1,1) + A[2] * M(2,1),
// A[0] * M(0,2) + A[1] * M(1,2) + A[2] * M(2,2));
//}
////==========================================
////=== Operations on Matrices ===
////==========================================
//inline Mat3x3 operator+( const Mat3x3 &A, const Mat3x3 &B )
//{
// Mat3x3 C;
// C(0,0) = A(0,0) + B(0,0); C(0,1) = A(0,1) + B(0,1); C(0,2) = A(0,2) + B(0,2);
// C(1,0) = A(1,0) + B(1,0); C(1,1) = A(1,1) + B(1,1); C(1,2) = A(1,2) + B(1,2);
// C(2,0) = A(2,0) + B(2,0); C(2,1) = A(2,1) + B(2,1); C(2,2) = A(2,2) + B(2,2);
// return C;
//}
//inline Mat3x3 operator-( const Mat3x3 &A, const Mat3x3 &B )
//{
// Mat3x3 C;
// C(0,0) = A(0,0) - B(0,0); C(0,1) = A(0,1) - B(0,1); C(0,2) = A(0,2) - B(0,2);
// C(1,0) = A(1,0) - B(1,0); C(1,1) = A(1,1) - B(1,1); C(1,2) = A(1,2) - B(1,2);
// C(2,0) = A(2,0) - B(2,0); C(2,1) = A(2,1) - B(2,1); C(2,2) = A(2,2) - B(2,2);
// return C;
//}
//inline Mat3x3 operator*( const Mat3x3 &A, const Mat3x3 &B )
//{
// Mat3x3 C;
// C(0,0) = A(0,0) * B(0,0) + A(0,1) * B(1,0) + A(0,2) * B(2,0);
// C(0,1) = A(0,0) * B(0,1) + A(0,1) * B(1,1) + A(0,2) * B(2,1);
// C(0,2) = A(0,0) * B(0,2) + A(0,1) * B(1,2) + A(0,2) * B(2,2);
// C(1,0) = A(1,0) * B(0,0) + A(1,1) * B(1,0) + A(1,2) * B(2,0);
// C(1,1) = A(1,0) * B(0,1) + A(1,1) * B(1,1) + A(1,2) * B(2,1);
// C(1,2) = A(1,0) * B(0,2) + A(1,1) * B(1,2) + A(1,2) * B(2,2);
// C(2,0) = A(2,0) * B(0,0) + A(2,1) * B(1,0) + A(2,2) * B(2,0);
// C(2,1) = A(2,0) * B(0,1) + A(2,1) * B(1,1) + A(2,2) * B(2,1);
// C(2,2) = A(2,0) * B(0,2) + A(2,1) * B(1,2) + A(2,2) * B(2,2);
// return C;
//}
//inline void Mat3x3::ScaleRows( float a, float b, float c )
//{
// m[0][0] *= a; m[0][1] *= a; m[0][2] *= a;
// m[1][0] *= b; m[1][1] *= b; m[1][2] *= b;
// m[2][0] *= c; m[2][1] *= c; m[2][2] *= c;
//}
//inline void Mat3x3::ScaleCols( float a, float b, float c )
//{
// m[0][0] *= a; m[0][1] *= b; m[0][2] *= c;
// m[1][0] *= a; m[1][1] *= b; m[1][2] *= c;
// m[2][0] *= a; m[2][1] *= b; m[2][2] *= c;
//}
//==========================================
//=== Special Matrices ===
//==========================================
//inline Mat3x3::Mat3x3()
//{
// m[0][0] = 0; m[0][1] = 0; m[0][2] = 0;
// m[1][0] = 0; m[1][1] = 0; m[1][2] = 0;
// m[2][0] = 0; m[2][1] = 0; m[2][2] = 0;
//}
//inline Mat3x3 Ident3x3()
//{
// Mat3x3 I;
// I(0,0) = 1.0;
// I(1,1) = 1.0;
// I(2,2) = 1.0;
// return I;
//}
//inline Mat4x4 Ident4x4()
//{
// Mat4x4 I;
// I(0,0) = 1.0;
// I(1,1) = 1.0;
// I(2,2) = 1.0;
// I(3,3) = 1.0;
// return I;
//}
//inline void Adjoint( const Mat3x3 &M, Mat3x3 &A )
//{
// A(0,0) = M(1,1) * M(2,2) - M(1,2) * M(2,1);
// A(0,1) = M(1,2) * M(2,0) - M(1,0) * M(2,2);
// A(0,2) = M(1,0) * M(2,1) - M(1,1) * M(2,0);
// A(1,0) = M(0,2) * M(2,1) - M(0,1) * M(2,2);
// A(1,1) = M(0,0) * M(2,2) - M(0,2) * M(2,0);
// A(1,2) = M(0,1) * M(2,0) - M(0,0) * M(2,1);
// A(2,0) = M(0,1) * M(1,2) - M(0,2) * M(1,1);
// A(2,1) = M(0,2) * M(1,0) - M(0,0) * M(1,2);
// A(2,2) = M(0,0) * M(1,1) - M(0,1) * M(1,0);
//}
//inline void TranspAdjoint( const Mat3x3 &M, Mat3x3 &A )
//{
// A(0,0) = M(1,1) * M(2,2) - M(1,2) * M(2,1);
// A(1,0) = M(1,2) * M(2,0) - M(1,0) * M(2,2);
// A(2,0) = M(1,0) * M(2,1) - M(1,1) * M(2,0);
// A(0,1) = M(0,2) * M(2,1) - M(0,1) * M(2,2);
// A(1,1) = M(0,0) * M(2,2) - M(0,2) * M(2,0);
// A(2,1) = M(0,1) * M(2,0) - M(0,0) * M(2,1);
// A(0,2) = M(0,1) * M(1,2) - M(0,2) * M(1,1);
// A(1,2) = M(0,2) * M(1,0) - M(0,0) * M(1,2);
// A(2,2) = M(0,0) * M(1,1) - M(0,1) * M(1,0);
//}
//inline void Adjoint( const Mat3x3 &M, Mat3x3 &A, double &det )
//{
// Adjoint( M, A );
// det = A(0,0) * M(0,0) + A(1,0) * M(1,0) + A(2,0) * M(2,0);
//}
//inline void TranspAdjoint( const Mat3x3 &M, Mat3x3 &A, double &det )
//{
// TranspAdjoint( M, A );
// det = A(0,0) * M(0,0) + A(0,1) * M(1,0) + A(0,2) * M(2,0);
//}
//==========================================
//=== Output routines ===
//==========================================
extern std::ostream &operator<<( std::ostream &out, const Vec3 & );
//extern std::ostream &operator<<( std::ostream &out, const Mat3x3 & );
//extern std::ostream &operator<<( std::ostream &out, const Mat4x4 & );
};
#endif