/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield * * This library is open source and may be redistributed and/or modified under * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or * (at your option) any later version. The full license is in LICENSE file * included with this distribution, and on the openscenegraph.org website. * * This library 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 * OpenSceneGraph Public License for more details. */ #ifndef OSG_CULLSETTINGS #define OSG_CULLSETTINGS 1 #include #include #include namespace osg { // forward declare class ArgumentParser; class ApplicationUsage; class OSG_EXPORT CullSettings { public: CullSettings() { setDefaults(); readEnvironmentalVariables(); } CullSettings(ArgumentParser& arguments) { setDefaults(); readEnvironmentalVariables(); readCommandLine(arguments); } CullSettings(const CullSettings& cs); virtual ~CullSettings() {} CullSettings& operator = (const CullSettings& settings) { if (this==&settings) return *this; setCullSettings(settings); return *this; } virtual void setDefaults(); enum VariablesMask { COMPUTE_NEAR_FAR_MODE = (0x1 << 0), CULLING_MODE = (0x1 << 1), LOD_SCALE = (0x1 << 2), SMALL_FEATURE_CULLING_PIXEL_SIZE = (0x1 << 3), CLAMP_PROJECTION_MATRIX_CALLBACK = (0x1 << 4), NEAR_FAR_RATIO = (0x1 << 5), IMPOSTOR_ACTIVE = (0x1 << 6), DEPTH_SORT_IMPOSTOR_SPRITES = (0x1 << 7), IMPOSTOR_PIXEL_ERROR_THRESHOLD = (0x1 << 8), NUM_FRAMES_TO_KEEP_IMPOSTORS_SPRITES = (0x1 << 9), CULL_MASK = (0x1 << 10), CULL_MASK_LEFT = (0x1 << 11), CULL_MASK_RIGHT = (0x1 << 12), CLEAR_COLOR = (0x1 << 13), CLEAR_MASK = (0x1 << 14), LIGHTING_MODE = (0x1 << 15), LIGHT = (0x1 << 16), DRAW_BUFFER = (0x1 << 17), READ_BUFFER = (0x1 << 18), NO_VARIABLES = 0x00000000, ALL_VARIABLES = 0x7FFFFFFF }; typedef int InheritanceMask; /** Set the inheritance mask used in inheritCullSettings to control which variables get overwritten by the passed in CullSettings object.*/ void setInheritanceMask(InheritanceMask mask) { _inheritanceMask = mask; } /** Get the inheritance mask used in inheritCullSettings to control which variables get overwritten by the passed in CullSettings object.*/ InheritanceMask getInheritanceMask() const { return _inheritanceMask; } /** Set the local cull settings values from specified CullSettings object.*/ void setCullSettings(const CullSettings& settings); /** Inherit the local cull settings variable from specified CullSettings object, according to the inheritance mask.*/ virtual void inheritCullSettings(const CullSettings& settings) { inheritCullSettings(settings, _inheritanceMask); } /** Inherit the local cull settings variable from specified CullSettings object, according to the inheritance mask.*/ virtual void inheritCullSettings(const CullSettings& settings, unsigned int inheritanceMask); /** read the environmental variables.*/ void readEnvironmentalVariables(); /** read the commandline arguments.*/ void readCommandLine(ArgumentParser& arguments); enum InheritanceMaskActionOnAttributeSetting { DISABLE_ASSOCIATED_INHERITANCE_MASK_BIT, DO_NOT_MODIFY_INHERITANCE_MASK }; void setInheritanceMaskActionOnAttributeSetting(InheritanceMaskActionOnAttributeSetting action) { _inheritanceMaskActionOnAttributeSetting = action; } InheritanceMaskActionOnAttributeSetting getInheritanceMaskActionOnAttributeSetting() const { return _inheritanceMaskActionOnAttributeSetting; } /** Apply the action, specified by the InheritanceMaskActionOnAttributeSetting, to apply to the inheritance bit mask. * This method is called by CullSettings::set*() parameter methods to ensure that CullSettings inheritance mechanisms doesn't overwrite the local parameter settings.*/ inline void applyMaskAction(unsigned int maskBit) { if (_inheritanceMaskActionOnAttributeSetting==DISABLE_ASSOCIATED_INHERITANCE_MASK_BIT) { _inheritanceMask = _inheritanceMask & (~maskBit); } } /** Switch the creation of Impostors on or off. * Setting active to false forces the CullVisitor to use the Impostor * LOD children for rendering. Setting active to true forces the * CullVisitor to create the appropriate pre-rendering stages which * render to the ImpostorSprite's texture.*/ void setImpostorsActive(bool active) { _impostorActive = active; applyMaskAction(IMPOSTOR_ACTIVE); } /** Get whether impostors are active or not. */ bool getImpostorsActive() const { return _impostorActive; } /** Set the impostor error threshold. * Used in calculation of whether impostors remain valid.*/ void setImpostorPixelErrorThreshold(float numPixels) { _impostorPixelErrorThreshold=numPixels; applyMaskAction(IMPOSTOR_PIXEL_ERROR_THRESHOLD); } /** Get the impostor error threshold.*/ float getImpostorPixelErrorThreshold() const { return _impostorPixelErrorThreshold; } /** Set whether ImpostorSprite's should be placed in a depth sorted bin for rendering.*/ void setDepthSortImpostorSprites(bool doDepthSort) { _depthSortImpostorSprites = doDepthSort; applyMaskAction(DEPTH_SORT_IMPOSTOR_SPRITES); } /** Get whether ImpostorSprite's are depth sorted bin for rendering.*/ bool getDepthSortImpostorSprites() const { return _depthSortImpostorSprites; } /** Set the number of frames that an ImpostorSprite is kept whilst not being beyond, * before being recycled.*/ void setNumberOfFrameToKeepImpostorSprites(int numFrames) { _numFramesToKeepImpostorSprites = numFrames; applyMaskAction(NUM_FRAMES_TO_KEEP_IMPOSTORS_SPRITES); } /** Get the number of frames that an ImpostorSprite is kept whilst not being beyond, * before being recycled.*/ int getNumberOfFrameToKeepImpostorSprites() const { return _numFramesToKeepImpostorSprites; } enum ComputeNearFarMode { DO_NOT_COMPUTE_NEAR_FAR = 0, COMPUTE_NEAR_FAR_USING_BOUNDING_VOLUMES, COMPUTE_NEAR_FAR_USING_PRIMITIVES, COMPUTE_NEAR_USING_PRIMITIVES }; void setComputeNearFarMode(ComputeNearFarMode cnfm) { _computeNearFar=cnfm; applyMaskAction(COMPUTE_NEAR_FAR_MODE); } ComputeNearFarMode getComputeNearFarMode() const { return _computeNearFar;} void setNearFarRatio(double ratio) { _nearFarRatio = ratio; applyMaskAction(NEAR_FAR_RATIO); } double getNearFarRatio() const { return _nearFarRatio; } enum CullingModeValues { NO_CULLING = 0x0, VIEW_FRUSTUM_SIDES_CULLING = 0x1, NEAR_PLANE_CULLING = 0x2, FAR_PLANE_CULLING = 0x4, VIEW_FRUSTUM_CULLING = VIEW_FRUSTUM_SIDES_CULLING| NEAR_PLANE_CULLING| FAR_PLANE_CULLING, SMALL_FEATURE_CULLING = 0x8, SHADOW_OCCLUSION_CULLING = 0x10, CLUSTER_CULLING = 0x20, DEFAULT_CULLING = VIEW_FRUSTUM_SIDES_CULLING| SMALL_FEATURE_CULLING| SHADOW_OCCLUSION_CULLING| CLUSTER_CULLING, ENABLE_ALL_CULLING = VIEW_FRUSTUM_CULLING| SMALL_FEATURE_CULLING| SHADOW_OCCLUSION_CULLING| CLUSTER_CULLING }; typedef int CullingMode; /** Set the culling mode for the CullVisitor to use.*/ void setCullingMode(CullingMode mode) { _cullingMode = mode; applyMaskAction(CULLING_MODE); } /** Returns the current CullingMode.*/ CullingMode getCullingMode() const { return _cullingMode; } void setCullMask(osg::Node::NodeMask nm) { _cullMask = nm; applyMaskAction(CULL_MASK); } osg::Node::NodeMask getCullMask() const { return _cullMask; } void setCullMaskLeft(osg::Node::NodeMask nm) { _cullMaskLeft = nm; applyMaskAction(CULL_MASK_LEFT); } osg::Node::NodeMask getCullMaskLeft() const { return _cullMaskLeft; } void setCullMaskRight(osg::Node::NodeMask nm) { _cullMaskRight = nm; applyMaskAction(CULL_MASK_RIGHT); } osg::Node::NodeMask getCullMaskRight() const { return _cullMaskRight; } /** Set the LOD bias for the CullVisitor to use.*/ void setLODScale(float scale) { _LODScale = scale; applyMaskAction(LOD_SCALE); } /** Get the LOD bias.*/ float getLODScale() const { return _LODScale; } /** Threshold at which small features are culled. \param value Bounding volume size in screen space. Default is 2.0. */ void setSmallFeatureCullingPixelSize(float value) { _smallFeatureCullingPixelSize=value; applyMaskAction(SMALL_FEATURE_CULLING_PIXEL_SIZE); } /** Get the Small Feature Culling Pixel Size.*/ float getSmallFeatureCullingPixelSize() const { return _smallFeatureCullingPixelSize; } /** Callback for overriding the CullVisitor's default clamping of the projection matrix to computed near and far values. * Note, both Matrixf and Matrixd versions of clampProjectionMatrixImplementation must be implemented as the CullVisitor * can target either Matrix data type, configured at compile time.*/ struct ClampProjectionMatrixCallback : public osg::Referenced { virtual bool clampProjectionMatrixImplementation(osg::Matrixf& projection, double& znear, double& zfar) const = 0; virtual bool clampProjectionMatrixImplementation(osg::Matrixd& projection, double& znear, double& zfar) const = 0; }; /** set the ClampProjectionMatrixCallback.*/ void setClampProjectionMatrixCallback(ClampProjectionMatrixCallback* cpmc) { _clampProjectionMatrixCallback = cpmc; applyMaskAction(CLAMP_PROJECTION_MATRIX_CALLBACK); } /** get the non const ClampProjectionMatrixCallback.*/ ClampProjectionMatrixCallback* getClampProjectionMatrixCallback() { return _clampProjectionMatrixCallback.get(); } /** get the const ClampProjectionMatrixCallback.*/ const ClampProjectionMatrixCallback* getClampProjectionMatrixCallback() const { return _clampProjectionMatrixCallback.get(); } /** Write out internal settings of CullSettings. */ void write(std::ostream& out); protected: InheritanceMask _inheritanceMask; InheritanceMaskActionOnAttributeSetting _inheritanceMaskActionOnAttributeSetting; ComputeNearFarMode _computeNearFar; CullingMode _cullingMode; float _LODScale; float _smallFeatureCullingPixelSize; ref_ptr _clampProjectionMatrixCallback; double _nearFarRatio; bool _impostorActive; bool _depthSortImpostorSprites; float _impostorPixelErrorThreshold; int _numFramesToKeepImpostorSprites; Node::NodeMask _cullMask; Node::NodeMask _cullMaskLeft; Node::NodeMask _cullMaskRight; }; template bool clampProjectionMatrix(matrix_type& projection, double& znear, double& zfar, value_type nearFarRatio) { double epsilon = 1e-6; if (zfar