00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "std3d.h"
00027
00028 #include "3d/surface_light_grid.h"
00029 #include "nel/misc/common.h"
00030 #include "3d/ig_surface_light.h"
00031 #include "3d/fast_floor.h"
00032 #include "3d/light_influence_interpolator.h"
00033 #include "3d/point_light_named.h"
00034 #include "3d/scene_group.h"
00035
00036
00037 using namespace NLMISC;
00038
00039 namespace NL3D {
00040
00041
00042
00043 CSurfaceLightGrid::CSurfaceLightGrid()
00044 {
00045 Width= 0;
00046 Height= 0;
00047 }
00048
00049
00050
00051 void CSurfaceLightGrid::serial(NLMISC::IStream &f)
00052 {
00053 (void)f.serialVersion(0);
00054 f.serial(Origin);
00055 f.serial(Width);
00056 f.serial(Height);
00057 f.serial(Cells);
00058 }
00059
00060
00061
00062 void CSurfaceLightGrid::getStaticLightSetup(const CVector &localPos, std::vector<CPointLightInfluence> &pointLightList, uint8 &sunContribution,
00063 CIGSurfaceLight &igsl, NLMISC::CRGBA &localAmbient) const
00064 {
00065
00066 float xfloat= (localPos.x - Origin.x) * igsl.getOOCellSize();
00067 float yfloat= (localPos.y - Origin.y) * igsl.getOOCellSize();
00068 sint wCell= Width-1;
00069 sint hCell= Height-1;
00070
00071 sint wfixed= wCell<<8;
00072 sint hfixed= hCell<<8;
00073 sint xfixed= OptFastFloor(xfloat * 256);
00074 sint yfixed= OptFastFloor(yfloat * 256);
00075 clamp(xfixed, 0, wfixed);
00076 clamp(yfixed, 0, hfixed);
00077
00078 sint xCell, yCell, xSub, ySub;
00079 xCell= xfixed>>8;
00080 yCell= yfixed>>8;
00081 clamp(xCell, 0, wCell-1);
00082 clamp(yCell, 0, hCell-1);
00083
00084 xSub= xfixed - (xCell<<8);
00085 ySub= yfixed - (yCell<<8);
00086
00087
00088
00089 CLightInfluenceInterpolator interp;
00090
00091 nlassert(CSurfaceLightGrid::NumLightPerCorner==2);
00092 nlassert(CLightInfluenceInterpolator::NumLightPerCorner==2);
00093
00094 CPointLightNamed *igPointLights= NULL;;
00095 if( igsl._Owner->getPointLightList().size() >0 )
00096 {
00097
00098
00099 igPointLights= const_cast<CPointLightNamed*>(&(igsl._Owner->getPointLightList()[0]));
00100 }
00101
00102 uint x,y;
00103 uint sunContribFixed= 0;
00104 uint rLocalAmbientFixed= 0;
00105 uint gLocalAmbientFixed= 0;
00106 uint bLocalAmbientFixed= 0;
00107 uint aLocalAmbientFixed= 0;
00108 for(y=0;y<2;y++)
00109 {
00110 for(x=0;x<2;x++)
00111 {
00112
00113
00114
00115 const CCellCorner &cellCorner= Cells[ (yCell+y)*Width + xCell+x ];
00116 CLightInfluenceInterpolator::CCorner &corner= interp.Corners[y*2 + x];
00117
00118 uint lid;
00119 for(lid= 0; lid<CSurfaceLightGrid::NumLightPerCorner; lid++)
00120 {
00121
00122 uint igLightId= cellCorner.Light[lid];
00123
00124 if(igLightId==0xFF)
00125 break;
00126 else
00127 {
00128
00129 corner.Lights[lid]= igPointLights + igLightId;
00130 }
00131 }
00132
00133 for(; lid<CSurfaceLightGrid::NumLightPerCorner; lid++)
00134 {
00135
00136 corner.Lights[lid]= NULL;
00137 }
00138
00139
00140
00141 uint xBi= (x==0)?256-xSub : xSub;
00142 uint yBi= (y==0)?256-ySub : ySub;
00143 uint mulBi= xBi * yBi;
00144 sunContribFixed+= cellCorner.SunContribution * mulBi;
00145
00146
00147
00148
00149
00150 if(cellCorner.LocalAmbientId!=0xFF)
00151 {
00152
00153 CRGBA ambCorner= igPointLights[cellCorner.LocalAmbientId].getAmbient();
00154 rLocalAmbientFixed+= ambCorner.R * mulBi;
00155 gLocalAmbientFixed+= ambCorner.G * mulBi;
00156 bLocalAmbientFixed+= ambCorner.B * mulBi;
00157
00158 aLocalAmbientFixed+= 255 * mulBi;
00159 }
00160 }
00161 }
00162
00163 interp.interpolate(pointLightList, xSub/256.f, ySub/256.f);
00164
00165
00166 sunContribution= sunContribFixed>>16;
00167
00168
00169 localAmbient.R= rLocalAmbientFixed>>16;
00170 localAmbient.G= gLocalAmbientFixed>>16;
00171 localAmbient.B= bLocalAmbientFixed>>16;
00172 localAmbient.A= aLocalAmbientFixed>>16;
00173
00174 }
00175
00176
00177
00178 }