Main Page | Modules | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members | Related Pages
vertexlight.h
00001 /* 00002 Copyright (C) 2005 by Marten Svanfeldt 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_VERTEXLIGHT_H__ 00020 #define __CS_VERTEXLIGHT_H__ 00021 00022 #include "csgeom/math.h" 00023 #include "csgeom/vector3.h" 00024 #include "iengine/movable.h" 00025 #include "iengine/light.h" 00026 00027 // Attenuation functors 00028 00032 struct CS_CSGFX_EXPORT csNoAttenuation 00033 { 00034 csNoAttenuation (iLight *light) 00035 {} 00036 00037 CS_FORCEINLINE void operator() (float distance, float &dp) const 00038 {} 00039 }; 00040 00045 struct CS_CSGFX_EXPORT csLinearAttenuation 00046 { 00047 csLinearAttenuation (iLight *light) 00048 { 00049 invrad = 1/light->GetAttenuationConstants ().x; 00050 } 00051 00052 CS_FORCEINLINE void operator() (float distance, float& dp) const 00053 { 00054 dp = dp * (1 - distance * invrad); 00055 } 00056 00057 float invrad; 00058 }; 00059 00064 struct CS_CSGFX_EXPORT csInverseAttenuation 00065 { 00066 csInverseAttenuation (iLight *light) 00067 {} 00068 00069 CS_FORCEINLINE void operator() (float distance, float& dp) const 00070 { 00071 dp = dp / distance; 00072 } 00073 }; 00074 00075 00080 struct CS_CSGFX_EXPORT csRealisticAttenuation 00081 { 00082 csRealisticAttenuation (iLight *light) 00083 {} 00084 00085 CS_FORCEINLINE void operator() (float distance, float& dp) const 00086 { 00087 dp = dp / (distance*distance); 00088 } 00089 }; 00090 00095 struct CS_CSGFX_EXPORT csCLQAttenuation 00096 { 00097 csCLQAttenuation (iLight *light) 00098 : attnVec (light->GetAttenuationConstants ()) 00099 {} 00100 00101 CS_FORCEINLINE void operator() (float distance, float& dp) const 00102 { 00103 dp = dp/(csVector3 (1.0, distance, distance*distance)*attnVec); 00104 } 00105 00106 csVector3 attnVec; 00107 }; 00108 00114 template<class AttenuationProc> 00115 class csPointLightProc 00116 { 00117 public: 00118 csPointLightProc (iLight *light, iMovable *objectMovable, 00119 float blackLimit = 0.0001f) 00120 : attn (light), nullColor (0.0f, 0.0f, 0.0f), blackLimit (blackLimit) 00121 { 00122 csReversibleTransform objT = objectMovable->GetFullTransform (); 00123 lightPos = objT.Other2This (light->GetMovable ()->GetFullPosition ()); 00124 lightCol = light->GetColor (); 00125 } 00126 00127 CS_FORCEINLINE 00128 csColor ProcessVertex (const csVector3 &v,const csVector3 &n) const 00129 { 00130 //compute gouraud shading.. 00131 csVector3 direction = v-lightPos; 00132 float distance = csQsqrt(direction.SquaredNorm ()); 00133 float dp = direction*n/distance; 00134 if (dp > blackLimit) 00135 { 00136 attn (distance, dp); 00137 return lightCol*dp; 00138 } 00139 return nullColor; 00140 } 00141 00142 private: 00143 AttenuationProc attn; 00144 csVector3 lightPos; //localspace 00145 csColor lightCol; 00146 csColor nullColor; 00147 float blackLimit; 00148 }; 00149 00155 template<class AttenuationProc> 00156 class csDirectionalLightProc 00157 { 00158 public: 00159 csDirectionalLightProc (iLight *light, iMovable *objectMovable, 00160 float blackLimit = 0.0001f) 00161 : attn (light), nullColor (0.0f, 0.0f, 0.0f), blackLimit (blackLimit) 00162 { 00163 csReversibleTransform objT = objectMovable->GetFullTransform (); 00164 csReversibleTransform lightT = light->GetMovable ()->GetFullTransform (); 00165 lightPos = objT.Other2This (lightT.GetOrigin ()); 00166 lightDir = objT.Other2ThisRelative (lightT.This2OtherRelative ( 00167 light->GetDirection ())); 00168 lightDir = lightDir.Unit (); 00169 lightCol = light->GetColor (); 00170 } 00171 00172 CS_FORCEINLINE 00173 csColor ProcessVertex (const csVector3 &v,const csVector3 &n) const 00174 { 00175 //compute gouraud shading.. 00176 float dp = lightDir*n; 00177 if (dp > blackLimit) 00178 { 00179 csVector3 direction = v-lightPos; 00180 float distance = csQsqrt(direction.SquaredNorm ()); 00181 attn (distance, dp); 00182 return lightCol*dp; 00183 } 00184 return nullColor; 00185 } 00186 00187 private: 00188 AttenuationProc attn; 00189 csVector3 lightPos; //localspace 00190 csVector3 lightDir; //localspace 00191 csColor lightCol; 00192 csColor nullColor; 00193 float blackLimit; 00194 }; 00195 00201 template<class AttenuationProc> 00202 class csSpotLightProc 00203 { 00204 public: 00205 csSpotLightProc (iLight *light, iMovable *objectMovable, 00206 float blackLimit = 0.0001f) 00207 : attn (light), nullColor (0.0f, 0.0f, 0.0f), blackLimit (blackLimit) 00208 { 00209 csReversibleTransform objT = objectMovable->GetFullTransform (); 00210 csReversibleTransform lightT = light->GetMovable ()->GetFullTransform (); 00211 lightPos = objT.Other2This (lightT.GetOrigin ()); 00212 lightDir = objT.Other2ThisRelative (lightT.This2OtherRelative ( 00213 light->GetDirection ())); 00214 lightDir = lightDir.Unit (); 00215 00216 lightCol = light->GetColor (); 00217 light->GetSpotLightFalloff (falloffInner, falloffOuter); 00218 } 00219 00220 CS_FORCEINLINE 00221 csColor ProcessVertex (const csVector3 &v,const csVector3 &n) const 00222 { 00223 csVector3 direction = (v-lightPos).Unit (); 00224 00225 //compute gouraud shading.. 00226 float dp = direction*n; 00227 if (dp > blackLimit) 00228 { 00229 float cosfact = 00230 csSmoothStep (-(direction*lightDir), falloffOuter, falloffInner); 00231 float distance = csQsqrt(direction.SquaredNorm ()); 00232 if (cosfact > 0) 00233 { 00234 attn (distance, dp); 00235 return lightCol*dp*cosfact; 00236 } 00237 } 00238 return nullColor; 00239 } 00240 00241 private: 00242 AttenuationProc attn; 00243 csVector3 lightPos; //localspace 00244 csVector3 lightDir; //localspace 00245 csColor lightCol; 00246 csColor nullColor; 00247 float blackLimit; 00248 float falloffInner, falloffOuter; 00249 }; 00250 00251 template<class LightProc, class VertexType = csVector3, 00252 class ColorType = csColor> 00253 class csVertexLightCalculator 00254 { 00255 public: 00256 csVertexLightCalculator () 00257 { 00258 } 00259 00260 void CalculateLighting (iLight *light, iMovable *objectMovable, 00261 size_t numvert, VertexType *vb, csVector3 *nb, ColorType *litColor) const 00262 { 00263 // setup the light calculator 00264 LightProc lighter (light, objectMovable); 00265 00266 for (size_t n = 0; n < numvert; n++) 00267 { 00268 litColor[n] = lighter.ProcessVertex (vb[n], nb[n]); 00269 } 00270 } 00271 00272 void CalculateLightingAdd (iLight *light, iMovable *objectMovable, 00273 size_t numvert, VertexType *vb, csVector3 *nb, ColorType *litColor) const 00274 { 00275 // setup the light calculator 00276 LightProc lighter (light, objectMovable); 00277 00278 for (size_t n = 0; n < numvert; n++) 00279 { 00280 litColor[n] += lighter.ProcessVertex (vb[n], nb[n]); 00281 } 00282 } 00283 00284 void CalculateLightingMul (iLight *light, iMovable *objectMovable, 00285 size_t numvert, VertexType *vb, csVector3 *nb, ColorType *litColor) const 00286 { 00287 // setup the light calculator 00288 LightProc lighter (light, objectMovable); 00289 00290 for (size_t n = 0; n < numvert; n++) 00291 { 00292 litColor[n] *= lighter.ProcessVertex (vb[n], nb[n]); 00293 } 00294 } 00295 }; 00296 00297 #endif //__CS_VERTEXLIGHT_H__
Generated for Crystal Space by doxygen 1.3.9.1