shadgen.h

Go to the documentation of this file.
00001 /**********************************************************************
00002  *<
00003 FILE: shadgen.h : pluggable shadow generators.
00004 
00005     DESCRIPTION:
00006 
00007     CREATED BY: Dan Silva
00008 
00009     HISTORY: Created 10/27/98
00010 
00011  *> Copyright (c) 1994, All Rights Reserved.
00012  **********************************************************************/
00013 
00014 #pragma once
00015 #include "maxheap.h"
00016 #include "ref.h"
00017 #include "plugapi.h"
00018 #include "render.h"
00019 
00020 // forward declarations
00021 class LightObject;
00022 class ObjLightDesc;
00023 class RendContext;
00024 class RenderGlobalContext;
00025 class ShadeContext;
00026 class Color;
00027 
00029 // Shadow Generator flags
00030 //
00031 // These define the the 'flags' parameter to the CreateShadowGeerator call
00032 // of the ShadowType class
00033 // 
00034 #define SHAD_PARALLEL       2   // light is directional, parallel projection
00035 #define SHAD_OMNI           4   // generator can do omni, so do it on create
00036 #define SHAD_2SIDED         8   // both sides of geometry shd cast shadows
00037 #define MIN_SHADOW_MAP_SIZE 1.0f    // Minimum allowed value for the shadow map size property
00038 #define MAX_SHADOW_MAP_SIZE 10000.0f    // Maximum allowed value for the shadow map size property
00039 #define MIN_SHADOW_BIAS_VALUE 0.0f // Minimum allowed value for the shadow map bias property
00040 #define MAX_SHADOW_BIAS_VALUE 10000.0f // Maximum allowed value for the shadow map bias property
00041 #define MIN_SHADOW_SAMPLE_RANGE 0.01f // Minimum allowed value for the shadow map sample range property
00042 #define MAX_SHADOW_SAMPLE_RANGE 50.0f // Maximum allowed value for the shadow map sample range property
00043 
00044 class ShadowGenerator;
00045 class AreaShadowGenerator;
00046 class IAreaShadowType;
00047 class ParamBlockDescID;
00048 class IParamBlock;
00049 
00050 #pragma warning(push)
00051 #pragma warning(disable:4100)
00052 
00053 
00061 class ShadowParamDlg: public MaxHeapOperators {
00062 public:
00064     virtual ~ShadowParamDlg() {}
00066     virtual void DeleteThis()=0;
00067     };
00068 
00069 //
00070 // NB: This Class needs to be made extensible w/ derivation from baseInterfaceServer
00071 // This will be done the next time the API is changed
00072 //
00073 // This class carries the parameters for the shadow type, and puts up the parameter rollup.
00074 #define AREA_SHADOW_TYPE_INTERFACE_ID Interface_ID(0x68436888, 0x5b5b2ab0)
00075 
00111 #pragma warning(push)
00112 #pragma warning(disable:4239)
00113 class ShadowType: public ReferenceTarget {
00114     public:
00115         SClass_ID SuperClassID() { return SHADOW_TYPE_CLASS_ID;}
00116         virtual ShadowParamDlg *CreateShadowParamDlg(Interface *ip) { return NULL; }
00117         virtual ShadowGenerator* CreateShadowGenerator(LightObject *l,  ObjLightDesc *ld, ULONG flags)=0;
00118         virtual BOOL SupportStdMapInterface() { return FALSE; }
00119 
00120         BOOL BypassPropertyLevel() { return TRUE; }  // want to promote shadowtype props to light level
00121 
00122         // If the shadow generator can handle omni's directly, this should return true. If it does,
00123         // then when doing an Omni light, the SHAD_OMNI flag will be passed in to 
00124         // the CreateShadowGenerator call, and only one ShadowGenerator will be created
00125         // instead of the normal 6 (up,down,right,left,front,back).
00126         virtual BOOL CanDoOmni() { return FALSE; }
00127 
00128         // This method used for converting old files: only needs to be supported by default 
00129         // shadow map and ray trace shadows.
00130         virtual void ConvertParamBlk( ParamBlockDescID *descOld, int oldCount, IParamBlock *oldPB ) { }
00131 
00132         // This method valid iff SupportStdMapInterface returns TRUE
00133         virtual int MapSize(TimeValue t) { return 512; } 
00134 
00135         // This interface is solely for the default shadow map type ( Class_ID(STD_SHADOW_MAP_CLASS_ID,0) )
00136         virtual void SetMapRange(TimeValue t, float f) {}
00137         virtual float GetMapRange(TimeValue t, Interval& valid = Interval(0,0)) { return 0.0f; }
00138         virtual void SetMapSize(TimeValue t, int f) {}
00139         virtual int GetMapSize(TimeValue t, Interval& valid = Interval(0,0)) { return 0; }
00140         virtual void SetMapBias(TimeValue t, float f) {} 
00141         virtual float GetMapBias(TimeValue t, Interval& valid = Interval(0,0)) { return 0.0f; }
00142         virtual void SetAbsMapBias(TimeValue t, int a) {}
00143         virtual int GetAbsMapBias(TimeValue t, Interval& valid = Interval(0,0)) { return 0; }
00144 
00145         // This interface is solely for the default raytrace shadow type ( Class_ID(STD_RAYTRACE_SHADOW_CLASS_ID,0) )
00146         virtual float GetRayBias(TimeValue t, Interval &valid = Interval(0,0)) { return 0.0f; }
00147         virtual void SetRayBias(TimeValue t, float f) {}
00148         virtual int GetMaxDepth(TimeValue t, Interval &valid = Interval(0,0)) { return 1; } 
00149         virtual void SetMaxDepth(TimeValue t, int f) {}
00150 
00151         // Because this method is inlined and only uses existing methods
00152         // it doesn't break the SDK. Return the IAreaShadowType interface
00153         IAreaShadowType* GetAreaShadowType();
00154             
00155     };
00156 
00157 #pragma warning(pop) // C4239
00158 
00159 // This class carries the parameters for area shadows. It also creates
00160 // an AreaShadowGenerator to process the shadows during rendering.
00161 class IAreaShadowType : public BaseInterface {
00162     public:
00163         // Create the AreaShadowGenerator to process shadows during rendering
00164         virtual AreaShadowGenerator* CreateAreaShadowGenerator(LightObject *l,  ObjLightDesc *ld, ULONG flags)=0;
00165 
00166         // This method can be used to disable the area related controls
00167         // in the UI. It is used by area and linear lights to disable
00168         // these controls because the lights will control the area shadows.
00169         virtual void EnableAreaUI(bool onoff) {}
00170 
00171         // These are the area shadow parameters. You don't need to
00172         // implement these if you only want to use the AreaShadowGenerator interface.
00173         virtual float GetLength(TimeValue t) { return 0.0f; }
00174         virtual void SetLength(TimeValue t, float w) {}
00175         virtual float GetWidth(TimeValue t) { return 0.0f; }
00176         virtual void SetWidth(TimeValue t, float w) {}
00177     };
00178 
00179 inline IAreaShadowType* ShadowType::GetAreaShadowType()
00180 {
00181     return static_cast<IAreaShadowType*>(GetInterface(AREA_SHADOW_TYPE_INTERFACE_ID));
00182 }
00183 
00185 //
00186 //  This controls the default value for the 2Sided shadow attribute
00187 //  of viz4 shadow generators. must be compile time const as it's
00188 //  compiled into pb2's
00189 //
00190 #define TWO_SIDED_SHADOW_DEFAULT    FALSE
00191 
00192 
00193 // This class generates the shadows. It only exists during render, one per instance of the light.
00214 class ShadowGenerator: public MaxHeapOperators {
00215 public:
00217     virtual ~ShadowGenerator() {}
00218 
00252     virtual int Update(
00253         TimeValue t,
00254         const RendContext& rendCntxt,   // Mostly for progress bar.
00255         RenderGlobalContext *rgc,       // Need to get at instance list.
00256         Matrix3& lightToWorld, // light to world space: not necessarly same as that of light
00257         float aspect,      // aspect
00258         float param,       // persp:field-of-view (radians) -- parallel : width in world coords
00259         float clipDist = DONT_CLIP  
00260         )=0;
00261 
00274     virtual int UpdateViewDepParams(const Matrix3& worldToCam)=0;
00275 
00278     virtual void FreeBuffer()=0;
00280     virtual void DeleteThis()=0; // call this to destroy the ShadowGenerator
00281 
00282     // Generic shadow sampling function
00283     // Implement this when ShadowType::SupportStdMapInterface() returns FALSE. 
00301     virtual float Sample(ShadeContext &sc, Point3 &norm, Color& color) { return 1.0f; }
00302 
00303     // Implement these methods when ShadowType::SupportStdMapInterface() returns TRUE. 
00304     // This interface allows illuminated atmospherics
00305     // Note: Sample should return a small NEGATIVE number ehen the sample falls outside of the shadow buffer, so
00306     //    the caller can know to take appropriate action.
00338     virtual float Sample(ShadeContext &sc, float x, float y, float z, float xslope, float yslope) { return 1.0f; }
00358     virtual BOOL QuickSample(int x, int y, float z) { return 1; }
00389     virtual float FiltSample(int x, int y, float z, int level) { return 1.0f; }
00421     virtual float LineSample(int x1, int y1, float z1, int x2, int y2, float z2) { return 1.0f; }
00422 
00423     };
00424 
00425 #pragma warning(pop) // C4100
00426 
00427 // For performance reasons, the area shadow generator is broken into two
00428 // parts, the AreaShadowGenerator and the AreaShadowSampler. This is to allow
00429 // some coherency in the multiple samples that are required to sample
00430 // and area light. The AreaShadowGenerator returns the size of the AreaShadowSampler,
00431 // which is allocated by the caller. The AreaShadowGenerator then initializes
00432 // the allocate memory and return the address of the sampler. The destructor
00433 // for the AreaShadowSampler is not called when the memory is freed. The
00434 // AreaShadowSampler may not be used by multiple threads.
00435 
00436 class AreaShadowSampler;
00437 
00438 // The class generates area shadows. It only exists during render, one per instance of the light.
00439 class AreaShadowGenerator : public ShadowGenerator {
00440     public:
00441         // Get the size of the sampler.
00442         virtual int GetSamplerSize() = 0;
00443 
00444         // Initialize the sampler and return a pointer to it. Memory must
00445         // be allocated by the caller and must be at least GetSamplerSize.
00446         virtual AreaShadowSampler* InitializeSampler(void* memory, ShadeContext& sc, bool antialias) = 0;
00447 
00448         // Return the number of samples we should use for
00449         // determining visibility of an area.
00450         virtual int GetNumSamples() { return 1; }
00451     };
00452 
00453 // The class samples area shadows. It only exists during render, and is dynamically
00454 // allocated on the stack using _alloca.
00455 class AreaShadowSampler: public MaxHeapOperators {
00456     public:
00457         virtual ~AreaShadowSampler() {}
00458         // Sample the area shadow generator. This call samples the occlusion
00459         // from sourcePnt to the point being shaded. SourcePnt needs to be
00460         // in local light space coordinates if the light is parallel,
00461         // and in camera space coordinate if the light is not parallel.
00462         // If antialias is true, the result is antialiased using the settings
00463         // for the generator. If antialias is false a single sample is returned.
00464         // The default implementation ignores the sourcePnt and anitalias
00465         // arguments and simply returns the result of the standard sampler.
00466         virtual float Sample(
00467             ShadeContext&   sc,
00468             const Point3&   sourcePnt,
00469             Point3&         norm,
00470             Color&          color
00471             ) = 0;
00472     };
00473 
00474 // This returns a new default shadow-map shadow generator
00477 CoreExport ShadowType *NewDefaultShadowMapType();
00478 
00479 // This returns a new default ray-trace shadow generator
00482 CoreExport ShadowType *NewDefaultRayShadowType();
00483 
00484