VR-Forces 5.0.3 Developer's Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
List of all members | Classes | Public Member Functions | Protected Types | Protected Member Functions | Static Protected Member Functions | Protected Attributes | Static Protected Attributes | Friends
makVrv::DtSpeedTreeForest Class Reference

DtSpeedTreeForest is the SpeedTree implementation of a distributed DtForestObject.

Inheritance diagram for makVrv::DtSpeedTreeForest:
Inheritance graph
[legend]

Classes

struct  ModelDefParams
 

Public Member Functions

virtual ~DtSpeedTreeForest ()
 
 DtSpeedTreeForest ()=delete
 
 DtSpeedTreeForest (const DtSpeedTreeForest &other)=delete
 
DtSpeedTreeForestoperator= (const DtSpeedTreeForest &other)=delete
 
virtual void setVisible (bool isVisible)
 
virtual void addUniqueTree (DtTreeRecord &record)
 
virtual void removeTree (DtUniqueID record)
 
virtual void removeAllTrees ()
 
virtual DtUniqueID addUniqueTreesToUniqueCell (DtVectorTreeRecords &records)
 
virtual void removeAllUniqueTreesAndUniqueCell (DtUniqueID cellID)
 
virtual void setTreeClippingPlane (float fFar)
 
virtual void getTreeClippingPlane (float &fFar)
 
virtual void setTree3DLodDistances (float fNear, float fFar)
 
virtual void getTree3DLodDistances (float &fNear, float &fFar)
 
virtual void setTreeBillboardDistances (float fStart, float fEnd)
 
virtual void getTreeBillboardDistances (float &fStart, float &fEnd)
 
virtual void setBillboardFadeOutRange (float fRange)
 
virtual void getBillboardFadeOutRange (float &fRange)
 
virtual void enableBillboardRendering (bool enable)
 
virtual bool isBillboardRenderingEnabled () const
 
virtual void enable3DTreeRendering (bool enable)
 
virtual bool is3DTreeRenderingEnabled () const
 
virtual void enableReceiveShadows (bool enable)
 
virtual bool isReceiveShadowsEnabled () const
 
virtual void setBoundingBox (const osg::BoundingBox &box)
 
virtual const osg::BoundingBox & getBoundingBox (void) const
 
virtual osg::ref_ptr< osg::Node > getRootNode (void)
 
virtual void programBoundCallback (osg::ref_ptr< makOsgSpeedTree::Forest > pForest, const makOsgSpeedTree::TreeType *pTreeType, uint32 programID)
 
virtual void slot_reloadShaders ()
 
virtual void slot_treeProfilingChanged (bool active)
 
virtual void slot_useGlobalAmbientChanged (bool enabled)
 
virtual void slot_useGlobalDiffuseChanged (bool enabled)
 
virtual void slot_perPixelLightingEnabledChanged (bool enabled)
 
virtual void slot_planarReflectionsShowSpeedTreesChanged (bool enabled)
 
virtual void processUnitialized ()
 
virtual bool initialized ()
 
virtual tbb::mutex & mergeDrawMutex ()
 
virtual tbb::mutex & mergeUpdateMutex ()
 
virtual osg::ref_ptr
< makOsgSpeedTree::Forest > & 
makSpeedTreeForest ()
 
virtual void preCullSetup (osg::ref_ptr< makOsgSpeedTree::Forest > forest, osg::Camera *camera)
 
- Public Member Functions inherited from makVrv::DtForestObject
virtual ~DtForestObject ()
 
virtual DtDede ()
 
void addTree (DtTreeRecord &record)
 

Protected Types

typedef std::map< std::string,
ModelDefParams
MapModelDefToSTFileName
 
typedef std::unordered_map
< DtUniqueID,
makOsgSpeedTree::TreeInstanceCollection > 
MapCellsToTrees
 
typedef std::unordered_map
< DtUniqueID,
makOsgSpeedTree::TreeInstance * > 
MapTreeIDToTree
 

Protected Member Functions

 DtSpeedTreeForest (DtDe &de, DtUniqueID id)
 
 DtSpeedTreeForest (DtDe &de, DtUniqueID id, const std::string &strVisManagerType)
 
void init (const std::string &strVisManagerType)
 
virtual void connectSignals (void)
 
virtual osg::Vec3f computeWindDirection (float fDirection)
 
virtual void setWindStrength (float fStrength)
 
virtual void setWindDirection (float fDirection)
 
virtual bool preUpdateCallback (osg::ref_ptr< makOsgSpeedTree::Forest > forest)
 
virtual bool preRenderCallback (osg::ref_ptr< makOsgSpeedTree::Forest > forest, osg::RenderInfo &renderInfo)
 
virtual void postRenderCallback (osg::ref_ptr< makOsgSpeedTree::Forest > forest, osg::RenderInfo &renderInfo)
 
virtual void provideTimeCallback (osg::ref_ptr< makOsgSpeedTree::Forest > forest, double &fTime)
 
virtual void pushGraphicsState (osg::RenderInfo &renderInfo)
 
virtual void popGraphicsState (osg::RenderInfo &renderInfo)
 
virtual DtModelDefinitionfindModelDefinition (const std::string &modelDef)
 
virtual bool createTree (DtTreeRecord &record)
 
virtual void initTreeDesc (makOsgSpeedTree::TreeInstanceDescriptor &desc, DtTreeRecord &record, const DtVector &up, DtCoordinateConverter *converter)
 
virtual void initTreeDesc (makOsgSpeedTree::TreeInstanceDescriptor &desc, DtTreeRecord &record, DtCoordinateConverter *converter, bool setupTopoFrame=true)
 
virtual void applyModelDefParameters (makOsgSpeedTree::TreeInstanceDescriptor &desc, DtTreeRecord &record)
 
virtual const bool bindLightingAttributes (const osg::Node *node, const uint32 programID, DtOsgRenderer *osgRenderer, const std::string &searchNodeName)
 
- Protected Member Functions inherited from makVrv::DtForestObject
 DtForestObject (DtDe &de, DtUniqueID id)
 

Static Protected Member Functions

static DtOsgCullVisitorParametersgetCullParameters (osg::RenderInfo &renderInfo)
 
static bool isCameraOrthographic (DtOsgCullVisitorParameters *params)
 
static bool isReflectionCamera (osg::Camera *camera)
 
static float getZoomFactor (DtOsgCullVisitorParameters *params, DtDe &de)
 

Protected Attributes

makOsgSpeedTree::TreeInstanceDescriptor myScratchTreeInstanceDesc
 
makOsgSpeedTree::TreeInstanceDescriptorCollection myScratchTreeInstanceDescCollection
 
makOsgSpeedTree::TreeInstanceCollection myScratchInstanceCollection
 
MapModelDefToSTFileName myMapModelDefToSTFileName
 
int myPreviousTU
 
osg::Camera * myCamera
 
DtSignalConnectionManager myConnections
 
std::unordered_map< int, boolmyShaderBoundMap
 
float myFarPlane
 
osg::ref_ptr< osg::Group > myRoot
 
osg::ref_ptr
< osg::PositionAttitudeTransform > 
myPat
 
osg::ref_ptr
< makOsgSpeedTree::Forest
myForest
 
osg::BoundingBox myBoundingBox
 
DtSpeedTreeCoremyCore
 
DtEnvironmentInfomyEnvInfo
 
MapCellsToTrees myMapCellsToTrees
 
MapTreeIDToTree myMapTreeIDtoTree
 
unsigned int myLastShaderHash
 
bool myReloadShaders
 
const std::string mySpeedTreeDefaultUserFuncsVertexShader
 
const std::string mySpeedTreeDefaultUserFuncsPixelShader
 
const std::string mySpeedTreeMultiViewUserFuncsVertexShader
 
osg::ref_ptr< osg::Uniform > myProjectionMatrixInverseUniform
 
osg::ref_ptr< osg::Uniform > myNormalMatrixUniform
 
osg::GLExtensions * myExt
 
bool myReceiveShadows
 
tbb::mutex myForestMergeDrawMutex
 
tbb::mutex myForestAddRemoveMutex
 
tbb::mutex myForestMergeUpdateMutex
 
DtCoordinateConvertermyMainThreadConverter
 
DtCoordinateConvertermyMergeBackgroundConverter
 
bool myShouldUpdateThisFrame
 
unsigned int myRestoreVisibilityNodeMask
 
- Protected Attributes inherited from makVrv::DtForestObject
DtDemyDe
 

Static Protected Attributes

static const float myCellSize
 
static unsigned int theLastImGuiFrameNumber
 
static bool theEnableAsyncUpdate
 

Friends

class DtSpeedTreeForestClassesCreator
 
class DtSpeedTreeForestObjectCreator
 

Additional Inherited Members

- Public Types inherited from makVrv::DtForestObject
typedef boost::unordered_map
< DtUniqueID, DtTreeRecord
TreeRecordMap
 

Member Typedef Documentation

typedef std::map<std::string, ModelDefParams> makVrv::DtSpeedTreeForest::MapModelDefToSTFileName
protected
typedef std::unordered_map<DtUniqueID, makOsgSpeedTree::TreeInstanceCollection> makVrv::DtSpeedTreeForest::MapCellsToTrees
protected
typedef std::unordered_map<DtUniqueID, makOsgSpeedTree::TreeInstance*> makVrv::DtSpeedTreeForest::MapTreeIDToTree
protected

Constructor & Destructor Documentation

virtual makVrv::DtSpeedTreeForest::~DtSpeedTreeForest ( )
virtual
makVrv::DtSpeedTreeForest::DtSpeedTreeForest ( )
delete

Default Constructor not implemented.

makVrv::DtSpeedTreeForest::DtSpeedTreeForest ( const DtSpeedTreeForest other)
delete

Copy Constructor not implemented – Copy Not Allowed.

makVrv::DtSpeedTreeForest::DtSpeedTreeForest ( DtDe de,
DtUniqueID  id 
)
protected

Constructors are protected because this class is created via the creator pattern.

makVrv::DtSpeedTreeForest::DtSpeedTreeForest ( DtDe de,
DtUniqueID  id,
const std::string &  strVisManagerType 
)
protected

Member Function Documentation

DtSpeedTreeForest& makVrv::DtSpeedTreeForest::operator= ( const DtSpeedTreeForest other)
delete

Assignment Operator Not implemented Assignment Not Allowed.

virtual void makVrv::DtSpeedTreeForest::setVisible ( bool  isVisible)
virtual

set the visibility of this speed tree forest. When invisible, the node mask of the root node is cached and set to 0 and, if visible, the node mask is restored to the cached non-zero value.

virtual void makVrv::DtSpeedTreeForest::addUniqueTree ( DtTreeRecord record)
virtual

Add a tree to the forest.

Implements makVrv::DtForestObject.

virtual void makVrv::DtSpeedTreeForest::removeTree ( DtUniqueID  treeId)
virtual

Remove a tree from the forest.

Implements makVrv::DtForestObject.

virtual void makVrv::DtSpeedTreeForest::removeAllTrees ( )
virtual

Remove all trees.

Implements makVrv::DtForestObject.

virtual DtUniqueID makVrv::DtSpeedTreeForest::addUniqueTreesToUniqueCell ( DtVectorTreeRecords records)
virtual
virtual void makVrv::DtSpeedTreeForest::removeAllUniqueTreesAndUniqueCell ( DtUniqueID  cellID)
virtual
virtual void makVrv::DtSpeedTreeForest::setTreeClippingPlane ( float  fFar)
virtual

Set the distance that trees are clipped. Not implemented in DtOsgForest (only DtSpeedTreeForest).

Implements makVrv::DtForestObject.

virtual void makVrv::DtSpeedTreeForest::getTreeClippingPlane ( float &  fFar)
virtual

Get the clipping planes.

Implements makVrv::DtForestObject.

virtual void makVrv::DtSpeedTreeForest::setTree3DLodDistances ( float  fNear,
float  fFar 
)
virtual

Set the distances for tree LOD's. Not implemented in DtOsgForest (only DtSpeedTreeForest).

Implements makVrv::DtForestObject.

virtual void makVrv::DtSpeedTreeForest::getTree3DLodDistances ( float &  fNear,
float &  fFar 
)
virtual

Set the distances for tree LOD's. Not implemented in DtOsgForest (only DtSpeedTreeForest).

Implements makVrv::DtForestObject.

virtual void makVrv::DtSpeedTreeForest::setTreeBillboardDistances ( float  fStart,
float  fEnd 
)
virtual

Set the distances for tree billboard LOD's. Not implemented in DtOsgForest (only DtSpeedTreeForest).

Implements makVrv::DtForestObject.

virtual void makVrv::DtSpeedTreeForest::getTreeBillboardDistances ( float &  fStart,
float &  fEnd 
)
virtual

Get the distances for tree billboard LOD's. Not implemented in DtOsgForest (only DtSpeedTreeForest).

Implements makVrv::DtForestObject.

virtual void makVrv::DtSpeedTreeForest::setBillboardFadeOutRange ( float  fRange)
virtual

set the fade out distance for the billboards. The Range - Cull distance = start transition dist

Implements makVrv::DtForestObject.

virtual void makVrv::DtSpeedTreeForest::getBillboardFadeOutRange ( float &  fRange)
virtual

get the fade out distance for the billboards. The Range - Cull distance = start transition dist

Implements makVrv::DtForestObject.

virtual void makVrv::DtSpeedTreeForest::enableBillboardRendering ( bool  enable)
virtual
virtual bool makVrv::DtSpeedTreeForest::isBillboardRenderingEnabled ( ) const
virtual
virtual void makVrv::DtSpeedTreeForest::enable3DTreeRendering ( bool  enable)
virtual
virtual bool makVrv::DtSpeedTreeForest::is3DTreeRenderingEnabled ( ) const
virtual
virtual void makVrv::DtSpeedTreeForest::enableReceiveShadows ( bool  enable)
virtual
virtual bool makVrv::DtSpeedTreeForest::isReceiveShadowsEnabled ( ) const
inlinevirtual
virtual void makVrv::DtSpeedTreeForest::setBoundingBox ( const osg::BoundingBox &  box)
virtual
virtual const osg::BoundingBox& makVrv::DtSpeedTreeForest::getBoundingBox ( void  ) const
virtual
virtual osg::ref_ptr<osg::Node> makVrv::DtSpeedTreeForest::getRootNode ( void  )
virtual

gets the root node for this forest which contains the stateset for the forest

virtual void makVrv::DtSpeedTreeForest::programBoundCallback ( osg::ref_ptr< makOsgSpeedTree::Forest pForest,
const makOsgSpeedTree::TreeType *  pTreeType,
uint32  programID 
)
virtual

callback from when a shader is loaded in speedtree so VRV can bind its own uniforms

virtual void makVrv::DtSpeedTreeForest::slot_reloadShaders ( )
virtual

Indicate to the SpeedTreeForest that it should recompile the SpeedTree (and related) shaders (done in the preUpdateCallback)

virtual void makVrv::DtSpeedTreeForest::slot_treeProfilingChanged ( bool  active)
virtual

turn tracy on or off

virtual void makVrv::DtSpeedTreeForest::slot_useGlobalAmbientChanged ( bool  enabled)
virtual

Runs when the user checks the Use Global Ambient Checkbox.

virtual void makVrv::DtSpeedTreeForest::slot_useGlobalDiffuseChanged ( bool  enabled)
virtual

Runs when the user checks the Use Global Diffuse Checkbox.

virtual void makVrv::DtSpeedTreeForest::slot_perPixelLightingEnabledChanged ( bool  enabled)
virtual

Runs when the user checks the Display Light Rendering Settings Enable Lighting checkbox.

virtual void makVrv::DtSpeedTreeForest::slot_planarReflectionsShowSpeedTreesChanged ( bool  enabled)
virtual

handles the flag that sets whether trees should be rendered in the planar reflections.

virtual void makVrv::DtSpeedTreeForest::processUnitialized ( )
virtual

called by job system post merge.

virtual bool makVrv::DtSpeedTreeForest::initialized ( )
virtual

has this forest been initialized yet.

virtual tbb::mutex& makVrv::DtSpeedTreeForest::mergeDrawMutex ( )
virtual

mutex for preventing the vis manager from being changed during draw

virtual tbb::mutex& makVrv::DtSpeedTreeForest::mergeUpdateMutex ( )
virtual

mutex for preventing the merge and update functions from running at the same time.

virtual osg::ref_ptr<makOsgSpeedTree::Forest>& makVrv::DtSpeedTreeForest::makSpeedTreeForest ( )
virtual

accessor for the underlying speedtree forest.

virtual void makVrv::DtSpeedTreeForest::preCullSetup ( osg::ref_ptr< makOsgSpeedTree::Forest forest,
osg::Camera *  camera 
)
virtual

check to see if this forest should be updated this frame and setup the fog color. This was moved from preUpdate so that it didn't happen in a background thread to avoid threading issues.

void makVrv::DtSpeedTreeForest::init ( const std::string &  strVisManagerType)
protected

Non-Virtual. Called by constructor.

virtual void makVrv::DtSpeedTreeForest::connectSignals ( void  )
protectedvirtual
virtual osg::Vec3f makVrv::DtSpeedTreeForest::computeWindDirection ( float  fDirection)
protectedvirtual
virtual void makVrv::DtSpeedTreeForest::setWindStrength ( float  fStrength)
protectedvirtual
virtual void makVrv::DtSpeedTreeForest::setWindDirection ( float  fDirection)
protectedvirtual
virtual bool makVrv::DtSpeedTreeForest::preUpdateCallback ( osg::ref_ptr< makOsgSpeedTree::Forest forest)
protectedvirtual

this now just returns the results of the preCullSetup check to see if update should happen this frame or not.

virtual bool makVrv::DtSpeedTreeForest::preRenderCallback ( osg::ref_ptr< makOsgSpeedTree::Forest forest,
osg::RenderInfo &  renderInfo 
)
protectedvirtual
virtual void makVrv::DtSpeedTreeForest::postRenderCallback ( osg::ref_ptr< makOsgSpeedTree::Forest forest,
osg::RenderInfo &  renderInfo 
)
protectedvirtual
virtual void makVrv::DtSpeedTreeForest::provideTimeCallback ( osg::ref_ptr< makOsgSpeedTree::Forest forest,
double fTime 
)
protectedvirtual
virtual void makVrv::DtSpeedTreeForest::pushGraphicsState ( osg::RenderInfo &  renderInfo)
protectedvirtual
virtual void makVrv::DtSpeedTreeForest::popGraphicsState ( osg::RenderInfo &  renderInfo)
protectedvirtual
virtual DtModelDefinition* makVrv::DtSpeedTreeForest::findModelDefinition ( const std::string &  modelDef)
protectedvirtual

Find a DtModelDefinition* from the model definition name.

virtual bool makVrv::DtSpeedTreeForest::createTree ( DtTreeRecord record)
protectedvirtual

No-op. Always returns true.

virtual void makVrv::DtSpeedTreeForest::initTreeDesc ( makOsgSpeedTree::TreeInstanceDescriptor &  desc,
DtTreeRecord record,
const DtVector up,
DtCoordinateConverter converter 
)
protectedvirtual

initialize a tree description. Pass in the coordinate converter since this can be called from both the main render thread or the merge thread

virtual void makVrv::DtSpeedTreeForest::initTreeDesc ( makOsgSpeedTree::TreeInstanceDescriptor &  desc,
DtTreeRecord record,
DtCoordinateConverter converter,
bool  setupTopoFrame = true 
)
protectedvirtual

initialize a tree description. Pass in the coordinate converter since this can be called from both the main render thread or the merge thread

virtual void makVrv::DtSpeedTreeForest::applyModelDefParameters ( makOsgSpeedTree::TreeInstanceDescriptor &  desc,
DtTreeRecord record 
)
protectedvirtual
virtual const bool makVrv::DtSpeedTreeForest::bindLightingAttributes ( const osg::Node *  node,
const uint32  programID,
DtOsgRenderer osgRenderer,
const std::string &  searchNodeName 
)
protectedvirtual

Recursively walk up the scenegraph searching for a node to bind lighting attributes to the shader program. This method assumes myExt is valid for this object. Returns true if search node was found.

Parameters
nodeThe current node to operate with.
programIDThe shader program to bind attributes to.
osgRendererA valid pointer to the renderer.
searchNodeNameThe node name to search for.
static DtOsgCullVisitorParameters* makVrv::DtSpeedTreeForest::getCullParameters ( osg::RenderInfo &  renderInfo)
staticprotected
static bool makVrv::DtSpeedTreeForest::isCameraOrthographic ( DtOsgCullVisitorParameters params)
staticprotected
static bool makVrv::DtSpeedTreeForest::isReflectionCamera ( osg::Camera *  camera)
staticprotected

is the current camera in the render info a reflection camera

static float makVrv::DtSpeedTreeForest::getZoomFactor ( DtOsgCullVisitorParameters params,
DtDe de 
)
staticprotected

Friends And Related Function Documentation

friend class DtSpeedTreeForestClassesCreator
friend
friend class DtSpeedTreeForestObjectCreator
friend

Member Data Documentation

const float makVrv::DtSpeedTreeForest::myCellSize
staticprotected
unsigned int makVrv::DtSpeedTreeForest::theLastImGuiFrameNumber
staticprotected
bool makVrv::DtSpeedTreeForest::theEnableAsyncUpdate
staticprotected
makOsgSpeedTree::TreeInstanceDescriptor makVrv::DtSpeedTreeForest::myScratchTreeInstanceDesc
protected
makOsgSpeedTree::TreeInstanceDescriptorCollection makVrv::DtSpeedTreeForest::myScratchTreeInstanceDescCollection
protected
makOsgSpeedTree::TreeInstanceCollection makVrv::DtSpeedTreeForest::myScratchInstanceCollection
protected
MapModelDefToSTFileName makVrv::DtSpeedTreeForest::myMapModelDefToSTFileName
protected
int makVrv::DtSpeedTreeForest::myPreviousTU
protected
osg::Camera* makVrv::DtSpeedTreeForest::myCamera
protected
DtSignalConnectionManager makVrv::DtSpeedTreeForest::myConnections
protected
std::unordered_map<int, bool> makVrv::DtSpeedTreeForest::myShaderBoundMap
protected
float makVrv::DtSpeedTreeForest::myFarPlane
protected
osg::ref_ptr<osg::Group> makVrv::DtSpeedTreeForest::myRoot
protected

The forest is a collection of trees under a group node.

osg::ref_ptr<osg::PositionAttitudeTransform> makVrv::DtSpeedTreeForest::myPat
protected
osg::ref_ptr<makOsgSpeedTree::Forest> makVrv::DtSpeedTreeForest::myForest
protected
osg::BoundingBox makVrv::DtSpeedTreeForest::myBoundingBox
protected
DtSpeedTreeCore& makVrv::DtSpeedTreeForest::myCore
protected
DtEnvironmentInfo& makVrv::DtSpeedTreeForest::myEnvInfo
protected
MapCellsToTrees makVrv::DtSpeedTreeForest::myMapCellsToTrees
protected
MapTreeIDToTree makVrv::DtSpeedTreeForest::myMapTreeIDtoTree
protected
unsigned int makVrv::DtSpeedTreeForest::myLastShaderHash
protected

shader hash for the last shaders passed down to SpeedTree

bool makVrv::DtSpeedTreeForest::myReloadShaders
protected

Should we reload the SpeedTree shaders.

const std::string makVrv::DtSpeedTreeForest::mySpeedTreeDefaultUserFuncsVertexShader
protected
const std::string makVrv::DtSpeedTreeForest::mySpeedTreeDefaultUserFuncsPixelShader
protected
const std::string makVrv::DtSpeedTreeForest::mySpeedTreeMultiViewUserFuncsVertexShader
protected
osg::ref_ptr<osg::Uniform> makVrv::DtSpeedTreeForest::myProjectionMatrixInverseUniform
protected
osg::ref_ptr<osg::Uniform> makVrv::DtSpeedTreeForest::myNormalMatrixUniform
protected
osg::GLExtensions* makVrv::DtSpeedTreeForest::myExt
protected
bool makVrv::DtSpeedTreeForest::myReceiveShadows
protected
tbb::mutex makVrv::DtSpeedTreeForest::myForestMergeDrawMutex
protected
tbb::mutex makVrv::DtSpeedTreeForest::myForestAddRemoveMutex
protected
tbb::mutex makVrv::DtSpeedTreeForest::myForestMergeUpdateMutex
protected
DtCoordinateConverter* makVrv::DtSpeedTreeForest::myMainThreadConverter
protected
DtCoordinateConverter* makVrv::DtSpeedTreeForest::myMergeBackgroundConverter
protected
bool makVrv::DtSpeedTreeForest::myShouldUpdateThisFrame
protected
unsigned int makVrv::DtSpeedTreeForest::myRestoreVisibilityNodeMask
protected

The documentation for this class was generated from the following file:

Document ID: Generated on Thu Jun 1 17:58:13 EDT 2023 from SVN revision 255404
Copyright © 2005-2021 MAK Technologies. All Rights Reserved (www.mak.com)