00001 /* 00002 File: GenLink.cc 00003 00004 Function: 00005 00006 Author: Andrew Willmott 00007 00008 Notes: 00009 */ 00010 00011 #include "GenLink.h" 00012 #include "HRElem.h" 00013 #include "Cluster.h" 00014 #include "RadMethod.h" 00015 00016 #define DBG_COUT if (0) cerr 00017 00018 #define RAD_NON_ISO_SOURCE 00019 #define RAD_NON_ISO_DEST 00020 // the above should always be defined, except for experiments showing how 00021 // bad the isotropic assumption is =) 00022 00023 // --- GenLink methods ---------------------------------------------------- 00024 00025 00026 Bool GenLink::CalcTransport() 00027 { 00028 Assert(to->NumCoeffs() == 1, "can't handle non-haar receiver yet"); 00029 Assert(from->NumCoeffs() == 1, "can't handle non-haar source yet"); 00030 Matd T(to->NumCoeffs(), from->NumCoeffs(), &transport); 00031 00032 error = to->EltCalcTransport(from, T); 00033 00034 Assert(vl_is_finite(transport), "bad transport coeff!!!"); 00035 00036 DBG_COUT << "transport = " << T << "error = " << error << ", vis = " 00037 << visibility << endl; 00038 00039 #ifdef RAD_VIS 00040 if (gRadControl->showLinks) 00041 { 00042 Int s1 = from->eltHighlight, s2 = to->eltHighlight; 00043 00044 from->SetHighlight(3); 00045 to->SetHighlight(2); 00046 00047 RM_DISPLAY_START; 00048 gRadControl->radObject->display->Begin(renLines) 00049 .C(cRed) 00050 .P(from->EltCentre()).P(to->EltCentre()) 00051 .End(); 00052 RM_DISPLAY_END; 00053 00054 RM_OUT1("Link transport/error: " << transport << " / " << error); 00055 RM_OUT2("Link Power: " << from->EltBA() << " -> " << to->EltBA()); 00056 RM_OUT3(BFAError()); 00057 if (RM_PAUSE) return(false); 00058 00059 from->SetHighlight(s1); 00060 to->SetHighlight(s2); 00061 } 00062 #endif 00063 00064 // if there's some error, keep the link around even if it's zero 00065 return(transport > 0.0 || error > 0.0); 00066 } 00067 00068 Bool GenLink::CalcVisibility(HRLink *parent, Bool reuse) 00069 { 00070 Bool result = HRLink::CalcVisibility(parent, reuse); 00071 00072 transport *= visibility; 00073 00074 return(result); 00075 } 00076 00077 Void GenLink::Gather() 00078 { 00079 Colour srcB; 00080 00081 // find irradiance at (to) 00082 // XXX generalise 00083 srcB = from->B_Coeffs()[0] * transport; 00084 00085 Assert(vl_is_finite(srcB[0]) && vl_is_finite(srcB[1]) && vl_is_finite(srcB[2]), 00086 "bad srcB coeffs"); 00087 00088 #ifdef RAD_NON_ISO_DEST 00089 if (to->IsCluster() && (from != to)) 00090 { 00091 // destination is a cluster: push radiosity to leaves to get 00092 // proper directional distribution on the destination... 00093 00094 Vector r = from->EltCentre() - to->EltCentre(); 00095 GCLReal rLen = len(r); 00096 00097 // r is unit vector from to -> from 00098 if (rLen > 0.0) 00099 r /= rLen; 00100 else 00101 Expect(false, "zero separation between source and destination elems."); 00102 00103 if (sqrlen(srcB) > 0.0) 00104 to->AddIrradiance(srcB, r); 00105 } 00106 else 00107 #endif 00108 { 00109 // XXX generalise 00110 to->R_Coeffs()[0] += srcB; 00111 DBG_COUT << "Gather: Dest(" << to->flags << ") updated to " 00112 << to->R_Coeffs()[0] << " from " 00113 << from->B_Coeffs()[0] << " (" << to->flags << ")" << endl; 00114 } 00115 00116 #ifdef DEBUG 00117 srcB = (to->R_Coeffs()[0]); 00118 Assert(vl_is_finite(srcB[0]) && vl_is_finite(srcB[1]) && vl_is_finite(srcB[2]), 00119 "bad R coeffs"); 00120 #endif 00121 } 00122 00123 GCLReal GenLink::Error() 00124 { 00125 return(error); 00126 } 00127 00128 GCLReal GenLink::BFAError() 00129 { 00130 GCLReal result; 00131 00132 DBG_COUT << "BFErr: area error rho from->BA = " 00133 << to->EltArea() << ' ' 00134 << error << ' ' 00135 << to->EltRho() << ' ' 00136 << from->EltBA() << endl; 00137 00138 result = to->EltArea() * error * 00139 dot(kRadRGBToLum, to->EltRho() * from->EltBA() / from->EltArea()); 00140 00141 DBG_COUT << "BFErr: result = " << result << endl; 00142 00143 return(result); 00144 } 00145 00146 RefChoice GenLink::RefineOracle() 00147 { 00148 // force refinement of mixed clusters, a la Gibson 00149 00150 if (from->flags.AreSet(hrMixed)) 00151 { 00152 if (from == to) 00153 return(kSubBoth); 00154 else 00155 return(kSubFrom); 00156 } 00157 else 00158 return(HRLink::RefineOracle()); 00159 }