Also, I forget to mention, the reference view is set as follows:
Code: Select all
DistanceLodStrategy::getSingleton().setReferenceView(viewportWidth, viewportHeight, fov);
Code: Select all
DistanceLodStrategy::getSingleton().setReferenceView(viewportWidth, viewportHeight, fov);
Code: Select all
Modified: branches/v1-6/OgreMain/include/OgreCamera.h
===================================================================
--- branches/v1-6/OgreMain/include/OgreCamera.h 2008-07-29 12:53:43 UTC (rev 7803)
+++ branches/v1-6/OgreMain/include/OgreCamera.h 2008-07-30 11:03:11 UTC (rev 7804)
@@ -149,6 +149,8 @@
Frustum *mCullFrustum;
/// Whether or not the rendering distance of objects should take effect for this camera
bool mUseRenderingDistance;
+ /// Camera to use for LOD calculation
+ const Camera* mLodCamera;
// Internal functions for calcs
@@ -427,8 +429,29 @@
*/
Real getLodBias(void) const;
+ /** Get a pointer to the camera which should be used to determine
+ LOD settings.
+ @remarks
+ Sometimes you don't want the LOD of a render to be based on the camera
+ that's doing the rendering, you want it to be based on a different
+ camera. A good example is when rendering shadow maps, since they will
+ be viewed from the perspective of another camera. Therefore this method
+ lets you associate a different camera instance to use to determine the LOD.
+ @par
+ To revert the camera to determining LOD based on itself, call this method with
+ a pointer to itself.
+ */
+ virtual void setLodCamera(const Camera* lodCam);
+ /** Get a pointer to the camera which should be used to determine
+ LOD settings.
+ @remarks
+ If setLodCamera hasn't been called with a different camera, this
+ method will return 'this'.
+ */
+ virtual const Camera* getLodCamera() const;
+
/** Gets a world space ray as cast from the camera through a viewport position.
@param screenx, screeny The x and y position at which the ray should intersect the viewport,
in normalised screen coordinates [0,1]
Modified: branches/v1-6/OgreMain/src/OgreCamera.cpp
===================================================================
--- branches/v1-6/OgreMain/src/OgreCamera.cpp 2008-07-29 12:53:43 UTC (rev 7803)
+++ branches/v1-6/OgreMain/src/OgreCamera.cpp 2008-07-30 11:03:11 UTC (rev 7804)
@@ -58,7 +58,8 @@
mLastViewport(0),
mAutoAspectRatio(false),
mCullFrustum(0),
- mUseRenderingDistance(true)
+ mUseRenderingDistance(true),
+ mLodCamera(0)
{
@@ -568,6 +569,19 @@
{
return mSceneLodFactorInv;
}
+ //-----------------------------------------------------------------------
+ void Camera::setLodCamera(const Camera* lodCam)
+ {
+ if (lodCam == this)
+ mLodCamera = 0;
+ else
+ mLodCamera = lodCam;
+ }
+ //---------------------------------------------------------------------
+ const Camera* Camera::getLodCamera() const
+ {
+ return mLodCamera? mLodCamera : this;
+ }
//-----------------------------------------------------------------------
Ray Camera::getCameraToViewportRay(Real screenX, Real screenY) const
{
Modified: branches/v1-6/OgreMain/src/OgreEntity.cpp
===================================================================
--- branches/v1-6/OgreMain/src/OgreEntity.cpp 2008-07-29 12:53:43 UTC (rev 7803)
+++ branches/v1-6/OgreMain/src/OgreEntity.cpp 2008-07-30 11:03:11 UTC (rev 7804)
@@ -370,13 +370,14 @@
// Calculate the LOD
if (mParentNode)
{
- Real squaredDepth = mParentNode->getSquaredViewDepth(cam);
+ const Camera* lodCamera = cam->getLodCamera();
+ Real squaredDepth = mParentNode->getSquaredViewDepth(lodCamera);
// Do Mesh LOD
// Adjust this depth by the entity bias factor
Real tmp = squaredDepth * mMeshLodFactorInv;
// Now adjust it by the camera bias
- tmp = tmp * cam->_getLodBiasInverse();
+ tmp = tmp * lodCamera->_getLodBiasInverse();
// Get the index at this biased depth
mMeshLodIndex = mMesh->getLodIndexSquaredDepth(tmp);
// Apply maximum detail restriction (remember lower = higher detail)
@@ -388,7 +389,7 @@
// Adjust this depth by the entity bias factor
tmp = squaredDepth * mMaterialLodFactorInv;
// Now adjust it by the camera bias
- tmp = tmp * cam->_getLodBiasInverse();
+ tmp = tmp * lodCamera->_getLodBiasInverse();
SubEntityList::iterator i, iend;
iend = mSubEntityList.end();
for (i = mSubEntityList.begin(); i != iend; ++i)
Modified: branches/v1-6/OgreMain/src/OgreInstancedGeometry.cpp
===================================================================
--- branches/v1-6/OgreMain/src/OgreInstancedGeometry.cpp 2008-07-29 12:53:43 UTC (rev 7803)
+++ branches/v1-6/OgreMain/src/OgreInstancedGeometry.cpp 2008-07-30 11:03:11 UTC (rev 7804)
@@ -1278,7 +1278,7 @@
void InstancedGeometry::BatchInstance::_notifyCurrentCamera(Camera* cam)
{
// Calculate squared view depth
- Vector3 diff = cam->getDerivedPosition() ;
+ Vector3 diff = cam->getLodCamera()->getDerivedPosition() ;
Real squaredDepth = diff.squaredLength();
// Determine whether to still render
Modified: branches/v1-6/OgreMain/src/OgreMovableObject.cpp
===================================================================
--- branches/v1-6/OgreMain/src/OgreMovableObject.cpp 2008-07-29 12:53:43 UTC (rev 7803)
+++ branches/v1-6/OgreMain/src/OgreMovableObject.cpp 2008-07-30 11:03:11 UTC (rev 7804)
@@ -239,7 +239,7 @@
if (cam->getUseRenderingDistance() && mUpperDistance > 0)
{
Real rad = getBoundingRadius();
- Real squaredDepth = mParentNode->getSquaredViewDepth(cam);
+ Real squaredDepth = mParentNode->getSquaredViewDepth(cam->getLodCamera());
// Max distance to still render
Real maxDist = mUpperDistance + rad;
if (squaredDepth > Math::Sqr(maxDist))
Modified: branches/v1-6/OgreMain/src/OgreSceneManager.cpp
===================================================================
--- branches/v1-6/OgreMain/src/OgreSceneManager.cpp 2008-07-29 12:53:43 UTC (rev 7803)
+++ branches/v1-6/OgreMain/src/OgreSceneManager.cpp 2008-07-30 11:03:11 UTC (rev 7804)
@@ -5705,6 +5705,9 @@
// rebind camera, incase another SM in use which has switched to its cam
shadowView->setCamera(texCam);
+ // Associate main view camera as LOD camera
+ texCam->setLodCamera(cam);
+
// update shadow cam - light mapping
ShadowCamLightMapping::iterator camLightIt = mShadowCamLightMapping.find( texCam );
assert(camLightIt != mShadowCamLightMapping.end());
Modified: branches/v1-6/OgreMain/src/OgreStaticGeometry.cpp
===================================================================
--- branches/v1-6/OgreMain/src/OgreStaticGeometry.cpp 2008-07-29 12:53:43 UTC (rev 7803)
+++ branches/v1-6/OgreMain/src/OgreStaticGeometry.cpp 2008-07-30 11:03:11 UTC (rev 7804)
@@ -849,7 +849,7 @@
void StaticGeometry::Region::_notifyCurrentCamera(Camera* cam)
{
// Calculate squared view depth
- Vector3 diff = cam->getDerivedPosition() - mCentre;
+ Vector3 diff = cam->getLodCamera()->getDerivedPosition() - mCentre;
Real squaredDepth = diff.squaredLength();
// Determine whether to still render
Code: Select all
Ogre::PixelCountLodStrategy::getSingleton().getValue(entity, camera)
Could you explain more in detail ?The camera is necessary, as the result depends upon the projection type and field of view in use, not only upon the distance.
Just in case anyone else picks up this thread without knowing the context, I just want to point out that all of this work has been in the mainstream trunk for a little while now, so anyone grabbing https://svn.ogre3d.org/svnroot/ogre/trunk will get it too. It's obviously on track for being part of the next stable release (1.7 aka Cthugha).LostEra wrote:As Sinbad said, you can check out the code at: https://svn.ogre3d.org/svnroot/ogre/branches/soc08-lod
I think, not only FOV, i have to set the aspect ratio of the frustrum viewportLostEra wrote:
By the way, it sounds like your FOV should probably be fixed at "arctan(real screen width / viewing distance)" radians for natural viewing and aiming and you said your viewing distance was fixed at 2 meters, so if you know the real width of your viewing screen ahead of time also, you can probably precompute the FOV and from that the appropriate distance. Just a thought.
Code: Select all
material PlainGreen
{
technique
{
pass
{
diffuse 0.0 1.0 0.0 0.0
}
}
}
Code: Select all
OgreEntity.cpp line 434:
// Recalculate lod value if strategies do not match
Real biasedMaterialLodValue;
if (meshStrategy == materialStrategy)
biasedMaterialLodValue = lodValue;
else
biasedMaterialLodValue = materialStrategy->getValue(this, cam) * materialStrategy->transformBias(mMaterialLodFactor); <--- this call is on top on the call stack