#ifndef __I3DSHENVIRONMENT__
#define __I3DSHENVIRONMENT__
/****************************************************************************************

		I3DShEnvironment.h

		Copyright: (c) 2001 Eovia Corp. All rights reserved.

		I3DShEnvironment definition
		I3DShAmbientLight definition
		I3DShAtmosphericShader definition
		I3DShBackground definition
		I3DShBackdrop definition

		Author:	Ray Dream
		Date:	3/2/98

		Revision History

		when		who			what & why
		==========	==========	======================================================
		7/6/99		Pierre-E	modification of the identifier in the methods SegmentFilter
								and DirectionFilter: filterOut --> inOutFilter

*****************************************************************************************/

#if CP_PRAGMA_ONCE
#pragma once
#endif

#include "COMTypes.h"
#include "APITypes.h"
#include "MCColorRGB.h"
#include "Vector2Fwd.h"

struct I3DShScene;
struct Ray3D;
struct TColorRGBLinearEffect;

class TBBox2D;
class TMCColorRGB;

//****** Globally Unique Ids *************************************************

MCDEFINE_GUID(IID_I3DShEnvironment, 0xA0629720L, 0x3A0D, 0x101C, 0x88, 0x5F, 0x04, 0x02, 0x1C, 0x00, 0x70, 0x02);
MCDEFINE_GUID(IID_I3DShAmbientLight, 0x8108eb84, 0x40c3, 0x11d1, 0xa0, 0xa0, 0x0, 0xaa, 0x0, 0xd3, 0x7, 0xeb);
MCDEFINE_GUID(IID_I3DShAtmosphericShader, 0x8108eb85, 0x40c3, 0x11d1, 0xa0, 0xa0, 0x0, 0xaa, 0x0, 0xd3, 0x7, 0xeb);
MCDEFINE_GUID(IID_I3DShBackground, 0x8108eb86, 0x40c3, 0x11d1, 0xa0, 0xa0, 0x0, 0xaa, 0x0, 0xd3, 0x7, 0xeb);
MCDEFINE_GUID(IID_I3DShBackdrop, 0x8108eb87, 0x40c3, 0x11d1, 0xa0, 0xa0, 0x0, 0xaa, 0x0, 0xd3, 0x7, 0xeb);


/*****************************************************************************\
*  I3DShEnvironment                                                           *
*                                                                             *
*  Environment as seen from other extensions                                  *
*                                                                             *
\*****************************************************************************/

struct BackGroundArea;
struct BackdropArea;
struct I3DExRaytracer;

/// \addtogroup ShellInterface
/// \{

/// This is the shell interface for environments (Atmosphere, Backdrop, Background...)
///
/// <P>There are two interfaces to access a component: The shell interface (ISh. or I3DSh.) and
/// the external interface (IEx. or I3DEx.) . You can get one from the other using QueryInterface.</P>
///
/// <P>Whenever it is possible you should use the Shell interface to access the component
/// because the Shell will make sure that the parameter map of the external component is valid.
/// This is especially important if the component is animated. For more information on components
/// see the Overview of the SDK.</P>
///
/// <P>This interface provides a convient way to access Atmospheres, Volumetric effects, Background, Backdrops...</P>
///
struct I3DShEnvironment: public IMCUnknown
{
	// ****************************************************************************
	//								SegmentFilter
	// 
	/// \deprecated use SegmentFilter2 instead.
	/// Calculates the effect of the atmosphere on a finite line segment on a ray.
	///
	/// \param beg				The point that defines the beginning of the segment in Global Coordinates.
	///							It is the point through which we "see" the atmosphere.
	///
	/// \param end				The point that is seen from beg.
	///
	/// \param inOutFilter		On input this is the color of the light coming from end in the direction
	///							of beg. On output it should contained the color of the light seen through beg
	///							once the light has been filtered by the atmosphere.
	///
	/// \param raytracer        The raytracer that should be used for lighting calculations.
	///
	/// \param indirectLight	True if the ray is used to calculate indirect lighting.
	///
	/// \param isShadowCasting  True if the ray is a shadow ray.
	///
	/// \param renderVolmetricEffects  True if volumetric Effects (lightCone, light sphere...) should be taken into account.
	/// \param isSunLightShadowCasting True if the current ray is a shadow ray from the sun
	virtual MCCOMErr MCCOMAPI SegmentFilter(const TVector3 &beg,const TVector3 &end,TMCColorRGBA &inOutFilter, I3DExRaytracer* raytracer, boolean isShadowCasting,boolean renderVolmetricEffects, boolean indirectLight, boolean isSunLightShadowCasting) = 0;
	
	// ****************************************************************************
	//								DirectionFilter
	// 
	/// \deprecated use DirectionFilter2 instead.
	/// Calculates the effect of the atmosphere on an infinite ray.
	///
	/// \param origin			The origin of the ray in Global Coordinates
	/// \param direction		A unit vector that defines the direction of the ray in Global coordinates
	/// \param inOutFilter		On input it contains the color of the Background. On output it contains the
	///							color of the light filtered through the atmosphere.
	/// \param raytracer        The raytracer that should be used for lighting calculations.
	/// \param indirectLight	True if the ray is used to calculate indirect lighting.
	/// \param renderVolmetricEffects  True if volumetric Effects (lightCone, light sphere...) should be taken into account.
	/// 
	virtual MCCOMErr MCCOMAPI DirectionFilter(const TVector3 &origin,const TVector3 &direction, TMCColorRGBA &inOutFilter, I3DExRaytracer* raytracer ,boolean renderVolmetricEffects,boolean indirectLight) = 0;
	
	// ****************************************************************************
	//								GetBackdropColor
	// 
	/// Returns the color of the backdrop at a particular location of the screen.
	///
	/// \param screenPoint   The coordinates of the point on the screen
	/// \param fullAreaDone  For future use.
	/// \param screenMinMax  The coordinates of the production frame in screen coordinates
	/// \param resultColor   The color that is returned.
	/// 
	virtual MCCOMErr MCCOMAPI GetBackdropColor(const TVector2 &screenPoint,boolean &fullAreaDone,const TBBox2D &screenMinMax, TMCColorRGB &resultColor) = 0;
	
	// ****************************************************************************
	//								GetEnvironmentColor
	// 
	/// Returns the color of the Background.
	/// 
	/// \param direction     The direction of the ray.
	/// \param fullAreaDone  For future use.
	/// \param resultColor   The color that is returned.
	/// 
	virtual MCCOMErr MCCOMAPI GetEnvironmentColor(const TVector3 &direction,boolean &fullAreaDone,TMCColorRGB &resultColor) = 0;
	
	// ****************************************************************************
	//								HasAtmosphere
	// 
	/// Returns true if the scene contains an Atmosphere (I3DShAtmosphericShader).
	/// 
	virtual boolean MCCOMAPI HasAtmosphere() const = 0;
	
	// ****************************************************************************
	//								HasBackdrop
	// 
	/// Returns true if the scene contains a Backdrop.
	/// 
	virtual boolean MCCOMAPI HasBackdrop() const = 0;
	
	// ****************************************************************************
	//								HasBackground
	// 
	/// Returns true if the scene contains a Background.
	/// 
	virtual boolean MCCOMAPI HasBackground() const = 0;


	// ****************************************************************************
	//								SegmentFilter2
	// 
	/// Calculates the effect of the environment (atmosphere + volume primitives) on
	/// a finite line segment on a ray. This function replaces SegmentFilter which is
	/// now obsolete.
	/// 
	/// \param ray                     The ray that should be filtered
	/// \param tmin                    The beginning of the segment on the ray
	/// \param tmax	                   The end of the segmenet on the ray
	/// \param inOutFilter		       On input this is the color of the light coming from the end of the ray (tmax).
	///							       On output it should contain the color of the light seen through the atmosphere and the volume primitives
	/// \param raytracer               The raytracer that should be used for lighting calculations
	/// \param isShadowCasting		   True if the ray is a shadow ray.
	/// \param renderVolmetricEffects  True if volumetric Effects (lightCone, light sphere...) should be taken into account.
	/// \param indirectLight		   True if the ray is used to calculate indirect lighting.
	/// \param isSunLightShadowCasting True if the ray is a shadow ray from the sun light.
	/// 
	virtual MCCOMErr MCCOMAPI SegmentFilter2(const Ray3D&			ray,
											real64					tmin,
											real64					tmax,
											TMCColorRGBA&			inOutFilter,
											I3DExRaytracer*			raytracer,
											boolean					isShadowCasting,
											boolean					renderVolmetricEffects,
											boolean					indirectLight,
											boolean					isSunLightShadowCasting) = 0;


	// ****************************************************************************
	//								DirectionFilter2
	// 
	/// Calculates the effect of the environment (atmosphere + volume primitives) on
	/// an infinite ray.
	/// 
	/// \param ray                     The ray that should be filtered
	/// \param inOutFilter             On input this is the color of the light coming from the end of the ray (tmax).
	///							       On output it should contain the color of the light seen through the atmosphere and the volume primitives
	/// \param raytracer               The raytracer that should be used for lighting calculations
	/// \param renderVolumePrimitives  True if volumetric Primitives (clouds,fire,...) should be taken into account.
	/// \param renderVolmetricEffects  True if volumetric Effects (lightCone, light sphere...) should be taken into account.
	/// \param indirectLight           True if the ray is used to calculate indirect lighting.
	/// 
	virtual MCCOMErr MCCOMAPI DirectionFilter2(	const Ray3D&			ray,
												TMCColorRGBA&			inOutFilter,
												I3DExRaytracer*			raytracer,
												boolean					renderVolumePrimitives,
												boolean					renderVolmetricEffects,
												boolean					indirectLight) = 0;

	// ****************************************************************************
	//								SegmentFilterExcludingVolumPrimitives
	// 
	/// Calculates the effect of only the atmosphere a segment of a ray. This call
	/// does not take into account volumetric primitives
	/// 
	/// \param ray                     The ray that should be filtered
	/// \param tmin                    The beginning of the segment on the ray
	/// \param tmax	                   The end of the segmenet on the ray
	/// \param inOutFilter		       On input this is the color of the light coming from the end of the ray (tmax).
	///							       On output it should contain the color of the light seen through the atmosphere and the volume primitives
	/// \param raytracer               The raytracer that should be used for lighting calculations
	/// \param isShadowCasting		   True if the ray is a shadow ray.
	/// \param renderVolmetricEffects  True if volumetric Effects (lightCone, light sphere...) should be taken into account.
	/// \param indirectLight		   True if the ray is used to calculate indirect lighting.
	/// \param isSunLightShadowCasting True if the ray is a shadow ray from the sun light.
	/// 
	virtual void	MCCOMAPI	SegmentFilterExcludingVolumPrimitives(
											const Ray3D&			ray,
											real64					tmin,
											real64					tmax,
											TMCColorRGBA&			inOutFilter,
											I3DExRaytracer*			raytracer,
											boolean					isShadowCasting,
											boolean					renderVolmetricEffects,
											boolean					indirectLight,
											boolean					isSunLightShadowCasting) = 0;

	// ****************************************************************************
	//								SegmentFilter3
	// 
	/// Calculates the effect of the environment (atmosphere + volume primitives) on
	/// a finite line segment on a ray. This function replaces SegmentFilter2 which is
	/// now obsolete.
	/// 
	/// \param ray                     The ray that should be filtered
	/// \param tmin                    The beginning of the segment on the ray
	/// \param tmax	                   The end of the segmenet on the ray
	/// \param inOutFilter		       On input this is the color of the light coming from the end of the ray (tmax).
	///							       On output it should contain the color of the light seen through the atmosphere and the volume primitives
	/// \param outLinearEffect		   If not null, will be filled by the linear effect of the environment.
	/// \param raytracer               The raytracer that should be used for lighting calculations
	/// \param isShadowCasting		   True if the ray is a shadow ray.
	/// \param renderAtmosphere		   True if the atmosphere sould be taken into account.
	/// \param renderVolumePrimitives  True if volumetric Primitives (clouds,fire,...) should be taken into account.
	/// \param renderVolmetricEffects  True if volumetric Effects (lightCone, light sphere...) should be taken into account.
	/// \param indirectLight		   True if the ray is used to calculate indirect lighting.
	/// \param isSunLightShadowCasting True if the ray is a shadow ray from the sun light.
	/// 
	virtual MCCOMErr MCCOMAPI SegmentFilter3(const Ray3D&			ray,
											real64					tmin,
											real64					tmax,
											TMCColorRGBA&			inOutFilter,
											TColorRGBLinearEffect*	outAtmosphereLinearEffect,
											TColorRGBLinearEffect*	outVolumeLinearEffect,
											TColorRGBLinearEffect*	outEffectLinearEffect,
											I3DExRaytracer*			raytracer,
											boolean					isShadowCasting,
											boolean					renderAtmosphere,
											boolean					renderVolumetricPrimitives,
											boolean					renderVolmetricEffects,
											boolean					indirectLight,
											boolean					isSunLightShadowCasting,
											boolean					oldShadowFiltering) = 0;

	// ****************************************************************************
	//								DirectionFilter3
	// 
	/// Calculates the effect of the environment (atmosphere + volume primitives) on
	/// an infinite ray.
	/// 
	/// \param ray                     The ray that should be filtered
	/// \param inOutFilter             On input this is the color of the light coming from the end of the ray (tmax).
	///							       On output it should contain the color of the light seen through the atmosphere and the volume primitives
	/// \param outLinearEffect		   If not null, will be filled by the linear effect of the environment.
	/// \param raytracer               The raytracer that should be used for lighting calculations
	/// \param renderAtmosphere		   True if the atmosphere sould be taken into account.
	/// \param renderVolumePrimitives  True if volumetric Primitives (clouds,fire,...) should be taken into account.
	/// \param renderVolmetricEffects  True if volumetric Effects (lightCone, light sphere...) should be taken into account.
	/// \param indirectLight           True if the ray is used to calculate indirect lighting.
	/// 
	virtual MCCOMErr MCCOMAPI DirectionFilter3(	const Ray3D&			ray,
												TMCColorRGBA&			inOutFilter,
												TColorRGBLinearEffect*	outAtmosphereLinearEffect,
												TColorRGBLinearEffect*	outVolumeLinearEffect,
												TColorRGBLinearEffect*	outEffectLinearEffect,
												I3DExRaytracer*			raytracer,
												boolean					renderAtmosphere,
												boolean					renderVolumePrimitives,
												boolean					renderVolmetricEffects,
												boolean					indirectLight) = 0;
};
 

/// This is the shell interface for ambient light plugins. An ambient light is a light
/// that shines in every direction and does not cast any shadows.
///
/// <P>There are two interfaces to access a component: The shell interface (ISh. or I3DSh.) and
/// the external interface (IEx. or I3DEx.) . You can get one from the other using QueryInterface.</P>
///
/// <P>Whenever it is possible you should use the Shell interface to access the component
/// because the Shell will make sure that the parameter map of the external component is valid.
/// This is especially important if the component is animated. For more information on components
/// see the Overview of the SDK.</P>
///
/// <P>To access the ambient light, you should use I3DShScene::GetAmbientLightColor() to make sure that
/// it is properly validated.</P>
///
struct I3DShAmbientLight: public IMCUnknown
{
	// ****************************************************************************
	//								GetScene
	// 
	/// Returns the scene that contains this ambient light.
	/// 
	virtual void		MCCOMAPI GetScene			(I3DShScene** scene) = 0;

};


enum EAtmosphericLightType
{
	kMoonLight,
	kSunLight
};

struct TAtmosphericLightInfo
{
	TAtmosphericLightInfo() : fDirection(0,0,0),fColor(0,0,0),fSizeFactor(1.0f) {}

	TVector3		fDirection;
	TMCColorRGB		fColor;
	real32			fSizeFactor;
};

///
/// <P>There are two interfaces to access a component: The shell interface (ISh. or I3DSh.) and
/// the external interface (IEx. or I3DEx.) . You can get one from the other using QueryInterface.</P>
///
/// <P>Whenever it is possible you should use the Shell interface to access the component
/// because the Shell will make sure that the parameter map of the external component is valid.
/// This is especially important if the component is animated. For more information on components
/// see the Overview of the SDK.</P>
///
/// <P>To access the Atmosphere, you should use I3DShEnvironment to make sure that
/// it is properly validated.</P>
///
struct I3DShAtmosphericShader: public IMCUnknown
{
	// ****************************************************************************
	//								GetScene
	// 
	/// Returns the scene that contains this Atmosphere.
	/// 
	virtual void		MCCOMAPI GetScene			(I3DShScene** scene) = 0;			// <- Scene of the object

	// ****************************************************************************
	//								PrepareRender
	// 
	/// Will be called before each rendering frame
	/// 
	virtual void		MCCOMAPI PrepareRender		() = 0;

	// ****************************************************************************
	//								EndRender
	// 
	/// Will be called after each rendering frame
	/// 
	virtual void		MCCOMAPI EndRender		() = 0;

	// ****************************************************************************
	//								GetLightInfo
	/// 
	/// \param info  The info about the sun or moon light position, color...
	/// \param lightType kMoonLight or kSunLight
	/// 
	virtual void		MCCOMAPI GetLightInfo(TAtmosphericLightInfo& info,EAtmosphericLightType lightType) = 0;

	// ****************************************************************************
	//								SetLightInfo
	/// 
	/// \param info  The info about the sun or moon light position, color...
	/// \param lightType kMoonLight or kSunLight
	/// 
	virtual void		MCCOMAPI SetLightInfo(TAtmosphericLightInfo& info,EAtmosphericLightType lightType) = 0;
};

///
/// <P>There are two interfaces to access a component: The shell interface (ISh. or I3DSh.) and
/// the external interface (IEx. or I3DEx.) . You can get one from the other using QueryInterface.</P>
///
/// <P>Whenever it is possible you should use the Shell interface to access the component
/// because the Shell will make sure that the parameter map of the external component is valid.
/// This is especially important if the component is animated. For more information on components
/// see the Overview of the SDK.</P>
///
/// <P>To access the Background, you should use I3DShEnvironment to make sure that
/// it is properly validated.</P>
///
struct I3DShBackground: public IMCUnknown
{
	// ****************************************************************************
	//								GetScene
	// 
	/// Returns the scene that contains this Background.
	/// 
	virtual void		MCCOMAPI GetScene			(I3DShScene** scene) = 0;			// <- Scene of the object
};

///
/// <P>There are two interfaces to access a component: The shell interface (ISh. or I3DSh.) and
/// the external interface (IEx. or I3DEx.) . You can get one from the other using QueryInterface.</P>
///
/// <P>Whenever it is possible you should use the Shell interface to access the component
/// because the Shell will make sure that the parameter map of the external component is valid.
/// This is especially important if the component is animated. For more information on components
/// see the Overview of the SDK.</P>
///
/// <P>To access the Backdrop, you should use I3DShEnvironment to make sure that
/// it is properly validated.</P>
///
struct I3DShBackdrop: public IMCUnknown
{
	// ****************************************************************************
	//								GetScene
	// 
	/// Returns the scene that contains this Backdrop
	/// 
	virtual void		MCCOMAPI GetScene			(I3DShScene** scene) = 0;			// <- Scene of the object
};

/// \}

#endif
