|
radiosty.h00001 /* 00002 Copyright (C) 2000 by W.C.A. Wijngaards 00003 00004 This library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Library General Public 00006 License as published by the Free Software Foundation; either 00007 version 2 of the License, or (at your option) any later version. 00008 00009 This library is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 Library General Public License for more details. 00013 00014 You should have received a copy of the GNU Library General Public 00015 License along with this library; if not, write to the Free 00016 Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 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; // Max size for every map. 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; // diffuse * area * avg_delta_level 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 // setup some necessary values 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.7f; } 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 // setup some necessary values 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 // @@@@@@@@@@@ REWRITE 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* /*(lview*/, 00423 csCoverageMatrix* /*shadow_matrix*/) 00424 { /* @@@ curve->GetCoverageMatrix(*lview, *shadow_matrix); */ } 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__ Generated for Crystal Space by doxygen 1.2.5 written by Dimitri van Heesch, ©1997-2000 |