176 lines
6.3 KiB
C++
176 lines
6.3 KiB
C++
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
|
|
// Copyright (C) 2010 Winch Gate Property Limited
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU Affero General Public License as
|
|
// published by the Free Software Foundation, either version 3 of the
|
|
// License, or (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU Affero General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Affero General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
#ifndef NL_SHADOW_MAP_H
|
|
#define NL_SHADOW_MAP_H
|
|
|
|
#include "nel/misc/types_nl.h"
|
|
#include "nel/3d/texture.h"
|
|
#include "nel/3d/vertex_buffer.h"
|
|
#include "nel/misc/aabbox.h"
|
|
|
|
|
|
namespace NL3D
|
|
{
|
|
|
|
|
|
using NLMISC::CPlane;
|
|
using NLMISC::CRefPtr;
|
|
using NLMISC::CAABBox;
|
|
|
|
class CShadowMapManager;
|
|
class CMaterial;
|
|
|
|
|
|
// ***************************************************************************
|
|
/**
|
|
* This class encapsulate all Data generated by a Shadow Caster, and read for a Shadow Receiver.
|
|
* \author Lionel Berenguier
|
|
* \author Nevrax France
|
|
* \date 2003
|
|
*/
|
|
class CShadowMap
|
|
{
|
|
public:
|
|
/** Computed at shadow casting time. The matrix used to cast the Shadow.
|
|
* It is actualy a World ProjectionMatrix, but is only local to the Position of the Model (not rotation/scale).
|
|
* Hence receiver have to add the position of the caster model to this matrix to get true World.
|
|
* The usage of this matrix is for UV projection: XYZ= WorldProjectionMatrix * UVW.
|
|
* NB: Vj (ie for W) is mapped such that Vp means NearClip of the shadow and Vp+Vj means FarClip of the shadow
|
|
*/
|
|
CMatrix LocalProjectionMatrix;
|
|
|
|
/** Computed at shadow casting time. They are clipping planes used to clip receivers (mirror of the OBB).
|
|
* Receivers may use them to clip sub received parts (as they which)
|
|
* Like the ProjectionLocalMatrix, this plane are in World, but the position of the Caster model.
|
|
* \see generateClipInfoFromMatrix()
|
|
*/
|
|
std::vector<CPlane> LocalClipPlanes;
|
|
|
|
/** Computed at shadow casting time. This is the LocalPos Bouding Box containing the shadow (AxisAligned).
|
|
* \see generateClipInfoFromMatrix()
|
|
*/
|
|
CAABBox LocalBoundingBox;
|
|
|
|
|
|
// Filled by ShadowMapManager. This is the Last Frame Id we had update the texture.
|
|
uint64 LastGenerationFrame;
|
|
|
|
|
|
/** They are the fade of the shadowMap, for Lod Shadow display. 0-1 values.
|
|
* NB: if DistanceFade==1 or TemporalOutScreenFade==1, then the ShadowMap Texture is released.
|
|
* Final Fade is the max of the 3.
|
|
*/
|
|
// Value computed according to pos of skeleton and Max Shadow Display value.
|
|
float DistanceFade;
|
|
// Value computed according to pos of skeleton and other skeletons in the area (whatever the visible state)
|
|
float TemporalOutScreenFade;
|
|
// Value computed according to pos of skeleton and other skeletons in the frustum
|
|
float TemporalInScreenFade;
|
|
/** This value represent the fade time we don't know what to do with TemporalInScreenFade because the
|
|
* shadowMap is not visible or frustum-clipped.
|
|
* Once the shadowMap will be visible again, This will be add/removed (according to TemporalInScreenFade
|
|
* rules) to the TemporalInScreenFade.
|
|
* NB: by default the value is 1 so the initial state is correct when you enable cast shadowMap!
|
|
*/
|
|
float InScreenFadeAccum;
|
|
|
|
public:
|
|
|
|
/// Constructor. NB: ptr is owned => shadowMap should no still live while smm dead.
|
|
CShadowMap(CShadowMapManager *smm);
|
|
~CShadowMap();
|
|
|
|
/// create the Texture. It reset the texture if not of same size.
|
|
void initTexture(uint textSize);
|
|
/// reset the Texture
|
|
void resetTexture();
|
|
/// get the TextureSize
|
|
uint32 getTextureSize() const {return _TextSize;}
|
|
|
|
/// You can only get the texture for filling / use in a material.
|
|
ITexture *getTexture() const {return _Texture;}
|
|
|
|
|
|
/// /name Tools
|
|
// @{
|
|
/** From A BBox in Object Space, the lightDir, and the (nearly) worldMatrix, build the Camera for common Render Projection
|
|
* The caller has then just to do
|
|
* driver->setFrustum(0,1,0,1,0,1,false);
|
|
* driver->setupViewMatrix(cameraMatrix.inverted());
|
|
* driver->setupModelMatrix(localPosMatrix);
|
|
* Then render his mesh.
|
|
*/
|
|
void buildCasterCameraMatrix(const CVector &lightDir, const CMatrix &localPosMatrix, const CAABBox &bbShape, CMatrix &cameraMatrix);
|
|
|
|
/** From the Camera matrix computed with buildCasterCameraMatrix, compute the LocalProjectionMatrix, which modify the
|
|
* J axis according to backPoint and Shadow Depth.
|
|
* NB: automatically calls the buildClipInfoFromMatrix() method
|
|
*/
|
|
void buildProjectionInfos(const CMatrix &cameraMatrix, const CVector &backPoint, float shadowMaxDepth);
|
|
|
|
/** The ShadowMap Caster can call this method after setting LocalProjectionMatrix. It computes auto the
|
|
* LocalClipPlanes and LocalBoundingBox from it. NB: don't use it if you use buildProjectionInfos().
|
|
*/
|
|
void buildClipInfoFromMatrix();
|
|
// @}
|
|
|
|
/** Clamp Fades to 0-1. Additionaly reset the texture if DistanceFade>=1 or TemporalOutScreenFade>=1
|
|
* See Implementation for Why. Additionally compile getFadeAround() and getFadeInScreen()
|
|
*/
|
|
void processFades();
|
|
|
|
/// return compiled max of DistanceFade and TemporalOutScreenFade.
|
|
float getFadeAround() const {return _FadeAround;}
|
|
/// same but maximize with the TemporalInScreenFade;
|
|
float getFinalFade() const {return _FinalFade;}
|
|
|
|
// *************
|
|
private:
|
|
NLMISC::CSmartPtr<ITexture> _Texture;
|
|
uint32 _TextSize;
|
|
CShadowMapManager *_ShadowMapManager;
|
|
float _FadeAround;
|
|
float _FinalFade;
|
|
|
|
};
|
|
|
|
|
|
// ***************************************************************************
|
|
/** Used to recompute the projection matrix, according to the receiver worldMatrix
|
|
* The problem is material don't support WorldSpace Coordinate Generation, but ObjectSpace ones.
|
|
* Hence must take back the coordinate in ObjectSpace before set textMat.
|
|
*/
|
|
class CShadowMapProjector
|
|
{
|
|
public:
|
|
CShadowMapProjector();
|
|
void setWorldSpaceTextMat(const CMatrix &ws);
|
|
void applyToMaterial(const CMatrix &receiverWorldMatrix, CMaterial &material);
|
|
|
|
private:
|
|
CMatrix _WsTextMat;
|
|
CMatrix _XYZToUWVMatrix;
|
|
CMatrix _XYZToWUVMatrix;
|
|
};
|
|
|
|
|
|
} // NL3D
|
|
|
|
|
|
#endif // NL_SHADOW_MAP_H
|
|
|
|
/* End of shadow_map.h */
|