Skip to content

Commit

Permalink
OgreInstanceBatch: correct bounding radius calculations and material LOD
Browse files Browse the repository at this point in the history
  • Loading branch information
BAntDit authored and paroj committed Jan 5, 2017
1 parent 13da0e8 commit 3317645
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 21 deletions.
2 changes: 2 additions & 0 deletions OgreMain/include/OgreInstanceBatch.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ namespace Ogre
/// False if a technique doesn't support skeletal animation
bool mTechnSupportsSkeletal;

/// Last update camera distance frame number
mutable unsigned long mCameraDistLastUpdateFrameNumber;
/// Cached distance to last camera for getSquaredViewDepth
mutable Real mCachedCameraDist;
/// The camera for which the cached distance is valid
Expand Down
6 changes: 4 additions & 2 deletions OgreMain/include/OgreMath.h
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ namespace Ogre
static inline double saturate(double t) { return (t < 0) ? 0 : ((t > 1) ? 1 : t); }

//Simulate the shader function lerp which performers linear interpolation
//given 3 parameters v0, v1 and t the function returns the value of (1 – t)* v0 + t * v1.
//given 3 parameters v0, v1 and t the function returns the value of (1 t)* v0 + t * v1.
//where v0 and v1 are matching vector or scalar types and t can be either a scalar or a vector of the same type as a and b.
template<typename V, typename T> static V lerp(const V& v0, const V& v1, const T& t) {
return v0 * (1 - t) + v1 * t; }
Expand Down Expand Up @@ -696,9 +696,11 @@ namespace Ogre
static Matrix4 makeViewMatrix(const Vector3& position, const Quaternion& orientation,
const Matrix4* reflectMatrix = 0);

/** Get a bounding radius value from a bounding box. */
/** Get the radius of the origin-centered bounding sphere from the bounding box. */
static Real boundingRadiusFromAABB(const AxisAlignedBox& aabb);

/** Get the radius of the bbox-centered bounding sphere from the bounding box. */
static Real boundingRadiusFromAABBCentered(const AxisAlignedBox &aabb);


static const Real POS_INFINITY;
Expand Down
73 changes: 56 additions & 17 deletions OgreMain/src/OgreInstanceBatch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ THE SOFTWARE.
#include "OgreCamera.h"
#include "OgreException.h"
#include "OgreRenderQueue.h"
#include "OgreLodListener.h"
#include "OgreSceneManager.h"
#include "OgreRoot.h"

namespace Ogre
{
Expand Down Expand Up @@ -158,7 +161,7 @@ namespace Ogre
mFullBoundingBox.setMinimum(mFullBoundingBox.getMinimum() - addToBound);


mBoundingRadius = Math::boundingRadiusFromAABB( mFullBoundingBox );
mBoundingRadius = Math::boundingRadiusFromAABBCentered( mFullBoundingBox );
mBoundsDirty = false;
}

Expand Down Expand Up @@ -487,9 +490,9 @@ namespace Ogre
//We use our own because our SceneNode is just filled with zeroes, and updating it
//with real values is expensive, plus we would need to make sure it doesn't get to
//the shader
Real depth = Math::Sqrt( getSquaredViewDepth(cam) ) -
mMeshReference->getBoundingSphereRadius();
Real depth = Math::Sqrt(getSquaredViewDepth(cam)) - getBoundingRadius();
depth = std::max( depth, Real(0) );

Real lodValue = depth * cam->_getLodBiasInverse();

//Now calculate Material LOD
Expand All @@ -513,10 +516,52 @@ namespace Ogre
//Notify LOD event listeners
cam->getSceneManager()->_notifyEntityMaterialLodChanged(subEntEvt);*/

//Change LOD index
// Change LOD index
mMaterialLodIndex = idx;

MovableObject::_notifyCurrentCamera( cam );
mBeyondFarDistance = false;

if (cam->getUseRenderingDistance() && mUpperDistance > 0)
{
if (depth > mUpperDistance)
mBeyondFarDistance = true;
}

if (!mBeyondFarDistance && cam->getUseMinPixelSize() && mMinPixelSize > 0)
{
Real pixelRatio = cam->getPixelDisplayRatio();

Ogre::Vector3 objBound =
getBoundingBox().getSize() * getParentNode()->_getDerivedScale();
objBound.x = Math::Sqr(objBound.x);
objBound.y = Math::Sqr(objBound.y);
objBound.z = Math::Sqr(objBound.z);
float sqrObjMedianSize = std::max(
std::max(std::min(objBound.x, objBound.y), std::min(objBound.x, objBound.z)),
std::min(objBound.y, objBound.z));

// If we have a perspective camera calculations are done relative to distance
Real sqrDistance = 1;

if (cam->getProjectionType() == PT_PERSPECTIVE)
sqrDistance = getSquaredViewDepth(cam->getLodCamera()); // it's ok

mBeyondFarDistance =
sqrObjMedianSize < sqrDistance * Math::Sqr(pixelRatio * mMinPixelSize);
}

if (mParentNode)
{
MovableObjectLodChangedEvent evt;
evt.movableObject = this;
evt.camera = cam;

cam->getSceneManager()->_notifyMovableObjectLodChanged(evt);
}

mRenderingDisabled = mListener && !mListener->objectRendering(this, cam);

// MovableObject::_notifyCurrentCamera( cam ); // it does not suit
}
//-----------------------------------------------------------------------
const AxisAlignedBox& InstanceBatch::getBoundingBox(void) const
Expand All @@ -531,21 +576,15 @@ namespace Ogre
//-----------------------------------------------------------------------
Real InstanceBatch::getSquaredViewDepth( const Camera* cam ) const
{
if( mCachedCamera != cam )
{
mCachedCameraDist = std::numeric_limits<Real>::infinity();

InstancedEntityVec::const_iterator itor = mInstancedEntities.begin();
InstancedEntityVec::const_iterator end = mInstancedEntities.end();
unsigned long currentFrameNumber = Root::getSingleton().getNextFrameNumber();

while( itor != end )
{
if( (*itor)->isVisible() )
mCachedCameraDist = std::min( mCachedCameraDist, (*itor)->getSquaredViewDepth( cam ) );
++itor;
}
if (mCameraDistLastUpdateFrameNumber != currentFrameNumber || mCachedCamera != cam)
{
mCachedCameraDist =
getBoundingBox().getCenter().squaredDistance(cam->getDerivedPosition());

mCachedCamera = cam;
mCameraDistLastUpdateFrameNumber = currentFrameNumber;
}

return mCachedCameraDist;
Expand Down
11 changes: 9 additions & 2 deletions OgreMain/src/OgreMath.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -973,8 +973,8 @@ namespace Ogre
//---------------------------------------------------------------------
Real Math::boundingRadiusFromAABB(const AxisAlignedBox& aabb)
{
Vector3 max = aabb.getMaximum();
Vector3 min = aabb.getMinimum();
const Vector3& max = aabb.getMaximum();
const Vector3& min = aabb.getMinimum();

Vector3 magnitude = max;
magnitude.makeCeil(-max);
Expand All @@ -984,4 +984,11 @@ namespace Ogre
return magnitude.length();
}

Real Math::boundingRadiusFromAABBCentered(const AxisAlignedBox& aabb)
{
const Vector3& max = aabb.getMaximum();
const Vector3& min = aabb.getMinimum();

return ((min - max) * 0.5f).length();
}
}

0 comments on commit 3317645

Please sign in to comment.