You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nvidia-texture-tools/src/nvtt/bc7/arvo/Vec4.h

239 lines
8.0 KiB
C++

/***************************************************************************
* Vec4.h *
* *
* Basic operations on 4-dimensional vectors. This special case is useful *
* because many operations are performed inline. *
* *
* HISTORY *
* Name Date Description *
* *
* walt 6/26/07 Edited Vec3 to make this new class *
* 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 __Vec4_INCLUDED__
#define __Vec4_INCLUDED__
#include <math.h>
#include <iostream>
#include "Vec2.h"
#include "Vec3.h"
namespace ArvoMath {
class Vec4 {
public:
Vec4( float c = 0.0 ) { x = c; y = c; z = c; w = c; }
Vec4( float a, float b, float c, float d ) { x = a; y = b; z = c; w = d; }
Vec4( const Vec4 &A ) { x = A.X(); y = A.Y(); z = A.Z(); w = A.W(); }
Vec4( const Vec3 &A, float d ) { x = A.X(); y = A.Y(); z = A.Z(); w = d; }
void operator=( float c ) { x = c; y = c; z = c; w = c; }
void operator=( const Vec4 &A ) { x = A.X(); y = A.Y(); z = A.Z(); w = A.W(); }
void operator=( const Vec3 &A ) { x = A.X(); y = A.Y(); z = A.Z(); w = 0.0; }
void operator=( const Vec2 &A ) { x = A.X(); y = A.Y(); z = 0.0; w = 0.0; }
~Vec4() {}
float X() const { return x; }
float Y() const { return y; }
float Z() const { return z; }
float W() const { return w; }
float & X() { return x; }
float & Y() { return y; }
float & Z() { return z; }
float & W() { return w; }
float operator[]( int i ) const { return *( &x + i ); }
float & operator[]( int i ) { return *( &x + i ); }
private:
float x, y, z, w;
};
//==========================================
//=== Norm-related functions ===
//==========================================
inline double LenSqr ( const Vec4 &A ) { return Sqr(A[0]) + Sqr(A[1]) + Sqr(A[2]) + Sqr(A[3]); }
inline double Len ( const Vec4 &A ) { return Sqrt( LenSqr( A ) ); }
inline double Norm1 ( const Vec4 &A ) { return Abs(A[0]) + Abs(A[1]) + Abs(A[2]) + Abs(A[3]); }
inline double Norm2 ( const Vec4 &A ) { return Len( A ); }
inline float SupNorm( const Vec4 &A ) { return MaxAbs( A[0], A[1], A[2], A[3] ); }
//==========================================
//=== Addition ===
//==========================================
inline Vec4 operator+( const Vec4 &A, const Vec4 &B )
{
return Vec4( A.X() + B.X(), A.Y() + B.Y(), A.Z() + B.Z(), A.W() + B.W() );
}
inline Vec4& operator+=( Vec4 &A, const Vec4 &B )
{
A.X() += B.X();
A.Y() += B.Y();
A.Z() += B.Z();
A.W() += B.W();
return A;
}
//==========================================
//=== Subtraction ===
//==========================================
inline Vec4 operator-( const Vec4 &A, const Vec4 &B )
{
return Vec4( A.X() - B.X(), A.Y() - B.Y(), A.Z() - B.Z(), A.W() - B.W());
}
inline Vec4 operator-( const Vec4 &A )
{
return Vec4( -A.X(), -A.Y(), -A.Z(), -A.W() );
}
inline Vec4& operator-=( Vec4 &A, const Vec4 &B )
{
A.X() -= B.X();
A.Y() -= B.Y();
A.Z() -= B.Z();
A.W() -= B.W();
return A;
}
//==========================================
//=== Multiplication ===
//==========================================
inline Vec4 operator*( float a, const Vec4 &x )
{
return Vec4( a * x.X(), a * x.Y(), a * x.Z(), a * x.W() );
}
inline Vec4 operator*( const Vec4 &x, float a )
{
return Vec4( a * x.X(), a * x.Y(), a * x.Z(), a * x.W() );
}
inline float operator*( const Vec4 &A, const Vec4 &B ) // Inner product.
{
return A.X() * B.X() + A.Y() * B.Y() + A.Z() * B.Z() + A.W() * B.W();
}
inline Vec4& operator*=( Vec4 &A, float a )
{
A.X() *= a;
A.Y() *= a;
A.Z() *= a;
A.W() *= a;
return A;
}
//==========================================
//=== Division ===
//==========================================
inline Vec4 operator/( const Vec4 &A, double c )
{
double t = 1.0 / c;
return Vec4( A.X() * t, A.Y() * t, A.Z() * t, A.W() * t);
}
inline Vec4& operator/=( Vec4 &A, double a )
{
A.X() /= a;
A.Y() /= a;
A.Z() /= a;
A.W() /= a;
return A;
}
inline Vec4 operator/( const Vec4 &A, const Vec4 &B ) // Remove component parallel to B.
{
Vec4 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/=( Vec4 &A, const Vec4 &B ) // Remove component parallel to B.
{
double x = LenSqr( B );
if( x > 0.0 ) A -= B * (( A * B ) / x);
}
//==========================================
//=== Miscellaneous ===
//==========================================
inline float operator|( const Vec4 &A, const Vec4 &B ) // Inner product.
{
return A * B;
}
inline Vec4 Unit( const Vec4 &A )
{
double d = LenSqr( A );
return d > 0.0 ? A / sqrt(d) : Vec4(0,0,0,0);
}
inline Vec4 Unit( float x, float y, float z, float w )
{
return Unit( Vec4( x, y, z, w ) );
}
inline Vec4 Ortho( const Vec4 &A, const Vec4 &B )
{
return Unit( A / B );
}
inline int operator==( const Vec4 &A, float x )
{
return (A[0] == x) && (A[1] == x) && (A[2] == x) && (A[3] == x);
}
// inline Vec4 operator^( const Vec4 &A, const Vec4 &B ) there is no 4ED "cross product" of 2 4D vectors -- we need six dimensions
inline double dist( const Vec4 &A, const Vec4 &B )
{
return Len( A - B );
}
// inline double Dihedral( const Vec4 &A, const Vec4 &B, const Vec4 &C )
inline Vec4 operator>>( const Vec4 &A, const Vec4 &B ) // Project A onto B.
{
Vec4 C;
double x = LenSqr( B );
if( x > 0.0 ) C = B * (( A * B ) / x);
return C;
}
inline Vec4 operator<<( const Vec4 &A, const Vec4 &B ) // Project B onto A.
{
return B >> A;
}
// inline double Triple( const Vec4 &A, const Vec4 &B, const Vec4 &C )
//==========================================
//=== Output routines ===
//==========================================
extern std::ostream &operator<<( std::ostream &out, const Vec4 & );
};
#endif