mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-16 21:49:55 +00:00
Merge remote branch 'scrawl/occlusionquery'
Reduced cout spam Conflicts: apps/openmw/mwrender/occlusionquery.cpp
This commit is contained in:
commit
cdd0182912
4 changed files with 112 additions and 19 deletions
|
@ -82,12 +82,20 @@ void OMW::Engine::updateFocusReport (float duration)
|
||||||
|
|
||||||
if (!handle.empty())
|
if (!handle.empty())
|
||||||
{
|
{
|
||||||
MWWorld::Ptr ptr = mEnvironment.mWorld->getPtrViaHandle (handle);
|
// the faced handle is not updated immediately, so on a cell change it might
|
||||||
|
// point to an object that doesn't exist anymore
|
||||||
|
// therefore, we are catching the "Unknown Ogre handle" exception that occurs in this case
|
||||||
|
try
|
||||||
|
{
|
||||||
|
MWWorld::Ptr ptr = mEnvironment.mWorld->getPtrViaHandle (handle);
|
||||||
|
|
||||||
if (!ptr.isEmpty()){
|
if (!ptr.isEmpty()){
|
||||||
name = MWWorld::Class::get (ptr).getName (ptr);
|
name = MWWorld::Class::get (ptr).getName (ptr);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
catch (std::runtime_error& e)
|
||||||
|
{}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name!=mFocusName)
|
if (name!=mFocusName)
|
||||||
|
@ -420,10 +428,21 @@ void OMW::Engine::activate()
|
||||||
if (handle.empty())
|
if (handle.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
MWWorld::Ptr ptr = mEnvironment.mWorld->getPtrViaHandle (handle);
|
// the faced handle is not updated immediately, so on a cell change it might
|
||||||
|
// point to an object that doesn't exist anymore
|
||||||
|
// therefore, we are catching the "Unknown Ogre handle" exception that occurs in this case
|
||||||
|
MWWorld::Ptr ptr;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ptr = mEnvironment.mWorld->getPtrViaHandle (handle);
|
||||||
|
|
||||||
if (ptr.isEmpty())
|
if (ptr.isEmpty())
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
catch (std::runtime_error&)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
MWScript::InterpreterContext interpreterContext (mEnvironment,
|
MWScript::InterpreterContext interpreterContext (mEnvironment,
|
||||||
&ptr.getRefData().getLocals(), ptr);
|
&ptr.getRefData().getLocals(), ptr);
|
||||||
|
|
|
@ -5,13 +5,14 @@
|
||||||
#include <OgreBillboardSet.h>
|
#include <OgreBillboardSet.h>
|
||||||
#include <OgreHardwareOcclusionQuery.h>
|
#include <OgreHardwareOcclusionQuery.h>
|
||||||
#include <OgreEntity.h>
|
#include <OgreEntity.h>
|
||||||
|
#include <OgreSubEntity.h>
|
||||||
|
|
||||||
using namespace MWRender;
|
using namespace MWRender;
|
||||||
using namespace Ogre;
|
using namespace Ogre;
|
||||||
|
|
||||||
OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNode* sunNode) :
|
OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNode* sunNode) :
|
||||||
mSunTotalAreaQuery(0), mSunVisibleAreaQuery(0), mSingleObjectQuery(0), mActiveQuery(0),
|
mSunTotalAreaQuery(0), mSunVisibleAreaQuery(0), mSingleObjectQuery(0), mActiveQuery(0),
|
||||||
mDoQuery(0), mSunVisibility(0), mQuerySingleObjectStarted(false), mTestResult(false),
|
mDoQuery(0), mSunVisibility(0), mQuerySingleObjectStarted(false), mTestResult(false),
|
||||||
mQuerySingleObjectRequested(false), mWasVisible(false), mObjectWasVisible(false), mDoQuery2(false),
|
mQuerySingleObjectRequested(false), mWasVisible(false), mObjectWasVisible(false), mDoQuery2(false),
|
||||||
mBBNode(0)
|
mBBNode(0)
|
||||||
{
|
{
|
||||||
|
@ -84,7 +85,6 @@ OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNod
|
||||||
mRendering->getScene()->addRenderObjectListener(this);
|
mRendering->getScene()->addRenderObjectListener(this);
|
||||||
mRendering->getScene()->addRenderQueueListener(this);
|
mRendering->getScene()->addRenderQueueListener(this);
|
||||||
mDoQuery = true;
|
mDoQuery = true;
|
||||||
mDoQuery2 = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OcclusionQuery::~OcclusionQuery()
|
OcclusionQuery::~OcclusionQuery()
|
||||||
|
@ -100,7 +100,7 @@ bool OcclusionQuery::supported()
|
||||||
return mSupported;
|
return mSupported;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OcclusionQuery::notifyRenderSingleObject(Renderable* rend, const Pass* pass, const AutoParamDataSource* source,
|
void OcclusionQuery::notifyRenderSingleObject(Renderable* rend, const Pass* pass, const AutoParamDataSource* source,
|
||||||
const LightList* pLightList, bool suppressRenderStateChanges)
|
const LightList* pLightList, bool suppressRenderStateChanges)
|
||||||
{
|
{
|
||||||
// The following code activates and deactivates the occlusion queries
|
// The following code activates and deactivates the occlusion queries
|
||||||
|
@ -134,7 +134,7 @@ void OcclusionQuery::notifyRenderSingleObject(Renderable* rend, const Pass* pass
|
||||||
mActiveQuery = mSingleObjectQuery;
|
mActiveQuery = mSingleObjectQuery;
|
||||||
mObjectWasVisible = true;
|
mObjectWasVisible = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mActiveQuery != NULL)
|
if (mActiveQuery != NULL)
|
||||||
mActiveQuery->beginOcclusionQuery();
|
mActiveQuery->beginOcclusionQuery();
|
||||||
}
|
}
|
||||||
|
@ -195,7 +195,6 @@ void OcclusionQuery::update(float duration)
|
||||||
// Stop occlusion queries until we get their information
|
// Stop occlusion queries until we get their information
|
||||||
// (may not happen on the same frame they are requested in)
|
// (may not happen on the same frame they are requested in)
|
||||||
mDoQuery = false;
|
mDoQuery = false;
|
||||||
mDoQuery2 = false;
|
|
||||||
|
|
||||||
if (!mSunTotalAreaQuery->isStillOutstanding()
|
if (!mSunTotalAreaQuery->isStillOutstanding()
|
||||||
&& !mSunVisibleAreaQuery->isStillOutstanding()
|
&& !mSunVisibleAreaQuery->isStillOutstanding()
|
||||||
|
@ -264,3 +263,40 @@ bool OcclusionQuery::getTestResult()
|
||||||
|
|
||||||
return mTestResult;
|
return mTestResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool OcclusionQuery::isPotentialOccluder(Ogre::SceneNode* node)
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
for (unsigned int i=0; i < node->numAttachedObjects(); ++i)
|
||||||
|
{
|
||||||
|
MovableObject* ob = node->getAttachedObject(i);
|
||||||
|
std::string type = ob->getMovableType();
|
||||||
|
if (type == "Entity")
|
||||||
|
{
|
||||||
|
Entity* ent = static_cast<Entity*>(ob);
|
||||||
|
for (unsigned int j=0; j < ent->getNumSubEntities(); ++j)
|
||||||
|
{
|
||||||
|
// if any sub entity has a material with depth write off,
|
||||||
|
// consider the object as not an occluder
|
||||||
|
MaterialPtr mat = ent->getSubEntity(j)->getMaterial();
|
||||||
|
|
||||||
|
Material::TechniqueIterator techIt = mat->getTechniqueIterator();
|
||||||
|
while (techIt.hasMoreElements())
|
||||||
|
{
|
||||||
|
Technique* tech = techIt.getNext();
|
||||||
|
Technique::PassIterator passIt = tech->getPassIterator();
|
||||||
|
while (passIt.hasMoreElements())
|
||||||
|
{
|
||||||
|
Pass* pass = passIt.getNext();
|
||||||
|
|
||||||
|
if (pass->getDepthWriteEnabled() == false)
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
|
@ -46,6 +46,14 @@ namespace MWRender
|
||||||
*/
|
*/
|
||||||
bool occlusionTestPending();
|
bool occlusionTestPending();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the objects held by this scenenode
|
||||||
|
* can be considered as potential occluders
|
||||||
|
* (which might not be the case when transparency is involved)
|
||||||
|
* @param Scene node
|
||||||
|
*/
|
||||||
|
bool isPotentialOccluder(Ogre::SceneNode* node);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if the object tested in the last request was occluded
|
* @return true if the object tested in the last request was occluded
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -543,7 +543,7 @@ namespace MWWorld
|
||||||
if (ptr==mPlayer->getPlayer())
|
if (ptr==mPlayer->getPlayer())
|
||||||
{
|
{
|
||||||
//std::cout << "X:" << ptr.getRefData().getPosition().pos[0] << " Z: " << ptr.getRefData().getPosition().pos[1] << "\n";
|
//std::cout << "X:" << ptr.getRefData().getPosition().pos[0] << " Z: " << ptr.getRefData().getPosition().pos[1] << "\n";
|
||||||
|
|
||||||
Ptr::CellStore *currentCell = mWorldScene->getCurrentCell();
|
Ptr::CellStore *currentCell = mWorldScene->getCurrentCell();
|
||||||
if (currentCell)
|
if (currentCell)
|
||||||
{
|
{
|
||||||
|
@ -750,15 +750,16 @@ namespace MWWorld
|
||||||
// figure out which object we want to test against
|
// figure out which object we want to test against
|
||||||
std::vector < std::pair < float, std::string > > results = mPhysics->getFacedObjects();
|
std::vector < std::pair < float, std::string > > results = mPhysics->getFacedObjects();
|
||||||
|
|
||||||
// ignore the player
|
// ignore the player and other things we're not interested in
|
||||||
for (std::vector < std::pair < float, std::string > >::iterator it = results.begin();
|
std::vector < std::pair < float, std::string > >::iterator it = results.begin();
|
||||||
it != results.end(); ++it)
|
while (it != results.end())
|
||||||
{
|
{
|
||||||
if ( (*it).second == mPlayer->getPlayer().getRefData().getHandle() )
|
if ( getPtrViaHandle((*it).second) == mPlayer->getPlayer() )
|
||||||
{
|
{
|
||||||
results.erase(it);
|
it = results.erase(it);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
++it;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (results.size() == 0)
|
if (results.size() == 0)
|
||||||
|
@ -774,6 +775,10 @@ namespace MWWorld
|
||||||
btVector3 p = mPhysics->getRayPoint(results.front().first);
|
btVector3 p = mPhysics->getRayPoint(results.front().first);
|
||||||
Ogre::Vector3 pos(p.x(), p.z(), -p.y());
|
Ogre::Vector3 pos(p.x(), p.z(), -p.y());
|
||||||
Ogre::SceneNode* node = mFaced1.getRefData().getBaseNode();
|
Ogre::SceneNode* node = mFaced1.getRefData().getBaseNode();
|
||||||
|
|
||||||
|
//std::cout << "Num facing 1 : " << mFaced1Name << std::endl;
|
||||||
|
//std::cout << "Type 1 " << mFaced1.getTypeName() << std::endl;
|
||||||
|
|
||||||
query->occlusionTest(pos, node);
|
query->occlusionTest(pos, node);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -786,8 +791,33 @@ namespace MWWorld
|
||||||
|
|
||||||
btVector3 p = mPhysics->getRayPoint(results[1].first);
|
btVector3 p = mPhysics->getRayPoint(results[1].first);
|
||||||
Ogre::Vector3 pos(p.x(), p.z(), -p.y());
|
Ogre::Vector3 pos(p.x(), p.z(), -p.y());
|
||||||
Ogre::SceneNode* node = mFaced2.getRefData().getBaseNode();
|
Ogre::SceneNode* node1 = mFaced1.getRefData().getBaseNode();
|
||||||
query->occlusionTest(pos, node);
|
Ogre::SceneNode* node2 = mFaced2.getRefData().getBaseNode();
|
||||||
|
|
||||||
|
// no need to test if the first node is not occluder
|
||||||
|
if (!query->isPotentialOccluder(node1) && (mFaced1.getTypeName().find("Static") == std::string::npos))
|
||||||
|
{
|
||||||
|
mFacedHandle = mFaced1Name;
|
||||||
|
//std::cout << "node1 Not an occluder" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// no need to test if the second object is static (thus cannot be activated)
|
||||||
|
if (mFaced2.getTypeName().find("Static") != std::string::npos)
|
||||||
|
{
|
||||||
|
mFacedHandle = mFaced1Name;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// work around door problems
|
||||||
|
if (mFaced1.getTypeName().find("Static") != std::string::npos
|
||||||
|
&& mFaced2.getTypeName().find("Door") != std::string::npos)
|
||||||
|
{
|
||||||
|
mFacedHandle = mFaced2Name;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
query->occlusionTest(pos, node2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue