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