# Home    # nevrax.com   
Nevrax
Nevrax.org
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
Docs
 
Documentation  
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  

surface_light_grid.cpp

Go to the documentation of this file.
00001 
00007 /* Copyright, 2000-2002 Nevrax Ltd.
00008  *
00009  * This file is part of NEVRAX NEL.
00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2, or (at your option)
00013  * any later version.
00014 
00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00018  * General Public License for more details.
00019 
00020  * You should have received a copy of the GNU General Public License
00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00023  * MA 02111-1307, USA.
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         // Get local coordinate to the grid.
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         // fastFloor: use a precision of 256 to avoid doing OptFastFloorBegin.
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         // compute the cell coord, and the subCoord for bilinear.
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         // Hence, xSub and ySub range is [0, 256].
00084         xSub= xfixed - (xCell<<8);
00085         ySub= yfixed - (yCell<<8);
00086 
00087 
00088         // Use a CLightInfluenceInterpolator to biLinear light influence
00089         CLightInfluenceInterpolator             interp;
00090         // Must support only 2 light per cell corner.
00091         nlassert(CSurfaceLightGrid::NumLightPerCorner==2);
00092         nlassert(CLightInfluenceInterpolator::NumLightPerCorner==2);
00093         // Get ref on array of PointLightNamed.
00094         CPointLightNamed        *igPointLights= NULL;;
00095         if( igsl._Owner->getPointLightList().size() >0 )
00096         {
00097                 // const_cast, because will only change _IdInfluence, and 
00098                 // also because CLightingManager will call appendLightedModel()
00099                 igPointLights= const_cast<CPointLightNamed*>(&(igsl._Owner->getPointLightList()[0]));
00100         }
00101         // For 4 corners.
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                         // Prepare compute for PointLights.
00113                         //-------------
00114                         // get ref on TLI, and on corner.
00115                         const CCellCorner                                               &cellCorner= Cells[ (yCell+y)*Width + xCell+x ];
00116                         CLightInfluenceInterpolator::CCorner    &corner= interp.Corners[y*2 + x];
00117                         // For all lights
00118                         uint lid;
00119                         for(lid= 0; lid<CSurfaceLightGrid::NumLightPerCorner; lid++)
00120                         {
00121                                 // get the id of the light in the ig
00122                                 uint    igLightId= cellCorner.Light[lid];
00123                                 // If empty id, stop
00124                                 if(igLightId==0xFF)
00125                                         break;
00126                                 else
00127                                 {
00128                                         // Set pointer of the light in the corner
00129                                         corner.Lights[lid]= igPointLights + igLightId;
00130                                 }
00131                         }
00132                         // Reset Empty slots.
00133                         for(; lid<CSurfaceLightGrid::NumLightPerCorner; lid++)
00134                         {
00135                                 // set to NULL
00136                                 corner.Lights[lid]= NULL;
00137                         }
00138 
00139                         // BiLinear SunContribution.
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                         // BiLinear Ambient Contribution.
00148                         //-------------
00149                         // If FF, then take Sun Ambient => leave color and alpha To 0.
00150                         if(cellCorner.LocalAmbientId!=0xFF)
00151                         {
00152                                 // take current ambient from pointLight
00153                                 CRGBA   ambCorner= igPointLights[cellCorner.LocalAmbientId].getAmbient();
00154                                 rLocalAmbientFixed+= ambCorner.R * mulBi;
00155                                 gLocalAmbientFixed+= ambCorner.G * mulBi;
00156                                 bLocalAmbientFixed+= ambCorner.B * mulBi;
00157                                 // increase the influence of igPointLights in alpha
00158                                 aLocalAmbientFixed+= 255 * mulBi;
00159                         }
00160                 }
00161         }
00162         // interpolate PointLights.
00163         interp.interpolate(pointLightList, xSub/256.f, ySub/256.f);
00164 
00165         // Final SunContribution
00166         sunContribution= sunContribFixed>>16;
00167 
00168         // Final SunContribution
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 } // NL3D