├── .gitignore ├── DataStructs ├── Array.h ├── CLinkedList.h ├── DataStructs.vcproj ├── DoubleRecurse.cpp ├── DoubleRecurse.h ├── KdTree.cpp ├── KdTree.h ├── ShellSort.h └── Stack.h ├── Graphics ├── BumpMapFunction.cpp ├── BumpMapFunction.h ├── CameraView.cpp ├── CameraView.h ├── DirectLight.cpp ├── DirectLight.h ├── Extents.cpp ├── Extents.h ├── Graphics.vcproj ├── Light.h ├── Material.cpp ├── Material.h ├── MaterialBase.h ├── MaterialCookTorrance.cpp ├── MaterialCookTorrance.h ├── PixelArray.cpp ├── PixelArray.h ├── RgbImage.cpp ├── RgbImage.h ├── TextureAffineXform.cpp ├── TextureAffineXform.h ├── TextureBilinearXform.cpp ├── TextureBilinearXform.h ├── TextureCheckered.cpp ├── TextureCheckered.h ├── TextureMapBase.cpp ├── TextureMapBase.h ├── TextureMultiFaces.cpp ├── TextureMultiFaces.h ├── TextureRgbImage.cpp ├── TextureRgbImage.h ├── TextureSequence.cpp ├── TextureSequence.h ├── TransformViewable.cpp ├── TransformViewable.h ├── ViewableBase.cpp ├── ViewableBase.h ├── ViewableBezierSet.cpp ├── ViewableBezierSet.h ├── ViewableCone.cpp ├── ViewableCone.h ├── ViewableCylinder.cpp ├── ViewableCylinder.h ├── ViewableEllipsoid.cpp ├── ViewableEllipsoid.h ├── ViewableParallelepiped.cpp ├── ViewableParallelepiped.h ├── ViewableParallelogram.cpp ├── ViewableParallelogram.h ├── ViewableSphere.cpp ├── ViewableSphere.h ├── ViewableTorus.cpp ├── ViewableTorus.h ├── ViewableTriangle.cpp ├── ViewableTriangle.h └── VisiblePoint.h ├── Makefile ├── OpenglRender ├── GlutRenderer.cpp ├── GlutRenderer.h └── OpenglRender.vcproj ├── README.md ├── RayTrace ├── RayTrace.cpp ├── RayTrace.vcproj ├── RayTraceData.cpp └── RayTraceData.h ├── RayTraceKd ├── RayTraceKd.cpp ├── RayTraceKd.ncb ├── RayTraceKd.sln ├── RayTraceKd.suo ├── RayTraceKd.vcproj ├── RayTraceSetup2.cpp ├── RayTraceSetup2.h ├── RayTraceStats.cpp ├── RayTraceStats.h ├── balls_2_1.nff ├── balls_3_1.nff ├── balls_4_1.nff ├── balls_5_1.nff ├── f15.obj ├── jacks_2_1.nff ├── jacks_3_1.nff ├── jacks_4_1.nff ├── jacks_5_1.nff ├── sponzaAlex.obj └── sponzaOrig.obj ├── RaytraceMgr ├── LoadNffFile.cpp ├── LoadNffFile.h ├── LoadObjFile.cpp ├── LoadObjFile.h ├── RayTraceMgr.vcproj ├── SceneDescription.cpp └── SceneDescription.h └── VrMath ├── Aabb.cpp ├── Aabb.h ├── LinearR2.cpp ├── LinearR2.h ├── LinearR3.cpp ├── LinearR3.h ├── LinearR4.cpp ├── LinearR4.h ├── MathMisc.h ├── Parallelepiped.cpp ├── Parallelepiped.h ├── PolygonClip.cpp ├── PolygonClip.h ├── PolynomialRC.cpp ├── PolynomialRC.h ├── Quaternion.cpp ├── Quaternion.h ├── VrData.h └── VrMath.vcproj /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | raytracekd.out 3 | -------------------------------------------------------------------------------- /DataStructs/DataStructs.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 11 | 12 | 13 | 19 | 30 | 32 | 35 | 37 | 39 | 41 | 43 | 45 | 47 | 49 | 51 | 53 | 54 | 60 | 70 | 72 | 75 | 77 | 79 | 81 | 83 | 85 | 87 | 89 | 91 | 93 | 94 | 95 | 96 | 97 | 98 | 102 | 104 | 105 | 107 | 108 | 109 | 113 | 115 | 116 | 118 | 119 | 121 | 122 | 124 | 125 | 127 | 128 | 130 | 131 | 132 | 136 | 137 | 139 | 140 | 141 | 142 | 143 | 144 | -------------------------------------------------------------------------------- /DataStructs/DoubleRecurse.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * RayTrace Software Package, release 3.0. May 3, 2006. 4 | * 5 | * Mathematics Subpackage (VrMath) 6 | * 7 | * Author: Samuel R. Buss 8 | * 9 | * Software accompanying the book 10 | * 3D Computer Graphics: A Mathematical Introduction with OpenGL, 11 | * by S. Buss, Cambridge University Press, 2003. 12 | * 13 | * Software is "as-is" and carries no warranty. It may be used without 14 | * restriction, but if you modify it, please change the filenames to 15 | * prevent confusion between different versions. Please acknowledge 16 | * all use of the software in any publications or products based on it. 17 | * 18 | * Bug reports: Sam Buss, sbuss@ucsd.edu. 19 | * Web page: http://math.ucsd.edu/~sbuss/MathCG 20 | * 21 | */ 22 | 23 | #include 24 | #include 25 | #include "DoubleRecurse.h" 26 | 27 | 28 | // Consider a function which satisfies the following properties: 29 | // 1. f(N) = 1 + A*f(alpha*N) + B*f(beta*N) 30 | // where A+B > 1 and alpha, beta in (0,1]. 31 | // 2 f(1) = 1. 32 | // 33 | // These conditions are satisfied by setting f(x) = C N^exponent + D, 34 | // where C, exponent, D are the values returned by FindDoubleRecurseSoln 35 | 36 | void FindDoubleRecurseSoln ( double A, double B, double alpha, double beta, 37 | double* C, double* exponent, double* D ) 38 | { 39 | // Pre-conditions 40 | assert ( A+B>1.0 ); 41 | assert ( 0.0 1 and alpha, beta in (0,1]. 74 | // 2 f(1) = 1. 75 | // 76 | // These conditions are satisfied by setting f(x) = C N^exponent + D, 77 | // where C, exponent, D are the values returned by FindDoubleRecurseSoln 78 | // This version takes an "exponentToBeat". If the exponent cannot be 79 | // beaten (i.e., if exponent would be greater than exponentToBeat, it 80 | // returns false without computing C, D and exponent. Otherwise, it 81 | // sets values of C, D and exponent with exponent1.0 ); 90 | assert ( 0.0=1.0 ) { 100 | return false; 101 | } 102 | 103 | // We are going to beat the exponentToBeat. 104 | double denom = A+B-1.0; 105 | double ZdenomInv = 1.0/denom; 106 | double AlogAlpha = A*log(alpha); 107 | double BlogBeta = B*log(beta); 108 | 109 | *D = -ZdenomInv; 110 | *C = 1.0+ZdenomInv; // Same as (A+B)/(A+B-1) = (A+B-1+1)/(A+B-1). 111 | 112 | double deltaX = (1.0-funcValue)/(AlogAlpha*alphaExpX+BlogBeta*betaExpX); 113 | X += deltaX; 114 | if ( X<0.0 ) { 115 | // If undershot zero, restart Newton iteration at zero 116 | funcValue = A+B; // Since alphaExpX and betaExpX equal 1 117 | deltaX = (1.0-funcValue)/(AlogAlpha+BlogBeta); 118 | X = deltaX; 119 | } 120 | else { 121 | deltaX = -deltaX; 122 | } 123 | while ( true ) { 124 | if ( deltaX<1.0e-12 ) { 125 | break; 126 | } 127 | alphaExpX = pow(alpha, X); 128 | betaExpX = pow(beta, X); 129 | funcValue = A*alphaExpX + B*betaExpX; 130 | deltaX = (1.0-funcValue)/(AlogAlpha*alphaExpX+BlogBeta*betaExpX); 131 | X += deltaX; 132 | } 133 | *exponent = X; 134 | 135 | return true; 136 | } 137 | 138 | 139 | // Consider a function which satisfies the following properties: 140 | // 1. f(N) = 1 + A*f(alpha*N) + B*f(beta*N) 141 | // where A+B > 1 and alpha, beta in (0,1]. 142 | // 2 f(1) = 1. 143 | // 144 | // These conditions are satisfied by setting f(x) = C N^exponent + D, 145 | // where C, exponent, D are the values returned by FindDoubleRecurseSoln 146 | 147 | void FindDoubleRecurseSolnOld ( double A, double B, double alpha, double beta, 148 | double* C, double* exponent, double* D ) 149 | { 150 | // Pre-conditions 151 | assert ( A+B>1.0 ); 152 | assert ( 0.0 1 and alpha, beta in (0,1]. 12 | // 2 f(1) = 1. 13 | // 14 | // These conditions are satisfied by setting f(x) = C N^exponent + D, 15 | // where C, e, D are the values returned by FindDoubleRecurseSoln 16 | 17 | void FindDoubleRecurseSoln ( double A, double B, double alpha, double beta, 18 | double* C, double* exponent, double* D ); 19 | 20 | // In the second form of FindDoubleRecurseSoln, there is an "exponentToBeat" 21 | // parameter. If the value of "exponent" would be less than "exponentToBeat", 22 | // then the function returns FALSE, and the values of C, exponent and D 23 | // are not returned as valid value. 24 | 25 | bool FindDoubleRecurseSoln ( double A, double B, double alpha, double beta, 26 | double* C, double* exponent, double* D, 27 | double exponentToBeat ); 28 | 29 | -------------------------------------------------------------------------------- /DataStructs/ShellSort.h: -------------------------------------------------------------------------------- 1 | 2 | // ShellSort.h 3 | // 4 | // A ShellSort, written as templated C++ code. 5 | // Uses the h = 3h+1 recursion to set increment size. 6 | // Uses pointers to improve runtime. 7 | // 8 | // Author: Sam Buss, sbuss@math.ucsd.edu. 9 | // Freely usable without restrictions, 10 | // Distributed "as is", with no warranties. 11 | // I would appreciate acknowledgements of its use, 12 | // as well as being informed of bugs or other improvements. 13 | 14 | 15 | // Do a shell sort. 16 | // Pass a pointer to an array, and the number of objects 17 | // The class "T" must have "operator< ()" defined. 18 | 19 | #include 20 | 21 | template 22 | bool DebugTestSort( T *array, long num, long* i ); 23 | 24 | template 25 | void ShellSort( T *array, long num ) 26 | { 27 | // Use the 3h+1 formula for shell sort increment. 28 | // (Not sure if this is really best. Sedgewick suggests another sequence) 29 | long incr = 1; 30 | long nextIncr = 4; 31 | while ( nextIncr0 ) { 38 | // Do many bubble sorts of step size incr 39 | T* startSort = array+incr; 40 | for ( long i = incr; i=0 && temp<(*backPtr) ); 52 | *thisPtr = temp; 53 | } 54 | } 55 | incr /= 3; 56 | } 57 | 58 | // DEBUG ONLY 59 | assert ( DebugTestSort( array, num, &incr ) ); 60 | 61 | } 62 | 63 | template 64 | bool DebugTestSort( T *array, long num, long* iFail ) 65 | { 66 | bool retCode = true; 67 | long i; 68 | for ( i=0; i 20 | 21 | #include "../VrMath/MathMisc.h" 22 | 23 | template class Stack { 24 | 25 | public: 26 | Stack(); // Constructor 27 | Stack(long initialSize); // Constructor 28 | ~Stack(); // Destructor 29 | 30 | void Reset(); 31 | 32 | void Resize( long newMaxSize ); // Increases allocated size (will not decrease size) 33 | 34 | T& Top() const { return *TopElement; }; 35 | T& Pop(); 36 | 37 | T* Push(); // New top element is arbitrary 38 | T* Push( const T& newElt ); // Push newElt onto stack. 39 | 40 | bool IsEmpty() const { return (SizeUsed==0); } 41 | 42 | long Size() const { return SizeUsed; } 43 | long SizeAllocated() const { return Allocated; } 44 | 45 | private: 46 | 47 | long SizeUsed; // Number of elements in the stack 48 | T* TopElement; // Pointer to the top element of the stack 49 | long Allocated; // Number of entries allocated 50 | T* TheStack; // Pointer to the array of entries 51 | }; 52 | 53 | template inline Stack::Stack() 54 | { 55 | SizeUsed = 0; 56 | TheStack = 0; 57 | Allocated = 0; 58 | Resize( 10 ); 59 | } 60 | 61 | template inline Stack::Stack(long initialSize) 62 | { 63 | SizeUsed = 0; 64 | TheStack = 0; 65 | Allocated = 0; 66 | Resize( initialSize ); 67 | } 68 | 69 | 70 | template inline Stack::~Stack() 71 | { 72 | delete[] TheStack; 73 | } 74 | 75 | template inline void Stack::Reset() 76 | { 77 | SizeUsed = 0; 78 | TopElement = TheStack-1; 79 | } 80 | 81 | template inline void Stack::Resize( long newMaxSize ) 82 | { 83 | if ( newMaxSize <= Allocated ) { 84 | return; 85 | } 86 | long newSize = Max(2*Allocated+1,newMaxSize); 87 | T* newArray = new T[newSize]; 88 | T* toPtr = newArray; 89 | T* fromPtr = TheStack; 90 | long i; 91 | for ( i=0; i inline T& Stack::Pop() 101 | { 102 | T* ret = TopElement; 103 | assert( SizeUsed>0 ); // Should be non-empty 104 | SizeUsed--; 105 | TopElement--; 106 | return *ret; 107 | } 108 | 109 | // Enlarge the stack but do not update the top element. 110 | // Returns a pointer to the top element (which is unchanged/uninitialized) 111 | template inline T* Stack::Push( ) 112 | { 113 | if ( SizeUsed >= Allocated ) { 114 | Resize(SizeUsed+1); 115 | } 116 | SizeUsed++; 117 | TopElement++; 118 | return TopElement; 119 | } 120 | 121 | template inline T* Stack::Push( const T& newElt ) 122 | { 123 | Push(); 124 | *TopElement = newElt; 125 | return TopElement; 126 | } 127 | 128 | 129 | #endif // STACK_H -------------------------------------------------------------------------------- /Graphics/BumpMapFunction.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * RayTrace Software Package, release 3.0. May 3, 2006. 4 | * 5 | * Author: Samuel R. Buss 6 | * 7 | * Software accompanying the book 8 | * 3D Computer Graphics: A Mathematical Introduction with OpenGL, 9 | * by S. Buss, Cambridge University Press, 2003. 10 | * 11 | * Software is "as-is" and carries no warranty. It may be used without 12 | * restriction, but if you modify it, please change the filenames to 13 | * prevent confusion between different versions. Please acknowledge 14 | * all use of the software in any publications or products based on it. 15 | * 16 | * Bug reports: Sam Buss, sbuss@ucsd.edu. 17 | * Web page: http://math.ucsd.edu/~sbuss/MathCG 18 | * 19 | */ 20 | 21 | 22 | #include "BumpMapFunction.h" 23 | #include "../VrMath/LinearR2.h" 24 | #include "../Graphics/VisiblePoint.h" 25 | 26 | // viewDir - unit vector giving direction from viewpoint 27 | 28 | void BumpMapFunction::ApplyTexture(VisiblePoint& visPoint, 29 | const VectorR3& viewDir ) const { 30 | 31 | VectorR2 deriv; // Partial derivative function 32 | if ( DerivFunc != 0 ) { 33 | deriv = DerivFunc(visPoint.GetU(), visPoint.GetV()); 34 | } 35 | else { 36 | assert( HeightFunc != 0 ); // At least one function must be given 37 | double u = visPoint.GetU(); 38 | double v = visPoint.GetV(); 39 | if ( u<0.0 || u>1.0 ) { 40 | switch (BorderType) { 41 | case BORDER_CLAMP: 42 | return; 43 | case BORDER_WRAP: 44 | u = u - floor(u); 45 | break; 46 | case BORDER_EXTEND: 47 | break; 48 | } 49 | } 50 | if ( v<0.0 || v>1.0 ) { 51 | switch (BorderType) { 52 | case BORDER_CLAMP: 53 | return; 54 | case BORDER_WRAP: 55 | v = v - floor(v); 56 | break; 57 | case BORDER_EXTEND: 58 | break; 59 | } 60 | } 61 | double uMinus = u-Epsilon; 62 | double uPlus = u+Epsilon; 63 | double vMinus = v-Epsilon; 64 | double vPlus = v+Epsilon; 65 | if ( BorderType!=BORDER_EXTEND) { 66 | ZeroBorderCheck( &uMinus ); 67 | OneBorderCheck( &uPlus ); 68 | ZeroBorderCheck( &vMinus ); 69 | OneBorderCheck( &vPlus ); 70 | } 71 | deriv.x = (HeightFunc(uPlus,v)-HeightFunc(uMinus,v))/(uPlus-uMinus); 72 | deriv.y = (HeightFunc(u,vPlus)-HeightFunc(u,vMinus))/(vPlus-vMinus); 73 | } 74 | 75 | VectorR3 retDerivU, retDerivV; 76 | bool partialsOK; 77 | partialsOK = visPoint.GetObject().CalcPartials( visPoint, retDerivU, retDerivV ); 78 | if ( !partialsOK ) { // If at a singularity 79 | return; // Cannot do anything with information about the partials. 80 | } 81 | 82 | const VectorR3& oldNormal = visPoint.GetNormal(); 83 | retDerivU.AddScaled(oldNormal,deriv.x); 84 | retDerivV.AddScaled(oldNormal,deriv.y); 85 | retDerivU *= retDerivV; // Cross product 86 | 87 | double newDotViewDir = (retDerivU^viewDir); // Positive if facing away from viewer (new value) 88 | double oldDotViewDir = (oldNormal^viewDir); // Positive if facing away from viewer (old value) 89 | if ( newDotViewDir*oldDotViewDir<0.0 ) { 90 | // If switched direction relative to viewDir. 91 | retDerivU.AddScaled(viewDir,-newDotViewDir); // Component perpindicular to viewDir 92 | } 93 | double norm = retDerivU.Norm(); 94 | if ( norm!=0.0 ) { 95 | retDerivU /= norm; 96 | visPoint.SetNormal( retDerivU ); 97 | } 98 | 99 | return; 100 | } 101 | 102 | void BumpMapFunction::ZeroBorderCheck( double *m ) const { 103 | if ( (*m)<0.0 ) { 104 | switch ( BorderType ) { 105 | case BORDER_CLAMP: 106 | *m = 0.0; 107 | break; 108 | case BORDER_WRAP: 109 | (*m) += 1.0; 110 | break; 111 | case BORDER_EXTEND: 112 | break; 113 | } 114 | } 115 | } 116 | 117 | void BumpMapFunction::OneBorderCheck( double *m ) const { 118 | if ( (*m) > 1.0 ) { 119 | switch ( BorderType ) { 120 | case BORDER_CLAMP: 121 | *m = 1.0; 122 | break; 123 | case BORDER_WRAP: 124 | (*m) -= 1.0; 125 | break; 126 | case BORDER_EXTEND: 127 | break; 128 | } 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /Graphics/BumpMapFunction.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * RayTrace Software Package, release 3.0. May 3, 2006. 4 | * 5 | * Author: Samuel R. Buss 6 | * 7 | * Software accompanying the book 8 | * 3D Computer Graphics: A Mathematical Introduction with OpenGL, 9 | * by S. Buss, Cambridge University Press, 2003. 10 | * 11 | * Software is "as-is" and carries no warranty. It may be used without 12 | * restriction, but if you modify it, please change the filenames to 13 | * prevent confusion between different versions. Please acknowledge 14 | * all use of the software in any publications or products based on it. 15 | * 16 | * Bug reports: Sam Buss, sbuss@ucsd.edu. 17 | * Web page: http://math.ucsd.edu/~sbuss/MathCG 18 | * 19 | */ 20 | 21 | #ifndef BUMPMAPFUNCTION_H 22 | #define BUMPMAPFUNCTION_H 23 | 24 | #include "TextureMapBase.h" 25 | #include "ViewableBase.h" 26 | 27 | class VectorR2; 28 | 29 | // Implements bump mapping with user-supplied functions which compute 30 | // either the height field or the directional derivatives. 31 | 32 | class BumpMapFunction : public TextureMapBase { 33 | 34 | public: 35 | BumpMapFunction(); 36 | BumpMapFunction( double f(double u, double v) ); // Height (displacement) function 37 | BumpMapFunction( VectorR2 f(double u, double v) ); // Derivatives function 38 | 39 | // You should set only one of these. Or you can use one of the constuctors. 40 | void SetHeightFunction ( double f(double u, double v) ); 41 | void SetDerivativesFunction( VectorR2 f(double u, double v) ); 42 | 43 | // The following are somewhat specialized: they set options on the way 44 | // height function is sampled to estimate the partial derivatives. 45 | // The height function always uses the interval [0,1]. 46 | // epsilon and "border type" apply ONLY to the height function case! 47 | void SetEpsilon( double epsilon ); // Step size (epsilon) to use for differencing 48 | void SetBorderType( int borderType ); // Clamp, extend or wrap. 49 | 50 | enum { 51 | BORDER_EXTEND = 0, // Extend height function arguments past border (Default) 52 | BORDER_CLAMP = 1, // Clamp height function arguments at border 53 | BORDER_WRAP = 2 // Wrap height functions around. 54 | }; 55 | static const double DefaultEpsilon() { return 0.001; } 56 | 57 | void ApplyTexture( VisiblePoint& visPoint, const VectorR3& viewDir ) const; 58 | 59 | private: 60 | double (*HeightFunc)(double u, double v); // Displacement (height) function 61 | VectorR2 (*DerivFunc)(double u, double v); // Partial derivative (gradient) function 62 | int BorderType; 63 | double Epsilon; 64 | 65 | void ZeroBorderCheck( double *m ) const; 66 | void OneBorderCheck( double *p ) const; 67 | }; 68 | 69 | inline BumpMapFunction::BumpMapFunction() { 70 | HeightFunc = 0; 71 | DerivFunc = 0; 72 | BorderType = BORDER_EXTEND; 73 | Epsilon = DefaultEpsilon(); 74 | } 75 | 76 | inline BumpMapFunction::BumpMapFunction( double f(double u, double v) ) { 77 | HeightFunc = f; 78 | DerivFunc = 0; 79 | BorderType = BORDER_EXTEND; 80 | Epsilon = DefaultEpsilon(); 81 | } 82 | 83 | inline BumpMapFunction::BumpMapFunction( VectorR2 f(double u, double v) ) { 84 | HeightFunc = 0; 85 | DerivFunc = f; 86 | BorderType = BORDER_EXTEND; 87 | Epsilon = DefaultEpsilon(); 88 | } 89 | 90 | inline void BumpMapFunction::SetHeightFunction( double f(double u, double v) ) { 91 | HeightFunc = f; 92 | BorderType = BORDER_EXTEND; 93 | Epsilon = DefaultEpsilon(); 94 | } 95 | 96 | inline void BumpMapFunction::SetDerivativesFunction( VectorR2 f(double u, double v) ) { 97 | DerivFunc = f; 98 | BorderType = BORDER_EXTEND; 99 | Epsilon = DefaultEpsilon(); 100 | } 101 | 102 | inline void BumpMapFunction::SetEpsilon( double epsilon ) 103 | { 104 | Epsilon = epsilon; 105 | } 106 | 107 | inline void BumpMapFunction::SetBorderType( int borderType ) 108 | { 109 | BorderType = borderType; 110 | } 111 | 112 | #endif // BUMPMAPFUNCTION_H 113 | -------------------------------------------------------------------------------- /Graphics/CameraView.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * RayTrace Software Package, release 3.1.2 February 12, 2007. 4 | * 5 | * Author: Samuel R. Buss 6 | * 7 | * Software accompanying the book 8 | * 3D Computer Graphics: A Mathematical Introduction with OpenGL, 9 | * by S. Buss, Cambridge University Press, 2003. 10 | * 11 | * Software is "as-is" and carries no warranty. It may be used without 12 | * restriction, but if you modify it, please change the filenames to 13 | * prevent confusion between different versions. Please acknowledge 14 | * all use of the software in any publications or products based on it. 15 | * 16 | * Bug reports: Sam Buss, sbuss@ucsd.edu. 17 | * Web page: http://math.ucsd.edu/~sbuss/MathCG 18 | * 19 | */ 20 | 21 | #include "CameraView.h" 22 | 23 | void CameraView::CalcScreenCenter() 24 | { 25 | ScreenCenter = Direction; 26 | ScreenCenter *= ScreenDistance; 27 | ScreenCenter += Position; 28 | } 29 | 30 | // Set the camera position according the "LookAt" data 31 | void CameraView::SetLookAt( const VectorR3& eyePos, const VectorR3& lookAt, const VectorR3& upDir ) 32 | { 33 | SetLocalViewer(); // This is a "local" viewer 34 | 35 | View::SetPosition(eyePos); 36 | ScreenCenter = lookAt; 37 | VectorR3 viewDir = lookAt-eyePos; 38 | ScreenDistance = viewDir.Norm(); 39 | assert ( ScreenDistance!=0.0 ); 40 | DistanceHasBeenSet = true; 41 | SetDefaultClippingDistances(); 42 | viewDir /= ScreenDistance; // Normalize the viewDir 43 | View::SetDirection( viewDir ); 44 | pixeldV = upDir; 45 | pixeldV.AddScaled( viewDir, -(upDir^viewDir) ); 46 | pixeldU = viewDir; 47 | pixeldU *= upDir; // Vector points rightward 48 | assert ( !viewDir.NearZero(1.0e-10) && !pixeldU.NearZero(1.0e-10) && !pixeldV.NearZero(1.0e-10) ); 49 | RecalcPixeldUdV(); 50 | } 51 | 52 | // This function must be called *AFTER* the distance to the screen has been 53 | // set (by either a call to SetDistance() or a call to SetLookAt().) 54 | void CameraView::SetViewFrustum( double aspectRatio, double fovy ) 55 | { 56 | assert ( DistanceHasBeenSet ); 57 | ScreenHeight = 2.0*ScreenDistance*tan(fovy*0.5); 58 | ScreenWidth = aspectRatio * ScreenHeight; 59 | RecalcPixeldUdV(); 60 | } 61 | 62 | // This routine assumes the view position (Position), and the view direction (Direction) 63 | // and distance to the screen (ScreenDistance) are already calculated. It computes 64 | // the u direction vector and v direction vector. 65 | void CameraView::PixelDirPreCalc( ) { 66 | 67 | VectorR3 u(-Direction.z,0.0,Direction.x); // Sideways direction (rightward) 68 | if ( u.IsZero() ) { 69 | u.Set(0.0,1.0,0.0); 70 | } 71 | VectorR3 v = u*Direction; // Cross product - gives "up" direction 72 | pixeldU = u; 73 | pixeldV = v; 74 | RecalcPixeldUdV(); 75 | } 76 | 77 | // Rescale dU and dV for changed screen size or screen resolution 78 | void CameraView::RecalcPixeldUdV() 79 | { 80 | pixeldU.Normalize(); 81 | if ( WidthPixels>1 ) { 82 | pixeldU *= ScreenWidth/(WidthPixels-1); 83 | } 84 | pixeldV.Normalize(); 85 | if ( HeightPixels>1 ) { 86 | pixeldV *= ScreenHeight/(HeightPixels-1); 87 | } 88 | } 89 | 90 | // Given a fully established camera and view, rotate the view upward around 91 | // screen's center. 92 | void CameraView::RotateViewUp( double theta ) 93 | { 94 | VectorR3 upDir = pixeldV; 95 | upDir.Normalize(); 96 | Direction *= cos(theta); 97 | Direction.AddScaled(upDir, -sin(theta) ); 98 | Direction.Normalize(); // Just in case.... 99 | 100 | pixeldV = pixeldU*Direction; // New up direction 101 | pixeldV.Normalize(); 102 | if ( HeightPixels>1 ) { 103 | pixeldV *= ScreenHeight/(HeightPixels-1); 104 | } 105 | 106 | Position = ScreenCenter - ScreenDistance*Direction; 107 | } 108 | 109 | // Given a fully established camera and view, rotate the view rightward around 110 | // screen's center. 111 | void CameraView::RotateViewRight( double theta ) 112 | { 113 | VectorR3 rightDir = pixeldU; 114 | rightDir.Normalize(); 115 | Direction *= cos(theta); 116 | Direction.AddScaled(rightDir, -sin(theta) ); 117 | Direction.Normalize(); // Just in case.... 118 | 119 | pixeldU = Direction*pixeldV; // New "right" direction 120 | pixeldU.Normalize(); 121 | if ( WidthPixels>1 ) { 122 | pixeldU *= ScreenWidth/(WidthPixels-1); 123 | } 124 | 125 | Position = ScreenCenter - ScreenDistance*Direction; 126 | } 127 | 128 | // Given a fully established camera and view, scale distance of viewer from 129 | // screen's center. 130 | void CameraView::RescaleDistanceOfViewer( double factor ) 131 | { 132 | assert ( factor>0.0 ); 133 | if ( factor>0.0 ) { 134 | ScreenDistance *= factor; 135 | } 136 | 137 | Position = ScreenCenter - ScreenDistance*Direction; 138 | } 139 | 140 | -------------------------------------------------------------------------------- /Graphics/Extents.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Extents.h 3 | * 4 | * RayTrace Software Package, release 3.0. May 3, 2006 5 | * 6 | * Author: Samuel R. Buss 7 | * 8 | * Software accompanying the book 9 | * 3D Computer Graphics: A Mathematical Introduction with OpenGL, 10 | * by S. Buss, Cambridge University Press, 2003. 11 | * 12 | * Software is "as-is" and carries no warranty. It may be used without 13 | * restriction, but if you modify it, please change the filenames to 14 | * prevent confusion between different versions. Please acknowledge 15 | * all use of the software in any publications or products based on it. 16 | * 17 | * Bug reports: Sam Buss, sbuss@ucsd.edu. 18 | * Web page: http://math.ucsd.edu/~sbuss/MathCG 19 | * 20 | */ 21 | 22 | #ifndef EXTENTS_H 23 | #define EXTENTS_H 24 | 25 | class VectorR3; 26 | class Parallelepiped; 27 | 28 | class ViewableParallelogram; 29 | class ViewableParallelepiped; 30 | class ViewableSphere; 31 | class ViewableTriangle; 32 | 33 | #include "../VrMath/LinearR3.h" 34 | 35 | // This is a file for collecting routines that find bounding box extents 36 | // of ViewableBase objects intersected with bounding boxes. 37 | // So far, implemented for only: 38 | // ViewableParallelogram, 39 | // ViewableParallelopiped, 40 | // ViewableSphere, 41 | // ViewableTriangle. 42 | // If and when the routines are implemented for enough kinds of ViewableBase 43 | // objects, its functionality might be moved into the ViewableBase objects' 44 | // classes. 45 | 46 | // ********************************************************************** 47 | // CalcExtentsInBox. Consider the intersection of the ViewableBase 48 | // with the bounding box defined by boundBoxMax/Min. 49 | // This intersection is inside the bounding box given by 50 | // the values extentsMin/Max. 51 | // The purpose of this routine is to compute extentsMin and extentsMax. 52 | // Returns true if the extents are nonempty. 53 | // If returns false, the extentsMin/Max values are not set. 54 | // ********************************************************************** 55 | bool CalcExtentsInBox( const ViewableParallelogram& parallelogram, 56 | const VectorR3& boxBoundMin, const VectorR3& boxBoundMax, 57 | VectorR3* extentsMin, VectorR3* extentsMax ); 58 | 59 | bool CalcExtentsInBox( const ViewableParallelepiped& ppiped, 60 | const VectorR3& boxBoundMin, const VectorR3& boxBoundMax, 61 | VectorR3* extentsMin, VectorR3* extentsMax ); 62 | 63 | bool CalcExtentsInBox( const ViewableSphere& sphere, 64 | const VectorR3& boxBoundMin, const VectorR3& boxBoundMax, 65 | VectorR3* extentsMin, VectorR3* extentsMax ); 66 | 67 | bool CalcExtentsInBox( const ViewableTriangle& tri, 68 | const VectorR3& boxBoundMin, const VectorR3& boxBoundMax, 69 | VectorR3* extentsMin, VectorR3* extentsMax ); 70 | 71 | // ********************************************************************** 72 | // CalcSolidExtentsInBox. Consider the intersection of a solid geometric 73 | // object with the bounding box defined by boundBoxMax/Min. 74 | // This intersection is inside the bounding box given by 75 | // the values extentsMin/Max. 76 | // The purpose of this routine is to compute extentsMin and extentsMax. 77 | // Returns true if the extents are nonempty. 78 | // If returns false, the extentsMin/Max values are not set. 79 | // ********************************************************************** 80 | 81 | bool CalcExtentsInBox( const Parallelepiped& ppiped, 82 | const VectorR3& boxBoundMin, const VectorR3& boxBoundMax, 83 | VectorR3* extentsMin, VectorR3* extentsMax ); 84 | 85 | 86 | // CalcBoundingBox intended for internal use. 87 | // Finds the bounding box of a set of points. 88 | bool CalcBoundingBox( int numPoints, const VectorR3* vertArray, 89 | VectorR3* extentsMin, VectorR3* extentsMax ); 90 | 91 | // Functions below are helper functions, intended for internal use. 92 | 93 | // CalcMinMaxSquares 94 | // Input values: valMin and valMax where valMin <= valMax 95 | // Returns the values Min{ x*x : x \in [valMin, valMax] } 96 | // and Max{ x*x : x \in [valMin, valMax] } 97 | void CalcMinMaxSquares( double valMin, double valMax, double* valSqMin, double* valSqMax ); 98 | bool CalcExtentsHelpForSphere( double boxMin, double boxMax, 99 | double radiusSq, double otherSqMin, double otherSqMax, 100 | double* inExtent, double* maxExtent ); 101 | 102 | inline void CEIB_AddOrSubtract( VectorR3* u, VectorR3* v, 103 | const VectorR3& addTerm, bool addOrSubtract ) 104 | { 105 | if ( addOrSubtract ) { 106 | *v += addTerm; 107 | } 108 | else { 109 | *u -= addTerm; 110 | } 111 | } 112 | 113 | inline bool InAABB( const VectorR3& pt, const VectorR3& boxBoundMin, const VectorR3& boxBoundMax ) 114 | { 115 | return ( boxBoundMin.x <= pt.x && pt.x <= boxBoundMax.x 116 | && boxBoundMin.y <= pt.y && pt.y <= boxBoundMax.y 117 | && boxBoundMin.z <= pt.z && pt.z <= boxBoundMax.z ); 118 | } 119 | 120 | #endif // EXTENTS_H 121 | -------------------------------------------------------------------------------- /Graphics/Material.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * RayTrace Software Package, release 3.0. May 3, 2006. 4 | * 5 | * Author: Samuel R. Buss 6 | * 7 | * Software accompanying the book 8 | * 3D Computer Graphics: A Mathematical Introduction with OpenGL, 9 | * by S. Buss, Cambridge University Press, 2003. 10 | * 11 | * Software is "as-is" and carries no warranty. It may be used without 12 | * restriction, but if you modify it, please change the filenames to 13 | * prevent confusion between different versions. Please acknowledge 14 | * all use of the software in any publications or products based on it. 15 | * 16 | * Bug reports: Sam Buss, sbuss@ucsd.edu. 17 | * Web page: http://math.ucsd.edu/~sbuss/MathCG 18 | * 19 | */ 20 | 21 | #include "Material.h" 22 | #include "Light.h" 23 | 24 | // This Material works with the Phong illumination model. 25 | 26 | const Material Material::Default; 27 | 28 | MaterialBase* Material::Clone() const { 29 | Material* ret = new Material(); 30 | *ret = *this; 31 | return (MaterialBase*)ret; 32 | } 33 | 34 | void Material::CalcLocalLighting( 35 | VectorR3& colorReturned, const Light& light, 36 | const VectorR3& percentLit, double lightAttenuation, 37 | const VectorR3& N, const VectorR3& V, 38 | const VectorR3& L, const VectorR3* H ) const 39 | { 40 | VectorR3 LightValue; // Used to hold light level components 41 | 42 | if ( percentLit.NearZero(1.0e-6) ) { 43 | colorReturned.SetZero(); // Light entirely hidden 44 | } 45 | else { 46 | bool facingViewer = ( (N^V)>=0.0 ); 47 | bool facingLight = ( (N^L)>=0.0 ); 48 | if ( (facingLight^facingViewer) && !this->IsTransmissive() ) { 49 | // Light and viewer on opposite sides and no transmission. 50 | colorReturned.SetZero(); 51 | } 52 | else { 53 | VectorR3 facingNormal(N); // The normal facing the light 54 | if (!facingLight) { 55 | facingNormal.Negate(); 56 | } 57 | 58 | // Diffuse light 59 | colorReturned = this->GetColorDiffuse(); 60 | colorReturned.ArrayProd(light.GetColorDiffuse()); 61 | colorReturned *= (L^facingNormal); 62 | 63 | // Specular light 64 | LightValue = this->GetColorSpecular(); 65 | LightValue.ArrayProd(light.GetColorSpecular()); 66 | double specularFactor; 67 | if ( !(facingLight^facingViewer) ) { // If view and light on same side 68 | if ( H ) { 69 | specularFactor = ((*H)^facingNormal); 70 | } 71 | else { 72 | // R = -(L-(L^N)N) + (L^N)N = 2(L^N)N - L // reflected direction 73 | // R^V = 2(L^N)(V^N) - V^L; 74 | specularFactor = 2.0*(L^N)*(V^N) - (V^L); // R^V. 75 | } 76 | } 77 | else { // If viewer and light on opposite sides 78 | VectorR3 T; // Transmission direction 79 | facingNormal = V; 80 | facingNormal.Negate(); // Use temporarily as incoming vector 81 | this->CalcRefractDir(N, facingNormal, IndexOfRefraction, T); 82 | specularFactor = (T^L); 83 | } 84 | if ( specularFactor>0.0 ) { 85 | if ( this->GetShininess() != 0.0) { 86 | specularFactor = pow(specularFactor,this->GetShininess()); 87 | } 88 | LightValue *= specularFactor; 89 | colorReturned += LightValue; 90 | } 91 | 92 | // Non-ambient light reduced by percentLit 93 | colorReturned.ArrayProd(percentLit); 94 | 95 | if ( (facingLight^facingViewer) ) { // ^ is "exclusive or" 96 | // If on opposite sides 97 | colorReturned.ArrayProd(this->GetColorTransmissive()); 98 | } 99 | } 100 | } 101 | 102 | // Ambient light 103 | LightValue = this->GetColorAmbient(); 104 | LightValue.ArrayProd(light.GetColorAmbient()); 105 | colorReturned += LightValue; 106 | 107 | // Scale by attenuation (the ambient part too) 108 | colorReturned *= lightAttenuation; 109 | 110 | } 111 | -------------------------------------------------------------------------------- /Graphics/Material.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * RayTrace Software Package, release 3.0. May 3, 2006. 4 | * 5 | * Author: Samuel R. Buss 6 | * 7 | * Software accompanying the book 8 | * 3D Computer Graphics: A Mathematical Introduction with OpenGL, 9 | * by S. Buss, Cambridge University Press, 2003. 10 | * 11 | * Software is "as-is" and carries no warranty. It may be used without 12 | * restriction, but if you modify it, please change the filenames to 13 | * prevent confusion between different versions. Please acknowledge 14 | * all use of the software in any publications or products based on it. 15 | * 16 | * Bug reports: Sam Buss, sbuss@ucsd.edu. 17 | * Web page: http://math.ucsd.edu/~sbuss/MathCG 18 | * 19 | */ 20 | 21 | #ifndef MATERIAL_H 22 | #define MATERIAL_H 23 | 24 | #include "assert.h" 25 | #include "../VrMath/LinearR4.h" 26 | #include "../VrMath/MathMisc.h" 27 | #include "MaterialBase.h" 28 | 29 | // the Material class inplements Phong lighting. The base class MaterialBase 30 | // has the basic date elements that are common to Phong lighting and 31 | // Cook-Torrance lighting 32 | 33 | class Material : public MaterialBase { 34 | 35 | public: 36 | 37 | static const Material Default; 38 | 39 | Material() { Reset(); } 40 | 41 | void Reset(); 42 | 43 | void SetShininess( double exponent ); 44 | double GetPhongShininess() const { return Shininess; } 45 | 46 | void SetIndexOfRefraction( double x ); 47 | double GetIndexOfRefraction () const { return IndexOfRefraction; } 48 | double GetEta () const { return IndexOfRefraction; } 49 | 50 | bool CalcRefractDir( const VectorR3& normal, const VectorR3& indir, const double& origEta, VectorR3& outdir ) const; 51 | 52 | bool IsTransmissive() const { return TransmissiveFlag; } 53 | bool IsReflective() const { return ReflectiveFlag; } 54 | 55 | void SetColorTransmissive( double r, double g, double b); 56 | void SetColorReflective( double r, double g, double b); 57 | 58 | void SetColorTransmissive( double* color ); 59 | void SetColorReflective( double* color ); 60 | 61 | void SetColorTransmissive( float* color ); 62 | void SetColorReflective( float* color ); 63 | 64 | void SetColorTransmissive( const VectorR3& color ); 65 | void SetColorReflective( const VectorR3& color ); 66 | 67 | double GetShininess() const { return Shininess; } 68 | 69 | void GetColorTransmissive( double* ) const; 70 | void GetColorReflective( double* ) const; 71 | 72 | const VectorR3& GetColorTransmissive() const; 73 | const VectorR3& GetColorReflective() const; 74 | 75 | virtual VectorR3 GetReflectionColor( const VisiblePoint& visPoint, 76 | const VectorR3& outDir, 77 | const VectorR3& fromDir) const 78 | { return GetColorReflective(); } 79 | virtual VectorR3 GetTransmissionColor( const VisiblePoint& visPoint, 80 | const VectorR3& outDir, 81 | const VectorR3& fromDir) const 82 | { return GetColorTransmissive(); } 83 | 84 | virtual void CalcLocalLighting( 85 | VectorR3& colorReturned, const Light& light, 86 | const VectorR3& percentLit, double lightAttenuation, 87 | const VectorR3& N, const VectorR3& V, 88 | const VectorR3& L, const VectorR3* H ) const; 89 | 90 | MaterialBase* Clone() const; 91 | 92 | 93 | protected: 94 | VectorR3 ColorTransmissive; 95 | VectorR3 ColorReflective; // Global reflection color coefficients 96 | 97 | double IndexOfRefraction; 98 | double IndexOfRefractionInv; // 1/(index of refraction) 99 | 100 | bool TransmissiveFlag; // Is transmissive color non-black? 101 | bool ReflectiveFlag; // Is reflective color non-black? 102 | 103 | double Shininess; // Shininess exponent 104 | 105 | }; 106 | 107 | inline void Material::Reset() 108 | { 109 | Roughness = 0.0; 110 | Translucent = 0.0; 111 | Shininess = 0.0f; 112 | SetColorAmbient( 0.2, 0.2, 0.2 ); 113 | SetColorDiffuse( 0.8, 0.8, 0.8 ); 114 | SetColorSpecular( 0.0, 0.0, 0.0 ); 115 | SetColorEmissive( 0.0, 0.0, 0.0 ); 116 | SetColorTransmissive( 0.0, 0.0, 0.0 ); 117 | SetColorReflective( 0.2, 0.2, 0.2 ); 118 | SetIndexOfRefraction( 1.0 ); 119 | } 120 | 121 | inline void Material::SetShininess( double exponent ) { 122 | Shininess = exponent; 123 | } 124 | 125 | inline void Material::SetIndexOfRefraction( double x ) 126 | { 127 | IndexOfRefraction = x; 128 | IndexOfRefractionInv = 1.0/x; 129 | } 130 | 131 | inline void Material::SetColorTransmissive(double r, double g, double b) { 132 | ColorTransmissive.Set( r, g, b ); 133 | TransmissiveFlag = !(r==0.0 && g==0.0 && b==0.0); 134 | } 135 | 136 | inline void Material::SetColorReflective(double r, double g, double b) { 137 | ColorReflective.Set( r, g, b ); 138 | ReflectiveFlag = !(r==0.0 && g==0.0 && b==0.0); 139 | } 140 | 141 | inline void Material::SetColorTransmissive( const VectorR3& color ) { 142 | SetColorTransmissive(color.x,color.y,color.z); 143 | } 144 | 145 | inline void Material::SetColorReflective( const VectorR3& color ) { 146 | SetColorReflective(color.x,color.y,color.z); 147 | } 148 | 149 | inline void Material::SetColorTransmissive( double* color ) { 150 | SetColorTransmissive( *color, *(color+1), *(color+2) ); 151 | } 152 | 153 | inline void Material::SetColorTransmissive( float* color ) { 154 | SetColorTransmissive( *color, *(color+1), *(color+2) ); 155 | } 156 | 157 | inline void Material::SetColorReflective( double* color ) { 158 | SetColorReflective( *color, *(color+1), *(color+2) ); 159 | } 160 | 161 | inline void Material::SetColorReflective( float* color ) { 162 | SetColorReflective( *color, *(color+1), *(color+2) ); 163 | } 164 | 165 | inline void Material::GetColorTransmissive( double* c) const { 166 | ColorReflective.Dump(c); 167 | } 168 | 169 | inline void Material::GetColorReflective( double* c) const { 170 | ColorReflective.Dump(c); 171 | } 172 | 173 | inline const VectorR3& Material::GetColorTransmissive() const { 174 | return ColorTransmissive; 175 | } 176 | 177 | inline const VectorR3& Material::GetColorReflective() const { 178 | return ColorReflective; 179 | } 180 | 181 | inline bool Material::CalcRefractDir( const VectorR3& normal, const VectorR3& indir, const double& origEta, VectorR3& outdir ) const 182 | { 183 | return MaterialBase::CalcRefractDir(IndexOfRefraction / origEta, IndexOfRefractionInv * origEta, 184 | normal, indir, outdir); 185 | } 186 | 187 | #endif // MATERIAL_H 188 | -------------------------------------------------------------------------------- /Graphics/PixelArray.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * RayTrace Software Package, release 3.2. May 3, 2007. 4 | * Graphics subpackage 5 | * 6 | * Author: Samuel R. Buss 7 | * 8 | * Software accompanying the book 9 | * 3D Computer Graphics: A Mathematical Introduction with OpenGL, 10 | * by S. Buss, Cambridge University Press, 2003. 11 | * 12 | * Software is "as-is" and carries no warranty. It may be used without 13 | * restriction, but if you modify it, please change the filenames to 14 | * prevent confusion between different versions. Please acknowledge 15 | * all use of the software in any publications or products based on it. 16 | * 17 | * Bug reports: Sam Buss, sbuss@ucsd.edu. 18 | * Web page: http://math.ucsd.edu/~sbuss/MathCG 19 | * 20 | */ 21 | 22 | #include "assert.h" 23 | #include "PixelArray.h" 24 | #include "RgbImage.h" 25 | 26 | // SetSize(width, height) resizes the pixel data info. 27 | // If necessary, it allocates new block of memory. 28 | // Returns true if new memory has been allocated. 29 | // Returns false if the memory location (and content) is unchanged 30 | bool PixelArray::SetSize( int width, int height ) { 31 | bool retValue = false; 32 | long widthAlloc = width; 33 | long newAlloc = ((long)widthAlloc)*((long)height)*3; 34 | if ( newAlloc>Allocated ) { 35 | delete[] ColorValues; 36 | Allocated = newAlloc; 37 | ColorValues = new float[Allocated]; 38 | assert(ColorValues != 0); 39 | retValue = true; 40 | } 41 | WidthAlloc = widthAlloc; 42 | Width = width; 43 | Height = height; 44 | return retValue; 45 | } 46 | 47 | // Set the size to the size of the viewport. 48 | void PixelArray::ResetSize() { 49 | GLint got[4]; // i,j, width, height 50 | glGetIntegerv( GL_VIEWPORT, got ); 51 | SetSize(got[2],got[3]); 52 | } 53 | 54 | // DrawFloats() writes the contents of the pixel array into 55 | // OpenGL's buffer. The floating point numbers are written 56 | // directly in. 57 | // Please note that same ATI graphics board drivers have software 58 | // bugs in that they do not clamp color values to the range [0,1], 59 | // and this will cause bad results on those graphics boards. 60 | 61 | void PixelArray::DrawFloats() const 62 | { 63 | glPixelStorei( GL_UNPACK_ROW_LENGTH, Width ); 64 | glPixelStorei( GL_UNPACK_ALIGNMENT, 4 ); 65 | glRasterPos2i(0,0); // Position at base of window 66 | glDrawPixels( Width, Height, GL_RGB, GL_FLOAT, ColorValues ); 67 | } 68 | 69 | // DrawViaRgbImage() writes the contents of the pixel array into 70 | // OpenGL's buffer. The floating point numbers are first converted 71 | // to unsigned integers (via an RgbImage). 72 | // This avoids the graphics board software bugs mentioned 73 | // in the comments for DrawFloats(); However, some ATI 74 | // graphics boards have another software bug (concerning 75 | // row length) that makes this method give a skewed image. 76 | 77 | void PixelArray::DrawViaRgbImage() const 78 | { 79 | glRasterPos2i(0,0); // Position at base of window 80 | RgbImage image( GetHeight(), GetWidth() ); 81 | Dump( image ); 82 | image.DrawToOpenglBuffer(); 83 | } 84 | 85 | // ClampAndDrawFloats() first clamps all values to the 86 | // interval [0,1] and then draws them. The whole point 87 | // is to avoid some software issues for some graphics 88 | // boards (particularly, ATI boards). 89 | 90 | void PixelArray::ClampAndDrawFloats() 91 | { 92 | ClampAllValues(); // Clamp values to range [0,1] 93 | DrawFloats(); 94 | } 95 | 96 | // Dumps the PixelArray data into an RgbImage object. 97 | // The RgbImage data (for now at least) must match the 98 | // size of the PixelArray dimensions. 99 | 100 | void PixelArray::Dump( RgbImage& image ) const 101 | { 102 | assert ( image.GetNumCols()==GetWidth() && image.GetNumRows()==GetHeight() ); 103 | for ( long i=0; i 28 | //#include // Basic OpenGL includes 29 | // Including stdlib.h and disabling the atexit_hack seem to work everywhere. 30 | // Eventually there should be a new version of glut.h that doesn't need this. 31 | #include 32 | #define GLUT_DISABLE_ATEXIT_HACK 33 | #ifdef __APPLE__ 34 | #include // Mac GLUT OpenGL includes 35 | #else 36 | #include // GLUT OpenGL includes 37 | #endif 38 | 39 | 40 | #include "../VrMath/LinearR3.h" 41 | #include "../VrMath/LinearR4.h" 42 | #include "../VrMath/MathMisc.h" 43 | class RgbImage; 44 | 45 | class PixelArray { 46 | 47 | public: 48 | PixelArray(); 49 | PixelArray( int width, int height ); 50 | ~PixelArray(); 51 | 52 | void ResetSize(); 53 | bool SetSize( int width, int height ); 54 | 55 | // Set a single pixel color -- i indexes left to right, j top to bottom 56 | void SetPixel( int i, int j, const float* color ); 57 | void SetPixel( int i, int j, const double* color ); 58 | void SetPixel( int i, int j, const VectorR4 color ); 59 | void SetPixel( int i, int j, const VectorR3 color ); 60 | 61 | // Draw into the OpenGL draw buffer 62 | // Any of the three methods could be used, but ClampAndDrawFloats 63 | // works best at circumventing bugs in graphics board drivers. 64 | void Draw() { ClampAndDrawFloats(); } 65 | void ClampAndDrawFloats(); 66 | void DrawFloats() const; 67 | void DrawViaRgbImage() const; 68 | 69 | // Write out to a RgbImage or to a BITMAP (.bmp) file. 70 | void Dump( RgbImage& image ) const; 71 | void DumpBmp( const char* filename ) const; 72 | 73 | long GetWidth() const { return Width; } 74 | long GetHeight() const { return Height; } 75 | 76 | void GetPixel( int i, int j, double* rgb ) const; 77 | void GetPixel( int i, int j, float* rgb ) const; 78 | const float* GetPixel( int i, int j ) const; 79 | 80 | // Clamps all values to [0,1] 81 | void ClampAllValues(); 82 | 83 | protected: 84 | long Allocated; 85 | long Width, Height; 86 | long WidthAlloc; 87 | float *ColorValues; 88 | 89 | }; 90 | 91 | inline PixelArray::PixelArray() 92 | { 93 | ColorValues = 0; 94 | Allocated = 0; 95 | ResetSize(); 96 | } 97 | inline PixelArray::PixelArray( int width, int height ) 98 | { 99 | ColorValues = 0; 100 | Allocated = 0; 101 | SetSize(width,height); 102 | } 103 | 104 | inline PixelArray::~PixelArray() 105 | { 106 | delete[] ColorValues; 107 | } 108 | 109 | inline void PixelArray::SetPixel( int i, int j, const float* color ) 110 | { 111 | float* cptr = const_cast(GetPixel(i,j)); 112 | *(cptr++) = *(color++); 113 | *(cptr++) = *(color++); 114 | *(cptr) = *(color); 115 | } 116 | 117 | inline void PixelArray::SetPixel( int i, int j, const double* color ) 118 | { 119 | float* cptr = const_cast(GetPixel(i,j)); 120 | *(cptr++) = (float)(*(color++)); 121 | *(cptr++) = (float)(*(color++)); 122 | *(cptr) = (float)(*(color)); 123 | } 124 | 125 | inline void PixelArray::SetPixel( int i, int j, const VectorR4 color ) 126 | { 127 | double t[3]={color.x,color.y,color.z}; 128 | SetPixel(i,j,t); 129 | } 130 | 131 | inline void PixelArray::SetPixel( int i, int j, const VectorR3 color ) 132 | { 133 | double t[3]={color.x,color.y,color.z}; 134 | SetPixel(i,j,t); 135 | } 136 | 137 | inline const float* PixelArray::GetPixel ( int i, int j ) const { 138 | return ColorValues + (((long) j)*WidthAlloc + ((long) i))*3; 139 | } 140 | 141 | inline void PixelArray::GetPixel( int i, int j, double* rgb ) const { 142 | const float* cptr = GetPixel(i,j); 143 | *(rgb++) = *(cptr++); 144 | *(rgb++) = *(cptr++); 145 | *(rgb) = *(cptr); 146 | } 147 | 148 | inline void PixelArray::GetPixel( int i, int j, float* rgb ) const { 149 | const float* cptr = GetPixel(i,j); 150 | *(rgb++) = (float)(*(cptr++)); 151 | *(rgb++) = (float)(*(cptr++)); 152 | *(rgb) = (float)(*(cptr)); 153 | } 154 | 155 | #endif // PIXELARRAY_H 156 | -------------------------------------------------------------------------------- /Graphics/RgbImage.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * RayTrace Software Package, release 3.2. May 3, 2007. 4 | * Graphics subpackage 5 | * 6 | * Author: Samuel R. Buss 7 | * 8 | * Software accompanying the book 9 | * 3D Computer Graphics: A Mathematical Introduction with OpenGL, 10 | * by S. Buss, Cambridge University Press, 2003. 11 | * 12 | * Software is "as-is" and carries no warranty. It may be used without 13 | * restriction, but if you modify it, please change the filenames to 14 | * prevent confusion between different versions. Please acknowledge 15 | * all use of the software in any publications or products based on it. 16 | * 17 | * Bug reports: Sam Buss, sbuss@ucsd.edu. 18 | * Web page: http://math.ucsd.edu/~sbuss/MathCG 19 | * 20 | */ 21 | 22 | #ifndef RGBIMAGE_H 23 | #define RGBIMAGE_H 24 | 25 | #include 26 | #include 27 | 28 | // Comment in the next line to turn off the routines that use OpenGL 29 | // #define RGBIMAGE_DONT_USE_OPENGL 30 | 31 | class RgbImage 32 | { 33 | public: 34 | RgbImage(); 35 | RgbImage( const char* filename ); 36 | RgbImage( int numRows, int numCols ); // Initialize a blank bitmap of this size. 37 | RgbImage(const RgbImage *image); // Copy constructor 38 | ~RgbImage(); 39 | 40 | // The next routines return "true" to indicate successful completion. 41 | bool LoadBmpFile( const char *filename ); // Loads the bitmap from the specified file 42 | bool WriteBmpFile( const char* filename ); // Write the bitmap to the specified file 43 | #ifndef RGBIMAGE_DONT_USE_OPENGL 44 | bool LoadFromOpenglBuffer(); // Load the bitmap from the current OpenGL buffer 45 | bool DrawToOpenglBuffer(); // Draw the bitmap into the current OpenGL buffer 46 | #endif 47 | 48 | long GetNumRows() const { return NumRows; } 49 | long GetNumCols() const { return NumCols; } 50 | // Rows are word aligned 51 | long GetNumBytesPerRow() const { return ((3*NumCols+3)>>2)<<2; } 52 | const void* ImageData() const { return (void*)ImagePtr; } 53 | 54 | const unsigned char* GetRgbPixel( long row, long col ) const; 55 | unsigned char* GetRgbPixel( long row, long col ); 56 | void GetRgbPixel( long row, long col, float* red, float* green, float* blue ) const; 57 | void GetRgbPixel( long row, long col, double* red, double* green, double* blue ) const; 58 | 59 | void SetRgbPixelf( long row, long col, double red, double green, double blue ); 60 | void SetRgbPixelc( long row, long col, 61 | unsigned char red, unsigned char green, unsigned char blue ); 62 | 63 | // Error reporting. (errors also print message to stderr) 64 | int GetErrorCode() const { return ErrorCode; } 65 | enum { 66 | NoError = 0, 67 | OpenError = 1, // Unable to open file for reading 68 | FileFormatError = 2, // Not recognized as a 24 bit BMP file 69 | MemoryError = 3, // Unable to allocate memory for image data 70 | ReadError = 4, // End of file reached prematurely 71 | WriteError = 5 // Unable to write out data (or no date to write out) 72 | }; 73 | bool ImageLoaded() const { return (ImagePtr!=0); } // Is an image loaded? 74 | 75 | void Reset(); // Frees image data memory 76 | 77 | private: 78 | unsigned char* ImagePtr; // array of pixel values (integers range 0 to 255) 79 | long NumRows; // number of rows in image 80 | long NumCols; // number of columns in image 81 | int ErrorCode; // error code 82 | 83 | static short readShort( FILE* infile ); 84 | static long readLong( FILE* infile ); 85 | static void skipChars( FILE* infile, int numChars ); 86 | static void writeLong( long data, FILE* outfile ); 87 | static void writeShort( short data, FILE* outfile ); 88 | 89 | static unsigned char doubleToUnsignedChar( double x ); 90 | 91 | }; 92 | 93 | inline RgbImage::RgbImage() 94 | { 95 | NumRows = 0; 96 | NumCols = 0; 97 | ImagePtr = 0; 98 | ErrorCode = 0; 99 | } 100 | 101 | inline RgbImage::RgbImage( const char* filename ) 102 | { 103 | NumRows = 0; 104 | NumCols = 0; 105 | ImagePtr = 0; 106 | ErrorCode = 0; 107 | LoadBmpFile( filename ); 108 | } 109 | 110 | inline RgbImage::~RgbImage() 111 | { 112 | delete[] ImagePtr; 113 | } 114 | 115 | // Returned value points to three "unsigned char" values for R,G,B 116 | inline const unsigned char* RgbImage::GetRgbPixel( long row, long col ) const 117 | { 118 | assert ( row 93 | double Bx, double By, // Image of <1,0> 94 | double Cx, double Cy) // Image of <0,1> 95 | { 96 | m13 = Ax; // Displacement 97 | m23 = Ay; 98 | m11 = Bx-Ax; // Column 1 99 | m21 = By-Ay; 100 | m12 = Cx-Ax; // Column 2 101 | m22 = Cy-Ay; 102 | } 103 | 104 | #endif //TEXTUREAFFINEXFORM_H 105 | -------------------------------------------------------------------------------- /Graphics/TextureBilinearXform.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * RayTrace Software Package, release 3.0. May 3, 2006 4 | * 5 | * Author: Samuel R. Buss 6 | * 7 | * Software accompanying the book 8 | * 3D Computer Graphics: A Mathematical Introduction with OpenGL, 9 | * by S. Buss, Cambridge University Press, 2003. 10 | * 11 | * Software is "as-is" and carries no warranty. It may be used without 12 | * restriction, but if you modify it, please change the filenames to 13 | * prevent confusion between different versions. Please acknowledge 14 | * all use of the software in any publications or products based on it. 15 | * 16 | * Bug reports: Sam Buss, sbuss@ucsd.edu. 17 | * Web page: http://math.ucsd.edu/~sbuss/MathCG 18 | * 19 | */ 20 | 21 | #include "TextureBilinearXform.h" 22 | #include "../Graphics/VisiblePoint.h" 23 | 24 | void TextureBilinearXform::ApplyTexture( VisiblePoint& visPoint ) const 25 | { 26 | double uCoord = visPoint.GetU(); 27 | double vCoord = visPoint.GetV(); 28 | visPoint.SetUV( (1.0-uCoord)*((1.0-vCoord)*TextureCoordA 29 | +vCoord*TextureCoordD) 30 | + uCoord*((1.0-vCoord)*TextureCoordB 31 | +vCoord*TextureCoordC)); 32 | return; 33 | } 34 | -------------------------------------------------------------------------------- /Graphics/TextureBilinearXform.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * RayTrace Software Package, release 3.0. May 3, 2006. 4 | * 5 | * Author: Samuel R. Buss 6 | * 7 | * Software accompanying the book 8 | * 3D Computer Graphics: A Mathematical Introduction with OpenGL, 9 | * by S. Buss, Cambridge University Press, 2003. 10 | * 11 | * Software is "as-is" and carries no warranty. It may be used without 12 | * restriction, but if you modify it, please change the filenames to 13 | * prevent confusion between different versions. Please acknowledge 14 | * all use of the software in any publications or products based on it. 15 | * 16 | * Bug reports: Sam Buss, sbuss@ucsd.edu. 17 | * Web page: http://math.ucsd.edu/~sbuss/MathCG 18 | * 19 | */ 20 | 21 | #ifndef TEXTUREBILINEARXFORM_H 22 | #define TEXTUREBILINEARXFORM_H 23 | 24 | #include "TextureMapBase.h" 25 | #include "../VrMath/LinearR2.h" 26 | 27 | // TextureBilinearXform - Warps texture map coordinates bilinearly. 28 | 29 | class TextureBilinearXform : public TextureMapBase { 30 | 31 | public: 32 | TextureBilinearXform(); 33 | 34 | void SetTextureCoords( double* ); // 4 pairs of doubles, giving texture coordinates 35 | void SetTextureCoords( float* ); // 4 pairs of float, giving texture coordinates 36 | 37 | void SetTextureCoordA ( double u, double v ) { TextureCoordA.Set(u,v); } 38 | void SetTextureCoordB ( double u, double v ) { TextureCoordB.Set(u,v); } 39 | void SetTextureCoordC ( double u, double v ) { TextureCoordC.Set(u,v); } 40 | void SetTextureCoordD ( double u, double v ) { TextureCoordD.Set(u,v); } 41 | 42 | void ApplyTexture( VisiblePoint& visPoint ) const; 43 | 44 | private: 45 | VectorR2 TextureCoordA; // Tex. coordinate for vertex A 46 | VectorR2 TextureCoordB; // Tex. coordinate for vertex B 47 | VectorR2 TextureCoordC; // Tex. coordinate for vertex C 48 | VectorR2 TextureCoordD; // Tex. coordinate for vertex D 49 | }; 50 | 51 | inline TextureBilinearXform::TextureBilinearXform() 52 | { 53 | TextureCoordA.Set( 0.0, 0.0 ); 54 | TextureCoordB.Set( 1.0, 0.0 ); 55 | TextureCoordC.Set( 1.0, 1.0 ); 56 | TextureCoordD.Set( 0.0, 1.0 ); 57 | } 58 | 59 | inline void TextureBilinearXform::SetTextureCoords( double* tc ) // 4 pairs of doubles, giving texture coordinates 60 | { 61 | TextureCoordA.Load( tc ); 62 | TextureCoordB.Load( tc+2 ); 63 | TextureCoordC.Load( tc+4 ); 64 | TextureCoordD.Load( tc+6 ); 65 | } 66 | 67 | inline void TextureBilinearXform::SetTextureCoords( float* tc ) // 4 pairs of doubles, giving texture coordinates 68 | { 69 | TextureCoordA.Load( tc ); 70 | TextureCoordB.Load( tc+2 ); 71 | TextureCoordC.Load( tc+4 ); 72 | TextureCoordD.Load( tc+6 ); 73 | } 74 | 75 | 76 | 77 | #endif //TEXTUREBILINEARXFORM_H 78 | -------------------------------------------------------------------------------- /Graphics/TextureCheckered.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * RayTrace Software Package, release 3.0. May 3, 2006. 4 | * 5 | * Author: Samuel R. Buss 6 | * 7 | * Software accompanying the book 8 | * 3D Computer Graphics: A Mathematical Introduction with OpenGL, 9 | * by S. Buss, Cambridge University Press, 2003. 10 | * 11 | * Software is "as-is" and carries no warranty. It may be used without 12 | * restriction, but if you modify it, please change the filenames to 13 | * prevent confusion between different versions. Please acknowledge 14 | * all use of the software in any publications or products based on it. 15 | * 16 | * Bug reports: Sam Buss, sbuss@ucsd.edu. 17 | * Web page: http://math.ucsd.edu/~sbuss/MathCG 18 | * 19 | */ 20 | 21 | #include "TextureCheckered.h" 22 | #include "ViewableBase.h" 23 | 24 | bool TextureCheckered::InOddSquare(double u, double v ) const // Compute even/odd ness 25 | { 26 | bool ans = false; 27 | if ( u<0.0 ) { 28 | ans = true; 29 | u = -u; 30 | } 31 | ans ^= (((long)(u/uWidth))&0x01); 32 | if ( v<0.0 ) { 33 | ans = !ans; 34 | v = -v; 35 | } 36 | ans ^= (((long)(v/vWidth))&0x01); 37 | return ans; 38 | } 39 | 40 | void TextureCheckered::ApplyTexture( 41 | VisiblePoint& visPoint ) const 42 | { 43 | if ( InOddSquare( visPoint.GetU(), visPoint.GetV() ) ) { 44 | if ( Material1 ) { 45 | visPoint.SetMaterial(*Material1); 46 | } 47 | } 48 | else if ( Material2 ) { 49 | visPoint.SetMaterial( *Material2 ); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Graphics/TextureCheckered.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * RayTrace Software Package, release 3.0. May 3, 2006. 4 | * 5 | * Author: Samuel R. Buss 6 | * 7 | * Software accompanying the book 8 | * 3D Computer Graphics: A Mathematical Introduction with OpenGL, 9 | * by S. Buss, Cambridge University Press, 2003. 10 | * 11 | * Software is "as-is" and carries no warranty. It may be used without 12 | * restriction, but if you modify it, please change the filenames to 13 | * prevent confusion between different versions. Please acknowledge 14 | * all use of the software in any publications or products based on it. 15 | * 16 | * Bug reports: Sam Buss, sbuss@ucsd.edu. 17 | * Web page: http://math.ucsd.edu/~sbuss/MathCG 18 | * 19 | */ 20 | 21 | #ifndef TEXTURECHECKERED_H 22 | #define TEXTURECHECKERED_H 23 | 24 | #include "TextureMapBase.h" 25 | 26 | class MaterialBase; 27 | 28 | // TextureCheckered makes a checkerboard style pattern. 29 | // It takes has one or two materials which replace 30 | // the material in the positions of subsquares. 31 | // The texture pattern repeats and tiles the whole uv-plane. 32 | 33 | class TextureCheckered : public TextureMapBase 34 | { 35 | public: 36 | TextureCheckered() : Material1(0),Material2(0) { SetWidths(0.5,0.5); } 37 | 38 | void SetWidths(double uwidth, double vwidth) 39 | { uWidth=uwidth; vWidth=vwidth; } 40 | void SetMaterials( const MaterialBase* mat1, const MaterialBase* mat2 ) 41 | { SetMaterial1(mat1); SetMaterial2(mat2); } 42 | void SetMaterial1( const MaterialBase* mat1 ) { Material1 = mat1; } 43 | void SetMaterial2( const MaterialBase* mat2 ) { Material2 = mat2; } 44 | 45 | const MaterialBase* GetMaterial1() const { return Material1; } 46 | const MaterialBase* GetMaterial2() const { return Material2; } 47 | 48 | bool InOddSquare(double u, double v ) const; // Compute even/odd ness 49 | virtual void ApplyTexture( VisiblePoint& visPoint ) const; 50 | 51 | protected: 52 | double uWidth, vWidth; // Width of squares in u and v directions 53 | const MaterialBase* Material1; // Null if material not applied 54 | const MaterialBase* Material2; // Null if material not applied 55 | }; 56 | 57 | #endif //TEXTURECHECKERED_H 58 | -------------------------------------------------------------------------------- /Graphics/TextureMapBase.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * RayTrace Software Package, release 3.0. May 3, 2006. 4 | * 5 | * Author: Samuel R. Buss 6 | * 7 | * Software accompanying the book 8 | * 3D Computer Graphics: A Mathematical Introduction with OpenGL, 9 | * by S. Buss, Cambridge University Press, 2003. 10 | * 11 | * Software is "as-is" and carries no warranty. It may be used without 12 | * restriction, but if you modify it, please change the filenames to 13 | * prevent confusion between different versions. Please acknowledge 14 | * all use of the software in any publications or products based on it. 15 | * 16 | * Bug reports: Sam Buss, sbuss@ucsd.edu. 17 | * Web page: http://math.ucsd.edu/~sbuss/MathCG 18 | * 19 | */ 20 | 21 | #include "TextureMapBase.h" 22 | #include "../VrMath/LinearR2.h" 23 | #include "../VrMath/LinearR3.h" 24 | #include "../VrMath/MathMisc.h" 25 | 26 | // Convert a unit vector reflection direction to cube map coordinates 27 | // The input is a unit vector: reflectDir 28 | // The return value is a VectorR2, a value in [0,1]x[0,1] 29 | // Layout of the cube map. 30 | // Up 31 | // Left Back Right Front 32 | // Down 33 | void TextureMapBase::ReflectDirToCubeMap( const VectorR3& reflectDir, 34 | VectorR2* cubeMapCoords ) { 35 | 36 | // Array of center positions. 37 | double centers[12] = { 38 | 7.0/8.0, 3.0/6.0, // Front 39 | 3.0/8.0, 3.0/6.0, // Back 40 | 5.0/8.0, 3.0/6.0, // Right 41 | 1.0/8.0, 3.0/6.0, // Left 42 | 3.0/8.0, 5.0/6.0, // Up (Ceiling) 43 | 3.0/8.0, 1.0/6.0, // Down (Floor) 44 | }; 45 | 46 | assert ( reflectDir.IsUnit() ); 47 | 48 | double maxAbs = fabs(reflectDir.x); 49 | int maxDir = 0; // Zero if max component is x. 50 | double t = fabs(reflectDir.y); 51 | if ( t > maxAbs ) { 52 | maxDir = 1; 53 | maxAbs = t; 54 | } 55 | t = fabs(reflectDir.z); 56 | if ( t > maxAbs ) { 57 | maxDir = 2; 58 | maxAbs = t; 59 | } 60 | 61 | double a, b; 62 | switch ( maxDir ) { 63 | case 0: 64 | if ( reflectDir.x>0.0 ) { // If right wall 65 | cubeMapCoords->Load(centers+4); 66 | } 67 | else { 68 | cubeMapCoords->Load(centers+6); // Left wall 69 | } 70 | a = reflectDir.z/reflectDir.x; 71 | b = reflectDir.y/maxAbs; 72 | break; 73 | case 1: 74 | if ( reflectDir.y>0.0 ) { // If up (ceiling) 75 | cubeMapCoords->Load(centers+8); 76 | } 77 | else { 78 | cubeMapCoords->Load(centers+10); // Else, it's down (floor) 79 | } 80 | a = reflectDir.x/maxAbs; 81 | b = reflectDir.z/reflectDir.y; 82 | break; 83 | case 2: 84 | if ( reflectDir.z>0.0 ) { // If front wall (viewer position) 85 | cubeMapCoords->Load(centers); 86 | } 87 | else { 88 | cubeMapCoords->Load(centers+2); // Back wall 89 | } 90 | a = -reflectDir.x/reflectDir.z; 91 | b = reflectDir.y/maxAbs; 92 | break; 93 | } 94 | 95 | cubeMapCoords->x += a*OneEighth; 96 | cubeMapCoords->y += b*OneSixth; 97 | 98 | } 99 | -------------------------------------------------------------------------------- /Graphics/TextureMapBase.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * RayTrace Software Package, release 3.0. May 3, 2006. 4 | * 5 | * Author: Samuel R. Buss 6 | * 7 | * Software accompanying the book 8 | * 3D Computer Graphics: A Mathematical Introduction with OpenGL, 9 | * by S. Buss, Cambridge University Press, 2003. 10 | * 11 | * Software is "as-is" and carries no warranty. It may be used without 12 | * restriction, but if you modify it, please change the filenames to 13 | * prevent confusion between different versions. Please acknowledge 14 | * all use of the software in any publications or products based on it. 15 | * 16 | * Bug reports: Sam Buss, sbuss@ucsd.edu. 17 | * Web page: http://math.ucsd.edu/~sbuss/MathCG 18 | * 19 | */ 20 | 21 | #ifndef TEXTUREMAPBASE_H 22 | #define TEXTUREMAPBASE_H 23 | 24 | #include 25 | class VisiblePoint; 26 | class VectorR2; 27 | class VectorR3; 28 | 29 | // TextureMapBase is purely virtual. 30 | 31 | class TextureMapBase { 32 | 33 | public: 34 | 35 | // The section ApplyTexture routine must be written for every 36 | // texture map class. It must modify the VisiblePoint according 37 | // to the texture map. At least one of the following two routines 38 | // *must* be written; 39 | 40 | 41 | virtual void ApplyTexture( VisiblePoint& visPoint ) const { assert(0); } 42 | virtual void ApplyTexture( VisiblePoint& visPoint, const VectorR3& viewDir ) const; 43 | 44 | // Convert a unit vector reflection direction to cube map coordinates 45 | static void ReflectDirToCubeMap( const VectorR3& reflectDir, 46 | VectorR2* cubeMapCoords ); 47 | 48 | virtual ~TextureMapBase() {} 49 | 50 | protected: 51 | 52 | }; 53 | 54 | inline void TextureMapBase::ApplyTexture( VisiblePoint& visPoint, const VectorR3& viewDir ) const 55 | { 56 | ApplyTexture( visPoint ); // Default implementation 57 | } 58 | 59 | #endif // TEXTUREMAPBASE_H 60 | -------------------------------------------------------------------------------- /Graphics/TextureMultiFaces.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * RayTrace Software Package, release 3.0. May 3, 2006. 4 | * 5 | * Author: Samuel R. Buss 6 | * 7 | * Software accompanying the book 8 | * 3D Computer Graphics: A Mathematical Introduction with OpenGL, 9 | * by S. Buss, Cambridge University Press, 2003. 10 | * 11 | * Software is "as-is" and carries no warranty. It may be used without 12 | * restriction, but if you modify it, please change the filenames to 13 | * prevent confusion between different versions. Please acknowledge 14 | * all use of the software in any publications or products based on it. 15 | * 16 | * Bug reports: Sam Buss, sbuss@ucsd.edu. 17 | * Web page: http://math.ucsd.edu/~sbuss/MathCG 18 | * 19 | */ 20 | 21 | #include "TextureMultiFaces.h" 22 | #include "VisiblePoint.h" 23 | 24 | void TextureMultiFaces::ApplyTexture( VisiblePoint& visPoint ) const 25 | { 26 | int i = visPoint.GetFaceNumber(); 27 | if ( i>= NumTextureMaps ) { 28 | i = NumTextureMaps-1; 29 | } 30 | TextureMapPointer p = TexMapPtrs[i]; 31 | if ( p ) { 32 | p->ApplyTexture(visPoint); 33 | } 34 | return; 35 | } 36 | 37 | void TextureMultiFaces::DeleteAll() { 38 | for (int i=0; iImageLoaded() ) { 39 | const VectorR2& uv = visPoint.GetUV(); 40 | VectorR3 color; 41 | GetTextureColor(uv.x, uv.y, &color); 42 | visPoint.MakeMaterialMutable(); 43 | visPoint.GetMaterialMutable().SetColorAmbientDiffuse(color); 44 | } 45 | } 46 | 47 | void TextureRgbImage::GetTextureColor( double u, double v, VectorR3 *retColor ) const 48 | { 49 | switch( WrapMode ) { 50 | case WrapUV: 51 | if ( u<0.0 || u>1.0 ) { 52 | u = u-floor(u); 53 | } 54 | if ( v<0.0 || v>1.0 ) { 55 | v = v-floor(v); 56 | } 57 | break; 58 | case ClampUV: 59 | ClampRange( &u, 0.0, 1.0 ); 60 | ClampRange( &v, 0.0, 1.0 ); 61 | break; 62 | case BackgroundColorMode: 63 | if ( u<0.0 || u>1.0 || v<0.0 || v>1.0 ) { 64 | *retColor = BackgroundColor; 65 | return; 66 | } 67 | break; 68 | } 69 | 70 | double s = TextureImage->GetNumRows(); 71 | double r = TextureImage->GetNumCols(); 72 | 73 | if ( UseBilinearFlag ) { 74 | long iLo, iHi; 75 | double alpha; 76 | if ( r==1.0 ) { 77 | iLo = iHi = 0; 78 | alpha = 0.0; 79 | } 80 | else { 81 | r -= 1.0; 82 | double temp = floor(u*r); 83 | iLo = (long)temp; 84 | ClampMax( &iLo, TextureImage->GetNumCols()-2 ); 85 | iHi = iLo + 1; 86 | alpha = u*r - temp; 87 | } 88 | long jLo, jHi; 89 | double beta; 90 | if ( s==1.0 ) { 91 | jLo = jHi = 0; 92 | beta = 0.0; 93 | } 94 | else { 95 | s -= 1.0; 96 | double temp = floor(v*s); 97 | jLo = (long)temp; 98 | ClampMax( &jLo, TextureImage->GetNumRows()-2 ); 99 | jHi = jLo + 1; 100 | beta = v*s - temp; 101 | } 102 | 103 | VectorR3 wk; 104 | TextureImage->GetRgbPixel( jLo, iLo, &(wk.x), &(wk.y), &(wk.z) ); 105 | wk *= (1.0-alpha)*(1.0-beta); 106 | *retColor = wk; 107 | TextureImage->GetRgbPixel( jHi, iLo, &(wk.x), &(wk.y), &(wk.z) ); 108 | wk *= (1.0-alpha)*beta; 109 | *retColor += wk; 110 | TextureImage->GetRgbPixel( jHi, iHi, &(wk.x), &(wk.y), &(wk.z) ); 111 | wk *= alpha*beta; 112 | *retColor += wk; 113 | TextureImage->GetRgbPixel( jLo, iHi, &(wk.x), &(wk.y), &(wk.z) ); 114 | wk *= alpha*(1.0-beta); 115 | *retColor += wk; 116 | } 117 | else { 118 | // Just get closest pixel 119 | double temp = floor(u*r); 120 | long i = (long)temp; 121 | temp = floor(v*s); 122 | long j = (long)temp; 123 | ClampRange( &i, 0, TextureImage->GetNumCols()-1 ); // Just in case (e.g. u=1) 124 | ClampRange( &j, 0, TextureImage->GetNumRows()-1 ); 125 | TextureImage->GetRgbPixel(j,i, &(retColor->x), &(retColor->y), &(retColor->z) ); 126 | } 127 | return; 128 | } 129 | -------------------------------------------------------------------------------- /Graphics/TextureRgbImage.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * RayTrace Software Package, release 3.0. May 3, 2006. 4 | * 5 | * Author: Samuel R. Buss 6 | * 7 | * Software accompanying the book 8 | * 3D Computer Graphics: A Mathematical Introduction with OpenGL, 9 | * by S. Buss, Cambridge University Press, 2003. 10 | * 11 | * Software is "as-is" and carries no warranty. It may be used without 12 | * restriction, but if you modify it, please change the filenames to 13 | * prevent confusion between different versions. Please acknowledge 14 | * all use of the software in any publications or products based on it. 15 | * 16 | * Bug reports: Sam Buss, sbuss@ucsd.edu. 17 | * Web page: http://math.ucsd.edu/~sbuss/MathCG 18 | * 19 | */ 20 | 21 | #ifndef TEXTURERGBIMAGE_H 22 | #define TEXTURERGBIMAGE_H 23 | 24 | #include "TextureMapBase.h" 25 | #include "RgbImage.h" 26 | #include "../VrMath/LinearR2.h" 27 | #include "../VrMath/LinearR3.h" 28 | 29 | // TextureRgbImage makes a texture map out of an RGB image. 30 | // Uses bilinear interpolation to set colors (by default) 31 | // Wraps around by default. 32 | 33 | class TextureRgbImage : public TextureMapBase { 34 | 35 | public: 36 | TextureRgbImage(); 37 | TextureRgbImage( const RgbImage& ); 38 | TextureRgbImage( const char* filename ); 39 | virtual ~TextureRgbImage(); 40 | 41 | const RgbImage& GetRgbImage() const { return *TextureImage; } 42 | bool TextureMapLoaded() const { return RgbImageLoadedFromFile; } 43 | void FreeRgbImage() { RgbImageLoadedFromFile = false; delete TextureImage; } 44 | 45 | void UseBilinearInterp( bool status ); // controls whether bilinear interpolate 46 | void SetWrapMode( int mode ); // Mode should be WrapUV or ClampUV 47 | void SetWrapMode( const VectorR3& color ); // Sets BackgroundColorMode 48 | void SetWrapMode( double* ); // Ditto 49 | void SetWrapMode( float* ); // Ditto 50 | void SetWrapMode( double r, double g, double b ); // Ditto 51 | 52 | enum { 53 | WrapUV = 0, 54 | ClampUV = 1, 55 | BackgroundColorMode = 2 56 | }; 57 | 58 | // ApplyTexture( visPoint ) merely "paints" in the color 59 | // The color becomes the ambient/diffuse color and is applied before 60 | // lighting calculuations. 61 | void ApplyTexture( VisiblePoint& visPoint ) const; 62 | 63 | void GetTextureColor( const VectorR2& uvCoords, VectorR3* retColor ) const; 64 | void GetTextureColor( double u, double v, VectorR3 *retColor ) const; 65 | 66 | private: 67 | const RgbImage* TextureImage; // Pointer to the RgbImage 68 | bool RgbImageLoadedFromFile; // true if loaded from a file. 69 | 70 | bool UseBilinearFlag; // if false, then just use closest pixel 71 | 72 | int WrapMode; 73 | VectorR3 BackgroundColor; // Color used in BackgroundColorMode 74 | }; 75 | 76 | inline TextureRgbImage::TextureRgbImage() 77 | { 78 | TextureImage = 0; 79 | WrapMode = WrapUV; 80 | UseBilinearFlag = true; 81 | RgbImageLoadedFromFile = false; 82 | } 83 | 84 | inline TextureRgbImage::TextureRgbImage( const RgbImage& img ) 85 | { 86 | TextureImage = &img; 87 | WrapMode = WrapUV; 88 | UseBilinearFlag = true; 89 | RgbImageLoadedFromFile = false; 90 | } 91 | 92 | inline TextureRgbImage::TextureRgbImage( const char* filename ) 93 | { 94 | WrapMode = WrapUV; 95 | UseBilinearFlag = true; 96 | RgbImageLoadedFromFile = true; 97 | TextureImage = new RgbImage( filename ); 98 | if ( TextureImage->GetErrorCode() ) { 99 | // Failed to open file! 100 | TextureImage = 0; 101 | RgbImageLoadedFromFile = false; 102 | } 103 | } 104 | 105 | inline TextureRgbImage::~TextureRgbImage() 106 | { 107 | if ( RgbImageLoadedFromFile ) { 108 | delete TextureImage; 109 | } 110 | } 111 | 112 | inline void TextureRgbImage::UseBilinearInterp( bool status ) 113 | { 114 | UseBilinearFlag = status; 115 | } 116 | 117 | inline void TextureRgbImage::SetWrapMode( int mode ) 118 | { 119 | assert ( mode==WrapUV || mode==ClampUV ); 120 | WrapMode = mode; 121 | } 122 | 123 | inline void TextureRgbImage::SetWrapMode( const VectorR3& color ) 124 | { 125 | WrapMode = BackgroundColorMode; 126 | BackgroundColor = color; 127 | } 128 | 129 | inline void TextureRgbImage::SetWrapMode( double* color ) 130 | { 131 | WrapMode = BackgroundColorMode; 132 | BackgroundColor.Load( color ); 133 | } 134 | 135 | inline void TextureRgbImage::SetWrapMode( float* color ) 136 | { 137 | WrapMode = BackgroundColorMode; 138 | BackgroundColor.Load( color ); 139 | } 140 | 141 | inline void TextureRgbImage::SetWrapMode( double r, double g, double b ) 142 | { 143 | WrapMode = BackgroundColorMode; 144 | BackgroundColor.Set( r, g, b ); 145 | } 146 | 147 | inline void TextureRgbImage::GetTextureColor( const VectorR2& uvCoords, VectorR3* retColor ) const 148 | { 149 | GetTextureColor( uvCoords.x, uvCoords.y, retColor ); 150 | } 151 | 152 | #endif // TEXTURERGBIMAGE_H 153 | -------------------------------------------------------------------------------- /Graphics/TextureSequence.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * RayTrace Software Package, release 3.0. May 3, 2006. 4 | * 5 | * Author: Samuel R. Buss 6 | * 7 | * Software accompanying the book 8 | * 3D Computer Graphics: A Mathematical Introduction with OpenGL, 9 | * by S. Buss, Cambridge University Press, 2003. 10 | * 11 | * Software is "as-is" and carries no warranty. It may be used without 12 | * restriction, but if you modify it, please change the filenames to 13 | * prevent confusion between different versions. Please acknowledge 14 | * all use of the software in any publications or products based on it. 15 | * 16 | * Bug reports: Sam Buss, sbuss@ucsd.edu. 17 | * Web page: http://math.ucsd.edu/~sbuss/MathCG 18 | * 19 | */ 20 | 21 | #include "TextureSequence.h" 22 | 23 | void TextureSequence::ApplyTexture( VisiblePoint& visPoint ) const 24 | { 25 | for (int i=0; iApplyTexture(visPoint); 29 | } 30 | } 31 | return; 32 | } 33 | 34 | void TextureSequence::DeleteAll() { 35 | for (int i=0; i0.0 && B>=0.0 ) { 44 | return false; // Pointing away from the ellipsoid 45 | } 46 | 47 | B += B; // Double B to get final factor of 2. 48 | double A = Square(udotuA) + Square(udotuB) + Square(udotuC); 49 | 50 | double alpha1, alpha2; 51 | int numRoots = QuadraticSolveRealSafe( A, B, C, &alpha1, &alpha2 ); 52 | if ( numRoots==0 ) { 53 | return false; 54 | } 55 | if ( alpha1>0.0 ) { 56 | if ( alpha1>=maxDistance ) { 57 | return false; // Too far away 58 | } 59 | // Found an intersection from outside. 60 | returnedPoint.SetFrontFace(); 61 | returnedPoint.SetMaterial( *OuterMaterial ); 62 | *intersectDistance = alpha1; 63 | } 64 | else if ( numRoots==2 && alpha2>0.0 && alpha20.0 && LengthAB>0.0 && LengthBC>0.0 ) { 42 | Normal /= mag; // Unit Vector to parallelogram 43 | } 44 | else { 45 | Normal.SetZero(); // In this case, the parallelogram is malformed. 46 | } 47 | PlaneCoef = VertexB^Normal; 48 | 49 | NormalAB = Normal*EdgeAB; // Normal in from edge AB 50 | NormalBC = Normal*EdgeBC; // Normal in from edge BC 51 | NormalAB.ReNormalize(); // Just in case 52 | NormalBC.ReNormalize(); 53 | 54 | CoefAB = VertexA^NormalAB; // Coef. for edge AB. 55 | CoefBC = VertexB^NormalBC; 56 | CoefCD = VertexC^NormalAB; 57 | CoefDA = VertexA^NormalBC; 58 | } 59 | 60 | bool ViewableParallelogram::IsWellFormed() const 61 | { 62 | return (Normal.NormSq()>0.0); 63 | } 64 | 65 | // Returns an intersection if found with distance maxDistance 66 | // viewDir must be a unit vector. 67 | // intersectDistance and visPoint are returned values. 68 | bool ViewableParallelogram::FindIntersectionNT ( 69 | const VectorR3& viewPos, const VectorR3& viewDir, double maxDistance, 70 | double *intersectDistance, VisiblePoint& returnedPoint ) const 71 | { 72 | assert( IsWellFormed() ); 73 | double mdotn = (viewDir^Normal); 74 | double planarDist = (viewPos^Normal)-PlaneCoef; 75 | 76 | // hit distance = -planarDist/mdotn 77 | if ( mdotn<=0.0 ) { 78 | if ( planarDist<=0 || planarDist >= -maxDistance*mdotn ) { 79 | return false; 80 | } 81 | returnedPoint.SetFrontFace(); 82 | } 83 | else { 84 | if ( BackFaceCulled() || planarDist>=0 || -planarDist >= maxDistance*mdotn ) { 85 | return false; 86 | } 87 | returnedPoint.SetBackFace(); 88 | } 89 | 90 | *intersectDistance = -planarDist/mdotn; 91 | VectorR3 v; 92 | v = viewDir; 93 | v *= *intersectDistance; 94 | v += viewPos; // Point of view line intersecting plane 95 | 96 | double dotABnormal = v^NormalAB; 97 | if ( dotABnormalCoefCD ) { 98 | return false; 99 | } 100 | double dotBCnormal = v^NormalBC; 101 | if ( dotBCnormalCoefDA ) { 102 | return false; 103 | } 104 | 105 | // Front/Back face info already set above 106 | returnedPoint.SetPosition( v ); 107 | returnedPoint.SetMaterial( (mdotn<=0) ? *FrontMat : *BackMat ); 108 | returnedPoint.SetNormal( Normal ); 109 | 110 | // Compute the u-v coordinates 111 | double uCoord = (dotBCnormal-CoefBC)/(CoefDA-CoefBC); 112 | double vCoord = (dotABnormal-CoefAB)/(CoefCD-CoefAB); 113 | returnedPoint.SetUV(uCoord, vCoord); 114 | returnedPoint.SetFaceNumber( 0 ); 115 | 116 | return true; 117 | } 118 | 119 | bool ViewableParallelogram::CalcPartials( const VisiblePoint& visPoint, 120 | VectorR3& retPartialU, VectorR3& retPartialV ) const 121 | { 122 | retPartialU = VertexB; 123 | retPartialU -= VertexA; 124 | retPartialV = VertexD; 125 | retPartialV -= VertexA; 126 | return true; // Not a singularity point (parallelograms should not be degenerate) 127 | } 128 | 129 | void ViewableParallelogram::CalcBoundingPlanes( const VectorR3& u, 130 | double *minDot, double *maxDot ) const 131 | { 132 | double startdot = (u^VertexB); 133 | double mind = startdot; 134 | double maxd = mind; 135 | double t; 136 | t = (u^VertexC)-startdot; 137 | if ( t<0 ) { 138 | mind += t; 139 | } 140 | else { 141 | maxd +=t; 142 | } 143 | t = (u^VertexA)-startdot; 144 | if ( t<0 ) { 145 | mind += t; 146 | } 147 | else { 148 | maxd += t; 149 | } 150 | *minDot = mind; 151 | *maxDot = maxd; 152 | } 153 | 154 | bool ViewableParallelogram::CalcExtentsInBox( const AABB& boundingAABB, AABB& retAABB ) const 155 | { 156 | return( ::CalcExtentsInBox( *this, boundingAABB.GetBoxMin(), boundingAABB.GetBoxMax(), 157 | &(retAABB.GetBoxMin()), &(retAABB.GetBoxMax()) ) ); 158 | } 159 | -------------------------------------------------------------------------------- /Graphics/ViewableParallelogram.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * RayTrace Software Package, release 3.1. December 20, 2006. 4 | * 5 | * Author: Samuel R. Buss 6 | * 7 | * Software accompanying the book 8 | * 3D Computer Graphics: A Mathematical Introduction with OpenGL, 9 | * by S. Buss, Cambridge University Press, 2003. 10 | * 11 | * Software is "as-is" and carries no warranty. It may be used without 12 | * restriction, but if you modify it, please change the filenames to 13 | * prevent confusion between different versions. Please acknowledge 14 | * all use of the software in any publications or products based on it. 15 | * 16 | * Bug reports: Sam Buss, sbuss@ucsd.edu. 17 | * Web page: http://math.ucsd.edu/~sbuss/MathCG 18 | * 19 | */ 20 | 21 | #ifndef VIEWABLEPARALLELOGRAM_H 22 | #define VIEWABLEPARALLELOGRAM_H 23 | 24 | #include "ViewableBase.h" 25 | #include "Material.h" 26 | #include "assert.h" 27 | 28 | // This class subsumes reactangles and squares 29 | 30 | class ViewableParallelogram : public ViewableBase { 31 | 32 | public: 33 | ViewableParallelogram (); 34 | 35 | // The Init() routines specify 3 (THREE) vertices in counterclockwise order 36 | // with the 4th vertex computed from the rest. 37 | void Init( const double* vertexpositions); 38 | void Init( const float* vertexpositions); 39 | void Init( const VectorR3& vA, const VectorR3& vB, const VectorR3& vC ); 40 | 41 | void SetMaterial( const MaterialBase* material ); 42 | void SetMaterialFront( const MaterialBase* frontmaterial ); 43 | void SetMaterialBack( const MaterialBase* backmaterial ); 44 | const MaterialBase* GetMaterialFront() const { return FrontMat; } 45 | const MaterialBase* GetMaterialBack() const { return BackMat; } 46 | 47 | bool IsTwoSided() const { return (BackMat!=0); } 48 | bool BackFaceCulled() const { return (BackMat==0); } 49 | 50 | bool IsWellFormed() const; 51 | 52 | // Returns an intersection if found with distance maxDistance 53 | // viewDir must be a unit vector. 54 | // intersectDistance and visPoint are returned values. 55 | virtual bool FindIntersectionNT ( 56 | const VectorR3& viewPos, const VectorR3& viewDir, double maxDistance, 57 | double *intersectDistance, VisiblePoint& returnedPoint ) const; 58 | void CalcBoundingPlanes( const VectorR3& u, double *minDot, double *maxDot ) const; 59 | bool CalcExtentsInBox( const AABB& boundingAABB, AABB& retAABB ) const; 60 | bool CalcPartials( const VisiblePoint& visPoint, 61 | VectorR3& retPartialU, VectorR3& retPartialV ) const; 62 | ViewableType GetViewableType() const { return Viewable_Parallelogram; } 63 | 64 | const VectorR3& GetVertexA() const { return VertexA; } 65 | const VectorR3& GetVertexB() const { return VertexB; } 66 | const VectorR3& GetVertexC() const { return VertexC; } 67 | const VectorR3& GetVertexD() const { return VertexD; } 68 | void GetVertices( double* vert ) const; 69 | void GetVertices( float* vert ) const; 70 | void GetVertices( VectorR3* vA, VectorR3* vB, VectorR3* vC, VectorR3 *vD ) const; 71 | const VectorR3& GetVertex( int vertnum ) const; 72 | const VectorR3& GetNormal() const { return Normal; } 73 | 74 | protected: 75 | VectorR3 VertexA; 76 | VectorR3 VertexB; 77 | VectorR3 VertexC; 78 | VectorR3 VertexD; 79 | 80 | const MaterialBase* FrontMat; 81 | const MaterialBase* BackMat; // Null point if not visible from back 82 | 83 | VectorR3 Normal; // Unit normal to the plane of Parallelogram 84 | double PlaneCoef; // Constant coef in def'n of the plane 85 | VectorR3 NormalAB, NormalBC; // Unit vectors in from edges AB and BC 86 | double CoefAB, CoefBC, CoefCD, CoefDA; // Coefs for line equations of edges 87 | double LengthAB, LengthBC; // Edge lengths 88 | 89 | void PreCalcInfo(); // Precalculations for intersection testing speed 90 | }; 91 | 92 | inline ViewableParallelogram::ViewableParallelogram () 93 | { 94 | SetMaterial(&Material::Default); 95 | VertexA.SetZero(); 96 | VertexB.SetUnitX(); 97 | VertexC.Set(1.0,1.0,0.0); 98 | PreCalcInfo(); 99 | } 100 | 101 | // The Init() routines specify 3 (THREE) vertices in counterclockwise order 102 | // with the 4th vertex computed from the rest. 103 | inline void ViewableParallelogram::Init( const double* vertexpositions) 104 | { 105 | VertexA.Load( vertexpositions ); 106 | VertexB.Load( vertexpositions+3 ); 107 | VertexC.Load( vertexpositions+6 ); 108 | PreCalcInfo(); 109 | } 110 | 111 | inline void ViewableParallelogram::Init( const float* vertexpositions) 112 | { 113 | VertexA.Load( vertexpositions ); 114 | VertexB.Load( vertexpositions+3 ); 115 | VertexC.Load( vertexpositions+6 ); 116 | PreCalcInfo(); 117 | } 118 | 119 | inline void ViewableParallelogram::Init(const VectorR3& vA, const VectorR3& vB, const VectorR3& vC ) 120 | { 121 | VertexA = vA; 122 | VertexB = vB; 123 | VertexC = vC; 124 | PreCalcInfo(); 125 | } 126 | 127 | inline void ViewableParallelogram::SetMaterial(const MaterialBase* material ) 128 | { 129 | SetMaterialFront(material); 130 | SetMaterialBack(material); 131 | } 132 | 133 | inline void ViewableParallelogram::SetMaterialFront(const MaterialBase* frontmaterial ) 134 | { 135 | FrontMat = frontmaterial; 136 | } 137 | 138 | inline void ViewableParallelogram::SetMaterialBack( const MaterialBase* backmaterial ) 139 | { 140 | BackMat = backmaterial; 141 | } 142 | 143 | inline void ViewableParallelogram::GetVertices( double* verts ) const 144 | { 145 | VertexA.Dump( verts ); 146 | VertexB.Dump( verts+3 ); 147 | VertexC.Dump( verts+6 ); 148 | VertexD.Dump( verts+9 ); 149 | } 150 | 151 | inline void ViewableParallelogram::GetVertices( float* verts ) const 152 | { 153 | VertexA.Dump( verts ); 154 | VertexB.Dump( verts+3 ); 155 | VertexC.Dump( verts+6 ); 156 | VertexD.Dump( verts+9 ); 157 | } 158 | 159 | inline void ViewableParallelogram::GetVertices( VectorR3* vA, VectorR3* vB, VectorR3* vC, VectorR3* vD ) const 160 | { 161 | *vA = VertexA; 162 | *vB = VertexB; 163 | *vC = VertexC; 164 | *vD = VertexD; 165 | } 166 | 167 | inline const VectorR3& ViewableParallelogram::GetVertex( int vertnum ) const 168 | { 169 | assert (0 <= vertnum && vertnum <= 3); 170 | switch( vertnum ) { 171 | case 0: 172 | return VertexA; 173 | case 1: 174 | return VertexB; 175 | case 2: 176 | return VertexC; 177 | case 3: 178 | return VertexD; 179 | } 180 | assert(0); 181 | return VertexA; // Never happens 182 | } 183 | 184 | #endif // VIEWABLEPARALLELOGRAM_H 185 | -------------------------------------------------------------------------------- /Graphics/ViewableTriangle.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * RayTrace Software Package, release 3.1. December 20, 2006. 4 | * 5 | * Author: Samuel R. Buss 6 | * 7 | * Software accompanying the book 8 | * 3D Computer Graphics: A Mathematical Introduction with OpenGL, 9 | * by S. Buss, Cambridge University Press, 2003. 10 | * 11 | * Software is "as-is" and carries no warranty. It may be used without 12 | * restriction, but if you modify it, please change the filenames to 13 | * prevent confusion between different versions. Please acknowledge 14 | * all use of the software in any publications or products based on it. 15 | * 16 | * Bug reports: Sam Buss, sbuss@ucsd.edu. 17 | * Web page: http://math.ucsd.edu/~sbuss/MathCG 18 | * 19 | */ 20 | 21 | #include "ViewableTriangle.h" 22 | #include "Extents.h" 23 | #include "../VrMath/Aabb.h" 24 | 25 | // PreCalcInfo takes the vertex values and computes information to 26 | // help with intersections with rays. 27 | void ViewableTriangle::PreCalcInfo() 28 | { 29 | VectorR3 EdgeAB = VertexB - VertexA; 30 | VectorR3 EdgeBC = VertexC - VertexB; 31 | VectorR3 EdgeCA = VertexA - VertexC; 32 | 33 | if ( (EdgeAB^EdgeBC) < (EdgeBC^EdgeCA) ) { 34 | Normal = EdgeAB*EdgeBC; 35 | } 36 | else { 37 | Normal = EdgeBC*EdgeCA; 38 | } 39 | double mag = Normal.Norm(); 40 | if ( mag>0.0 ) { 41 | Normal /= mag; // Unit vector to triangle's plane 42 | } 43 | 44 | PlaneCoef = (Normal^VertexA); // Same coef for all three vertices. 45 | 46 | double A = EdgeAB.NormSq(); 47 | double B = (EdgeAB^EdgeCA); 48 | double C = EdgeCA.NormSq(); 49 | double Dinv = 1.0/(A*C-B*B); 50 | A *= Dinv; 51 | B *= Dinv; 52 | C *= Dinv; 53 | Ubeta = EdgeAB; 54 | Ubeta *= C; 55 | Ubeta.AddScaled( EdgeCA, -B ); 56 | Ugamma = EdgeCA; 57 | Ugamma *= -A; 58 | Ugamma.AddScaled( EdgeAB, B ); 59 | } 60 | 61 | bool ViewableTriangle::IsWellFormed() const 62 | { 63 | return (Normal.NormSq()>0.0); 64 | } 65 | 66 | // Returns an intersection if found with distance maxDistance 67 | // viewDir must be a unit vector. 68 | // intersectDistance and visPoint are returned values. 69 | bool ViewableTriangle::FindIntersectionNT ( 70 | const VectorR3& viewPos, const VectorR3& viewDir, double maxDistance, 71 | double *intersectDistance, VisiblePoint& returnedPoint ) const 72 | { 73 | assert( IsWellFormed() ); 74 | double mdotn = (viewDir^Normal); 75 | double planarDist = (viewPos^Normal)-PlaneCoef; 76 | 77 | // hit distance = -planarDist/mdotn 78 | bool frontFace = (mdotn<=0.0); 79 | if ( frontFace ) { 80 | if ( planarDist<=0 || planarDist >= -maxDistance*mdotn ) { 81 | return false; 82 | } 83 | } 84 | else { 85 | if ( BackFaceCulled() || planarDist>=0 || -planarDist >= maxDistance*mdotn ) { 86 | return false; 87 | } 88 | } 89 | 90 | *intersectDistance = -planarDist/mdotn; 91 | VectorR3 q; 92 | q = viewDir; 93 | q *= *intersectDistance; 94 | q += viewPos; // Point of view line intersecting plane 95 | 96 | // Compute barycentric coordinates 97 | VectorR3 v(q); 98 | v -= VertexA; 99 | double vCoord = (v^Ubeta); 100 | if ( vCoord<0.0 ) { 101 | return false; 102 | } 103 | double wCoord = (v^Ugamma); 104 | if ( wCoord<0.0 || vCoord+wCoord>1.0 ) { 105 | return false; 106 | } 107 | 108 | returnedPoint.SetPosition( q ); // Set point of intersection 109 | returnedPoint.SetUV( vCoord, wCoord ); 110 | 111 | // Front/Back face info already set above 112 | if ( frontFace ) { 113 | returnedPoint.SetMaterial( *FrontMat ); 114 | returnedPoint.SetFrontFace(); 115 | } 116 | else { 117 | returnedPoint.SetMaterial( *BackMat ); 118 | returnedPoint.SetBackFace(); 119 | } 120 | returnedPoint.SetNormal( Normal ); 121 | returnedPoint.SetFaceNumber( 0 ); 122 | 123 | return true; 124 | } 125 | 126 | void ViewableTriangle::CalcBoundingPlanes( const VectorR3& u, double *minDot, double *maxDot ) const 127 | { 128 | double mind = (u^VertexA); 129 | double maxd = (u^VertexB); 130 | double t; 131 | if ( maxd < mind ) { 132 | t = maxd; // Swap values, so mind < maxd 133 | maxd = mind; 134 | mind = t; 135 | } 136 | t = (u^VertexC); 137 | if ( tmaxd ) { 141 | maxd = t; 142 | } 143 | *minDot = mind; 144 | *maxDot = maxd; 145 | } 146 | 147 | bool ViewableTriangle::CalcExtentsInBox( const AABB& boundingAABB, AABB& retAABB ) const 148 | { 149 | return ( ::CalcExtentsInBox( *this, boundingAABB.GetBoxMin(), boundingAABB.GetBoxMax(), 150 | &(retAABB.GetBoxMin()), &(retAABB.GetBoxMax()) ) ); 151 | } 152 | 153 | bool ViewableTriangle::CalcPartials( const VisiblePoint& visPoint, 154 | VectorR3& retPartialU, VectorR3& retPartialV ) const 155 | { 156 | retPartialU = VertexB; 157 | retPartialU -= VertexA; 158 | retPartialV = VertexC; 159 | retPartialV -= VertexA; 160 | return true; // Not a singularity point (triangles should not be degenerate) 161 | } 162 | -------------------------------------------------------------------------------- /Graphics/ViewableTriangle.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * RayTrace Software Package, release 3.1. December 20, 2006. 4 | * 5 | * Author: Samuel R. Buss 6 | * 7 | * Software accompanying the book 8 | * 3D Computer Graphics: A Mathematical Introduction with OpenGL, 9 | * by S. Buss, Cambridge University Press, 2003. 10 | * 11 | * Software is "as-is" and carries no warranty. It may be used without 12 | * restriction, but if you modify it, please change the filenames to 13 | * prevent confusion between different versions. Please acknowledge 14 | * all use of the software in any publications or products based on it. 15 | * 16 | * Bug reports: Sam Buss, sbuss@ucsd.edu. 17 | * Web page: http://math.ucsd.edu/~sbuss/MathCG 18 | * 19 | */ 20 | 21 | #ifndef VIEWABLETRIANGLE_H 22 | #define VIEWABLETRIANGLE_H 23 | 24 | #include "ViewableBase.h" 25 | #include "../VrMath/LinearR2.h" 26 | #include "Material.h" 27 | 28 | class ViewableTriangle : public ViewableBase { 29 | 30 | public: 31 | ViewableTriangle(); 32 | 33 | // Three vertices in counter-clockwise order. 34 | void Init( const double* vertexpositions); 35 | void Init( const float* vertexpositions); 36 | void Init( const VectorR3& vA, const VectorR3& vB, const VectorR3& vC ); 37 | 38 | void SetMaterial( const MaterialBase* material ); 39 | void SetMaterialFront( const MaterialBase* frontmaterial ); 40 | void SetMaterialBack( const MaterialBase* backmaterial ); 41 | const MaterialBase* GetMaterialFront() const { return FrontMat; } 42 | const MaterialBase* GetMaterialBack() const { return BackMat; } 43 | 44 | bool IsTwoSided() const { return (BackMat!=0); } 45 | bool BackFaceCulled() const { return (BackMat==0); } 46 | 47 | bool IsWellFormed() const; 48 | 49 | // Returns an intersection if found with distance maxDistance 50 | // viewDir must be a unit vector. 51 | // intersectDistance and visPoint are returned values. 52 | virtual bool FindIntersectionNT ( 53 | const VectorR3& viewPos, const VectorR3& viewDir, double maxDistance, 54 | double *intersectDistance, VisiblePoint& returnedPoint ) const; 55 | void CalcBoundingPlanes( const VectorR3& u, double *minDot, double *maxDot ) const; 56 | bool CalcExtentsInBox( const AABB& boundingAABB, AABB& retAABB ) const; 57 | bool CalcPartials( const VisiblePoint& visPoint, 58 | VectorR3& retPartialU, VectorR3& retPartialV ) const; 59 | ViewableType GetViewableType() const { return Viewable_Triangle; } 60 | 61 | const VectorR3& GetVertexA() const { return VertexA; } 62 | const VectorR3& GetVertexB() const { return VertexB; } 63 | const VectorR3& GetVertexC() const { return VertexC; } 64 | void GetVertices( double* verts ) const; // Returns 9 doubles 65 | void GetVertices( float* verts ) const; // Returns 9 floats 66 | void GetVertices( VectorR3* vertA, VectorR3* vertB, VectorR3* vertC ) const; 67 | const VectorR3& GetNormal() const { return Normal; } 68 | 69 | protected: 70 | VectorR3 VertexA; 71 | VectorR3 VertexB; 72 | VectorR3 VertexC; 73 | 74 | const MaterialBase* FrontMat; 75 | const MaterialBase* BackMat; // Null point if not visible from back 76 | 77 | VectorR3 Normal; // Unit normal to the plane of triangle 78 | double PlaneCoef; // Constant coef in def'n of the plane 79 | VectorR3 Ubeta; // Vector for finding beta coef 80 | VectorR3 Ugamma; // Vector for finding gamma coef 81 | 82 | void PreCalcInfo(); // Precalculations for intersection testing speed 83 | }; 84 | 85 | inline ViewableTriangle::ViewableTriangle() { 86 | FrontMat = &Material::Default; 87 | BackMat = &Material::Default; 88 | } 89 | 90 | inline void ViewableTriangle::Init( const double* v ) { 91 | VertexA.Load( v ); 92 | VertexB.Load( v+3 ); 93 | VertexC.Load( v+6 ); 94 | PreCalcInfo(); 95 | } 96 | 97 | inline void ViewableTriangle::Init( const float* v ) { 98 | VertexA.Load( v ); 99 | VertexB.Load( v+3 ); 100 | VertexC.Load( v+6 ); 101 | PreCalcInfo(); 102 | } 103 | 104 | inline void ViewableTriangle::Init( const VectorR3& vA, 105 | const VectorR3& vB, 106 | const VectorR3& vC ) { 107 | VertexA = vA; 108 | VertexB = vB; 109 | VertexC = vC; 110 | PreCalcInfo(); 111 | } 112 | 113 | inline void ViewableTriangle::SetMaterial(const MaterialBase* material ) 114 | { 115 | SetMaterialFront(material); 116 | SetMaterialBack(material); 117 | } 118 | 119 | inline void ViewableTriangle::SetMaterialFront(const MaterialBase* frontmaterial ) 120 | { 121 | FrontMat = frontmaterial; 122 | } 123 | 124 | inline void ViewableTriangle::SetMaterialBack( const MaterialBase* backmaterial ) 125 | { 126 | BackMat = backmaterial; 127 | } 128 | 129 | inline void ViewableTriangle::GetVertices( double* v ) const 130 | { 131 | VertexA.Dump( v ); 132 | VertexB.Dump( v+3 ); 133 | VertexC.Dump( v+6 ); 134 | } 135 | 136 | inline void ViewableTriangle::GetVertices( float* v ) const 137 | { 138 | VertexA.Dump( v ); 139 | VertexB.Dump( v+3 ); 140 | VertexC.Dump( v+6 ); 141 | } 142 | 143 | inline void ViewableTriangle::GetVertices( 144 | VectorR3* vertA, VectorR3* vertB, VectorR3* vertC) const 145 | { 146 | *vertA = VertexA; 147 | *vertB = VertexB; 148 | *vertC = VertexC; 149 | } 150 | 151 | #endif // VIEWABLETRIANGLE_H 152 | -------------------------------------------------------------------------------- /Graphics/VisiblePoint.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * RayTrace Software Package, release 3.2. May 3, 2007. 4 | * 5 | * Author: Samuel R. Buss 6 | * 7 | * Software accompanying the book 8 | * 3D Computer Graphics: A Mathematical Introduction with OpenGL, 9 | * by S. Buss, Cambridge University Press, 2003. 10 | * 11 | * Software is "as-is" and carries no warranty. It may be used without 12 | * restriction, but if you modify it, please change the filenames to 13 | * prevent confusion between different versions. Please acknowledge 14 | * all use of the software in any publications or products based on it. 15 | * 16 | * Bug reports: Sam Buss, sbuss@ucsd.edu. 17 | * Web page: http://math.ucsd.edu/~sbuss/MathCG 18 | * 19 | */ 20 | 21 | #ifndef VISIBLEPOINT_H 22 | #define VISIBLEPOINT_H 23 | 24 | // **************************************************************************** 25 | // The class VisiblePoint is defined in this file. 26 | // **************************************************************************** 27 | 28 | #include "../VrMath/LinearR2.h" 29 | #include "../VrMath/LinearR3.h" 30 | #include "MaterialBase.h" 31 | class ViewableBase; 32 | 33 | // VisiblePoint is a class storing information about a visible point. 34 | 35 | class VisiblePoint { 36 | friend class ViewableBase; 37 | 38 | public: 39 | VisiblePoint() { FrontFace = true; MatNeedsFreeing = false; }; 40 | VisiblePoint(const VisiblePoint &p); 41 | ~VisiblePoint(); 42 | 43 | VisiblePoint& operator=(const VisiblePoint& p); 44 | 45 | void SetPosition( const VectorR3& pos ) { Position = pos;} 46 | void SetNormal( const VectorR3& normal ) { Normal = normal; } 47 | void SetMaterial( const MaterialBase& material ); 48 | void SetFrontFace ( bool frontface=true ) { FrontFace = frontface; } 49 | void SetBackFace () { FrontFace = false; } 50 | 51 | bool IsFrontFacing() const { return FrontFace; } 52 | bool IsBackFacing() const { return !FrontFace; } 53 | 54 | const VectorR3& GetPosition() const { return Position; } 55 | const VectorR3& GetNormal() const { return Normal; } 56 | const MaterialBase& GetMaterial() const { return *Mat; } 57 | MaterialBase& GetMaterialMutable() { assert(MatNeedsFreeing); return *Mat; } 58 | 59 | void SetUV( double u, double v ) { uvCoords.Set(u,v); } 60 | void SetUV( const VectorR2& uv ) { uvCoords = uv; } 61 | 62 | double GetU() const { return uvCoords.x; } 63 | double GetV() const { return uvCoords.y; } 64 | const VectorR2& GetUV() const { return uvCoords; } 65 | VectorR2& GetUV() { return uvCoords; } 66 | 67 | // Face numbers allow different texture maps to be applied to different faces of an object. 68 | // Typically, the front and back side of a face get the same face number. However, they 69 | // get different texture maps, and also "FrontFace" can be used to distinguish front and back faces. 70 | // Face numbers are non-negative integers. Generally: 0 is the "main" face. 71 | void SetFaceNumber( int faceNumber ) { FaceNumber = faceNumber; } 72 | int GetFaceNumber() const { return FaceNumber; } 73 | 74 | void SetObject( const ViewableBase *object ) { TheObject = object; } 75 | const ViewableBase& GetObject() const { return *TheObject; } 76 | 77 | void MakeMaterialMutable(); 78 | 79 | private: 80 | VectorR3 Position; 81 | VectorR3 Normal; // Outward Normal 82 | MaterialBase* Mat; 83 | VectorR2 uvCoords; // (u,v) coordinates for texture mapping & etc. 84 | int FaceNumber; // Index of face number (non-negative). 85 | const ViewableBase* TheObject; // The object from which the visible point came. 86 | bool FrontFace; // Is it being viewed from the front side? 87 | 88 | bool MatNeedsFreeing; // true if we are responsible for freeing the material. 89 | 90 | }; 91 | 92 | inline VisiblePoint::VisiblePoint(const VisiblePoint& vp) 93 | { 94 | MatNeedsFreeing = false; 95 | *this = vp; 96 | } 97 | 98 | inline VisiblePoint::~VisiblePoint() 99 | { 100 | if ( MatNeedsFreeing ) { 101 | delete Mat; 102 | } 103 | } 104 | 105 | inline VisiblePoint& VisiblePoint::operator=(const VisiblePoint& vp) 106 | { 107 | Position = vp.Position; 108 | Normal = vp.Normal; 109 | uvCoords = vp.uvCoords; 110 | FaceNumber = vp.FaceNumber; 111 | TheObject = vp.TheObject; 112 | FrontFace = vp.FrontFace; 113 | 114 | if ( MatNeedsFreeing ) { 115 | delete Mat; 116 | } 117 | 118 | MatNeedsFreeing = vp.MatNeedsFreeing; 119 | if (MatNeedsFreeing) { 120 | Mat = vp.Mat->Clone(); 121 | } else { 122 | Mat = vp.Mat; 123 | } 124 | 125 | return *this; 126 | } 127 | 128 | inline void VisiblePoint::SetMaterial( const MaterialBase& material ) 129 | { 130 | if ( MatNeedsFreeing ) { 131 | delete Mat; 132 | } 133 | Mat = const_cast(&material); 134 | MatNeedsFreeing = false; 135 | } 136 | 137 | // Mutable and deletable materials are the same thing (properties not separable) 138 | 139 | inline void VisiblePoint::MakeMaterialMutable( ) 140 | { 141 | if ( MatNeedsFreeing ) { 142 | return; // Material already mutable. 143 | } 144 | else { 145 | Mat = Mat->Clone(); 146 | MatNeedsFreeing = true; 147 | } 148 | } 149 | 150 | 151 | #endif // VISIBLEPOINT_H 152 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: all clean 2 | 3 | CC = g++ 4 | CPPFLAGS = -O3 -Wall -Wno-deprecated-declarations -std=c++11 5 | MACFLAG = -framework GLUT -framework OpenGL -framework Cocoa 6 | LINUXFLAG = -lGL -lGLU -lglut -lpthread 7 | 8 | UNAME_S := $(shell uname -s) 9 | ifeq ($(UNAME_S),Linux) 10 | FLAGS = $(CPPFLAGS) $(LINUXFLAG) 11 | else 12 | FLAGS = $(CPPFLAGS) $(MACFLAG) 13 | endif 14 | 15 | OBJ = \ 16 | DataStructs/DoubleRecurse.o \ 17 | DataStructs/KdTree.o \ 18 | Graphics/BumpMapFunction.o \ 19 | Graphics/CameraView.o \ 20 | Graphics/DirectLight.o \ 21 | Graphics/Extents.o \ 22 | Graphics/Material.o \ 23 | Graphics/MaterialCookTorrance.o \ 24 | Graphics/PixelArray.o \ 25 | Graphics/RgbImage.o \ 26 | Graphics/TextureAffineXform.o \ 27 | Graphics/TextureBilinearXform.o \ 28 | Graphics/TextureCheckered.o \ 29 | Graphics/TextureMapBase.o \ 30 | Graphics/TextureMultiFaces.o \ 31 | Graphics/TextureRgbImage.o \ 32 | Graphics/TextureSequence.o \ 33 | Graphics/TransformViewable.o \ 34 | Graphics/ViewableBase.o \ 35 | Graphics/ViewableBezierSet.o \ 36 | Graphics/ViewableCone.o \ 37 | Graphics/ViewableCylinder.o \ 38 | Graphics/ViewableEllipsoid.o \ 39 | Graphics/ViewableParallelepiped.o \ 40 | Graphics/ViewableParallelogram.o \ 41 | Graphics/ViewableSphere.o \ 42 | Graphics/ViewableTorus.o \ 43 | Graphics/ViewableTriangle.o \ 44 | OpenglRender/GlutRenderer.o \ 45 | RayTraceKd/RayTraceKd.o \ 46 | RayTraceKd/RayTraceSetup2.o \ 47 | RayTraceKd/RayTraceStats.o \ 48 | RaytraceMgr/LoadNffFile.o \ 49 | RaytraceMgr/LoadObjFile.o \ 50 | RaytraceMgr/SceneDescription.o \ 51 | VrMath/Aabb.o \ 52 | VrMath/LinearR2.o \ 53 | VrMath/LinearR3.o \ 54 | VrMath/LinearR4.o \ 55 | VrMath/Parallelepiped.o \ 56 | VrMath/PolygonClip.o \ 57 | VrMath/PolynomialRC.o \ 58 | VrMath/Quaternion.o \ 59 | 60 | raytracekd.out: $(OBJ) 61 | $(CC) $(OBJ) -o raytracekd.out $(FLAGS) 62 | 63 | clean: 64 | @rm $(OBJ) raytracekd.out 2>/dev/null || true 65 | 66 | -------------------------------------------------------------------------------- /OpenglRender/OpenglRender.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 11 | 12 | 13 | 19 | 30 | 32 | 35 | 37 | 39 | 41 | 43 | 45 | 47 | 49 | 51 | 53 | 54 | 60 | 68 | 70 | 73 | 75 | 77 | 79 | 81 | 83 | 85 | 87 | 89 | 91 | 92 | 93 | 94 | 95 | 96 | 100 | 102 | 103 | 104 | 108 | 110 | 111 | 112 | 116 | 117 | 119 | 120 | 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # VR_RayTracing 2 | VR course final project 3 | 4 | Please install freeglut package if using Linux systems. 5 | macOS has GLUT included into the system. -------------------------------------------------------------------------------- /RayTrace/RayTrace.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 11 | 12 | 13 | 19 | 30 | 32 | 40 | 42 | 44 | 46 | 48 | 50 | 52 | 54 | 56 | 58 | 60 | 61 | 67 | 75 | 77 | 86 | 88 | 90 | 92 | 94 | 96 | 98 | 100 | 102 | 104 | 106 | 107 | 108 | 109 | 110 | 111 | 115 | 117 | 118 | 120 | 121 | 122 | 126 | 128 | 129 | 130 | 134 | 135 | 136 | 137 | 138 | 139 | -------------------------------------------------------------------------------- /RayTrace/RayTraceData.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * RayTrace Software Package, release 3.0. May 3, 2006. 4 | * 5 | * Author: Samuel R. Buss 6 | * 7 | * Software accompanying the book 8 | * 3D Computer Graphics: A Mathematical Introduction with OpenGL, 9 | * by S. Buss, Cambridge University Press, 2003. 10 | * 11 | * Software is "as-is" and carries no warranty. It may be used without 12 | * restriction, but if you modify it, please change the filenames to 13 | * prevent confusion between different versions. Please acknowledge 14 | * all use of the software in any publications or products based on it. 15 | * 16 | * Bug reports: Sam Buss, sbuss@ucsd.edu. 17 | * Web page: http://math.ucsd.edu/~sbuss/MathCG 18 | * 19 | */ 20 | 21 | class VectorR3; 22 | class Light; 23 | class Material; 24 | class ViewableBase; 25 | class CameraView; 26 | 27 | // Camera and camera information 28 | 29 | extern CameraView* MainView; 30 | extern double Cpos[3]; // Position of camera 31 | extern double Cdir[3]; // Direction of camera 32 | extern double Cdist; // Distance to "screen" 33 | extern double Cdims[2]; // Width & height of "screen" 34 | 35 | // Here are the arrays that hold information about the scene 36 | 37 | extern int NumLights; // Number of lights 38 | extern Light* LightArray[]; // Array of light pointers 39 | 40 | extern int NumMaterials; // Number of materials 41 | extern Material* MatArray[]; // Array of material pointers. 42 | 43 | extern int NumObjects; // Number of objects 44 | extern ViewableBase* ViewObj[]; // Array of viewable object pointers 45 | 46 | extern double GlobalAmbientLight[3]; 47 | extern double* BackgroundColor; 48 | extern VectorR3 GlobalAmbientR3; 49 | extern VectorR3 BackgroundColorR3; 50 | 51 | // Routines that load the data into the above arrays: 52 | void SetUpMainView(); 53 | void SetUpMaterials(); 54 | void SetUpLights(); 55 | void SetUpViewableObjects(); 56 | -------------------------------------------------------------------------------- /RayTraceKd/RayTraceKd.ncb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topjohnwu/VR_RayTracing/4cfae839f55ef87e5117d5444b32a5c0b30af442/RayTraceKd/RayTraceKd.ncb -------------------------------------------------------------------------------- /RayTraceKd/RayTraceKd.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 8.00 2 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RayTraceKd", "RayTraceKd.vcproj", "{7EB20FD1-2FA2-411A-8D7D-FB37AD166368}" 3 | ProjectSection(ProjectDependencies) = postProject 4 | {0D0A9C43-9C08-4107-9D74-E00A2AB7A9F0} = {0D0A9C43-9C08-4107-9D74-E00A2AB7A9F0} 5 | {77E4FB4E-BD90-499A-81E0-60B2A1736AD5} = {77E4FB4E-BD90-499A-81E0-60B2A1736AD5} 6 | {F8CBABFB-8DC5-42BE-ABCE-55CBA529B5EF} = {F8CBABFB-8DC5-42BE-ABCE-55CBA529B5EF} 7 | EndProjectSection 8 | EndProject 9 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RayTrace", "..\RayTrace\RayTrace.vcproj", "{A8184171-45B8-46EA-83D0-438331143201}" 10 | ProjectSection(ProjectDependencies) = postProject 11 | {8071E214-584E-4FF4-AF82-61CE9FCD6701} = {8071E214-584E-4FF4-AF82-61CE9FCD6701} 12 | {77E4FB4E-BD90-499A-81E0-60B2A1736AD5} = {77E4FB4E-BD90-499A-81E0-60B2A1736AD5} 13 | {F8CBABFB-8DC5-42BE-ABCE-55CBA529B5EF} = {F8CBABFB-8DC5-42BE-ABCE-55CBA529B5EF} 14 | EndProjectSection 15 | EndProject 16 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RayTraceMgr", "..\RayTraceMgr\RayTraceMgr.vcproj", "{0D0A9C43-9C08-4107-9D74-E00A2AB7A9F0}" 17 | ProjectSection(ProjectDependencies) = postProject 18 | {8071E214-584E-4FF4-AF82-61CE9FCD6701} = {8071E214-584E-4FF4-AF82-61CE9FCD6701} 19 | {F8CBABFB-8DC5-42BE-ABCE-55CBA529B5EF} = {F8CBABFB-8DC5-42BE-ABCE-55CBA529B5EF} 20 | EndProjectSection 21 | EndProject 22 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VrMath", "..\VrMath\VrMath.vcproj", "{29BCE164-20FC-472D-BFE0-F0BDB9BFABD9}" 23 | ProjectSection(ProjectDependencies) = postProject 24 | EndProjectSection 25 | EndProject 26 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DataStructs", "..\DataStructs\DataStructs.vcproj", "{F8CBABFB-8DC5-42BE-ABCE-55CBA529B5EF}" 27 | ProjectSection(ProjectDependencies) = postProject 28 | EndProjectSection 29 | EndProject 30 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OpenglRender", "..\OpenglRender\OpenglRender.vcproj", "{77E4FB4E-BD90-499A-81E0-60B2A1736AD5}" 31 | ProjectSection(ProjectDependencies) = postProject 32 | {8071E214-584E-4FF4-AF82-61CE9FCD6701} = {8071E214-584E-4FF4-AF82-61CE9FCD6701} 33 | EndProjectSection 34 | EndProject 35 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Graphics", "..\Graphics\Graphics.vcproj", "{8071E214-584E-4FF4-AF82-61CE9FCD6701}" 36 | ProjectSection(ProjectDependencies) = postProject 37 | {29BCE164-20FC-472D-BFE0-F0BDB9BFABD9} = {29BCE164-20FC-472D-BFE0-F0BDB9BFABD9} 38 | EndProjectSection 39 | EndProject 40 | Global 41 | GlobalSection(SolutionConfiguration) = preSolution 42 | Debug = Debug 43 | Release = Release 44 | EndGlobalSection 45 | GlobalSection(ProjectConfiguration) = postSolution 46 | {7EB20FD1-2FA2-411A-8D7D-FB37AD166368}.Debug.ActiveCfg = Debug|Win32 47 | {7EB20FD1-2FA2-411A-8D7D-FB37AD166368}.Debug.Build.0 = Debug|Win32 48 | {7EB20FD1-2FA2-411A-8D7D-FB37AD166368}.Release.ActiveCfg = Release|Win32 49 | {7EB20FD1-2FA2-411A-8D7D-FB37AD166368}.Release.Build.0 = Release|Win32 50 | {A8184171-45B8-46EA-83D0-438331143201}.Debug.ActiveCfg = Debug|Win32 51 | {A8184171-45B8-46EA-83D0-438331143201}.Debug.Build.0 = Debug|Win32 52 | {A8184171-45B8-46EA-83D0-438331143201}.Release.ActiveCfg = Release|Win32 53 | {A8184171-45B8-46EA-83D0-438331143201}.Release.Build.0 = Release|Win32 54 | {0D0A9C43-9C08-4107-9D74-E00A2AB7A9F0}.Debug.ActiveCfg = Debug|Win32 55 | {0D0A9C43-9C08-4107-9D74-E00A2AB7A9F0}.Debug.Build.0 = Debug|Win32 56 | {0D0A9C43-9C08-4107-9D74-E00A2AB7A9F0}.Release.ActiveCfg = Release|Win32 57 | {0D0A9C43-9C08-4107-9D74-E00A2AB7A9F0}.Release.Build.0 = Release|Win32 58 | {29BCE164-20FC-472D-BFE0-F0BDB9BFABD9}.Debug.ActiveCfg = Debug|Win32 59 | {29BCE164-20FC-472D-BFE0-F0BDB9BFABD9}.Debug.Build.0 = Debug|Win32 60 | {29BCE164-20FC-472D-BFE0-F0BDB9BFABD9}.Release.ActiveCfg = Release|Win32 61 | {29BCE164-20FC-472D-BFE0-F0BDB9BFABD9}.Release.Build.0 = Release|Win32 62 | {F8CBABFB-8DC5-42BE-ABCE-55CBA529B5EF}.Debug.ActiveCfg = Debug|Win32 63 | {F8CBABFB-8DC5-42BE-ABCE-55CBA529B5EF}.Debug.Build.0 = Debug|Win32 64 | {F8CBABFB-8DC5-42BE-ABCE-55CBA529B5EF}.Release.ActiveCfg = Release|Win32 65 | {F8CBABFB-8DC5-42BE-ABCE-55CBA529B5EF}.Release.Build.0 = Release|Win32 66 | {77E4FB4E-BD90-499A-81E0-60B2A1736AD5}.Debug.ActiveCfg = Debug|Win32 67 | {77E4FB4E-BD90-499A-81E0-60B2A1736AD5}.Debug.Build.0 = Debug|Win32 68 | {77E4FB4E-BD90-499A-81E0-60B2A1736AD5}.Release.ActiveCfg = Release|Win32 69 | {77E4FB4E-BD90-499A-81E0-60B2A1736AD5}.Release.Build.0 = Release|Win32 70 | {8071E214-584E-4FF4-AF82-61CE9FCD6701}.Debug.ActiveCfg = Debug|Win32 71 | {8071E214-584E-4FF4-AF82-61CE9FCD6701}.Debug.Build.0 = Debug|Win32 72 | {8071E214-584E-4FF4-AF82-61CE9FCD6701}.Release.ActiveCfg = Release|Win32 73 | {8071E214-584E-4FF4-AF82-61CE9FCD6701}.Release.Build.0 = Release|Win32 74 | EndGlobalSection 75 | GlobalSection(ExtensibilityGlobals) = postSolution 76 | EndGlobalSection 77 | GlobalSection(ExtensibilityAddIns) = postSolution 78 | EndGlobalSection 79 | EndGlobal 80 | -------------------------------------------------------------------------------- /RayTraceKd/RayTraceKd.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topjohnwu/VR_RayTracing/4cfae839f55ef87e5117d5444b32a5c0b30af442/RayTraceKd/RayTraceKd.suo -------------------------------------------------------------------------------- /RayTraceKd/RayTraceKd.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 11 | 12 | 13 | 19 | 30 | 32 | 40 | 42 | 44 | 46 | 48 | 50 | 52 | 54 | 56 | 58 | 60 | 61 | 67 | 75 | 77 | 86 | 88 | 90 | 92 | 94 | 96 | 98 | 100 | 102 | 104 | 106 | 107 | 108 | 109 | 110 | 111 | 115 | 117 | 118 | 120 | 121 | 123 | 124 | 125 | 129 | 131 | 132 | 134 | 135 | 136 | 140 | 141 | 142 | 143 | 144 | 145 | -------------------------------------------------------------------------------- /RayTraceKd/RayTraceSetup2.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * RayTrace Software Package, release 3.0. May 3, 2006. 4 | * 5 | * Author: Samuel R. Buss 6 | * 7 | * Software accompanying the book 8 | * 3D Computer Graphics: A Mathematical Introduction with OpenGL, 9 | * by S. Buss, Cambridge University Press, 2003. 10 | * 11 | * Software is "as-is" and carries no warranty. It may be used without 12 | * restriction, but if you modify it, please change the filenames to 13 | * prevent confusion between different versions. Please acknowledge 14 | * all use of the software in any publications or products based on it. 15 | * 16 | * Bug reports: Sam Buss, sbuss@ucsd.edu. 17 | * Web page: http://math.ucsd.edu/~sbuss/MathCG 18 | * 19 | */ 20 | 21 | class VectorR3; 22 | class Light; 23 | class Material; 24 | class ViewableBase; 25 | class CameraView; 26 | class SceneDescription; 27 | 28 | // Camera and camera information 29 | 30 | extern double Cpos[3]; // Position of camera 31 | extern double Cdir[3]; // Direction of camera 32 | extern double Cdist; // Distance to "screen" 33 | extern double Cdims[2]; // Width & height of "screen" 34 | 35 | // Here are the arrays that hold information about the scene 36 | 37 | extern SceneDescription TheScene2; 38 | 39 | // Routines that load the data into the scene description: 40 | void SetUpScene2(); 41 | void SetUpMainView(); 42 | void SetUpMaterials(); 43 | void SetUpLights( SceneDescription& scene ); 44 | void SetUpViewableObjects(); 45 | -------------------------------------------------------------------------------- /RayTraceKd/RayTraceStats.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * RayTrace Software Package, release 3.0. May 3, 2006 4 | * 5 | * Author: Samuel R. Buss 6 | * 7 | * Software accompanying the book 8 | * 3D Computer Graphics: A Mathematical Introduction with OpenGL, 9 | * by S. Buss, Cambridge University Press, 2003. 10 | * 11 | * Software is "as-is" and carries no warranty. It may be used without 12 | * restriction, but if you modify it, please change the filenames to 13 | * prevent confusion between different versions. Please acknowledge 14 | * all use of the software in any publications or products based on it. 15 | * 16 | * Bug reports: Sam Buss, sbuss@ucsd.edu. 17 | * Web page: http://math.ucsd.edu/~sbuss/MathCG 18 | * 19 | */ 20 | 21 | // RayTraceStats.cpp 22 | // Ray Trace Statistics 23 | 24 | #include "RayTraceStats.h" 25 | #include "../DataStructs/Stack.h" 26 | #include "../DataStructs/KdTree.h" 27 | 28 | void RayTraceStats::Init() 29 | { 30 | NumberRaysTraced = 0; 31 | NumberReflectionRays = 0; 32 | NumberXmitRays = 0; 33 | NumberShadowFeelers = 0; 34 | NumberIsectTests = 0; 35 | NumberSuccessIsectTests = 0; 36 | 37 | NumberKdNodesTraversed = 0; 38 | NumberKdLeavesTraversed = 0; 39 | NumberKdObjectsInLeaves = 0; 40 | 41 | } 42 | 43 | void RayTraceStats::GetKdRunData( const KdTree& kdTree ) 44 | { 45 | kdTree.Stats_GetAll( &NumberKdNodesTraversed, &NumberKdLeavesTraversed, &NumberKdObjectsInLeaves ); 46 | } 47 | 48 | void RayTraceStats::PrintStats( FILE* out ) 49 | { 50 | #if TrackRaysTraced 51 | fprintf( out, "Run time statistics:\n"); 52 | fprintf( out, " Number of rays traced = %ld.\n", NumberRaysTraced ); 53 | #endif 54 | #if TrackShadowFeelers 55 | fprintf( out, " Number of shadow feelers = %ld.\n", NumberShadowFeelers ); 56 | #endif 57 | #if TrackKdTraversal 58 | fprintf( out, " KdTree: Nodes traversed, %ld. Non-empty leaves traversed, %ld.\n", 59 | NumberKdNodesTraversed, NumberKdLeavesTraversed ); 60 | fprintf( out, " Objects tested, %ld. Mean number per leaf, %0.6lf.\n", 61 | NumberKdObjectsInLeaves, 62 | (double)NumberKdObjectsInLeaves/(double)NumberKdLeavesTraversed ); 63 | double numRays = NumberRaysTraced; 64 | fprintf( out, " Kd per ray: Nodes, %0.6lf. Leaves, %0.6lf. Objects, %lf.\n", 65 | (double)NumberKdNodesTraversed/numRays, 66 | (double)NumberKdLeavesTraversed/numRays, 67 | (double)NumberKdObjectsInLeaves/numRays ); 68 | #endif 69 | } 70 | 71 | void RayTraceStats::PrintKdStats( const KdTree& kdTree, FILE* out ) 72 | { 73 | #if TrackKdProperties 74 | long numNodes = 0; 75 | long maxDepth = 0; 76 | long numLeaves = 0; 77 | long numAtDepth[128]; 78 | long sumLeafDepths = 0; 79 | long sumNodeDepths = 0; 80 | long numEmptyLeaves = 0; 81 | long numObjectsAtLeaves = 0; 82 | 83 | // Traverse the tree, gathering data 84 | Stack treeNodeStack; 85 | Stack levelStack; 86 | treeNodeStack.Push(0); 87 | levelStack.Push(0); 88 | while ( !treeNodeStack.IsEmpty() ) { 89 | numNodes++; 90 | long i = treeNodeStack.Pop(); 91 | long level = levelStack.Pop(); 92 | if ( level>maxDepth ) { 93 | maxDepth = level; 94 | } 95 | sumNodeDepths += level; 96 | numAtDepth[Min((long)127,level)]++; 97 | const KdTreeNode& thisNode = kdTree.GetNode(i); 98 | if ( thisNode.IsLeaf() ) { 99 | numLeaves++; 100 | sumLeafDepths += level; 101 | numObjectsAtLeaves += thisNode.GetNumObjects(); 102 | } 103 | else { 104 | if ( !thisNode.RightChildEmpty() ) { 105 | treeNodeStack.Push( thisNode.RightChildIndex() ); 106 | levelStack.Push( level+1 ); 107 | } 108 | else { 109 | numEmptyLeaves++; 110 | } 111 | if ( !thisNode.LeftChildEmpty() ) { 112 | treeNodeStack.Push( thisNode.LeftChildIndex() ); 113 | levelStack.Push ( level+1 ); 114 | } 115 | else { 116 | numEmptyLeaves++; 117 | } 118 | } 119 | } 120 | 121 | fprintf( out, "KdTree statistics:\n"); 122 | fprintf( out, " Number of objects: %ld.\n", kdTree.NumObjects ); 123 | fprintf( out, " Number of nodes: %ld.\n", numNodes); 124 | fprintf( out, " Number of leaves: %ld.\n", numLeaves); 125 | fprintf( out, " Number of empty leaves: %ld.\n", numEmptyLeaves ); 126 | fprintf( out, " Objects at leaves: Total number is %ld. Average per leaf: %.5lf.\n", 127 | numObjectsAtLeaves, (double)(numObjectsAtLeaves)/(double)(numLeaves) ); 128 | fprintf( out, " Depth: %ld.\n", maxDepth); 129 | fprintf( out, " Mean depths: All nodes, %.5lf. Leaf nodes, %.5lf.\n", 130 | (double)sumNodeDepths/(double)(numNodes), (double)sumLeafDepths/(double)(numLeaves) ); 131 | #endif 132 | 133 | } 134 | -------------------------------------------------------------------------------- /RayTraceKd/RayTraceStats.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * RayTrace Software Package, release 3.0. May 3, 2006 4 | * 5 | * Author: Samuel R. Buss 6 | * 7 | * Software accompanying the book 8 | * 3D Computer Graphics: A Mathematical Introduction with OpenGL, 9 | * by S. Buss, Cambridge University Press, 2003. 10 | * 11 | * Software is "as-is" and carries no warranty. It may be used without 12 | * restriction, but if you modify it, please change the filenames to 13 | * prevent confusion between different versions. Please acknowledge 14 | * all use of the software in any publications or products based on it. 15 | * 16 | * Bug reports: Sam Buss, sbuss@ucsd.edu. 17 | * Web page: http://math.ucsd.edu/~sbuss/MathCG 18 | * 19 | */ 20 | 21 | 22 | // RayTraceStats.h 23 | // A class for maintaining statistics about ray tracing 24 | 25 | 26 | #include 27 | class KdTree; 28 | 29 | #define TrackRaysTraced 1 30 | #define TrackReflectionRays 1 31 | #define TrackXmitRays 1 32 | #define TrackShadowFeelers 1 33 | #define TrackIsectTests 1 34 | #define TrackSuccessIsectTests 1 35 | #define TrackKdProperties 1 36 | #define TrackKdTraversal 1 37 | 38 | class RayTraceStats 39 | { 40 | public: 41 | RayTraceStats() { Init(); } 42 | ~RayTraceStats() {} 43 | 44 | void Init(); 45 | 46 | void PrintStats( FILE* out = stdout ); 47 | 48 | void AddRayTraced(); 49 | void AddReflectionRay(); 50 | void AddXmitRay(); 51 | void AddShadowFeeler(); 52 | void AddIsectTest(); 53 | void AddSuccessIsectTest(); 54 | 55 | void AddKdNodeTraversed(); 56 | void AddKdLeavesTraversed(); 57 | void AddKdObjectsInLeavesTraversed( int numObjects = 1 ); 58 | 59 | public: 60 | void GetKdRunData( const KdTree& kdTree ); 61 | static void PrintKdStats( const KdTree& kdTree, FILE* out = stdout ); 62 | 63 | private: 64 | long NumberRaysTraced; 65 | long NumberReflectionRays; 66 | long NumberXmitRays; 67 | long NumberShadowFeelers; 68 | long NumberIsectTests; 69 | long NumberSuccessIsectTests; 70 | 71 | // KdTree operations 72 | long NumberKdNodesTraversed; 73 | long NumberKdLeavesTraversed; 74 | long NumberKdObjectsInLeaves; 75 | 76 | }; 77 | 78 | inline void RayTraceStats::AddRayTraced() 79 | { 80 | #if TrackRaysTraced 81 | NumberRaysTraced++; 82 | #endif 83 | } 84 | 85 | inline void RayTraceStats::AddReflectionRay() 86 | { 87 | #if TrackReflectionRays 88 | NumberReflectionRays++; 89 | #endif 90 | } 91 | 92 | inline void RayTraceStats::AddXmitRay() 93 | { 94 | #if TrackXmitRays 95 | NumberXmitRays++; 96 | #endif 97 | } 98 | 99 | inline void RayTraceStats::AddShadowFeeler() 100 | { 101 | #if TrackShadowFeelers 102 | NumberShadowFeelers++; 103 | #endif 104 | } 105 | 106 | inline void RayTraceStats::AddIsectTest() 107 | { 108 | #if TrackIsectTests 109 | NumberIsectTests++; 110 | #endif 111 | } 112 | 113 | inline void RayTraceStats::AddSuccessIsectTest() 114 | { 115 | #if TrackSuccessIsectTests 116 | NumberSuccessIsectTests++; 117 | #endif 118 | } 119 | 120 | inline void RayTraceStats::AddKdNodeTraversed() 121 | { 122 | #if TrackKdTraversals 123 | NumberKdNodesTraversed++; 124 | #endif 125 | } 126 | 127 | inline void RayTraceStats::AddKdLeavesTraversed() 128 | { 129 | #if TrackKdTraversals 130 | NumberKdNodesTraversed++; 131 | #endif 132 | } 133 | 134 | inline void RayTraceStats::AddKdObjectsInLeavesTraversed( int numObjects ) 135 | { 136 | #if TrackKdTraversals 137 | NumberKdNodesTraversed += numObjects; 138 | #endif 139 | } 140 | -------------------------------------------------------------------------------- /RayTraceKd/balls_2_1.nff: -------------------------------------------------------------------------------- 1 | b 0.078 0.361 0.753 2 | v 3 | from 2.1 1.3 1.7 4 | at 0 0 0 5 | up 0 0 1 6 | angle 45 7 | hither 0.01 8 | resolution 512 512 9 | l 4 3 2 0.25 0.25 0.25 10 | l 1 -4 4 0.25 0.25 0.25 11 | l -3 1 5 0.25 0.25 0.25 12 | f 1 0.75 0.33 0.8 0 100000 0 1 13 | p 4 14 | 12 12 -0.5 15 | -12 12 -0.5 16 | -12 -12 -0.5 17 | 12 -12 -0.5 18 | f 1 0.9 0.7 0.5 0.5 3.0827 0 1 19 | s 0 0 0 0.5 20 | s 0.272166 0.272166 0.544331 0.166667 21 | s 0.420314 0.420314 0.618405 0.0555556 22 | s 0.461844 0.304709 0.43322 0.0555556 23 | s 0.304709 0.461844 0.43322 0.0555556 24 | s 0.230635 0.38777 0.729516 0.0555556 25 | s 0.115031 0.4293 0.544331 0.0555556 26 | s 0.082487 0.239622 0.655442 0.0555556 27 | s 0.38777 0.230635 0.729516 0.0555556 28 | s 0.239622 0.082487 0.655442 0.0555556 29 | s 0.4293 0.115031 0.544331 0.0555556 30 | s 0.643951 0.172546 1.11022e-016 0.166667 31 | s 0.802608 0.281471 -0.111111 0.0555556 32 | s 0.643951 0.172546 -0.222222 0.0555556 33 | s 0.594141 0.358439 -0.111111 0.0555556 34 | s 0.802608 0.281471 0.111111 0.0555556 35 | s 0.594141 0.358439 0.111111 0.0555556 36 | s 0.643951 0.172546 0.222222 0.0555556 37 | s 0.852418 0.0955788 1.89979e-016 0.0555556 38 | s 0.69376 -0.0133465 0.111111 0.0555556 39 | s 0.69376 -0.0133465 -0.111111 0.0555556 40 | s 0.172546 0.643951 1.11022e-016 0.166667 41 | s 0.281471 0.802608 -0.111111 0.0555556 42 | s 0.358439 0.594141 -0.111111 0.0555556 43 | s 0.172546 0.643951 -0.222222 0.0555556 44 | s 0.0955788 0.852418 1.03628e-016 0.0555556 45 | s -0.0133465 0.69376 -0.111111 0.0555556 46 | s -0.0133465 0.69376 0.111111 0.0555556 47 | s 0.281471 0.802608 0.111111 0.0555556 48 | s 0.172546 0.643951 0.222222 0.0555556 49 | s 0.358439 0.594141 0.111111 0.0555556 50 | s -0.371785 0.0996195 0.544331 0.166667 51 | s -0.393621 0.220501 0.729516 0.0555556 52 | s -0.191247 0.166275 0.655442 0.0555556 53 | s -0.31427 0.31427 0.544331 0.0555556 54 | s -0.574159 0.153845 0.618405 0.0555556 55 | s -0.494808 0.247614 0.43322 0.0555556 56 | s -0.552323 0.0329639 0.43322 0.0555556 57 | s -0.451136 0.0058509 0.729516 0.0555556 58 | s -0.4293 -0.115031 0.544331 0.0555556 59 | s -0.248762 -0.0483751 0.655442 0.0555556 60 | s -0.471405 0.471405 1.11022e-016 0.166667 61 | s -0.508983 0.690426 8.51247e-017 0.0555556 62 | s -0.335322 0.607487 0.111111 0.0555556 63 | s -0.335322 0.607487 -0.111111 0.0555556 64 | s -0.645066 0.554344 -0.111111 0.0555556 65 | s -0.471405 0.471405 -0.222222 0.0555556 66 | s -0.607487 0.335322 -0.111111 0.0555556 67 | s -0.645066 0.554344 0.111111 0.0555556 68 | s -0.607487 0.335322 0.111111 0.0555556 69 | s -0.471405 0.471405 0.222222 0.0555556 70 | s -0.643951 -0.172546 1.11022e-016 0.166667 71 | s -0.835815 -0.157543 0.111111 0.0555556 72 | s -0.643951 -0.172546 0.222222 0.0555556 73 | s -0.69376 0.0133465 0.111111 0.0555556 74 | s -0.835815 -0.157543 -0.111111 0.0555556 75 | s -0.69376 0.0133465 -0.111111 0.0555556 76 | s -0.643951 -0.172546 -0.222222 0.0555556 77 | s -0.786005 -0.343435 7.89568e-017 0.0555556 78 | s -0.594141 -0.358439 -0.111111 0.0555556 79 | s -0.594141 -0.358439 0.111111 0.0555556 80 | s 0.0996195 -0.371785 0.544331 0.166667 81 | s 0.220501 -0.393621 0.729516 0.0555556 82 | s 0.31427 -0.31427 0.544331 0.0555556 83 | s 0.166275 -0.191247 0.655442 0.0555556 84 | s 0.0058509 -0.451136 0.729516 0.0555556 85 | s -0.0483751 -0.248762 0.655442 0.0555556 86 | s -0.115031 -0.4293 0.544331 0.0555556 87 | s 0.153845 -0.574159 0.618405 0.0555556 88 | s 0.0329639 -0.552323 0.43322 0.0555556 89 | s 0.247614 -0.494808 0.43322 0.0555556 90 | s -0.172546 -0.643951 1.11022e-016 0.166667 91 | s -0.157543 -0.835815 0.111111 0.0555556 92 | s 0.0133465 -0.69376 0.111111 0.0555556 93 | s -0.172546 -0.643951 0.222222 0.0555556 94 | s -0.343435 -0.786005 7.27889e-017 0.0555556 95 | s -0.358439 -0.594141 0.111111 0.0555556 96 | s -0.358439 -0.594141 -0.111111 0.0555556 97 | s -0.157543 -0.835815 -0.111111 0.0555556 98 | s -0.172546 -0.643951 -0.222222 0.0555556 99 | s 0.0133465 -0.69376 -0.111111 0.0555556 100 | s 0.471405 -0.471405 1.11022e-016 0.166667 101 | s 0.690426 -0.508983 1.83811e-016 0.0555556 102 | s 0.607487 -0.335322 -0.111111 0.0555556 103 | s 0.607487 -0.335322 0.111111 0.0555556 104 | s 0.554344 -0.645066 0.111111 0.0555556 105 | s 0.471405 -0.471405 0.222222 0.0555556 106 | s 0.335322 -0.607487 0.111111 0.0555556 107 | s 0.554344 -0.645066 -0.111111 0.0555556 108 | s 0.335322 -0.607487 -0.111111 0.0555556 109 | s 0.471405 -0.471405 -0.222222 0.0555556 110 | -------------------------------------------------------------------------------- /RayTraceKd/jacks_2_1.nff: -------------------------------------------------------------------------------- 1 | b 0.2 0.05 0.2 2 | v 3 | from 0 0 -8 4 | at 0 0 0 5 | up 0 1 0 6 | angle 25 7 | hither 0.001 8 | resolution 256 256 9 | l -10 3 -20 10 | f 0.737 0.561 0.561 0.7 0.7 11.1434 0 1 11 | c -0.704769 -0.128258 -0.222149 0.075 0.704769 0.128258 0.222149 0.075 12 | c 0 -0.649519 0.375 0.075 0 0.649519 -0.375 0.075 13 | c 0.256515 -0.352385 -0.610348 0.075 -0.256515 0.352385 0.610348 0.075 14 | s 0.704769 0.128258 0.222149 0.15 15 | s 0 0.649519 -0.375 0.15 16 | s -0.256515 0.352385 0.610348 0.15 17 | s -0.704769 -0.128258 -0.222149 0.15 18 | s 0 -0.649519 0.375 0.15 19 | s 0.256515 -0.352385 -0.610348 0.15 20 | c -0.651221 -0.81757 -0.416072 0.0375 0.0535485 -0.689312 -0.193924 0.0375 21 | c -0.298836 -1.0782 -0.117498 0.0375 -0.298836 -0.428681 -0.492498 0.0375 22 | c -0.170579 -0.929633 -0.610172 0.0375 -0.427094 -0.577249 0.000176223 0.0375 23 | s 0.0535485 -0.689312 -0.193924 0.075 24 | s -0.298836 -0.428681 -0.492498 0.075 25 | s -0.427094 -0.577249 0.000176223 0.075 26 | s -0.651221 -0.81757 -0.416072 0.075 27 | s -0.298836 -1.0782 -0.117498 0.075 28 | s -0.170579 -0.929633 -0.610172 0.075 29 | c -0.993241 -0.347723 0.397725 0.0375 -0.288472 -0.219466 0.619874 0.0375 30 | c -0.640856 -0.608354 0.6963 0.0375 -0.640856 0.0411649 0.3213 0.0375 31 | c -0.512599 -0.459787 0.203626 0.0375 -0.769114 -0.107402 0.813974 0.0375 32 | s -0.288472 -0.219466 0.619874 0.075 33 | s -0.640856 0.0411649 0.3213 0.075 34 | s -0.769114 -0.107402 0.813974 0.075 35 | s -0.993241 -0.347723 0.397725 0.075 36 | s -0.640856 -0.608354 0.6963 0.075 37 | s -0.512599 -0.459787 0.203626 0.075 38 | c -0.651221 0.0484557 -0.916072 0.0375 0.0535485 0.176713 -0.693924 0.0375 39 | c -0.298836 -0.212175 -0.617498 0.0375 -0.298836 0.437344 -0.992498 0.0375 40 | c -0.170579 -0.0636079 -1.11017 0.0375 -0.427094 0.288777 -0.499824 0.0375 41 | s 0.0535485 0.176713 -0.693924 0.075 42 | s -0.298836 0.437344 -0.992498 0.075 43 | s -0.427094 0.288777 -0.499824 0.075 44 | s -0.651221 0.0484557 -0.916072 0.075 45 | s -0.298836 -0.212175 -0.617498 0.075 46 | s -0.170579 -0.0636079 -1.11017 0.075 47 | c -0.993241 0.518302 -0.102275 0.0375 -0.288472 0.64656 0.119874 0.0375 48 | c -0.640856 0.257671 0.1963 0.0375 -0.640856 0.90719 -0.1787 0.0375 49 | c -0.512599 0.406238 -0.296374 0.0375 -0.769114 0.758623 0.313974 0.0375 50 | s -0.288472 0.64656 0.119874 0.075 51 | s -0.640856 0.90719 -0.1787 0.075 52 | s -0.769114 0.758623 0.313974 0.075 53 | s -0.993241 0.518302 -0.102275 0.075 54 | s -0.640856 0.257671 0.1963 0.075 55 | s -0.512599 0.406238 -0.296374 0.075 56 | c 0.288472 -0.64656 -0.119874 0.0375 0.993241 -0.518302 0.102275 0.0375 57 | c 0.640856 -0.90719 0.1787 0.0375 0.640856 -0.257671 -0.1963 0.0375 58 | c 0.769114 -0.758623 -0.313974 0.0375 0.512599 -0.406238 0.296374 0.0375 59 | s 0.993241 -0.518302 0.102275 0.075 60 | s 0.640856 -0.257671 -0.1963 0.075 61 | s 0.512599 -0.406238 0.296374 0.075 62 | s 0.288472 -0.64656 -0.119874 0.075 63 | s 0.640856 -0.90719 0.1787 0.075 64 | s 0.769114 -0.758623 -0.313974 0.075 65 | c -0.0535485 -0.176713 0.693924 0.0375 0.651221 -0.0484557 0.916072 0.0375 66 | c 0.298836 -0.437344 0.992498 0.0375 0.298836 0.212175 0.617498 0.0375 67 | c 0.427094 -0.288777 0.499824 0.0375 0.170579 0.0636079 1.11017 0.0375 68 | s 0.651221 -0.0484557 0.916072 0.075 69 | s 0.298836 0.212175 0.617498 0.075 70 | s 0.170579 0.0636079 1.11017 0.075 71 | s -0.0535485 -0.176713 0.693924 0.075 72 | s 0.298836 -0.437344 0.992498 0.075 73 | s 0.427094 -0.288777 0.499824 0.075 74 | c 0.288472 0.219466 -0.619874 0.0375 0.993241 0.347723 -0.397725 0.0375 75 | c 0.640856 -0.0411649 -0.3213 0.0375 0.640856 0.608354 -0.6963 0.0375 76 | c 0.769114 0.107402 -0.813974 0.0375 0.512599 0.459787 -0.203626 0.0375 77 | s 0.993241 0.347723 -0.397725 0.075 78 | s 0.640856 0.608354 -0.6963 0.075 79 | s 0.512599 0.459787 -0.203626 0.075 80 | s 0.288472 0.219466 -0.619874 0.075 81 | s 0.640856 -0.0411649 -0.3213 0.075 82 | s 0.769114 0.107402 -0.813974 0.075 83 | c -0.0535485 0.689312 0.193924 0.0375 0.651221 0.81757 0.416072 0.0375 84 | c 0.298836 0.428681 0.492498 0.0375 0.298836 1.0782 0.117498 0.0375 85 | c 0.427094 0.577249 -0.000176223 0.0375 0.170579 0.929633 0.610172 0.0375 86 | s 0.651221 0.81757 0.416072 0.075 87 | s 0.298836 1.0782 0.117498 0.075 88 | s 0.170579 0.929633 0.610172 0.075 89 | s -0.0535485 0.689312 0.193924 0.075 90 | s 0.298836 0.428681 0.492498 0.075 91 | s 0.427094 0.577249 -0.000176223 0.075 92 | -------------------------------------------------------------------------------- /RaytraceMgr/LoadNffFile.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * RayTrace Software Package, release 3.0. May 3, 2006 4 | * 5 | * Author: Samuel R. Buss 6 | * 7 | * Software accompanying the book 8 | * 3D Computer Graphics: A Mathematical Introduction with OpenGL, 9 | * by S. Buss, Cambridge University Press, 2003. 10 | * 11 | * Software is "as-is" and carries no warranty. It may be used without 12 | * restriction, but if you modify it, please change the filenames to 13 | * prevent confusion between different versions. Please acknowledge 14 | * all use of the software in any publications or products based on it. 15 | * 16 | * Bug reports: Sam Buss, sbuss@ucsd.edu. 17 | * Web page: http://math.ucsd.edu/~sbuss/MathCG 18 | * 19 | */ 20 | 21 | #ifndef LOAD_NFF_FILE_H 22 | #define LOAD_NFF_FILE_H 23 | 24 | #include "../DataStructs/Array.h" 25 | #include "SceneDescription.h" 26 | #include "../VrMath/LinearR2.h" 27 | #include "../VrMath/LinearR3.h" 28 | #include "../VrMath/LinearR4.h" 29 | 30 | class SceneDescription; 31 | class ObjFileLoader; 32 | class CameraView; 33 | 34 | // This is the preferred method for loading from nff (neutral file format) files. 35 | // Filename should usually end with ".nff". 36 | // Any items in the SceneDescription already are unaltered. 37 | // Returns true if parsing succeeded. 38 | bool LoadNffFile( const char* filename, SceneDescription& theScene ); 39 | 40 | 41 | // NffFileLoader are intended for future internal use. 42 | 43 | class NffFileLoader { 44 | 45 | public: 46 | NffFileLoader(); 47 | 48 | // The "Load()" routines reads from the file and includes whatever it 49 | // knows how to process into the scene. (If the scene already includes 50 | // items, they are left unchanged.) 51 | bool Load( const char* filename, SceneDescription& theScene ); 52 | 53 | // By default, the screen resolution is ignored. 54 | // Change IgnoreResolution to false to have the screen resolution 55 | // loaded into the Scene Description 56 | bool IgnoreResolution; 57 | 58 | private: 59 | bool ReportUnsupportedFeatures; 60 | bool UnsupFlagTooManyVerts; 61 | bool UnsupFlagTruncatedCone; 62 | bool UnsupFlagNormals; 63 | bool UnsupFlagConeCylinderWarning; 64 | long FileLineNumber; 65 | 66 | private: 67 | SceneDescription* ScenePtr; 68 | void Reset(); 69 | 70 | static char* PreparseNff( char* inbuf ); 71 | static int GetCommandNumber( char *cmd ); 72 | 73 | void SetCameraViewInfo( CameraView& theView, 74 | const VectorR3& viewPos, const VectorR3& lookAtPos, 75 | const VectorR3& upVector, double fovy, 76 | int screenWidth, int screenHeight, double nearClipping); 77 | 78 | bool ProcessFaceNFF( int numVerts, const Material* mat, FILE* infile ); 79 | void ProcessConeCylNFF( const VectorR3& baseCenter, double baseRadius, 80 | const VectorR3& topCenter, double topRadius ); 81 | static bool ReadVertexR3( VectorR3& vertReturned, FILE* infile ); 82 | 83 | //static char* ScanForNonwhite( char* inbuf ); 84 | //static char* ScanForWhite( char* inbuf ); 85 | //static char* ScanForWhiteOrSlash( char* inbuf ); 86 | //static char* ScanForSecondField( char* inbuf ); 87 | //static bool ReadVectorR4Hg( char* inbuf, VectorR4* theVec ); 88 | //bool ReadTexCoords( char* inbuf, VectorR2* theVec ); 89 | //static int NextTriVertIdx( int start, int* step, int totalNum ); 90 | 91 | void UnsupportedTooManyVerts( int maxVerts ); 92 | void UnsupportedNormals(); 93 | void UnsupConeCylinderWarning(); 94 | void UnsupportedTruncatedCone(); 95 | void AddUnsupportedCmd( char *cmd ); 96 | void PrintCmdNotSupportedErrors( FILE* outstream ); 97 | 98 | Array UnsupportedCmds; 99 | 100 | }; 101 | 102 | inline NffFileLoader::NffFileLoader() 103 | { 104 | IgnoreResolution = true; // By default, ignore the view resolution specification 105 | 106 | ReportUnsupportedFeatures = true; 107 | UnsupFlagTooManyVerts = false; 108 | UnsupFlagNormals = false; 109 | UnsupFlagTruncatedCone = false; 110 | UnsupFlagConeCylinderWarning = false; 111 | UnsupFlagTruncatedCone = false; 112 | } 113 | 114 | 115 | #endif // LOAD_NFF_FILE_H -------------------------------------------------------------------------------- /RaytraceMgr/LoadObjFile.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * RayTrace Software Package, release 3.0. May 3, 2006 4 | * 5 | * Author: Samuel R. Buss 6 | * 7 | * Software accompanying the book 8 | * 3D Computer Graphics: A Mathematical Introduction with OpenGL, 9 | * by S. Buss, Cambridge University Press, 2003. 10 | * 11 | * Software is "as-is" and carries no warranty. It may be used without 12 | * restriction, but if you modify it, please change the filenames to 13 | * prevent confusion between different versions. Please acknowledge 14 | * all use of the software in any publications or products based on it. 15 | * 16 | * Bug reports: Sam Buss, sbuss@ucsd.edu. 17 | * Web page: http://math.ucsd.edu/~sbuss/MathCG 18 | * 19 | */ 20 | 21 | #ifndef LOAD_OBJ_FILE_H 22 | #define LOAD_OBJ_FILE_H 23 | 24 | #include "../DataStructs/Array.h" 25 | #include "SceneDescription.h" 26 | #include "../VrMath/LinearR2.h" 27 | #include "../VrMath/LinearR3.h" 28 | #include "../VrMath/LinearR4.h" 29 | 30 | class SceneDescription; 31 | class ObjFileLoader; 32 | 33 | // This is the preferred method for loading from obj files. 34 | // Filename should end with ".obj". 35 | // Returns true if parsing succeeded. 36 | bool LoadObjFile( const char* filename, SceneDescription& theScene ); 37 | 38 | 39 | // ObjFileLoader are intended for future internal use. 40 | 41 | class ObjFileLoader { 42 | 43 | friend class NffFileLoader; 44 | 45 | public: 46 | ObjFileLoader(); 47 | 48 | // The "Load()" routines reads from the file and includes whatever it 49 | // knows how to process into the scene. (If the scene already includes 50 | // items, they are left unchanged.) 51 | bool Load( const char* filename, SceneDescription& theScene ); 52 | 53 | private: 54 | bool ReportUnsupportedFeatures; 55 | bool UnsupFlagTextureDepth; 56 | bool UnsupFlagTooManyVerts; 57 | bool UnsupFlagLines; 58 | long FileLineNumber; 59 | 60 | private: 61 | SceneDescription* ScenePtr; 62 | void Reset(); 63 | 64 | static char* Preparse( char* inbuf ); 65 | static char* ScanForNonwhite( char* inbuf ); 66 | static char* ScanForWhite( char* inbuf ); 67 | static char* ScanForWhiteOrSlash( char* inbuf ); 68 | static char* ScanForSecondField( char* inbuf ); 69 | static int GetCommandNumber( char *cmd ); 70 | static bool ReadVectorR4Hg( char* inbuf, VectorR4* theVec ); 71 | bool ReadTexCoords( char* inbuf, VectorR2* theVec ); 72 | bool ProcessFace( char *inbuf ); 73 | static int NextTriVertIdx( int start, int* step, int totalNum ); 74 | 75 | void UnsupportedTextureDepth(); 76 | void UnsupportedLines(); 77 | void UnsupportedTooManyVerts( int maxVerts ); 78 | void AddUnsupportedCmd( char *cmd ); 79 | void PrintCmdNotSupportedErrors( FILE* outstream ); 80 | 81 | Array Vertices; // Vertices in homogenous format 82 | Array TextureCoords; // Texture coordinates not supported yet 83 | Array VertexNormals; // Vertex normals not supported yet 84 | 85 | Array UnsupportedCmds; 86 | 87 | }; 88 | 89 | inline ObjFileLoader::ObjFileLoader() 90 | { 91 | ReportUnsupportedFeatures = true; 92 | UnsupFlagTextureDepth = false; 93 | UnsupFlagTooManyVerts = false; 94 | UnsupFlagLines = false; 95 | } 96 | 97 | 98 | #endif // LOAD_OBJ_FILE_H -------------------------------------------------------------------------------- /RaytraceMgr/RayTraceMgr.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 11 | 12 | 13 | 19 | 30 | 32 | 35 | 37 | 39 | 41 | 43 | 45 | 47 | 49 | 51 | 53 | 54 | 60 | 68 | 70 | 73 | 75 | 77 | 79 | 81 | 83 | 85 | 87 | 89 | 91 | 92 | 93 | 94 | 95 | 96 | 100 | 102 | 103 | 105 | 106 | 108 | 109 | 110 | 114 | 116 | 117 | 119 | 120 | 122 | 123 | 124 | 128 | 129 | 131 | 132 | 133 | 134 | 135 | 136 | -------------------------------------------------------------------------------- /RaytraceMgr/SceneDescription.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * RayTrace Software Package, release 3.0. May 3, 2006 4 | * 5 | * Author: Samuel R. Buss 6 | * 7 | * Software accompanying the book 8 | * 3D Computer Graphics: A Mathematical Introduction with OpenGL, 9 | * by S. Buss, Cambridge University Press, 2003. 10 | * 11 | * Software is "as-is" and carries no warranty. It may be used without 12 | * restriction, but if you modify it, please change the filenames to 13 | * prevent confusion between different versions. Please acknowledge 14 | * all use of the software in any publications or products based on it. 15 | * 16 | * Bug reports: Sam Buss, sbuss@ucsd.edu. 17 | * Web page: http://math.ucsd.edu/~sbuss/MathCG 18 | * 19 | */ 20 | 21 | #include "SceneDescription.h" 22 | 23 | // Once you have set up an initial CameraView, you can call RegisterCameraView. 24 | // After that, you may call CalcNewSceenDims( aspectRatio ) to get 25 | // a suggested width and height for the camera screen. 26 | void SceneDescription::RegisterCameraView() 27 | { 28 | RegisteredScreenWidth = CameraAndViewer.GetScreenWidth(); 29 | RegisteredScreenHeight = CameraAndViewer.GetScreenHeight(); 30 | ScreenRegistered = true; 31 | } 32 | 33 | void SceneDescription::CalcNewScreenDims( float aspectRatio ) 34 | { 35 | assert ( ScreenRegistered ); 36 | assert ( aspectRatio>0.0 ); 37 | if ( ScreenRegistered ) { 38 | double registeredAspectRatio = RegisteredScreenWidth/RegisteredScreenHeight; 39 | if ( registeredAspectRatio <= aspectRatio ) { 40 | // Match up heights 41 | CameraAndViewer.SetScreenDimensions( RegisteredScreenHeight*aspectRatio, RegisteredScreenHeight ); 42 | } 43 | else { 44 | // Match up widths 45 | CameraAndViewer.SetScreenDimensions( RegisteredScreenWidth, RegisteredScreenWidth/aspectRatio ); 46 | } 47 | } 48 | } 49 | 50 | 51 | void SceneDescription::DeleteAllLights() 52 | { 53 | long i; 54 | for ( i=NumLights(); i>0; i-- ) { 55 | delete LightArray.Pop(); 56 | } 57 | } 58 | 59 | void SceneDescription::DeleteAllMaterials() 60 | { 61 | long i; 62 | for ( i=NumMaterials(); i>0; i-- ) { 63 | delete MaterialArray.Pop(); 64 | } 65 | } 66 | 67 | void SceneDescription::DeleteAllTextures() 68 | { 69 | long i; 70 | for ( i=NumTextures(); i>0; i-- ) { 71 | delete TextureArray.Pop(); 72 | } 73 | } 74 | 75 | void SceneDescription::DeleteAllViewables() 76 | { 77 | long i; 78 | for ( i=NumViewables(); i>0; i-- ) { 79 | delete ViewableArray.Pop(); 80 | } 81 | } 82 | 83 | 84 | -------------------------------------------------------------------------------- /VrMath/Aabb.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * RayTrace Software Package, release 3.0. May 3, 2006. 4 | * 5 | * Mathematics Subpackage (VrMath) 6 | * 7 | * Author: Samuel R. Buss 8 | * 9 | * Software accompanying the book 10 | * 3D Computer Graphics: A Mathematical Introduction with OpenGL, 11 | * by S. Buss, Cambridge University Press, 2003. 12 | * 13 | * Software is "as-is" and carries no warranty. It may be used without 14 | * restriction, but if you modify it, please change the filenames to 15 | * prevent confusion between different versions. Please acknowledge 16 | * all use of the software in any publications or products based on it. 17 | * 18 | * Bug reports: Sam Buss, sbuss@ucsd.edu. 19 | * Web page: http://math.ucsd.edu/~sbuss/MathCG 20 | * 21 | */ 22 | 23 | // Aabb.cpp 24 | // 25 | // Axis Aligned Bounding Box (AABB) 26 | // 27 | // Implements a fairly simple minded data structure for 28 | // holding information about an AABB. 29 | // 30 | // Author: Sam Buss. 31 | // Contact: sbuss@math.ucsd.edu 32 | // All rights reserved. May be used for any purpose as long 33 | // as use is acknowledged. 34 | 35 | #include "Aabb.h" 36 | #include "MathMisc.h" 37 | 38 | // Update the Aabb to include the "newAabb" 39 | void AABB::EnlargeToEnclose ( const AABB& aabbToEnclose ) 40 | { 41 | UpdateMin( aabbToEnclose.BoxMin.x, BoxMin.x ); 42 | UpdateMin( aabbToEnclose.BoxMin.y, BoxMin.y ); 43 | UpdateMin( aabbToEnclose.BoxMin.z, BoxMin.z ); 44 | UpdateMax( aabbToEnclose.BoxMax.x, BoxMax.x ); 45 | UpdateMax( aabbToEnclose.BoxMax.y, BoxMax.y ); 46 | UpdateMax( aabbToEnclose.BoxMax.z, BoxMax.z ); 47 | } 48 | 49 | double AABB::SurfaceArea() const 50 | { 51 | VectorR3 delta = BoxMax; 52 | delta -= BoxMin; 53 | return 2.0*(delta.x*delta.y + delta.x*delta.z + delta.y*delta.z); 54 | } 55 | 56 | // Find intersection points with a ray. 57 | bool AABB::RayEntryExit( const VectorR3& startPos, const VectorR3& dir, 58 | double *entryDist, int *entryFaceId, 59 | double *exitDist, int *exitFaceId ) 60 | { 61 | VectorR3 dirInv; 62 | int signDirX = Sign(dir.x); 63 | if ( signDirX!=0 ) { 64 | dirInv.x = 1.0/dir.x; 65 | } 66 | int signDirY = Sign(dir.y); 67 | if ( signDirY!=0 ) { 68 | dirInv.y = 1.0/dir.y; 69 | } 70 | int signDirZ = Sign(dir.z); 71 | if ( signDirZ!=0 ) { 72 | dirInv.z = 1.0/dir.z; 73 | } 74 | return RayEntryExit( startPos, signDirX, signDirY, signDirZ, dirInv, 75 | entryDist, entryFaceId, exitDist, exitFaceId ); 76 | } 77 | 78 | bool AABB::RayEntryExit( const VectorR3& startPos, 79 | int signDirX, int signDirY, int signDirZ, const VectorR3& dirInv, 80 | double *entryDist, int *entryFaceId, 81 | double *exitDist, int *exitFaceId ) 82 | { 83 | double& maxEnterDist=*entryDist; 84 | int& maxEnterAxis = *entryFaceId; 85 | double& minExitDist = *exitDist; 86 | int& minExitAxis = *exitFaceId; 87 | 88 | double mx, mn; 89 | if ( signDirX!=0 ) { 90 | if ( signDirX==1 ) { 91 | mx = BoxMax.x; 92 | mn = BoxMin.x; 93 | } 94 | else { 95 | mx = BoxMin.x; 96 | mn = BoxMax.x; 97 | } 98 | maxEnterDist = (mn-startPos.x)*dirInv.x; 99 | minExitDist = (mx-startPos.x)*dirInv.x; 100 | maxEnterAxis = 0; 101 | minExitAxis = 0; 102 | } 103 | else { 104 | if ( startPos.xBoxMax.x ) { 105 | return false; 106 | } 107 | maxEnterDist = -DBL_MAX; 108 | minExitDist = DBL_MAX; 109 | maxEnterAxis = -1; 110 | minExitAxis = -1; 111 | } 112 | 113 | if ( signDirY!=0 ) { 114 | if ( signDirY==1 ) { 115 | mx = BoxMax.y; 116 | mn = BoxMin.y; 117 | } 118 | else { 119 | mx = BoxMin.y; 120 | mn = BoxMax.y; 121 | } 122 | double newEnterDist = (mn-startPos.y)*dirInv.y; 123 | double newExitDist = (mx-startPos.y)*dirInv.y; 124 | if ( maxEnterDistnewExitDist ) { 129 | minExitDist = newExitDist; 130 | minExitAxis = 1; 131 | } 132 | } 133 | else { 134 | if ( startPos.yBoxMax.y ) { 135 | return false; 136 | } 137 | } 138 | 139 | if ( signDirZ!=0 ) { 140 | if ( signDirZ==1 ) { 141 | mx = BoxMax.z; 142 | mn = BoxMin.z; 143 | } 144 | else { 145 | mx = BoxMin.z; 146 | mn = BoxMax.z; 147 | } 148 | double newEnterDist = (mn-startPos.z)*dirInv.z; 149 | double newExitDist = (mx-startPos.z)*dirInv.z; 150 | if ( maxEnterDistnewExitDist ) { 155 | minExitDist = newExitDist; 156 | minExitAxis = 2; 157 | } 158 | } 159 | else { 160 | if ( startPos.zBoxMax.z ) { 161 | return false; 162 | } 163 | } 164 | 165 | if ( minExitDist 39 | #include "LinearR3.h" 40 | 41 | class AABB { 42 | public: 43 | 44 | AABB() {} 45 | AABB( const VectorR3& boxMin, const VectorR3& boxMax ); 46 | AABB( const AABB& aabb ); 47 | 48 | void Set( const VectorR3& boxMin, const VectorR3& boxMax ); 49 | 50 | void SetNewAxisMin ( int axisNum, double newMin ); // Use 0, 1, 2, for x, y, z axes 51 | void SetNewAxisMax ( int axisNum, double newMax ); 52 | 53 | const VectorR3& GetBoxMin() const { return BoxMin; } 54 | const VectorR3& GetBoxMax() const { return BoxMax; } 55 | 56 | VectorR3& GetBoxMin() { return BoxMin; } 57 | VectorR3& GetBoxMax() { return BoxMax; } 58 | 59 | double GetMinX() const { return BoxMin.x; } 60 | double GetMaxX() const { return BoxMax.x; } 61 | double GetMinY() const { return BoxMin.y; } 62 | double GetMaxY() const { return BoxMax.y; } 63 | double GetMinZ() const { return BoxMin.z; } 64 | double GetMaxZ() const { return BoxMax.z; } 65 | 66 | bool IsFlatX() const { return (BoxMin.x==BoxMax.x); } 67 | bool IsFlatY() const { return (BoxMin.y==BoxMax.y); } 68 | bool IsFlatZ() const { return (BoxMin.z==BoxMax.z); } 69 | 70 | bool WellFormed() const; // If has non-negative volume 71 | bool IsEmpty() const; // If has negative volume (definitely misformed in this case) 72 | 73 | // Update the Aabb to include the "newAabb" 74 | void EnlargeToEnclose ( const AABB& newAabb ); 75 | 76 | // Miscellaneous functions 77 | double SurfaceArea() const; 78 | 79 | // Intersection functions 80 | // Form the intersection of two AABB's. 81 | // "this" is updating by intersecting it with aabb1. 82 | // Use IsEmpty to check if result has is non-empty. 83 | void IntersectAgainst( const AABB& aabb1 ); 84 | 85 | // Find intersection points with a ray. 86 | bool RayEntryExit( const VectorR3& startPos, const VectorR3& dir, 87 | double *entryDist, int *entryFaceId, 88 | double *exitDist, int *exitFaceId ); 89 | bool RayEntryExit( const VectorR3& startPos, 90 | int signDirX, int signDirY, int signDirZ, const VectorR3& dirInv, 91 | double *entryDist, int *entryFaceId, 92 | double *exitDist, int *exitFaceId ); 93 | 94 | private: 95 | VectorR3 BoxMin; // Lower corner (min value for all three coordinates) 96 | VectorR3 BoxMax; // Upper corner (max value for all three coordinates) 97 | }; 98 | 99 | inline AABB::AABB( const VectorR3& boxMin, const VectorR3& boxMax ) 100 | : BoxMin(boxMin), BoxMax(boxMax) 101 | { 102 | assert( WellFormed() ); 103 | } 104 | 105 | inline AABB::AABB( const AABB& aabb ) 106 | : BoxMin(aabb.BoxMin), BoxMax(aabb.BoxMax ) 107 | { 108 | assert( WellFormed() ); 109 | } 110 | 111 | inline void AABB::Set( const VectorR3& boxMin, const VectorR3& boxMax ) 112 | { 113 | BoxMin = boxMin; 114 | BoxMax = boxMax; 115 | assert( WellFormed() ); 116 | 117 | } 118 | 119 | // Use 0, 1, 2, for x, y, z axes 120 | inline void AABB::SetNewAxisMin ( int axisNum, double newMin ) 121 | { 122 | switch (axisNum) { 123 | case 0: 124 | BoxMin.x = newMin; 125 | break; 126 | case 1: 127 | BoxMin.y = newMin; 128 | break; 129 | case 2: 130 | BoxMin.z = newMin; 131 | break; 132 | } 133 | } 134 | 135 | // Use 0, 1, 2, for x, y, z axes 136 | inline void AABB::SetNewAxisMax ( int axisNum, double newMax ) 137 | { 138 | switch (axisNum) { 139 | case 0: 140 | BoxMax.x = newMax; 141 | break; 142 | case 1: 143 | BoxMax.y = newMax; 144 | break; 145 | case 2: 146 | BoxMax.z = newMax; 147 | break; 148 | } 149 | } 150 | 151 | // Form the intersection of two AABB's. Result is aabb2. 152 | // Use IsEmpty to check if result has is non-empty. 153 | inline void AABB::IntersectAgainst( const AABB& aabb1 ) 154 | { 155 | UpdateMax( aabb1.BoxMin.x, BoxMin.x ); 156 | UpdateMax( aabb1.BoxMin.y, BoxMin.y ); 157 | UpdateMax( aabb1.BoxMin.z, BoxMin.z ); 158 | UpdateMin( aabb1.BoxMax.x, BoxMax.x ); 159 | UpdateMin( aabb1.BoxMax.y, BoxMax.y ); 160 | UpdateMin( aabb1.BoxMax.z, BoxMax.z ); 161 | } 162 | 163 | inline bool AABB::WellFormed() const { 164 | return ( BoxMin.x<=BoxMax.x 165 | && BoxMin.y<=BoxMax.y 166 | && BoxMin.z<=BoxMax.z); 167 | } 168 | 169 | // Flat boxes do not count as "empty" 170 | inline bool AABB::IsEmpty() const { 171 | return ( BoxMax.x 27 | 28 | // ****************************************************** 29 | // * VectorR2 class - math library functions * 30 | // * * * * * * * * * * * * * * * * * * * * * * * * * * ** 31 | 32 | const VectorR2 VectorR2::Zero; 33 | // Deprecated due to unsafeness of global initialization 34 | //const VectorR2 VectorR2::UnitX( 1.0, 0.0); 35 | //const VectorR2 VectorR2::UnitY( 0.0, 1.0); 36 | //const VectorR2 VectorR2::NegUnitX(-1.0, 0.0); 37 | //const VectorR2 VectorR2::NegUnitY( 0.0,-1.0); 38 | 39 | // Deprecated due to unsafeness of global initialization 40 | //const Matrix2x2 Matrix2x2::Identity(1.0, 0.0, 0.0, 1.0); 41 | 42 | // ****************************************************** 43 | // * Matrix2x2 class - math library functions * 44 | // * * * * * * * * * * * * * * * * * * * * * * * * * * ** 45 | 46 | 47 | // ****************************************************** 48 | // * LinearMapR2 class - math library functions * 49 | // * * * * * * * * * * * * * * * * * * * * * * * * * * ** 50 | 51 | 52 | LinearMapR2 LinearMapR2::Inverse() const // Returns inverse 53 | { 54 | 55 | 56 | double detInv = 1.0/(m11*m22 - m12*m21) ; 57 | 58 | return( LinearMapR2( m22*detInv, -m21*detInv, -m12*detInv, m11*detInv ) ); 59 | } 60 | 61 | LinearMapR2& LinearMapR2::Invert() // Converts into inverse. 62 | { 63 | double detInv = 1.0/(m11*m22 - m12*m21) ; 64 | 65 | double temp; 66 | temp = m11*detInv; 67 | m11= m22*detInv; 68 | m22=temp; 69 | m12 = -m12*detInv; 70 | m21 = -m22*detInv; 71 | 72 | return ( *this ); 73 | } 74 | 75 | VectorR2 LinearMapR2::Solve(const VectorR2& u) const // Returns solution 76 | { 77 | // Just uses Inverse() for now. 78 | return ( Inverse()*u ); 79 | } 80 | 81 | // ****************************************************** 82 | // * RotationMapR2 class - math library functions * 83 | // * * * * * * * * * * * * * * * * * * * * * * * * * * ** 84 | 85 | 86 | 87 | // *************************************************************** 88 | // * 2-space vector and matrix utilities * 89 | // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 90 | 91 | 92 | 93 | 94 | // *************************************************************** 95 | // Stream Output Routines * 96 | // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 97 | 98 | ostream& operator<< ( ostream& os, const VectorR2& u ) 99 | { 100 | return (os << "<" << u.x << "," << u.y << ">"); 101 | } 102 | 103 | 104 | -------------------------------------------------------------------------------- /VrMath/Parallelepiped.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * RayTrace Software Package, release 3.0. May 3, 2006 4 | * 5 | * Author: Samuel R. Buss 6 | * 7 | * Software accompanying the book 8 | * 3D Computer Graphics: A Mathematical Introduction with OpenGL, 9 | * by S. Buss, Cambridge University Press, 2003. 10 | * 11 | * Software is "as-is" and carries no warranty. It may be used without 12 | * restriction, but if you modify it, please change the filenames to 13 | * prevent confusion between different versions. Please acknowledge 14 | * all use of the software in any publications or products based on it. 15 | * 16 | * Bug reports: Sam Buss, sbuss@ucsd.edu. 17 | * Web page: http://math.ucsd.edu/~sbuss/MathCG 18 | * 19 | */ 20 | 21 | // Parallelepiped.cpp 22 | // Author: Sam Buss, January 2005. 23 | 24 | #include "Parallelepiped.h" 25 | 26 | VectorR3 Parallelepiped::GetNormalFront() const 27 | { 28 | VectorR3 ret( EdgeA ); 29 | ret *= EdgeB; 30 | ret.Normalize(); 31 | return ret; 32 | } 33 | 34 | VectorR3 Parallelepiped::GetNormalLeft() const 35 | { 36 | VectorR3 ret( EdgeB ); 37 | ret *= EdgeC; 38 | ret.Normalize(); 39 | return ret; 40 | } 41 | 42 | VectorR3 Parallelepiped::GetNormalBottom() const 43 | { 44 | VectorR3 ret( EdgeC ); 45 | ret *= EdgeA; 46 | ret.Normalize(); 47 | return ret; 48 | } 49 | 50 | 51 | // The six GetFace functions return the fours vertices of the face 52 | // in counterclockwise order as seen from outside the parallelepiped 53 | // "Front" means bounded by edges A and B. 54 | // "Left" means bounded by edges B and C. 55 | // "Bottom" means bounded by edges C and A. 56 | // The base point lies at the bottom left front corner. 57 | 58 | void Parallelepiped::GetFrontFace( VectorR3 *retVerts ) const 59 | { 60 | *retVerts = BasePoint; 61 | *(retVerts+1) = BasePoint; 62 | *(retVerts+1) += EdgeA; 63 | *(retVerts+2) = *(retVerts+1); 64 | *(retVerts+2) += EdgeB; 65 | *(retVerts+3) = BasePoint; 66 | *(retVerts+3) += EdgeB; 67 | } 68 | 69 | void Parallelepiped::GetBackFace( VectorR3 *retVerts ) const 70 | { 71 | *retVerts = BasePoint; 72 | *retVerts += EdgeC; 73 | *(retVerts+3) = *retVerts; 74 | *(retVerts+3) += EdgeA; 75 | *(retVerts+2) = *(retVerts+3); 76 | *(retVerts+2) += EdgeB; 77 | *(retVerts+1) = *retVerts; 78 | *(retVerts+1) += EdgeB; 79 | } 80 | 81 | void Parallelepiped::GetLeftFace( VectorR3 *retVerts ) const 82 | { 83 | *retVerts = BasePoint; 84 | *(retVerts+1) = BasePoint; 85 | *(retVerts+1) += EdgeB; 86 | *(retVerts+2) = *(retVerts+1); 87 | *(retVerts+2) += EdgeC; 88 | *(retVerts+3) = BasePoint; 89 | *(retVerts+3) += EdgeC; 90 | } 91 | 92 | void Parallelepiped::GetRightFace( VectorR3 *retVerts ) const 93 | { 94 | *retVerts = BasePoint; 95 | *retVerts += EdgeA; 96 | *(retVerts+3) = *retVerts; 97 | *(retVerts+3) += EdgeB; // Base + EdgeA + EdgeB 98 | *(retVerts+2) = *(retVerts+3); 99 | *(retVerts+2) += EdgeC; // Base + EdgeA + EdgeB + EdgeC 100 | *(retVerts+1) = *retVerts; 101 | *(retVerts+1) += EdgeC; // Base + EdgeA + EdgeC 102 | } 103 | 104 | 105 | void Parallelepiped::GetBottomFace( VectorR3 *retVerts ) const 106 | { 107 | *retVerts = BasePoint; 108 | *(retVerts+1) = BasePoint; 109 | *(retVerts+1) += EdgeC; 110 | *(retVerts+2) = *(retVerts+1); 111 | *(retVerts+2) += EdgeA; 112 | *(retVerts+3) = BasePoint; 113 | *(retVerts+3) += EdgeA; 114 | } 115 | 116 | void Parallelepiped::GetTopFace( VectorR3 *retVerts ) const 117 | { 118 | *retVerts = BasePoint; 119 | *retVerts += EdgeB; 120 | *(retVerts+3) = *retVerts; 121 | *(retVerts+3) += EdgeC; 122 | *(retVerts+2) = *(retVerts+3); 123 | *(retVerts+2) += EdgeA; 124 | *(retVerts+1) = *retVerts; 125 | *(retVerts+1) += EdgeA; 126 | } 127 | -------------------------------------------------------------------------------- /VrMath/Parallelepiped.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * RayTrace Software Package, release 3.0. May 3, 2006 4 | * 5 | * Author: Samuel R. Buss 6 | * 7 | * Software accompanying the book 8 | * 3D Computer Graphics: A Mathematical Introduction with OpenGL, 9 | * by S. Buss, Cambridge University Press, 2003. 10 | * 11 | * Software is "as-is" and carries no warranty. It may be used without 12 | * restriction, but if you modify it, please change the filenames to 13 | * prevent confusion between different versions. Please acknowledge 14 | * all use of the software in any publications or products based on it. 15 | * 16 | * Bug reports: Sam Buss, sbuss@ucsd.edu. 17 | * Web page: http://math.ucsd.edu/~sbuss/MathCG 18 | * 19 | */ 20 | 21 | // Parallelepiped.h 22 | // Author: Sam Buss, January 2005. 23 | 24 | #ifndef PARALLELEPIPED_H 25 | #define PARALLELEPIPED_H 26 | 27 | #include 28 | 29 | 30 | // Stores a parallelepiped in terms of 31 | // (a) base point 32 | // (b) three edge vectors 33 | 34 | #include "LinearR3.h" 35 | 36 | class Parallelepiped 37 | { 38 | public: 39 | 40 | Parallelepiped(); 41 | Parallelepiped( const VectorR3& basePt, const VectorR3& edgeA, 42 | const VectorR3& edgeB, const VectorR3& edgeC ); 43 | 44 | void Set( const VectorR3& basePt, const VectorR3& edgeA, 45 | const VectorR3& edgeB, const VectorR3& edgeC ); 46 | 47 | const VectorR3& GetBasePt() const { return BasePoint; } 48 | const VectorR3& GetEdgeA() const { return EdgeA; } 49 | const VectorR3& GetEdgeB() const { return EdgeB; } 50 | const VectorR3& GetEdgeC() const { return EdgeC; } 51 | 52 | VectorR3 GetNormalFront() const; 53 | VectorR3 GetNormalLeft() const; 54 | VectorR3 GetNormalBottom() const; 55 | 56 | // The six GetFace functions return the fours vertices of the face 57 | // in counterclockwise order as seen from outside the parallelepiped 58 | // "Front" means bounded by edges A and B. 59 | // "Left" means bounded by edges B and C. 60 | // "Bottom" means bounded by edges C and A. 61 | // The base point lies at the bottom left front corner. 62 | void GetFrontFace( VectorR3 *retVerts ) const; 63 | void GetBackFace( VectorR3 *retVerts ) const; 64 | void GetRightFace( VectorR3 *retVerts ) const; 65 | void GetLeftFace( VectorR3 *retVerts ) const; 66 | void GetTopFace( VectorR3 *retVerts ) const; 67 | void GetBottomFace( VectorR3 *retVerts ) const; 68 | 69 | private: 70 | VectorR3 BasePoint; 71 | VectorR3 EdgeA; 72 | VectorR3 EdgeB; 73 | VectorR3 EdgeC; 74 | }; 75 | 76 | inline Parallelepiped::Parallelepiped() 77 | { 78 | BasePoint.SetZero(); 79 | EdgeA.SetUnitX(); 80 | EdgeB.SetUnitY(); 81 | EdgeC.SetUnitZ(); 82 | } 83 | 84 | inline Parallelepiped::Parallelepiped( const VectorR3& basePt, const VectorR3& edgeA, 85 | const VectorR3& edgeB, const VectorR3& edgeC ) 86 | : BasePoint(basePt), EdgeA(edgeA), EdgeB(edgeB), EdgeC(edgeC) 87 | { 88 | } 89 | 90 | inline void Parallelepiped::Set( const VectorR3& basePt, const VectorR3& edgeA, 91 | const VectorR3& edgeB, const VectorR3& edgeC ) 92 | { 93 | BasePoint = basePt; 94 | EdgeA = edgeA; 95 | EdgeB = edgeB; 96 | EdgeC = edgeC; 97 | } 98 | 99 | 100 | #endif // PARALLELEPIPED_H -------------------------------------------------------------------------------- /VrMath/PolynomialRC.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * RayTrace Software Package, release 3.0. May 3, 2006. 4 | * 5 | * Mathematics Subpackage (VrMath) 6 | * 7 | * Author: Samuel R. Buss 8 | * 9 | * Software accompanying the book 10 | * 3D Computer Graphics: A Mathematical Introduction with OpenGL, 11 | * by S. Buss, Cambridge University Press, 2003. 12 | * 13 | * Software is "as-is" and carries no warranty. It may be used without 14 | * restriction, but if you modify it, please change the filenames to 15 | * prevent confusion between different versions. Please acknowledge 16 | * all use of the software in any publications or products based on it. 17 | * 18 | * Bug reports: Sam Buss, sbuss@ucsd.edu. 19 | * Web page: http://math.ucsd.edu/~sbuss/MathCG 20 | * 21 | */ 22 | 23 | #ifndef POLYNOMIALRC_H 24 | #define POLYNOMIALRC_H 25 | 26 | #include 27 | #include "MathMisc.h" 28 | using namespace std; 29 | 30 | // 31 | // Routines for polynomials over reals/complexes 32 | // 33 | 34 | // QuadraticSolveReal: solves degree to polynomial with 35 | // real coefficients over the reals. Returns the 36 | // number of real roots (0,1,2; or 3 if a=b=c=0). 37 | // root1 will be the smaller root. 38 | // The "Safe" versions should be used only if the leading coefficient, a, 39 | // is known to be non-zero. 40 | int QuadraticSolveReal( double a, double b, double c, 41 | double *root1, double *root2); 42 | int QuadraticSolveReal( double a, double b, double c, 43 | double* rootlist); 44 | int QuadraticSolveRealSafe( double a, double b, double c, 45 | double *root1, double *root2); 46 | int QuadraticSolveRealSafe( double a, double b, double c, 47 | double* rootlist); 48 | 49 | int CubicSolveReal( double a, double b, double c, double d, 50 | double* rootlist ); 51 | 52 | // Finds all the real roots of a polynomial of given degree. 53 | int PolySolveReal( int degree, double *coefs, double *roots); 54 | 55 | // Intended only for internal use: 56 | int QuadraticSolveRealDescrimPos( double a, double b, double c, 57 | double descrim, double *root1, double *root2); 58 | int PolySolveRealAll( int degree, double *coefsarray, double* rootsarray ); 59 | 60 | // 61 | // Routines for 2-variable homogeneous polynomials over the reals. 62 | // 63 | // Solves homogeneous equation. 64 | // Solves an equation a x^2 + (2b)xy + c y^2, returning two 65 | // homogenous vectors describing all solutions. Also returns 66 | // the number of distinct solutions (0,1,2) or returns 3 if 67 | // all vectors are solutions (the latter case occurs only if 68 | // a, b, and c are all zero. 69 | // Note the factor "2" is applied to the second coefficient!! 70 | // This is the same as the matrix equation (x y) X (x y)^T, 71 | // where X is the matrix ( a b ) 72 | // ( b c ). 73 | // In the general case, solutions all have the form 74 | // (alpha)(soln1A, soln1Y) and (alpha)(soln2X, soln2Y), 75 | // where alpha can be any constant. 76 | // Special case: if the determinant is non-zero, it still 77 | // returns values for x and y. Namely the values where the 78 | // value of the quadratic polynomial is maximized. 79 | int QuadraticSolveHomogeneousReal( double a, double b, double c, 80 | double* soln1X, double* soln1Y, 81 | double* soln2X, double* soln2Y ); 82 | 83 | /*****************************************************/ 84 | /* Inlined routines */ 85 | /*****************************************************/ 86 | 87 | inline int QuadraticSolveReal( double a, double b, double c, 88 | double* rootlist) 89 | { 90 | return QuadraticSolveReal(a, b, c, rootlist, rootlist+1); 91 | } 92 | 93 | inline int QuadraticSolveRealSafe( double a, double b, double c, 94 | double* rootlist) 95 | { 96 | return QuadraticSolveRealSafe(a, b, c, rootlist, rootlist+1); 97 | } 98 | 99 | inline int QuadraticSolveRealSafe( double a, double b, double c, 100 | double* root1, double *root2) 101 | { 102 | double descrim = b*b-4.0*a*c; 103 | if ( descrim<0.0 ) { 104 | return 0; 105 | } 106 | return QuadraticSolveRealDescrimPos( a, b, c, descrim, 107 | root1, root2 ); 108 | } 109 | 110 | #endif //POLYNOMIALRC_H 111 | -------------------------------------------------------------------------------- /VrMath/Quaternion.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * RayTrace Software Package, release 3.2b. May 3, 2006; October 5, 2008. 4 | * 5 | * Mathematics Subpackage (VrMath) 6 | * 7 | * Author: Samuel R. Buss 8 | * 9 | * Software is "as-is" and carries no warranty. It may be used without 10 | * restriction, but if you modify it, please change the filenames to 11 | * prevent confusion between different versions. Please acknowledge 12 | * all use of the software in any publications or products based on it. 13 | * 14 | * Bug reports: Sam Buss, sbuss@ucsd.edu. 15 | * Web page: http://math.ucsd.edu/~sbuss/MathCG 16 | * 17 | */ 18 | 19 | #include "Quaternion.h" 20 | #include "MathMisc.h" 21 | #include "LinearR2.h" 22 | #include "LinearR3.h" 23 | #include "LinearR4.h" 24 | 25 | const Quaternion Quaternion::Identity( 0.0, 0.0, 0.0, 1.0 ); 26 | 27 | // ****************************************************************** 28 | // * Quaternion class - member functions * 29 | // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** 30 | 31 | // Convert a rotation map into an equivalent Quaternion. 32 | Quaternion& Quaternion::Set( const RotationMapR3& A) 33 | { 34 | // Use Shepperd's algorithm, which is stable, does not lose 35 | // significant precision and uses only one sqrt. 36 | // J. Guidance and Control, 1 (1978) 223-224. 37 | double m00 = A.m11 + A.m22 + A.m33; // Trace of A 38 | double temp; 39 | if ( m00 >= 0.5 ) { 40 | w = sqrt( 1.0+m00 ); 41 | double wInv = 1.0/w; 42 | x = (A.m32-A.m23)*wInv; 43 | y = (A.m13-A.m31)*wInv; 44 | z = (A.m21-A.m12)*wInv; 45 | } 46 | else if ( (temp = A.m11+A.m11-m00)>=0.5 ) { 47 | x = sqrt(1.0+temp); 48 | double xInv = 1.0/x; 49 | w = (A.m32-A.m23)*xInv; 50 | y = (A.m21+A.m12)*xInv; 51 | z = (A.m31+A.m13)*xInv; 52 | } 53 | else if ( (temp=A.m22+A.m22-m00) >=0.5 ) { 54 | y = sqrt(1.0+temp); 55 | double yInv = 1.0/y; 56 | w = (A.m13-A.m31)*yInv; 57 | x = (A.m21+A.m12)*yInv; 58 | z = (A.m32+A.m23)*yInv; 59 | } 60 | else { 61 | z = sqrt(1.0+A.m33+A.m33-m00); 62 | double zInv = 1.0/z; 63 | w = (A.m21-A.m12)*zInv; 64 | x = (A.m31+A.m13)*zInv; 65 | y = (A.m32+A.m23)*zInv; 66 | } 67 | w *= 0.5; 68 | x *= 0.5; 69 | y *= 0.5; 70 | z *= 0.5; 71 | return *this; 72 | } 73 | 74 | // Convert rotation specified by vector to an equivalent quaternion 75 | Quaternion& Quaternion::SetRotate( const VectorR3& rotVec) 76 | { 77 | double theta = rotVec.Norm(); 78 | double halftheta = theta*0.5; 79 | double sOver = SineOver(halftheta)*0.5; // sin(theta/2)/theta 80 | x = rotVec.x*sOver; 81 | y = rotVec.y*sOver; 82 | z = rotVec.z*sOver; 83 | w = cos(halftheta); 84 | return *this; 85 | } 86 | 87 | // ****************************************************************** 88 | // * VectorR3/RotationMapR3 class - member functions * 89 | // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** 90 | 91 | // this.Rotate( q ) -- Apply quaternion q to rotate this vector. 92 | VectorR3& VectorR3::Rotate( const Quaternion& quat ) 93 | { 94 | RotationMapR3 M; 95 | M.Set(quat); 96 | (*this) = M*(*this); 97 | return *this; 98 | } 99 | 100 | VectorR3& VectorR3::Set( const Quaternion& q ) 101 | { 102 | double sinhalf = sqrt( Square(q.x)+Square(q.y)+Square(q.z) ); 103 | if (sinhalf>0.0) { 104 | double theta = atan2( sinhalf, q.w ); 105 | theta += theta; 106 | this->Set( q.x, q.y, q.z ); 107 | (*this) *= (theta/sinhalf); 108 | } 109 | else { 110 | this->SetZero(); 111 | } 112 | return *this; 113 | } 114 | 115 | RotationMapR3& RotationMapR3::Set( const Quaternion& quat ) 116 | { 117 | double wSq = quat.w*quat.w; 118 | double xSq = quat.x*quat.x; 119 | double ySq = quat.y*quat.y; 120 | double zSq = quat.z*quat.z; 121 | double Dqwx = 2.0*quat.w*quat.x; 122 | double Dqwy = 2.0*quat.w*quat.y; 123 | double Dqwz = 2.0*quat.w*quat.z; 124 | double Dqxy = 2.0*quat.x*quat.y; 125 | double Dqyz = 2.0*quat.y*quat.z; 126 | double Dqxz = 2.0*quat.x*quat.z; 127 | m11 = wSq+xSq-ySq-zSq; 128 | m22 = wSq-xSq+ySq-zSq; 129 | m33 = wSq-xSq-ySq+zSq; 130 | m12 = Dqxy-Dqwz; 131 | m21 = Dqxy+Dqwz; 132 | m13 = Dqxz+Dqwy; 133 | m31 = Dqxz-Dqwy; 134 | m23 = Dqyz-Dqwx; 135 | m32 = Dqyz+Dqwx; 136 | return *this; 137 | } 138 | 139 | 140 | //******************************************************************* 141 | // Solid Geometry routines * 142 | //******************************************************************* 143 | 144 | // Compute the angle formed by two geodesics on the unit sphere. 145 | // Three unit vectors u,v,w specify the geodesics u-v and v-w which 146 | // meet at vertex v. The angle from v-w to v-u is returned. This 147 | // is always in the range [0, 2PI). 148 | // The three vectors should be unit vectors and should be distinct 149 | double SphereAngle( const VectorR3& u, const VectorR3& v, const VectorR3& w ) { 150 | VectorR3 vuPerp = ProjectPerpUnit ( u, v ); 151 | VectorR3 vwPerp = ProjectPerpUnit ( w, v ); 152 | double costheta = vwPerp^vuPerp; 153 | double sintheta = (v*vuPerp)^vwPerp; 154 | double normProdInv = 1.0/sqrt(vuPerp.NormSq()*vwPerp.NormSq()); 155 | costheta *= normProdInv; 156 | sintheta *= normProdInv; 157 | 158 | double theta = atan2( sintheta, costheta ); 159 | if (theta<0.0) { 160 | theta += PI2; 161 | } 162 | return theta; 163 | } 164 | 165 | 166 | 167 | 168 | -------------------------------------------------------------------------------- /VrMath/VrMath.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 11 | 12 | 13 | 19 | 30 | 32 | 35 | 37 | 39 | 41 | 43 | 45 | 47 | 49 | 51 | 53 | 54 | 60 | 68 | 70 | 73 | 75 | 77 | 79 | 81 | 83 | 85 | 87 | 89 | 91 | 92 | 93 | 94 | 95 | 96 | 100 | 102 | 103 | 105 | 106 | 108 | 109 | 111 | 112 | 114 | 115 | 117 | 118 | 120 | 121 | 123 | 124 | 125 | 129 | 131 | 132 | 134 | 135 | 137 | 138 | 140 | 141 | 143 | 144 | 146 | 147 | 149 | 150 | 152 | 153 | 155 | 156 | 158 | 159 | 160 | 164 | 165 | 167 | 168 | 169 | 170 | 171 | 172 | --------------------------------------------------------------------------------