Revision: 1655
          http://rigsofrods.svn.sourceforge.net/rigsofrods/?rev=1655&view=rev
Author:   rorthomas
Date:     2011-02-06 00:10:04 +0000 (Sun, 06 Feb 2011)

Log Message:
-----------


Modified Paths:
--------------
    trunk/source/main/CMakeLists.txt

Added Paths:
-----------
    trunk/source/main/gfx/dof/
    trunk/source/main/gfx/dof/DepthOfFieldEffect.cpp
    trunk/source/main/gfx/dof/DepthOfFieldEffect.h
    trunk/source/main/gfx/dof/Lens.cpp
    trunk/source/main/gfx/dof/Lens.h

Removed Paths:
-------------
    trunk/source/main/dof/

Modified: trunk/source/main/CMakeLists.txt
===================================================================
--- trunk/source/main/CMakeLists.txt    2011-02-06 00:09:04 UTC (rev 1654)
+++ trunk/source/main/CMakeLists.txt    2011-02-06 00:10:04 UTC (rev 1655)
@@ -91,9 +91,9 @@
 #additional include dirs
 include_directories(.)
 add_sub_dir(audio)
-add_sub_dir(dof)
 add_sub_dir(gameplay)
 add_sub_dir(gfx)
+add_sub_dir(gfx/dof)
 add_sub_dir(gui)
 add_sub_dir(gui/mygui)
 add_sub_dir(physics)

Added: trunk/source/main/gfx/dof/DepthOfFieldEffect.cpp
===================================================================
--- trunk/source/main/gfx/dof/DepthOfFieldEffect.cpp                            
(rev 0)
+++ trunk/source/main/gfx/dof/DepthOfFieldEffect.cpp    2011-02-06 00:10:04 UTC 
(rev 1655)
@@ -0,0 +1,436 @@
+// "Depth of Field" demo for Ogre
+// Copyright (C) 2006  Christian Lindequist Larsen
+//
+// This code is in the public domain. You may do whatever you want with it.
+
+#include "DepthOfFieldEffect.h"
+#include <Ogre.h>
+#include "Lens.h"
+
+#include "RoRPrerequisites.h"
+
+#include "Settings.h"
+
+using namespace Ogre;
+
+const int DepthOfFieldEffect::BLUR_DIVISOR = 2;
+
+DepthOfFieldEffect::DepthOfFieldEffect(Ogre::Viewport *v, Ogre::Camera *cam) :
+       mNearDepth(10.0)
+       , mFocalDepth(100.0)
+       , mFarDepth(190.0)
+       , mFarBlurCutoff(1.0)
+       , mViewport(v)
+       , mCamera(cam)
+{
+       mWidth = mViewport->getActualWidth();
+       mHeight = mViewport->getActualHeight();
+
+       mCompositor = NULL;
+       mDepthTechnique = NULL;
+       mDepthTarget = NULL;
+       mDepthViewport = NULL;
+       mDepthTexture.setNull();
+       mDepthMaterial.setNull();
+
+       createDepthRenderTexture();
+       addCompositor();
+}
+
+DepthOfFieldEffect::~DepthOfFieldEffect()
+{
+       removeCompositor();
+       destroyDepthRenderTexture();
+}
+
+void DepthOfFieldEffect::setFocalDepths(float nearDepth, float focalDepth, 
float farDepth)
+{
+       mNearDepth = nearDepth;
+       mFocalDepth = focalDepth;
+       mFarDepth = farDepth;
+}
+
+void DepthOfFieldEffect::setFarBlurCutoff(float cutoff)
+{
+       mFarBlurCutoff = cutoff;
+}
+
+bool DepthOfFieldEffect::getEnabled() const
+{
+       return mCompositor->getEnabled();
+}
+
+void DepthOfFieldEffect::setEnabled(bool value)
+{
+       mCompositor->setEnabled(value);
+}
+
+void DepthOfFieldEffect::createDepthRenderTexture()
+{
+       // Create the depth render texture
+       mDepthTexture = TextureManager::getSingleton().createManual(
+               "DoF_Depth",ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
+               TEX_TYPE_2D, mWidth, mHeight,
+               0, PF_L8, TU_RENDERTARGET);
+
+       // Get its render target and add a viewport to it
+       mDepthTarget = mDepthTexture->getBuffer()->getRenderTarget();
+       mDepthViewport = mDepthTarget->addViewport(mCamera);
+
+       // Register 'this' as a render target listener
+       mDepthTarget->addListener(this);
+
+       // Get the technique to use when rendering the depth render texture
+       mDepthMaterial = MaterialManager::getSingleton().getByName("DoF_Depth");
+       mDepthMaterial->load(); // needs to be loaded manually
+       mDepthTechnique = mDepthMaterial->getBestTechnique();
+
+       // Create a custom render queue invocation sequence for the depth 
render texture
+    RenderQueueInvocationSequence* invocationSequence = 
Root::getSingleton().createRenderQueueInvocationSequence("DoF_Depth");
+
+       // Add a render queue invocation to the sequence, and disable shadows 
for it
+       /*
+       RenderQueueInvocation* invocation = 
invocationSequence->add(RENDER_QUEUE_MAIN, "main");
+    invocation->setSuppressShadows(true);
+       //invocation->setSuppressRenderStateChanges(true);
+       
invocation->setSolidsOrganisation(QueuedRenderableCollection::OM_SORT_ASCENDING);
+       // Set the render queue invocation sequence for the depth render 
texture viewport
+    mDepthViewport->setRenderQueueInvocationSequenceName("DoF_Depth");
+       */
+
+       mDepthViewport->setShadowsEnabled(false);
+       mDepthViewport->setOverlaysEnabled(false);
+       //mDepthViewport->setSkiesEnabled(false);
+
+       mDepthViewport->setVisibilityMask(~DEPTHMAP_DISABLED);
+
+       //re-set texture "DoF_Depth"
+       MaterialPtr p = 
MaterialManager::getSingleton().getByName("DoF_DepthOfField");
+       p->load();
+       
p->getBestTechnique()->getPass(0)->getTextureUnitState("depth")->setTextureName("DoF_Depth");
+       p->unload();
+}
+
+void DepthOfFieldEffect::destroyDepthRenderTexture()
+{
+       mDepthViewport->setRenderQueueInvocationSequenceName("");
+       Root::getSingleton().destroyRenderQueueInvocationSequence("DoF_Depth");
+
+       mDepthMaterial->unload();
+
+       mDepthTarget->removeAllListeners();
+       mDepthTarget->removeAllViewports();
+       //TextureManager::getSingleton().unload("DoF_Depth");
+       TextureManager::getSingleton().remove("DoF_Depth");
+}
+
+void DepthOfFieldEffect::addCompositor()
+{
+       mCompositor = 
CompositorManager::getSingleton().addCompositor(mViewport, 
"DoF_Compositor_test");
+       mCompositor->addListener(this);
+
+       mCompositor->setEnabled(true);
+}
+
+void DepthOfFieldEffect::removeCompositor()
+{
+       mCompositor->setEnabled(false);
+
+       mCompositor->removeListener(this);
+       CompositorManager::getSingleton().removeCompositor(mViewport, 
"DoF_Compositor_test");
+}
+
+void DepthOfFieldEffect::notifyMaterialSetup(uint32 passId, MaterialPtr& 
material)
+{
+       switch (passId)
+       {
+       case BlurPass:
+               {
+                       //float pixelSize[2] = {
+                       //      1.0f / (mViewport->getActualWidth() / 
BLUR_DIVISOR),
+                       //      1.0f / (mViewport->getActualHeight() / 
BLUR_DIVISOR)};
+
+                       // Adjust fragment program parameters
+                       Ogre::Vector3 ps = Ogre::Vector3(1.0f / (mWidth / 
BLUR_DIVISOR),1.0f / (mHeight / BLUR_DIVISOR), 1.0f);
+                       float pixelSize[3] = { ps.x, ps.y, ps.z };
+                       GpuProgramParametersSharedPtr fragParams = 
material->getBestTechnique()->getPass(0)->getFragmentProgramParameters();
+                       
if((!fragParams.isNull())&&(fragParams->_findNamedConstantDefinition("pixelSize")))
+                               fragParams->setNamedConstant("pixelSize", 
pixelSize, 1, 3);
+
+                       break;
+               }
+
+       case OutputPass:
+               {
+                       float pixelSizeScene[3] = {
+                               1.0f / mWidth,
+                               1.0f / mHeight,
+                               0};
+
+                       float pixelSizeBlur[3] = {
+                               1.0f / (mWidth / BLUR_DIVISOR),
+                               1.0f / (mHeight / BLUR_DIVISOR),
+                               0};
+
+                       // Adjust fragment program parameters
+                       GpuProgramParametersSharedPtr fragParams =
+                               
material->getBestTechnique()->getPass(0)->getFragmentProgramParameters();
+                       
if((!fragParams.isNull())&&(fragParams->_findNamedConstantDefinition("pixelSizeScene")))
+                               fragParams->setNamedConstant("pixelSizeScene", 
pixelSizeScene,1,3);
+                       
if((!fragParams.isNull())&&(fragParams->_findNamedConstantDefinition("pixelSizeBlur")))
+                               fragParams->setNamedConstant("pixelSizeBlur", 
pixelSizeBlur,1,3);
+
+                       break;
+               }
+       }
+}
+
+void DepthOfFieldEffect::preViewportUpdate(const 
Ogre::RenderTargetViewportEvent& evt)
+{
+
+       float dofParams[4] = {mNearDepth, mFocalDepth, mFarDepth, 
mFarBlurCutoff};
+
+       // Adjust fragment program parameters for depth pass
+       GpuProgramParametersSharedPtr fragParams =
+               mDepthTechnique->getPass(0)->getFragmentProgramParameters();
+       
if((!fragParams.isNull())&&(fragParams->_findNamedConstantDefinition("dofParams")))
+               fragParams->setNamedConstant("dofParams", dofParams,1,4);       
        
+
+       evt.source->setVisibilityMask(~DEPTHMAP_DISABLED);
+
+       // Add 'this' as a RenderableListener to replace the technique for all 
renderables
+       RenderQueue* queue = 
evt.source->getCamera()->getSceneManager()->getRenderQueue();
+       queue->setRenderableListener(this);
+}
+
+void DepthOfFieldEffect::postViewportUpdate(const 
Ogre::RenderTargetViewportEvent& evt)
+{
+       // Reset the RenderableListener
+       RenderQueue* queue = 
evt.source->getCamera()->getSceneManager()->getRenderQueue();
+       queue->setRenderableListener(0);
+}
+
+bool DepthOfFieldEffect::renderableQueued(Ogre::Renderable* rend, Ogre::uint8 
groupID, 
+                               Ogre::ushort priority, Ogre::Technique** 
ppTech, Ogre::RenderQueue* pQueue)
+{
+       // Replace the technique of all renderables
+       *ppTech = mDepthTechnique;
+       return true;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////
+DOFManager::DOFManager(Ogre::SceneManager *m, Ogre::Viewport *mViewport, 
Ogre::Root *root, Ogre::Camera *cam) : mRoot(root), mCamera(cam), mSceneMgr(m)
+{
+       mFocusMode = Manual;
+       mAutoSpeed = 30;
+       mAutoTime = 0.5f;
+       targetFocalDistance = 5;
+
+       mDepthOfFieldEffect = new DepthOfFieldEffect(mViewport, mCamera);
+       mLens = new Lens(mCamera->getFOVy(), 1);
+       mLens->setFocalDistance(5);
+       //mLens->setFStop(10);
+//     mDepthOfFieldEffect->setEnabled(false);
+       mRoot->addFrameListener(this);
+
+       mRaySceneQuery = mSceneMgr->createRayQuery(Ogre::Ray());
+       mRaySceneQuery->setSortByDistance(true);
+       //mRaySceneQuery->setQueryMask(queryMask);
+
+       debugNode = 0;
+       bool debug = (SETTINGS.getSetting("DOFDebug") == "Yes");
+       if(debug)
+       {
+               MaterialPtr material = 
MaterialManager::getSingleton().getByName("DoF_DepthDebug");
+               
material->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName("DoF_Depth");
+               Overlay* overlay = 
OverlayManager::getSingleton().getByName("DoF_DepthDebugOverlay");
+               overlay->show();
+
+               debugNode = 
mSceneMgr->getRootSceneNode()->createChildSceneNode();
+               Entity *ent = mSceneMgr->createEntity("sphere.mesh");
+               debugNode->attachObject(ent);
+               debugNode->setScale(0.001, 0.001, 0.001);
+       }
+}
+
+DOFManager::~DOFManager()
+{
+       cleanup();
+}
+
+void DOFManager::cleanup()
+{
+       mRoot->removeFrameListener(this);
+
+       delete mLens;
+       mLens = NULL;
+
+       delete mDepthOfFieldEffect;
+       mDepthOfFieldEffect = NULL;
+}
+
+void DOFManager::setAutoSpeed(float f)
+{
+       mAutoSpeed = f;
+}
+
+void DOFManager::setEnabled(bool enabled)
+{
+       mDepthOfFieldEffect->setEnabled(enabled);
+       /*
+       // crashes for some reason
+       if(enabled && !mDepthOfFieldEffect->getEnabled())
+       {
+               // turn on
+               mDepthOfFieldEffect->setEnabled(true);
+               mRoot->addFrameListener(this);
+       } else if(!enabled && mDepthOfFieldEffect->getEnabled())
+       {
+               // turn off
+               mDepthOfFieldEffect->setEnabled(false);
+               mRoot->removeFrameListener(this);
+       }
+       */
+}
+
+bool DOFManager::getEnabled()
+{
+       return mDepthOfFieldEffect->getEnabled();
+}
+
+void DOFManager::zoomView(float delta)
+{
+       Real fieldOfView = mLens->getFieldOfView().valueRadians();
+       fieldOfView += delta;
+       fieldOfView = std::max<Real>(0.1, std::min<Real>(fieldOfView, 2.0));
+       mLens->setFieldOfView(Radian(fieldOfView));
+       mCamera->setFOVy(Radian(fieldOfView));
+}
+
+void DOFManager::Aperture(float delta)
+{
+       if (mFocusMode == Pinhole)
+               return;
+       Real fStop = mLens->getFStop();
+       fStop += delta;
+       fStop = std::max<Real>(0.5, std::min<Real>(fStop, 12.0));
+       mLens->setFStop(fStop);
+}
+
+void DOFManager::moveFocus(float delta)
+{
+       mLens->setFocalDistance(mLens->getFocalDistance() + delta);
+}
+
+void  DOFManager::setZoom(float f)
+{
+       Real fieldOfView = Degree(Real(f)).valueRadians();
+       fieldOfView = std::max<Real>(0.1, std::min<Real>(fieldOfView, 2.0));
+       mLens->setFieldOfView(Radian(fieldOfView));
+       mCamera->setFOVy(Radian(fieldOfView));
+}
+
+void  DOFManager::setLensFOV(Radian fov)
+{
+       mLens->setFieldOfView(fov);
+}
+
+void  DOFManager::setAperture(float f)
+{
+       if (mFocusMode == Pinhole)
+               return;
+       Real fStop = f;
+       fStop = std::max<Real>(0.5, std::min<Real>(fStop, 12.0));
+       mLens->setFStop(fStop);
+}
+
+void  DOFManager::setFocus(float f)
+{
+       mLens->setFocalDistance(f);
+}
+
+bool DOFManager::frameStarted(const FrameEvent& evt)
+{
+       Camera *camera = mCamera;
+       // Focusing
+       switch (mFocusMode)
+       {
+               case Auto:
+               {
+                       // TODO: Replace with accurate ray/triangle collision 
detection
+                       Real currentFocalDistance = mLens->getFocalDistance();
+
+                       // TODO: Continous AF / triggered
+                       mAutoTime -= evt.timeSinceLastFrame;
+                       if(mAutoTime <= 0.0f)
+                       {
+                               mAutoTime = 0.5f;
+
+                               targetFocalDistance = currentFocalDistance;
+
+                               // Ryan Booker's (eyevee99) ray scene query 
auto focus
+                               Ray focusRay;
+                               
focusRay.setOrigin(camera->getDerivedPosition());
+                               
focusRay.setDirection(camera->getDerivedDirection());
+                               Vector3 v;
+                               Vector3 vn;
+                               
+                               mRaySceneQuery->setRay(focusRay);
+                               Ogre::RaySceneQueryResult &qryResult = 
mRaySceneQuery->execute();
+                               for (Ogre::RaySceneQueryResult::iterator it = 
qryResult.begin();it != qryResult.end(); it++)
+                               {
+                                       if(it->worldFragment)
+                                       {
+                                               if(debugNode) 
debugNode->setPosition(it->worldFragment->singleIntersection + 
Vector3(0.5,0,0));
+                                               targetFocalDistance = 
(mCamera->getPosition() - it->worldFragment->singleIntersection).length();
+                                               break;
+                                       } else
+                                       {
+                                               /*
+                                               // this wont work since we 
would need to go down to the polygon level :(
+                                               if(debugNode) 
debugNode->setPosition(focusRay.getPoint(it->distance));
+                                               targetFocalDistance = 
it->distance;
+                                               break;
+                                               */
+                                       }
+
+                               }
+                       }
+
+                       // Slowly adjust the focal distance (emulate auto focus 
motor)
+                       if (currentFocalDistance < targetFocalDistance)
+                       {
+                               mLens->setFocalDistance(
+                                       std::min<Real>(currentFocalDistance + 
mAutoSpeed * evt.timeSinceLastFrame, targetFocalDistance));
+                       }
+                       else if (currentFocalDistance > targetFocalDistance)
+                       {
+                               mLens->setFocalDistance(
+                                       std::max<Real>(currentFocalDistance - 
mAutoSpeed * evt.timeSinceLastFrame, targetFocalDistance));
+                       }
+
+                       break;
+               }
+
+               case Manual:
+                       //we set the values elsewhere
+                       break;
+       }
+
+       // Update Depth of Field effect
+       if (mFocusMode != Pinhole)
+       {
+               mDepthOfFieldEffect->setEnabled(true);
+
+               // Calculate and set depth of field using lens
+               float nearDepth, focalDepth, farDepth;
+               mLens->recalculateDepthOfField(nearDepth, focalDepth, farDepth);
+               mDepthOfFieldEffect->setFocalDepths(nearDepth, focalDepth, 
farDepth);
+       }
+       else
+       {
+               mDepthOfFieldEffect->setEnabled(false);
+       }
+
+       return true;
+}

Added: trunk/source/main/gfx/dof/DepthOfFieldEffect.h
===================================================================
--- trunk/source/main/gfx/dof/DepthOfFieldEffect.h                              
(rev 0)
+++ trunk/source/main/gfx/dof/DepthOfFieldEffect.h      2011-02-06 00:10:04 UTC 
(rev 1655)
@@ -0,0 +1,119 @@
+// "Depth of Field" demo for Ogre
+// Copyright (C) 2006  Christian Lindequist Larsen
+//
+// This code is in the public domain. You may do whatever you want with it.
+
+#ifndef __DepthOfFieldEffect_H__
+#define __DepthOfFieldEffect_H__
+
+#include "OgrePrerequisites.h"
+#include "OgreCompositorInstance.h"
+#include "OgreRenderTargetListener.h"
+#include "OgreFrameListener.h"
+#include "OgreRenderQueue.h"
+
+class Lens;
+
+class DepthOfFieldEffect : public Ogre::CompositorInstance::Listener,
+                                                  public 
Ogre::RenderTargetListener,
+                                                  public 
Ogre::RenderQueue::RenderableListener
+{
+public:
+       DepthOfFieldEffect(Ogre::Viewport *mViewport, Ogre::Camera *cam);
+       ~DepthOfFieldEffect();
+
+       float getNearDepth() const {return mNearDepth; }
+       float getFocalDepth() const {return mFocalDepth; }
+       float getFarDepth() const {return mFarDepth; }
+       void setFocalDepths(float nearDepth, float focalDepth, float farDepth);
+       float getFarBlurCutoff() const {return mFarBlurCutoff; }
+       void setFarBlurCutoff(float cutoff);
+       bool getEnabled() const;
+       void setEnabled(bool value);
+
+private:
+       // Implementation of Ogre::CompositorInstance::Listener
+       virtual void notifyMaterialSetup(Ogre::uint32 passId, 
Ogre::MaterialPtr& material);
+
+       // Implementation of Ogre::RenderTargetListener
+       virtual void preViewportUpdate(const Ogre::RenderTargetViewportEvent& 
evt);
+       virtual void postViewportUpdate(const Ogre::RenderTargetViewportEvent& 
evt);
+
+       // Implementation of Ogre::RenderQueue::RenderableListener
+       virtual bool renderableQueued(Ogre::Renderable* rend, Ogre::uint8 
groupID, 
+                               Ogre::ushort priority, Ogre::Technique** 
ppTech, Ogre::RenderQueue* pQueue);
+
+       int mWidth;
+       int mHeight;
+
+       static const int BLUR_DIVISOR;
+
+       enum PassId
+       {
+               BlurPass,
+               OutputPass
+       };
+
+       Ogre::Viewport* mDepthViewport;
+       Ogre::RenderTexture* mDepthTarget;
+       Ogre::TexturePtr mDepthTexture;
+       Ogre::MaterialPtr mDepthMaterial;
+       Ogre::Technique* mDepthTechnique;
+       Ogre::CompositorInstance* mCompositor;
+       Ogre::Viewport *mViewport;
+       Ogre::Camera *mCamera;
+
+       float mNearDepth;
+       float mFocalDepth;
+       float mFarDepth;
+       float mFarBlurCutoff;
+
+       void createDepthRenderTexture();
+       void destroyDepthRenderTexture();
+//     void createCompositor();
+//     void destroyCompositor();
+       void addCompositor();
+       void removeCompositor();
+};
+
+class DOFManager : public Ogre::FrameListener
+{
+public:
+       DOFManager(Ogre::SceneManager *m, Ogre::Viewport *v, Ogre::Root *r, 
Ogre::Camera *cam);
+       ~DOFManager();
+
+
+       void setEnabled(bool enabled);
+       bool getEnabled();
+
+       // controls
+       enum FocusMode {Auto, Manual, Pinhole};
+       void setFocusMode(int mode) {mFocusMode = (FocusMode)mode;}
+       void setAutoSpeed(float f);
+       void zoomView(float delta);
+       void Aperture(float delta);
+       void moveFocus(float delta);
+       void setZoom(float f);
+       void setLensFOV(Ogre::Radian fov);
+       void setAperture(float f);
+       void setFocus(float f);
+
+protected:
+       virtual bool frameStarted(const Ogre::FrameEvent& evt);
+
+       Ogre::Root *mRoot;
+       Ogre::Camera *mCamera;
+       Ogre::RaySceneQuery *mRaySceneQuery;
+       Ogre::SceneManager *mSceneMgr;
+
+       void cleanup();
+       DepthOfFieldEffect* mDepthOfFieldEffect;
+       Lens* mLens;
+       FocusMode mFocusMode;
+       float mAutoSpeed;
+       float mAutoTime;
+       Ogre::Real targetFocalDistance;
+       Ogre::SceneNode *debugNode;
+};
+
+#endif // __DepthOfFieldEffect_H__

Added: trunk/source/main/gfx/dof/Lens.cpp
===================================================================
--- trunk/source/main/gfx/dof/Lens.cpp                          (rev 0)
+++ trunk/source/main/gfx/dof/Lens.cpp  2011-02-06 00:10:04 UTC (rev 1655)
@@ -0,0 +1,128 @@
+// "Depth of Field" demo for Ogre
+// Copyright (C) 2006  Christian Lindequist Larsen
+//
+// This code is in the public domain. You may do whatever you want with it.
+//
+// Author: Ryan Booker (eyevee99)
+
+#include "Lens.h"
+#include "Ogre.h"
+
+using namespace Ogre;
+
+#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
+#undef min
+#undef max
+#endif
+
+template<class T>
+const T& min(const T& a, const T& b) {
+  return (a < b) ? a : b;
+};
+
+
+template<class T>
+const T& max(const T& a, const T& b) {
+  return (a > b) ? a : b;
+};
+
+
+Lens::Lens(const Real& _focalLength, const Real& _fStop, const Real& 
_frameSize, const Real& _circleOfConfusion) {
+  init(_focalLength, _fStop, _frameSize, _circleOfConfusion);
+}
+
+
+Lens::Lens(const Radian& _fieldOfView, const Real& _fStop, const Real& 
_frameSize, const Real& _circleOfConfusion) {
+  init(_fieldOfView, _fStop, _frameSize, _circleOfConfusion);
+}
+
+
+void Lens::init(const Real& _focalLength, const Real& _fStop, const Real& 
_frameSize, const Real& _circleOfConfusion) {
+  mFocalLength = _focalLength;
+  mFStop = _fStop;
+  mFrameSize = _frameSize;
+  mCircleOfConfusion = _circleOfConfusion;
+  recalculateFieldOfView();
+}
+
+
+void Lens::init(const Radian& _fieldOfView, const Real& _fStop, const Real& 
_frameSize, const Real& _circleOfConfusion) {
+  mFieldOfView = _fieldOfView;
+  mFStop = _fStop;
+  mFrameSize = _frameSize;
+  mCircleOfConfusion = _circleOfConfusion;
+  recalculateFocalLength();
+}
+
+
+void Lens::setFrameSize(const Real& _frameSize) {
+  mFrameSize = _frameSize;
+  recalculateFieldOfView();
+}
+
+
+void Lens::setFocalDistance(const Real& _focalDistance) {
+  mFocalDistance = max(_focalDistance, Real(0));
+}
+
+
+void Lens::setFocalLength(const Real& _focalLength) {
+  mFocalLength = max(_focalLength, Real(0.3));
+  recalculateFieldOfView();
+}
+
+
+void Lens::setFieldOfView(const Radian& _fieldOfView) {
+  mFieldOfView = min(_fieldOfView, Radian(2.8));
+  recalculateFocalLength();
+}
+
+
+void Lens::setFStop(const Real& _fStop) {
+  mFStop = max(_fStop, Real(0));
+}
+
+
+void Lens::recalculateFocalLength(void) {
+  mFocalLength = (mFrameSize / Math::Tan(mFieldOfView / 2.0)) / 2.0;
+}
+
+
+void Lens::recalculateFieldOfView(void) {
+  mFieldOfView = 2.0 * Math::ATan(mFrameSize / (2.0 * mFocalLength));
+}
+
+
+void Lens::recalculateHyperfocalLength(void) {
+  mHyperfocalLength = (mFocalLength * mFocalLength) / (mFStop * 
mCircleOfConfusion) + mFocalLength;
+}
+
+
+void Lens::recalculateDepthOfField(Real& _nearDepth, Real& _focalDepth, Real& 
_farDepth) {
+  // Set focalDepth to the current focalDistance
+  _focalDepth = mFocalDistance;
+
+  // Recalculate the Hyperfocal length
+  recalculateHyperfocalLength();
+
+  // Calculate the numerator of the optics equations
+  Real numerator = (mFocalDistance * (mHyperfocalLength - mFocalLength));
+
+  Real nearClear = numerator / (mHyperfocalLength + mFocalDistance - (2.0 * 
mFocalLength));
+
+  // Adjust the nearDepth relative to the aperture. This is an approximation.
+  _nearDepth = min(nearClear - nearClear * mFStop, (Real)0);
+
+  if(mFocalDistance < mHyperfocalLength)
+  {
+    // Calculate the far clear plane
+    Real farClear = numerator / (mHyperfocalLength - mFocalDistance);
+
+    // Adjust the farDepth relative to the aperture. This is an approximation.
+    _farDepth = farClear + farClear * mFStop;
+  }
+
+  // Far depth of field should be infinite
+  else
+    _farDepth = Math::POS_INFINITY;
+}

Added: trunk/source/main/gfx/dof/Lens.h
===================================================================
--- trunk/source/main/gfx/dof/Lens.h                            (rev 0)
+++ trunk/source/main/gfx/dof/Lens.h    2011-02-06 00:10:04 UTC (rev 1655)
@@ -0,0 +1,60 @@
+// "Depth of Field" demo for Ogre
+// Copyright (C) 2006  Christian Lindequist Larsen
+//
+// This code is in the public domain. You may do whatever you want with it.
+//
+// Author: Ryan Booker (eyevee99)
+
+#ifndef __Lens_H__
+#define __Lens_H__
+
+#include "OgrePrerequisites.h"
+#include "OgreMath.h"
+
+class Lens {
+public:
+  Lens(void) {};
+  Lens(const Ogre::Real& _focalLength, const Ogre::Real& _fStop, const 
Ogre::Real& _frameSize = 3.5, const Ogre::Real& _circleOfConfusion = 0.003);
+  Lens(const Ogre::Radian& _fieldOfView, const Ogre::Real& _fStop, const 
Ogre::Real& _frameSize = 3.5, const Ogre::Real& _circleOfConfusion = 0.003);
+  ~Lens(void) {};
+
+  void init(const Ogre::Real& _focalLength, const Ogre::Real& _fStop, const 
Ogre::Real& _frameSize = 3.5, const Ogre::Real& _circleOfConfusion = 0.003);
+  void init(const Ogre::Radian& _fieldOfView, const Ogre::Real& _fStop, const 
Ogre::Real& _frameSize = 3.5, const Ogre::Real& _circleOfConfusion = 0.003);
+
+  void setFrameSize(const Ogre::Real& _frameSize);
+  void setFocalDistance(const Ogre::Real& _focalDistance);
+  void setFocalLength(const Ogre::Real& _focalLength);
+  void setFieldOfView(const Ogre::Radian& _fieldOfView);
+  void setFStop(const Ogre::Real& _fStop);
+
+  const Ogre::Real& getFrameSize(void)            { return mFrameSize; }
+  const Ogre::Real& getFocalDistance(void)        { return mFocalDistance; }
+  const Ogre::Real& getFocalLength(void)          { return mFocalLength; }
+  const Ogre::Radian& getFieldOfView(void)        { return mFieldOfView; }
+  const Ogre::Real& getFStop(void)                { return mFStop; }
+  const Ogre::Real& getHyperfocalLength(void)     { return mHyperfocalLength; }
+
+  void recalculateDepthOfField(Ogre::Real& _nearDepth, Ogre::Real& 
_focalDepth, Ogre::Real& _farDepth);
+
+
+protected:
+  // NOTE: All units must be the same, eg mm, cm or m etc
+  // Primary attributes
+  Ogre::Real mFrameSize;                // Film stock/sensor size, arbitrarily 
selected to help mimic the properties of film, eg 35mm, 3.5cm, 0.035m etc
+  Ogre::Real mCircleOfConfusion;        // The area within which the depth of 
field is clear, it's tied to frame size, eg 0.03mm, 0.003cm, 0.0003m etc
+  Ogre::Real mFocalDistance;            // The distance to the object we are 
focusing on
+  Ogre::Real mFocalLength;              // Focal length of the lens, this 
directly effects field of view, we can do anything from wide angle to telephoto 
as we don't have the limitations of physical lenses.  Focal length is the 
distance from the optical centre of the lens to the film stock/sensor etc
+  Ogre::Real mFStop;                    // FStop number, ie aperture, changing 
the aperture of a lens has an effect of depth of field, the narrower the 
aperture/higher the fstop number, the greater the depth of field/clearer the 
picture is.
+
+  // Secondary attributes
+  Ogre::Real mHyperfocalLength;         // The hyperfocal length is the point 
at which far depth of field is infinite, ie if mFocalDistance is >= to this 
value everythig will be clear to infinity
+  Ogre::Radian mFieldOfView;            // Field of view of the lens, directly 
related to focal length
+
+
+private:
+  void recalculateHyperfocalLength(void);
+  void recalculateFieldOfView(void);
+  void recalculateFocalLength(void);
+};
+
+#endif


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
The modern datacenter depends on network connectivity to access resources
and provide services. The best practices for maximizing a physical server's
connectivity to a physical network are well understood - see how these
rules translate into the virtual world? 
http://p.sf.net/sfu/oracle-sfdevnlfb
_______________________________________________
Rigsofrods-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/rigsofrods-devel

Reply via email to