#ifndef SCRATCHPAD_H #define SCRATCHPAD_H #include "vector.h" #include "color.h" #include "vector2d.h" #include "CoefficientStream.h" #include "Kernel.h" #include "Surface.h" // Define a scratchpad element typedef struct { COLOR rad; RGB rgb; float amc; union { VEC2D dde; // Used when doing density estimation COLOR drc; // Used when doing radiance-based wavelet compression VECTOR dd; // Used when doing the display } data; } ScratchPadElement, *ScratchPadElementPtr; class ScratchPad { public: // Constructs a new ScratchPad. // IN: The maximum recursion level you will ever use with this scratchpad. // OUT: A pointer to a newly allocated scratchpad (NULL if memory allocation failed). // POST: The ScratchPad is ready to be used. The content is random. ScratchPad(const int r); // Destroy the ScratchPad. // POST: the memory is released. ~ScratchPad(); // Basic configuration of the ScratchPad. // IN: p is a pointer to the patch we will be working with (display or density estimation) // r is a recursive sudivision level // POST: you can use the scratchpadelement array. void basicConfigure(PATCH* p,const int r); // Configure the Scratchpad for the construction of a new SurfWav2D. // IN: p is a pointer to the patch we want to reconstruct the illumination onto. // gridsz is the grid size for the mesh // POST: you are allowed to call addImpact. void configure(PATCH* p,const float gridsz); // Change the reconstruction kernel type. // IN: a new kernel. // POST: the previous kernel has been deleted. void setKernel(Kernel *k); // Change the reconstruction kernel size. // IN: h is the new size of the reconstruction kernel. // OUT: The new size will be taken into account for subsequent impacts. void setKernelSize(const float h); // Set an overall lightning (used for edf for instance) // IN: an additional radiance for every point of the patch. // (if you never call this function it will be assumed to be equal to 0,0,0) // POST: this additional radiance will be taken into account for the SurfWav construction void setBaseRadiance(const COLOR &base); // Add an impact for the construction. // IN: pos is the position of the impact in parameter space of the patch. // weight is the weight of the reconstruction kernel (w>0). // POST: The impact has been taken into account. void addImpact(const VEC2D &pos,const COLOR &weight); // Construct a SurfWav2D from the ScratchPad contents. // IN: The expected compression ratio. // OUT: A pointer to a SurfWav2D. (NULL if memory allocation failed). DiffuseCompressedSurface* constructDiffuseCompressedSurface(const float t); DiffuseDecimatedSurface* constructDiffuseDecimatedSurface(const float t); // Display a SurfWav. // IN: A SurfWav. // POST: The SurfWav is displayed on screen. void display(CoefficientStore *); // Print some information about the scratchpad. // (could be used for debugging purposes ) void print(); // Add the contents of an another scratchpad multiplied by a constant to this scratchpad. void add(const ScratchPad *toadd,const COLOR& c); void writePlyFile(int fd,const float f); // HemisphereScratchPad has more control than only the public interface... friend class HemisphereScratchPad; private: int maxr; // r = maximum recursion level int maxnumsub; // numsub = 2^r int maxnumline; // numline = (2^r)+1 int maxnumcoef; // numline*numline int curr; // r = actual recursion level int curnumsub; // numsub = 2^r int curnumline; // numline = (2^r)+1 int curnumcoef; // numline*numline float curnumsubfp; // floating point numsub PATCH* patch; // current patch int issquare; // 3 or 4 vertices ? float invarea; // Inverse area of the current patch Kernel* kernel; // the reconstruction kernel ScratchPadElementPtr elems; // vertex related stuff CoefficientStream coefstream; // wavelet compression results static const int maxrefl = 50; // Maximum number of reflections for one impact. VEC2D refl[maxrefl]; // Positions of these reflections. int nrefl; // Number of reflections. int insideo,insideu,insidev,insidew;// Are the corners inside the kernel ? int reflo,reflu,reflv,reflw; // How many reflections around a corner ? float scalef; // Scale factor int *idxs; COLOR curweight; // Current weigth COLOR accum; // Accumulated color double hmin,hmax; // Kernel properties double ihs,iht,ihu,ihv,ihw; // Inverse altitudes length double ao,au,av,aw; double ls,lt,lu,lv,lw; int nao,nau,nav,naw; VEC2D cs,ct,cu,cv,cw; // Edges VEC2D ds,dt,du,dv,dw; // Elementary edges VEC2D ns,nt,nu,nv,nw; // Normalised edges VEC2D nns,nnt,nnu,nnv,nnw; // Opposites normalised edges // Clear the content of the scratchpad. // POST: the scratchpad content is zeroed. void clear(); void basicConfigurePatch(PATCH* p); void basicConfigureRecursionLevel(const int r); void chooseRecursionLevel(const float gridsz); // Configure the Scratchpad for the construction of a new triangular SurfWav2D. void configureTriangular(const float gridsz); // Configure the Scratchpad for the construction of a new quadrilateral SurfWav2D. void configureQuadrilateral(const float gridsz); // Add an impact for the construction. // IN: pos is the position of the impact in parameter space of the patch. // weight is the weight of the reconstruction kernel (w>0). // POST: The impact has been taken into account. void addImpactTriangular(const VEC2D &pos,const COLOR &weight); // Add an impact for the construction. // IN: pos is the position of the impact in parameter space of the patch. // weight is the weight of the reconstruction kernel (w>0). // POST: The impact has been taken into account. void addImpactQuadrilateral(const VEC2D &pos,const COLOR &weight); void addImpactQuadrilateralAux(int u,int v,int goUp); int testAndSetImpact(int idx); // Add accumlation parameter to all points void addAccum(); // Reflect an impact around the edges of the triangle. void doReflexTriangular(const VEC2D &toreflect,const int forbid); // Reflect an impact around the edges of the quadrilateral. void doReflexQuadrilateral(const VEC2D &toreflect,const int forbid); // Construct a CoefficientStore with the ScratchPad contents // IN: The expected compression ratio. // OUT: The corresponding coefficient store. CoefficientStore* constructCoefficientStore(const float t); // Find wavelet scale coefficients // POST: Each data.drc field of ScratchPadElement contains a wavelet coefficient. void findWaveletCoefficients(); // Simplify wavelet coefficients // IN: Expected compression ratio. // OUT: The number of remaining coefficients . // POST: Some coefficients are set to zero. int simplifyWaveletCoefficients(const float t); // Iterate a scratchpad in OUT->IN order. // IN: function to call at each step (returns 0 to stop) void iterateOutIn(int (ScratchPad::*functocall)(ScratchPadElement&,ScratchPadElement&,ScratchPadElement&),int); void iterateOutInTriangular(int (ScratchPad::*functocall)(ScratchPadElement&,ScratchPadElement&,ScratchPadElement&),int); void iterateOutInQuadrilateral(int (ScratchPad::*functocall)(ScratchPadElement&,ScratchPadElement&,ScratchPadElement&),int); // Iterate a scratchpad in IN->OUT order. // IN: function to call at each step (returns 0 to stop) void iterateInOut(int (ScratchPad::*functocall)(ScratchPadElement&,ScratchPadElement&,ScratchPadElement&)); void iterateInOutTriangular(int (ScratchPad::*functocall)(ScratchPadElement&,ScratchPadElement&,ScratchPadElement&)); void iterateInOutQuadrilateral(int (ScratchPad::*functocall)(ScratchPadElement&,ScratchPadElement&,ScratchPadElement&)); // Iterate a scratchpad in sequential order. // Helper functions int calculateCoefficient(ScratchPadElement &left,ScratchPadElement &right,ScratchPadElement &middle); int calculateCoefficient2(ScratchPadElement &left,ScratchPadElement &right,ScratchPadElement &middle); int storeCoefficient(ScratchPadElement &left,ScratchPadElement &right,ScratchPadElement &middle); void writeCoefficient(ScratchPadElement &left); }; #endif