00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef __CS_RADIOSTY_H__
00020 #define __CS_RADIOSTY_H__
00021
00022 #include "csutil/csobject.h"
00023 #include "csgeom/vector3.h"
00024 #include "csutil/cscolor.h"
00025 #include "csengine/polygon.h"
00026 #include "csengine/curve.h"
00027 #include "csengine/polytext.h"
00028 #include "csengine/lghtmap.h"
00029 #include "csengine/lview.h"
00030
00031 class csEngine;
00032 class csPolygon3D;
00033 class csLightMap;
00034 class csRGBMap;
00035 class csProgressPulse;
00036 class csShadowFrustum;
00037 struct iProgressMeter;
00038
00040 float FastPow2(float x, const int y);
00041
00047 class csRGBFloatLightMap
00048 {
00049 private:
00050 int max_sizeRGB;
00051 float* map;
00052
00053 public:
00055 void Clear ()
00056 {
00057 delete [] map; map = NULL;
00058 max_sizeRGB = 0;
00059 }
00060
00062 csRGBFloatLightMap () : max_sizeRGB (0), map (NULL) { }
00064 ~csRGBFloatLightMap () { Clear (); }
00065
00067 int GetMaxSize () { return max_sizeRGB; }
00069 void SetMaxSize (int s) { max_sizeRGB = s; }
00070
00072 float* GetMap () const { return map; }
00074 float* GetRed () const { return map; }
00076 float* GetGreen () const { return map+max_sizeRGB; }
00078 float* GetBlue () const { return map+(max_sizeRGB<<1); }
00079
00081 void SetMap (float* m) { map = m; }
00082
00084 void Alloc (int size)
00085 {
00086 max_sizeRGB = size;
00087 delete [] map;
00088 map = new float [size*3];
00089 }
00090
00092 void Copy (csRGBFloatLightMap& other, int size)
00093 {
00094 Clear ();
00095 if (other.map) { Alloc (size); memcpy (map, other.map,
00096 size * 3 * sizeof(float)); }
00097 }
00098
00100 void Copy (csRGBMap& other, int size)
00101 {
00102 Clear ();
00103 if (other.GetArray()) {
00104 Alloc (size);
00105 csRGBpixel* m = other.GetArray ();
00106 int i;
00107 for(i=0; i<size; i++)
00108 {
00109 GetRed()[i] = m[i].red;
00110 GetGreen()[i] = m[i].green;
00111 GetBlue()[i] = m[i].blue;
00112 }
00113 }
00114 }
00115
00117 void CopyTo (csRGBMap& other, int size)
00118 {
00119 other.Clear ();
00120 if (GetMap()) {
00121 other.Alloc (size);
00122 csRGBpixel* m = other.GetArray ();
00123 int i;
00124 for(i=0; i<size; i++)
00125 {
00126 m[i].red = (unsigned char)GetRed()[i];
00127 m[i].green = (unsigned char)GetGreen()[i];
00128 m[i].blue = (unsigned char)GetBlue()[i];
00129 }
00130 }
00131 }
00132 };
00133
00138 class csRadElement : public csObject {
00139 protected:
00140 float area;
00141
00142 float total_unshot_light;
00143
00144 public:
00145 csLightMap *csmap;
00146
00147 protected:
00148 int width, height, size;
00149
00151 csRGBMap *lightmap;
00152
00154 csRGBFloatLightMap *deltamap;
00155
00161 csRGBMap* copy_lightmap;
00162
00164 float one_lumel_area;
00165
00167 float last_shoot_priority;
00168 int num_repeats;
00169
00170 protected:
00171
00173 virtual iMaterialWrapper* GetMaterialWrapper () = 0;
00174
00176 virtual csColor GetFlatColor() const = 0;
00177
00178
00179 virtual void Setup() {};
00180
00181
00182
00183 public:
00184 csRadElement();
00185 ~csRadElement();
00186
00188 inline float GetPriority() { return total_unshot_light; }
00189
00191 inline float GetArea() const { return area; }
00192
00194 inline float GetDiffuse() const { return 0.7; }
00195
00197 inline int GetWidth() const{ return width; }
00198
00200 inline int GetHeight() const { return height; }
00201
00203 inline int GetSize() const { return size; }
00204
00206 inline bool DeltaIsZero(int suv)
00207 { return !(deltamap->GetRed()[suv] || deltamap->GetGreen()[suv] ||
00208 deltamap->GetBlue()[suv] ); }
00209
00211 virtual csSector* GetSector () const = 0;
00212
00214 virtual const csVector3& GetNormal(int x, int y) const = 0;
00215
00217 csVector3 GetAvgNormal() const;
00218
00220 bool DeltaIsZero(int suv, int w, int h);
00221
00223 void GetTextureColour(int suv, int w, int h, csColor &avg,
00224 csRGBMap *texturemap);
00225
00227 void CapDelta(int suv, int w, int h, float max);
00228
00230 void GetSummedDelta(int suv, int w, int h, csColor& sum);
00231
00233 inline csRGBFloatLightMap* GetDeltaMap() { return deltamap; }
00234
00239 void ShowDeltaMap ();
00240
00245 void RestoreStaticMap ();
00246
00248 inline float GetLastShootingPriority() { return last_shoot_priority;}
00249
00251 inline void SetLastShootingPriority(float val) {last_shoot_priority=val;}
00252
00254 inline int GetRepeatCount() { return num_repeats; }
00255
00257 inline void IncNumRepeats() {num_repeats++;}
00258
00260 virtual void Lumel2World(csVector3& res, int x, int y) = 0;
00261
00263 inline float GetOneLumelArea() const { return one_lumel_area; }
00264
00265
00267 virtual void GetCoverageMatrix(csFrustumView* lview,
00268 csCoverageMatrix* shadow_matrix) = 0;
00269
00275 void ComputePriority();
00276
00281 void AddDelta(csRadElement *src, int suv, int ruv, float fraction,
00282 const csColor& filtercolor);
00283
00287 inline void AddToDelta(int ruv, const csColor& value)
00288 { deltamap->GetRed()[ruv] += value.red;
00289 deltamap->GetGreen()[ruv] += value.green;
00290 deltamap->GetBlue()[ruv] += value.blue;
00291 }
00292
00298 void CopyAndClearDelta();
00299
00303 void GetDeltaSums(float &red, float &green, float &blue);
00304
00308 void ApplyAmbient(int red, int green, int blue);
00309
00314 csRGBMap *ComputeTextureLumelSized();
00315
00317 static csRadElement* GetRadElement(csPolygon3D &object);
00318
00320 static csRadElement* GetRadElement(csCurve &object);
00321 };
00322
00323
00324 SCF_VERSION (csRadPoly, 0, 0, 1);
00325
00330 class csRadPoly : public csRadElement
00331 {
00332 private:
00333 csPolygon3D* polygon;
00334 csSector* sector;
00335 csVector3 lumel_origin, lumel_x_axis, lumel_y_axis;
00336
00337 protected:
00339 virtual iMaterialWrapper * GetMaterialWrapper ()
00340 { return &(polygon->GetMaterialWrapper ())->scfiMaterialWrapper; }
00341
00343 virtual csColor GetFlatColor() const;
00344
00345
00346 virtual void Setup();
00347
00348 public:
00349 csRadPoly(csPolygon3D *original, csSector* sector);
00350 ~csRadPoly();
00351
00353 const csVector3& GetNormal(int x, int y) const
00354 { (void)x; (void)y; return polygon->GetPolyPlane()->Normal();}
00355
00357 inline csPolygon3D *GetPolygon3D() const { return polygon; }
00358
00360 void CalcLumel2World(csVector3& res, int x, int y);
00361
00363 virtual void Lumel2World(csVector3& res, int x, int y);
00364
00365 csSector* GetSector () const { return sector; }
00366
00368 virtual void GetCoverageMatrix(csFrustumView* lview,
00369 csCoverageMatrix* shadow_matrix)
00370 {
00371 (void)lview;
00372 (void)shadow_matrix;
00373 #if 0
00374
00375 GetPolygon3D()->GetLightMapInfo()->GetPolyTex()->
00376 GetCoverageMatrix(*lview, *shadow_matrix);
00377 #endif
00378 }
00379 SCF_DECLARE_IBASE_EXT (csRadElement);
00380 };
00381
00382
00383 SCF_VERSION (csRadCurve, 0, 0, 1);
00384
00389 class csRadCurve : public csRadElement {
00390 private:
00391 csCurve* curve;
00392 csSector* sector;
00393
00394 protected:
00396 virtual iMaterialWrapper * GetMaterialWrapper ()
00397 { return curve->Material; }
00398
00400 virtual csColor GetFlatColor() const
00401 {
00404 return csColor(0.5, 0.5, 0.5);
00405 }
00406
00407 virtual void Setup();
00408
00409 public:
00410 csRadCurve (csCurve* curve, csSector* sector);
00411 ~csRadCurve();
00412
00414 virtual const csVector3& GetNormal(int x, int y) const;
00415
00417 virtual void Lumel2World(csVector3& res, int x, int y);
00418
00419 csSector* GetSector () const { return sector; }
00420
00422 virtual void GetCoverageMatrix(csFrustumView* ,
00423 csCoverageMatrix* )
00424 { }
00425
00426 SCF_DECLARE_IBASE_EXT (csRadElement);
00427 };
00428
00429
00433 class csRadTree{
00434 private:
00435 csRadElement *element;
00436
00437 csRadTree *left, *right;
00438
00440 void DelNode();
00441
00443 csRadTree* FindLeftMost(csRadTree*& parent);
00444
00446 csRadTree* FindRightMost(csRadTree*& parent);
00447
00448 public:
00450 inline csRadTree(csRadElement *n, csRadTree *l, csRadTree *r)
00451 {element = n; left=l; right=r;}
00452
00454 inline ~csRadTree() {if (left) delete left; if (right) delete right;}
00455
00457 void Insert(csRadElement *e);
00458
00460 csRadTree* Delete(csRadElement *e);
00461
00463 csRadTree* PopHighest(csRadElement*& e);
00464
00466 inline float GetPriority() { return element->GetPriority(); }
00467
00469 void TraverseInOrder( void (*func)( csRadElement * ) );
00470 };
00471
00472
00476 class csRadList {
00477 private:
00479 csRadTree *tree;
00481 int num;
00482
00483 public:
00485 csRadList();
00486
00488 ~csRadList();
00489
00491 void InsertElement(csRadElement *e);
00492
00494 void DeleteElement(csRadElement *e);
00495
00497 csRadElement *PopHighest();
00498
00500 void Print();
00501
00503 void Traverse( void (*func)( csRadElement * ) )
00504 { if(tree) tree->TraverseInOrder(func); }
00505
00507 inline int GetElementCount() { return num; }
00508 };
00509
00513 class csRadiosity {
00514 public:
00520 static bool do_static_specular;
00522 static float static_specular_amount;
00528 static int static_specular_tightness;
00529
00535 static float colour_bleed;
00536
00540 static float stop_priority;
00544 static float stop_improvement;
00546 static int stop_iterations;
00547
00551 static int source_patch_size;
00552
00553 private:
00555 csEngine *engine;
00557 csRadList *list;
00558
00563 bool showing_deltamaps;
00564
00566 iProgressMeter *meter;
00568 csProgressPulse *pulse;
00570 float start_priority;
00572 int iterations;
00573
00576 float factor;
00578 csRadElement *shoot_src, *shoot_dest;
00580 csVector3 src_lumel, dest_lumel;
00582 csVector3 src_normal, dest_normal;
00584 float source_poly_patch_area;
00586 int srcp_width, srcp_height;
00588 float source_patch_area;
00590 int src_uv;
00592 int src_x, src_y;
00595 csRGBMap *texturemap;
00597 csCoverageMatrix *shadow_matrix;
00599 csColor trajectory_color;
00601 csColor src_lumel_color;
00603 csColor delta_color;
00604
00605 public:
00607 csRadiosity(csEngine *current_engine, iProgressMeter* meter);
00609 ~csRadiosity();
00611 void DoRadiosity();
00612
00617 bool DoRadiosityStep (int steps);
00619 csPolygon3D* GetNextPolygon ();
00624 void ToggleShowDeltaMaps ();
00629 void RestoreStaticMaps ();
00630
00632 csRadElement* FetchNext();
00634 void StartFrustum();
00636 void ProcessDest(csRadElement *dest, csFrustumView *lview);
00638 void ShootRadiosityToElement(csRadElement* dest);
00640 void PrepareShootSource(csRadElement* src);
00642 bool PrepareShootDest(csRadElement* dest, csFrustumView *lview);
00644 void PrepareShootSourceLumel(int sx, int sy, int suv);
00646 void ShootPatch(int rx, int ry, int ruv);
00647
00648
00650 void ApplyDeltaAndAmbient();
00652 void RemoveAmbient();
00653
00654 };
00655
00656 #endif // __CS_RADIOSTY_H__