00001 /* 00002 File: RadMesh.h 00003 00004 Function: Defines a basic mesh of radiosity elements. These can be either 00005 quads (parallelograms), or triangles. 00006 00007 Author(s): Andrew Willmott 00008 00009 Copyright: (c) 1995-2000, Andrew Willmott 00010 */ 00011 00012 #ifndef __RadMesh__ 00013 #define __RadMesh__ 00014 00015 #include "gcl/Geometry.h" 00016 #include "gcl/Renderer.h" 00017 #include "RadControl.h" 00018 #include "gcl/Texture.h" 00019 #include "cl/PtrArray.h" 00020 #include "cl/NArray.h" 00021 00022 class RadElem; 00023 00024 class RadProps 00026 { 00027 public: 00028 RadProps(); 00029 00030 Colour reflectance; 00031 Colour emittance; 00032 00033 PointList *points; 00034 ColourList *colours; 00035 PointList *normals; 00036 CoordList *texCoords; 00037 00038 Texture *texture; 00039 Int id; 00040 00041 Void InterpolateIndexes( 00042 RadElem *srcElt, 00043 Int srcVtx1, 00044 Int srcVtx2, 00045 RadElem *dstElt, 00046 Int dstVtx, 00047 GCLReal m = 0.5 00048 ); 00049 00052 }; 00053 00054 struct CompareStats 00056 { 00057 GCLReal areaSum; 00058 Colour cSum; 00059 Colour cSqrSum; 00060 Colour refSum; 00061 }; 00062 00063 class PatchStats 00065 { 00066 public: 00067 Void Init(); 00068 Void Update(RadElem *patch); 00069 Void Report(ostream &s); 00070 00071 GCLReal minArea; 00072 GCLReal maxArea; 00073 Reflectance minRefl; 00074 Reflectance maxRefl; 00075 Colour maxPower; 00076 Colour totalPower; 00077 }; 00078 00079 00080 typedef RadElem *RadElemPtr; 00081 typedef PtrArray<RadElem> PatchList; 00082 typedef Array<RadElem> RadElemList; 00083 00084 class RadElem 00085 { 00086 public: 00087 RadElem(); 00088 virtual ~RadElem(); 00089 00090 Int index[4]; 00091 Int clrIdx[4]; 00092 Int normIdx[4]; 00093 Int texIdx[4]; 00094 RadProps *props; 00095 00096 Point centre; 00097 Vector normal; 00098 Colour colour; 00099 GCLReal area; 00100 #ifdef RAD_TEXTURE 00101 Colour localRefl; 00102 #endif 00103 #ifdef RAD_VIS 00104 Byte highlight; 00105 #endif 00106 00107 virtual Void Draw(Renderer &r); 00108 // Draw this element 00109 00110 // Sampling methods 00111 00112 Void Compare(RadElem *to, GCLReal edgeLen, CompareStats &stats); 00113 virtual Colour Sample(Coord c); 00115 00116 Coord FindCoord(Point &p); 00118 virtual RadElem *FindContainer(Coord &coord); 00120 virtual Colour SampleLeaf(Coord c); 00122 00123 // Form factor-calculation methods 00124 00125 GCLReal EstPatchFactor(const Point &p, const Vector &n); 00127 GCLReal PatchFactor(const Point &p, const Vector &n); 00129 GCLReal ApproxPatchFactor(const Point &p, const Vector &np); 00132 GCLReal EstFormFactor(RadElem *to); 00136 GCLReal EdgeArea(const Vector &p, const Vector &q, 00137 const Vector &n); 00138 GCLReal SampledFormFactor(Int n, RadElem *to, GCLReal &error); 00139 Int OrientInfo(RadElem *to); 00140 00141 // Visibility methods 00142 00143 GCLReal Visibility(RadElem *to); 00144 00145 GCLReal CentreVis(const Point &p, const Vector &n); 00146 GCLReal Visibility16(const Point &p, const Vector &n); 00147 Bool PotentiallyVis(RadElem *to); 00148 Bool PotentiallyVisAndTouching(RadElem *to, Bool &touching); 00149 GCLReal Visibility44(RadElem *to); 00150 00151 Void SetVisPoints(Point p[]); 00152 GCLReal RadVis4x4(RadElem *to); 00153 GCLReal RadVis16x1(const Point &p, const Vector &n); 00154 00155 // Radiosity methods.... 00156 00157 virtual Void ColourVertices(Int weights[]); 00159 virtual Void CreatePatches(PatchList &patches); 00161 // Utility 00162 00163 virtual Void Print(ostream &s); 00164 virtual Void Parse(istream &s); 00165 virtual Void Reanimate(RadElem *parent); 00166 virtual StrConst Name(); 00167 00168 Void SetProps(RadProps *props); 00169 Void SetHighlight(Int h); 00170 Void DrawHighlight(Renderer &r); 00171 Void RaiseVertex(Renderer &r, Int i); 00173 Void SetColour(const Colour &c) 00175 { colour = c; }; 00176 00177 // Property accessor methods 00178 00179 Vector &Vertex(Int i) {return((*props->points)[index[i]]);}; 00180 Colour &VtxClr(Int i) {return((*props->colours)[clrIdx[i]]);}; 00181 Vector &Normal(Int i) {return((*props->normals)[normIdx[i]]);}; 00182 Coord &TexCoord(Int i) {return((*props->texCoords)[texIdx[i]]);}; 00183 00184 Void SetIndexes( 00185 Int dstIdx, 00186 RadElem *src, 00187 Int srcIdx 00188 ); 00189 00190 Void SetAllIndexes( 00191 RadElem *s0, 00192 Int i0, 00193 RadElem *s1, 00194 Int i1, 00195 RadElem *s2, 00196 Int i2, 00197 RadElem *s3, 00198 Int i3 00199 ); 00200 00201 Vector &Normal() {return(normal);}; 00202 Vector &Centre() {return(centre);}; 00203 Colour &Emittance() {return(props->emittance);}; 00204 #ifdef RAD_TEXTURE 00205 Colour &Reflectance() {return(localRefl);}; 00206 #else 00207 Colour &Reflectance() {return(props->reflectance);}; 00208 #endif 00209 Int Sides() {return((index[3] < 0) ? 3 : 4);}; 00210 00211 Bool IsTri() {return(index[3] < 0);}; 00212 Bool IsQuad() {return(index[3] >= 0);}; 00213 Bool IsTextured() {return(props->texCoords != 0);}; 00214 Bool HasNormals() {return(props->normals != 0);}; 00215 Void SendPoints(Renderer &r) 00216 { r.P(Vertex(0)).P(Vertex(1)).P(Vertex(2)); 00217 if (IsQuad()) r.P(Vertex(3)); }; 00218 00219 virtual GCLReal 00220 MemoryUse(); 00221 00222 static Int sGridMem; 00223 static Int sGridChildMem; 00224 }; 00225 00226 ostream &operator << (ostream &s, RadElem &rq); 00227 istream &operator >> (istream &s, RadElem &rq); 00228 00229 // --- An elem with neighbour info -------------------------------------------- 00230 00231 class NbRadElem : public RadElem 00232 { 00233 public: 00234 NbRadElem(); 00235 00236 NbRadElem *nbFace[4]; 00238 Byte nbEdge[4]; 00243 GCLReal MemoryUse(); 00244 }; 00245 00246 00247 // --- An elem that can be gridded -------------------------------------------- 00248 00249 00250 class GridBase : public NbRadElem 00251 { 00252 public: 00253 Void Mesh(GCLReal density); 00254 00255 virtual RadElemPtr AddChild(RadElem &elem, Int i, Int j, Int in, Int jn) = 0; 00257 Int FindChildIndex(Coord &coord); 00259 00260 Int rows, cols; 00261 }; 00262 00263 class RadGrid : public GridBase 00264 { 00265 public: 00266 Void CreatePatches(PatchList &patches); 00267 Void Draw(Renderer &r); 00268 Void ColourVertices(Int weights[]); 00269 RadElem *FindContainer(Coord &coord); 00270 Void Reanimate(RadElem *parent); 00271 00272 Void Print(ostream &s); 00273 Void Parse(istream &s); 00274 StrConst Name(); 00275 00276 GCLReal MemoryUse(); 00277 00278 RadElemPtr AddChild(RadElem &elem, Int i, Int j, Int in, Int jn); 00279 RadElemList children; 00280 }; 00281 00282 const GCLReal kRaySurfEps = 1e-6; // amount to offset vis testing from 00283 // surfaces to aVoid self-intersection. 00284 00285 #endif