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 #if 0
00023
00024
00025 #include "csutil/csobject.h"
00026 #include "csgeom/vector3.h"
00027 #include "csutil/cscolor.h"
00028 #include "csengine/lview.h"
00029
00030 class csEngine;
00031 class csPolygon3D;
00032 class csLightMap;
00033 class csRGBMap;
00034 class csProgressPulse;
00035 class csShadowFrustum;
00036 struct iProgressMeter;
00037
00039 float FastPow2(float x, const int y);
00040
00046 class csRGBFloatLightMap
00047 {
00048 private:
00049 int max_sizeRGB;
00050 float* map;
00051
00052 public:
00054 void Clear ()
00055 {
00056 delete [] map; map = NULL;
00057 max_sizeRGB = 0;
00058 }
00059
00061 csRGBFloatLightMap () : max_sizeRGB (0), map (NULL) { }
00063 ~csRGBFloatLightMap () { Clear (); }
00064
00066 int GetMaxSize () { return max_sizeRGB; }
00068 void SetMaxSize (int s) { max_sizeRGB = s; }
00069
00071 float* GetMap () const { return map; }
00073 float* GetRed () const { return map; }
00075 float* GetGreen () const { return map+max_sizeRGB; }
00077 float* GetBlue () const { return map+(max_sizeRGB<<1); }
00078
00080 void SetMap (float* m) { map = m; }
00081
00083 void Alloc (int size)
00084 {
00085 max_sizeRGB = size;
00086 delete [] map;
00087 map = new float [size*3];
00088 }
00089
00091 void Copy (csRGBFloatLightMap& other, int size)
00092 {
00093 Clear ();
00094 if (other.map) { Alloc (size); memcpy (map, other.map,
00095 size * 3 * sizeof(float)); }
00096 }
00097
00099 void Copy (csRGBMap& other, int size)
00100 {
00101 Clear ();
00102 if (other.GetArray()) {
00103 Alloc (size);
00104 csRGBpixel* m = other.GetArray ();
00105 int i;
00106 for(i=0; i<size; i++)
00107 {
00108 GetRed()[i] = m[i].red;
00109 GetGreen()[i] = m[i].green;
00110 GetBlue()[i] = m[i].blue;
00111 }
00112 }
00113 }
00114
00116 void CopyTo (csRGBMap& other, int size)
00117 {
00118 other.Clear ();
00119 if (GetMap()) {
00120 other.Alloc (size);
00121 csRGBpixel* m = other.GetArray ();
00122 int i;
00123 for(i=0; i<size; i++)
00124 {
00125 m[i].red = (unsigned char)GetRed()[i];
00126 m[i].green = (unsigned char)GetGreen()[i];
00127 m[i].blue = (unsigned char)GetBlue()[i];
00128 }
00129 }
00130 }
00131 };
00132
00137 class csRadElement : public csObject {
00138 protected:
00139 float area;
00140
00141 float total_unshot_light;
00142
00143 public:
00144 csLightMap *csmap;
00145
00146 protected:
00147 int width, height, size;
00148
00150 csRGBMap *lightmap;
00151
00153 csRGBFloatLightMap *deltamap;
00154
00160 csRGBMap* copy_lightmap;
00161
00163 float one_lumel_area;
00164
00166 float last_shoot_priority;
00167 int num_repeats;
00168
00169 protected:
00170
00172 virtual iMaterialWrapper* GetMaterialWrapper () = 0;
00173
00175 virtual csColor GetFlatColor() const = 0;
00176
00177
00178 virtual void Setup() {};
00179
00180
00181
00182 public:
00183 csRadElement();
00184 ~csRadElement();
00185
00187 inline float GetPriority() { return total_unshot_light; }
00188
00190 inline float GetArea() const { return area; }
00191
00193 inline float GetDiffuse() const { return 0.7f; }
00194
00196 inline int GetWidth() const{ return width; }
00197
00199 inline int GetHeight() const { return height; }
00200
00202 inline int GetSize() const { return size; }
00203
00205 inline bool DeltaIsZero(int suv)
00206 { return !(deltamap->GetRed()[suv] || deltamap->GetGreen()[suv] ||
00207 deltamap->GetBlue()[suv] ); }
00208
00210 virtual csSector* GetSector () const = 0;
00211
00213 virtual const csVector3& GetNormal(int x, int y) const = 0;
00214
00216 csVector3 GetAvgNormal() const;
00217
00219 bool DeltaIsZero(int suv, int w, int h);
00220
00222 void GetTextureColour(int suv, int w, int h, csColor &avg,
00223 csRGBMap *texturemap);
00224
00226 void CapDelta(int suv, int w, int h, float max);
00227
00229 void GetSummedDelta(int suv, int w, int h, csColor& sum);
00230
00232 inline csRGBFloatLightMap* GetDeltaMap() { return deltamap; }
00233
00238 void ShowDeltaMap ();
00239
00244 void RestoreStaticMap ();
00245
00247 inline float GetLastShootingPriority() { return last_shoot_priority;}
00248
00250 inline void SetLastShootingPriority(float val) {last_shoot_priority=val;}
00251
00253 inline int GetRepeatCount() { return num_repeats; }
00254
00256 inline void IncNumRepeats() {num_repeats++;}
00257
00259 virtual void Lumel2World(csVector3& res, int x, int y) = 0;
00260
00262 inline float GetOneLumelArea() const { return one_lumel_area; }
00263
00264
00266 virtual void GetCoverageMatrix(csFrustumView* lview,
00267 csCoverageMatrix* shadow_matrix) = 0;
00268
00274 void ComputePriority();
00275
00280 void AddDelta(csRadElement *src, int suv, int ruv, float fraction,
00281 const csColor& filtercolor);
00282
00286 inline void AddToDelta(int ruv, const csColor& value)
00287 { deltamap->GetRed()[ruv] += value.red;
00288 deltamap->GetGreen()[ruv] += value.green;
00289 deltamap->GetBlue()[ruv] += value.blue;
00290 }
00291
00297 void CopyAndClearDelta();
00298
00302 void GetDeltaSums(float &red, float &green, float &blue);
00303
00307 void ApplyAmbient(int red, int green, int blue);
00308
00313 csRGBMap *ComputeTextureLumelSized();
00314
00316 static csRadElement* GetRadElement(csPolygon3D &object);
00317
00319 static csRadElement* GetRadElement(csCurve &object);
00320 };
00321
00322
00323 SCF_VERSION (csRadPoly, 0, 0, 1);
00324
00329 class csRadPoly : public csRadElement
00330 {
00331 private:
00332 csPolygon3D* polygon;
00333 csSector* sector;
00334 csVector3 lumel_origin, lumel_x_axis, lumel_y_axis;
00335
00336 protected:
00338 virtual iMaterialWrapper * GetMaterialWrapper ()
00339 { return polygon->GetMaterialWrapper (); }
00340
00342 virtual csColor GetFlatColor() const;
00343
00344
00345 virtual void Setup();
00346
00347 public:
00348 csRadPoly(csPolygon3D *original, csSector* sector);
00349 ~csRadPoly();
00350
00352 const csVector3& GetNormal(int x, int y) const
00353 { (void)x; (void)y; return polygon->GetPolyPlane()->Normal();}
00354
00356 inline csPolygon3D *GetPolygon3D() const { return polygon; }
00357
00359 void CalcLumel2World(csVector3& res, int x, int y);
00360
00362 virtual void Lumel2World(csVector3& res, int x, int y);
00363
00364 csSector* GetSector () const { return sector; }
00365
00367 virtual void GetCoverageMatrix(csFrustumView* lview,
00368 csCoverageMatrix* shadow_matrix)
00369 {
00370 (void)lview;
00371 (void)shadow_matrix;
00372 #if 0
00373
00374 GetPolygon3D()->GetLightMapInfo()->GetPolyTex()->
00375 GetCoverageMatrix(*lview, *shadow_matrix);
00376 #endif
00377 }
00378 SCF_DECLARE_IBASE_EXT (csRadElement);
00379 };
00380
00381
00382 SCF_VERSION (csRadCurve, 0, 0, 1);
00383
00388 class csRadCurve : public csRadElement {
00389 private:
00390 csCurve* curve;
00391 csSector* sector;
00392
00393 protected:
00395 virtual iMaterialWrapper * GetMaterialWrapper ()
00396 { return curve->Material; }
00397
00399 virtual csColor GetFlatColor() const
00400 {
00403 return csColor(0.5, 0.5, 0.5);
00404 }
00405
00406 virtual void Setup();
00407
00408 public:
00409 csRadCurve (csCurve* curve, csSector* sector);
00410 ~csRadCurve();
00411
00413 virtual const csVector3& GetNormal(int x, int y) const;
00414
00416 virtual void Lumel2World(csVector3& res, int x, int y);
00417
00418 csSector* GetSector () const { return sector; }
00419
00421 virtual void GetCoverageMatrix(csFrustumView* ,
00422 csCoverageMatrix* )
00423 { }
00424
00425 SCF_DECLARE_IBASE_EXT (csRadElement);
00426 };
00427
00428
00432 class csRadTree{
00433 private:
00434 csRadElement *element;
00435
00436 csRadTree *left, *right;
00437
00439 void DelNode();
00440
00442 csRadTree* FindLeftMost(csRadTree*& parent);
00443
00445 csRadTree* FindRightMost(csRadTree*& parent);
00446
00447 public:
00449 inline csRadTree(csRadElement *n, csRadTree *l, csRadTree *r)
00450 {element = n; left=l; right=r;}
00451
00453 inline ~csRadTree() {if (left) delete left; if (right) delete right;}
00454
00456 void Insert(csRadElement *e);
00457
00459 csRadTree* Delete(csRadElement *e);
00460
00462 csRadTree* PopHighest(csRadElement*& e);
00463
00465 inline float GetPriority() { return element->GetPriority(); }
00466
00468 void TraverseInOrder( void (*func)( csRadElement * ) );
00469 };
00470
00471
00475 class csRadList {
00476 private:
00478 csRadTree *tree;
00480 int num;
00481
00482 public:
00484 csRadList();
00485
00487 ~csRadList();
00488
00490 void InsertElement(csRadElement *e);
00491
00493 void DeleteElement(csRadElement *e);
00494
00496 csRadElement *PopHighest();
00497
00499 void Print();
00500
00502 void Traverse( void (*func)( csRadElement * ) )
00503 { if(tree) tree->TraverseInOrder(func); }
00504
00506 inline int GetElementCount() { return num; }
00507 };
00508
00512 class csRadiosity {
00513 public:
00519 static bool do_static_specular;
00521 static float static_specular_amount;
00527 static int static_specular_tightness;
00528
00534 static float colour_bleed;
00535
00539 static float stop_priority;
00543 static float stop_improvement;
00545 static int stop_iterations;
00546
00550 static int source_patch_size;
00551
00552 private:
00554 csEngine *engine;
00556 csRadList *list;
00557
00562 bool showing_deltamaps;
00563
00565 iProgressMeter *meter;
00567 csProgressPulse *pulse;
00569 float start_priority;
00571 int iterations;
00572
00575 float factor;
00577 csRadElement *shoot_src, *shoot_dest;
00579 csVector3 src_lumel, dest_lumel;
00581 csVector3 src_normal, dest_normal;
00583 float source_poly_patch_area;
00585 int srcp_width, srcp_height;
00587 float source_patch_area;
00589 int src_uv;
00591 int src_x, src_y;
00594 csRGBMap *texturemap;
00596 csCoverageMatrix *shadow_matrix;
00598 csColor trajectory_color;
00600 csColor src_lumel_color;
00602 csColor delta_color;
00603
00604 public:
00606 csRadiosity(csEngine *current_engine, iProgressMeter* meter);
00608 ~csRadiosity();
00610 void DoRadiosity();
00611
00616 bool DoRadiosityStep (int steps);
00618 csPolygon3D* GetNextPolygon ();
00623 void ToggleShowDeltaMaps ();
00628 void RestoreStaticMaps ();
00629
00631 csRadElement* FetchNext();
00633 void StartFrustum();
00635 void ProcessDest(csRadElement *dest, csFrustumView *lview);
00637 void ShootRadiosityToElement(csRadElement* dest);
00639 void PrepareShootSource(csRadElement* src);
00641 bool PrepareShootDest(csRadElement* dest, csFrustumView *lview);
00643 void PrepareShootSourceLumel(int sx, int sy, int suv);
00645 void ShootPatch(int rx, int ry, int ruv);
00646
00647
00649 void ApplyDeltaAndAmbient();
00651 void RemoveAmbient();
00652
00653 };
00654
00655 #endif
00656
00657 #endif // __CS_RADIOSTY_H__