# 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  

point_light_model.cpp

Go to the documentation of this file.
00001 
00007 /* Copyright, 2001 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/point_light_model.h"
00029 #include "3d/light_trav.h"
00030 #include "3d/root_model.h"
00031 #include "3d/skeleton_model.h"
00032 
00033 
00034 namespace NL3D {
00035 
00036 
00037 // ***************************************************************************
00038 void    CPointLightModel::registerBasic()
00039 {
00040         CMOT::registerModel( PointLightModelId, TransformId, CPointLightModel::creator);
00041         CMOT::registerObs( LightTravId,                 PointLightModelId, CPointLightModelLightObs::creator );
00042 }
00043 
00044 // ***************************************************************************
00045 CPointLightModel::CPointLightModel()
00046 {
00047         _DeltaPosToSkeletonWhenOutOfFrustum.set(0, 0, 1.5f);
00048         _TimeFromLastClippedSpotDirection= 0;
00049 }
00050 
00051 
00052 // ***************************************************************************
00053 CPointLightModel::~CPointLightModel()
00054 {
00055 }
00056 
00057 
00058 // ***************************************************************************
00059 void    CPointLightModel::initModel()
00060 {
00061         CTransform::initModel();
00062 
00063         // link to the LightModelRoot in the lightTrav.
00064         IObs            *obs= getObs(LightTravId);
00065         CLightTrav      *lightTrav= (CLightTrav*)obs->Trav;
00066         nlassert( lightTrav->LightModelRoot );
00067         // link me to the root of light.
00068         lightTrav->link(lightTrav->LightModelRoot, this);
00069         
00070 }
00071 
00072 
00073 // ***************************************************************************
00074 void                    CPointLightModel::setDeltaPosToSkeletonWhenOutOfFrustum(const CVector &deltaPos)
00075 {
00076         _DeltaPosToSkeletonWhenOutOfFrustum= deltaPos;
00077 }
00078 
00079 
00080 // ***************************************************************************
00081 const CVector   &CPointLightModel::getDeltaPosToSkeletonWhenOutOfFrustum() const
00082 {
00083         return _DeltaPosToSkeletonWhenOutOfFrustum;
00084 }
00085 
00086 
00087 // ***************************************************************************
00088 void    CPointLightModelLightObs::traverse(IObs *caller)
00089 {
00090         CPointLightModel        *plModel= (CPointLightModel*)Model;
00091         CLightTrav                      *lightTrav= (CLightTrav*)Trav;
00092 
00093         // Note: any dynamic light is supposed to always move each frame, so they are re-inserted in the 
00094         // quadGrid each frame.
00095 
00096 
00097         // reset all models lighted by this light.
00098         // Then models are marked dirty and their light setup is reseted
00099         plModel->PointLight.resetLightedModels();
00100 
00101 
00102         // if the light is visible (ie not hiden)
00103         if( plModel->isHrcVisible() )
00104         {
00105                 // If the light is not hidden by any skeleton.
00106                 if( plModel->isClipVisible() )
00107                 {
00108                         // recompute the worldPosition of the light.
00109                         plModel->PointLight.setPosition( plModel->getWorldMatrix().getPos() );
00110 
00111                         // recompute the worldSpotDirection of the light.
00112                         if(plModel->PointLight.getType() == CPointLight::SpotLight)
00113                         {
00114                                 // Interpolate over time. (hardcoded)
00115                                 plModel->_TimeFromLastClippedSpotDirection-= 0.05f;
00116                                 if(plModel->_TimeFromLastClippedSpotDirection <= 0)
00117                                 {
00118                                         plModel->PointLight.setupSpotDirection(plModel->getWorldMatrix().getJ());
00119                                 }
00120                                 else
00121                                 {
00122                                         CVector         actualSpotDir= plModel->getWorldMatrix().getJ();
00123                                         // Interpolate
00124                                         float   t= plModel->_TimeFromLastClippedSpotDirection;
00125                                         CVector         interpSpotDir= actualSpotDir*(1-t) + plModel->_LastWorldSpotDirectionWhenOutOfFrustum * t;
00126                                         // set the interpolated one.
00127                                         plModel->PointLight.setupSpotDirection(interpSpotDir);
00128                                 }
00129                         }
00130                 }
00131                 else
00132                 {
00133                         // We are hidden because a skeleton has hide us (or else don't know why).
00134                         nlassert(plModel->getHrcObs()->_AncestorSkeletonModel);
00135                         const CMatrix &skMatrix= plModel->getHrcObs()->_AncestorSkeletonModel->getWorldMatrix();
00136 
00137                         plModel->PointLight.setPosition( skMatrix * plModel->_DeltaPosToSkeletonWhenOutOfFrustum );
00138 
00139                         // recompute the worldSpotDirection of the light.
00140                         if(plModel->PointLight.getType() == CPointLight::SpotLight)
00141                         {
00142                                 // If last frame, this pointLight was visible (Time is not 1)
00143                                 if(plModel->_TimeFromLastClippedSpotDirection != 1)
00144                                 {
00145                                         // Take the current World spot direction
00146                                         plModel->_LastWorldSpotDirectionWhenOutOfFrustum= plModel->PointLight.getSpotDirection();
00147                                         // reset time.
00148                                         plModel->_TimeFromLastClippedSpotDirection= 1;
00149                                 }
00150 
00151                                 // Don't need to modify PointLight spot direction since already setuped (when model was visible)
00152                         }
00153                 }
00154 
00155                 // now, insert this light in the quadGrid. NB: in CLightTrav::traverse(), the quadGrid is cleared before here.
00156                 // This light will touch (resetLighting()) any model it may influence.
00157                 lightTrav->LightingManager.addDynamicLight(&plModel->PointLight);
00158         }
00159 
00160 }
00161 
00162 
00163 
00164 } // NL3D