518 lines
18 KiB
C++
Executable File
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
|