forked from teamnwah/openmw-tes3coop
object pickup should work everywhere
This commit is contained in:
parent
17a4adfe88
commit
53d4be5cf6
8 changed files with 198 additions and 46 deletions
|
@ -47,7 +47,7 @@ OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNod
|
||||||
matQueryArea->setDepthCheckEnabled(false); // Not occluded by objects
|
matQueryArea->setDepthCheckEnabled(false); // Not occluded by objects
|
||||||
MaterialPtr matQueryVisible = matBase->clone("QueryVisiblePixels");
|
MaterialPtr matQueryVisible = matBase->clone("QueryVisiblePixels");
|
||||||
matQueryVisible->setDepthWriteEnabled(false);
|
matQueryVisible->setDepthWriteEnabled(false);
|
||||||
matQueryVisible->setColourWriteEnabled(false);
|
matQueryVisible->setColourWriteEnabled(false); // Uncomment this to visualize the occlusion query
|
||||||
matQueryVisible->setDepthCheckEnabled(true); // Occluded by objects
|
matQueryVisible->setDepthCheckEnabled(true); // Occluded by objects
|
||||||
|
|
||||||
mBBNode = mSunNode->getParentSceneNode()->createChildSceneNode();
|
mBBNode = mSunNode->getParentSceneNode()->createChildSceneNode();
|
||||||
|
@ -69,13 +69,14 @@ OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNod
|
||||||
mBBNode->attachObject(mBBQueryVisible);
|
mBBNode->attachObject(mBBQueryVisible);
|
||||||
|
|
||||||
mBBQuerySingleObject = mRendering->getScene()->createBillboardSet(1);
|
mBBQuerySingleObject = mRendering->getScene()->createBillboardSet(1);
|
||||||
mBBQuerySingleObject->setDefaultDimensions(10, 10);
|
mBBQuerySingleObject->setDefaultDimensions(0.01, 0.01);
|
||||||
mBBQuerySingleObject->createBillboard(Vector3::ZERO);
|
mBBQuerySingleObject->createBillboard(Vector3::ZERO);
|
||||||
mBBQuerySingleObject->setMaterialName("QueryVisiblePixels");
|
mBBQuerySingleObject->setMaterialName("QueryVisiblePixels");
|
||||||
mBBQuerySingleObject->setRenderQueueGroup(queue);
|
mBBQuerySingleObject->setRenderQueueGroup(queue);
|
||||||
mObjectNode->attachObject(mBBQuerySingleObject);
|
mObjectNode->attachObject(mBBQuerySingleObject);
|
||||||
|
|
||||||
mRendering->getScene()->addRenderObjectListener(this);
|
mRendering->getScene()->addRenderObjectListener(this);
|
||||||
|
mRendering->getScene()->addRenderQueueListener(this);
|
||||||
mDoQuery = true;
|
mDoQuery = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,8 +96,6 @@ bool OcclusionQuery::supported()
|
||||||
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)
|
||||||
{
|
{
|
||||||
if (!mSupported) return;
|
|
||||||
|
|
||||||
// The following code activates and deactivates the occlusion queries
|
// The following code activates and deactivates the occlusion queries
|
||||||
// so that the queries only include the rendering of their intended targets
|
// so that the queries only include the rendering of their intended targets
|
||||||
|
|
||||||
|
@ -112,10 +111,16 @@ void OcclusionQuery::notifyRenderSingleObject(Renderable* rend, const Pass* pass
|
||||||
if (mDoQuery == true)
|
if (mDoQuery == true)
|
||||||
{
|
{
|
||||||
if (rend == mBBQueryTotal)
|
if (rend == mBBQueryTotal)
|
||||||
|
{
|
||||||
mActiveQuery = mSunTotalAreaQuery;
|
mActiveQuery = mSunTotalAreaQuery;
|
||||||
|
mWasVisible = true;
|
||||||
|
}
|
||||||
else if (rend == mBBQueryVisible)
|
else if (rend == mBBQueryVisible)
|
||||||
|
{
|
||||||
mActiveQuery = mSunVisibleAreaQuery;
|
mActiveQuery = mSunVisibleAreaQuery;
|
||||||
else if (rend == mBBQuerySingleObject && mQuerySingleObjectRequested)
|
}
|
||||||
|
}
|
||||||
|
if (rend == mBBQuerySingleObject && mQuerySingleObjectRequested)
|
||||||
{
|
{
|
||||||
mQuerySingleObjectStarted = true;
|
mQuerySingleObjectStarted = true;
|
||||||
mQuerySingleObjectRequested = false;
|
mQuerySingleObjectRequested = false;
|
||||||
|
@ -125,12 +130,27 @@ void OcclusionQuery::notifyRenderSingleObject(Renderable* rend, const Pass* pass
|
||||||
if (mActiveQuery != NULL)
|
if (mActiveQuery != NULL)
|
||||||
mActiveQuery->beginOcclusionQuery();
|
mActiveQuery->beginOcclusionQuery();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OcclusionQuery::renderQueueEnded(uint8 queueGroupId, const String& invocation, bool& repeatThisInvocation)
|
||||||
|
{
|
||||||
|
if (queueGroupId == RENDER_QUEUE_SKIES_LATE && mWasVisible == false)
|
||||||
|
{
|
||||||
|
// for some reason our single object query returns wrong results when the sun query was never executed
|
||||||
|
// (which can happen when we are in interiors, or when the sun is outside of the view frustum and gets culled)
|
||||||
|
// so we force it here once everything has been rendered
|
||||||
|
mSunTotalAreaQuery->beginOcclusionQuery();
|
||||||
|
mSunTotalAreaQuery->endOcclusionQuery();
|
||||||
|
mSunVisibleAreaQuery->beginOcclusionQuery();
|
||||||
|
mSunVisibleAreaQuery->endOcclusionQuery();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OcclusionQuery::update()
|
void OcclusionQuery::update()
|
||||||
{
|
{
|
||||||
if (!mSupported) return;
|
if (!mSupported) return;
|
||||||
|
|
||||||
|
mWasVisible = false;
|
||||||
|
|
||||||
// Adjust the position of the sun billboards according to camera viewing distance
|
// Adjust the position of the sun billboards according to camera viewing distance
|
||||||
// we need to do this to make sure that _everything_ can occlude the sun
|
// we need to do this to make sure that _everything_ can occlude the sun
|
||||||
float dist = mRendering->getCamera()->getFarClipDistance();
|
float dist = mRendering->getCamera()->getFarClipDistance();
|
||||||
|
@ -145,8 +165,7 @@ void OcclusionQuery::update()
|
||||||
mDoQuery = false;
|
mDoQuery = false;
|
||||||
|
|
||||||
if (!mSunTotalAreaQuery->isStillOutstanding()
|
if (!mSunTotalAreaQuery->isStillOutstanding()
|
||||||
&& !mSunVisibleAreaQuery->isStillOutstanding()
|
&& !mSunVisibleAreaQuery->isStillOutstanding())
|
||||||
&& !mSingleObjectQuery->isStillOutstanding())
|
|
||||||
{
|
{
|
||||||
unsigned int totalPixels;
|
unsigned int totalPixels;
|
||||||
unsigned int visiblePixels;
|
unsigned int visiblePixels;
|
||||||
|
@ -165,24 +184,33 @@ void OcclusionQuery::update()
|
||||||
if (mSunVisibility > 1) mSunVisibility = 1;
|
if (mSunVisibility > 1) mSunVisibility = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mQuerySingleObjectStarted)
|
mDoQuery = true;
|
||||||
|
}
|
||||||
|
if (!mSingleObjectQuery->isStillOutstanding() && mQuerySingleObjectStarted)
|
||||||
{
|
{
|
||||||
unsigned int visiblePixels;
|
unsigned int result;
|
||||||
|
|
||||||
mSingleObjectQuery->pullOcclusionQuery(&visiblePixels);
|
mSingleObjectQuery->pullOcclusionQuery(&result);
|
||||||
|
|
||||||
|
//std::cout << "Single object query result: " << result << " pixels " << std::endl;
|
||||||
|
mTestResult = (result != 0);
|
||||||
|
|
||||||
mBBQuerySingleObject->setVisible(false);
|
mBBQuerySingleObject->setVisible(false);
|
||||||
mObject->setRenderQueueGroup(mObjectOldRenderQueue);
|
|
||||||
|
// restore old render queues
|
||||||
|
for (std::vector<ObjectInfo>::iterator it=mObjectsInfo.begin();
|
||||||
|
it!=mObjectsInfo.end(); ++it)
|
||||||
|
{
|
||||||
|
if (!mRendering->getScene()->hasMovableObject((*it).name, (*it).typeName)) return;
|
||||||
|
mRendering->getScene()->getMovableObject((*it).name, (*it).typeName)->setRenderQueueGroup( (*it).oldRenderqueue );
|
||||||
|
}
|
||||||
|
|
||||||
mQuerySingleObjectStarted = false;
|
mQuerySingleObjectStarted = false;
|
||||||
mQuerySingleObjectRequested = false;
|
mQuerySingleObjectRequested = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
mDoQuery = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OcclusionQuery::occlusionTest(const Ogre::Vector3& position, Ogre::Entity* entity)
|
void OcclusionQuery::occlusionTest(const Ogre::Vector3& position, Ogre::SceneNode* object)
|
||||||
{
|
{
|
||||||
assert( !occlusionTestPending()
|
assert( !occlusionTestPending()
|
||||||
&& "Occlusion test still pending");
|
&& "Occlusion test still pending");
|
||||||
|
@ -190,11 +218,24 @@ void OcclusionQuery::occlusionTest(const Ogre::Vector3& position, Ogre::Entity*
|
||||||
mBBQuerySingleObject->setVisible(true);
|
mBBQuerySingleObject->setVisible(true);
|
||||||
|
|
||||||
// we don't want the object to occlude itself
|
// we don't want the object to occlude itself
|
||||||
mObjectOldRenderQueue = entity->getRenderQueueGroup();
|
// put it in a render queue _after_ the occlusion query
|
||||||
if (mObjectOldRenderQueue < RENDER_QUEUE_MAIN+2)
|
mObjectsInfo.clear();
|
||||||
entity->setRenderQueueGroup(RENDER_QUEUE_MAIN+2);
|
for (int i=0; i<object->numAttachedObjects(); ++i)
|
||||||
|
{
|
||||||
|
ObjectInfo info;
|
||||||
|
MovableObject* obj = object->getAttachedObject(i);
|
||||||
|
info.name = obj->getName();
|
||||||
|
info.typeName = obj->getMovableType();
|
||||||
|
info.oldRenderqueue = obj->getRenderQueueGroup();
|
||||||
|
|
||||||
|
mObjectsInfo.push_back(info);
|
||||||
|
|
||||||
|
object->getAttachedObject(i)->setRenderQueueGroup(RENDER_QUEUE_MAIN+5);
|
||||||
|
}
|
||||||
|
|
||||||
mObjectNode->setPosition(position);
|
mObjectNode->setPosition(position);
|
||||||
|
// scale proportional to camera distance, in order to always give the billboard the same size in screen-space
|
||||||
|
mObjectNode->setScale( Vector3(1,1,1)*(position - mRendering->getCamera()->getRealPosition()).length() );
|
||||||
|
|
||||||
mQuerySingleObjectRequested = true;
|
mQuerySingleObjectRequested = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define _GAME_OCCLUSION_QUERY_H
|
#define _GAME_OCCLUSION_QUERY_H
|
||||||
|
|
||||||
#include <OgreRenderObjectListener.h>
|
#include <OgreRenderObjectListener.h>
|
||||||
|
#include <OgreRenderQueueListener.h>
|
||||||
|
|
||||||
namespace Ogre
|
namespace Ogre
|
||||||
{
|
{
|
||||||
|
@ -17,7 +18,14 @@ namespace MWRender
|
||||||
///
|
///
|
||||||
/// \brief Implements hardware occlusion queries on the GPU
|
/// \brief Implements hardware occlusion queries on the GPU
|
||||||
///
|
///
|
||||||
class OcclusionQuery : public Ogre::RenderObjectListener
|
struct ObjectInfo
|
||||||
|
{
|
||||||
|
int oldRenderqueue;
|
||||||
|
std::string name;
|
||||||
|
std::string typeName;
|
||||||
|
};
|
||||||
|
|
||||||
|
class OcclusionQuery : public Ogre::RenderObjectListener, public Ogre::RenderQueueListener
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
OcclusionQuery(OEngine::Render::OgreRenderer*, Ogre::SceneNode* sunNode);
|
OcclusionQuery(OEngine::Render::OgreRenderer*, Ogre::SceneNode* sunNode);
|
||||||
|
@ -36,9 +44,9 @@ namespace MWRender
|
||||||
/**
|
/**
|
||||||
* request occlusion test for a billboard at the given position, omitting an entity
|
* request occlusion test for a billboard at the given position, omitting an entity
|
||||||
* @param position of the billboard in ogre coordinates
|
* @param position of the billboard in ogre coordinates
|
||||||
* @param entity to exclude from the occluders
|
* @param object to exclude from the occluders
|
||||||
*/
|
*/
|
||||||
void occlusionTest(const Ogre::Vector3& position, Ogre::Entity* entity);
|
void occlusionTest(const Ogre::Vector3& position, Ogre::SceneNode* object);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if a request is still outstanding
|
* @return true if a request is still outstanding
|
||||||
|
@ -66,10 +74,10 @@ namespace MWRender
|
||||||
Ogre::SceneNode* mBBNode;
|
Ogre::SceneNode* mBBNode;
|
||||||
float mSunVisibility;
|
float mSunVisibility;
|
||||||
|
|
||||||
Ogre::Entity* mObject;
|
|
||||||
|
|
||||||
Ogre::SceneNode* mObjectNode;
|
Ogre::SceneNode* mObjectNode;
|
||||||
int mObjectOldRenderQueue;
|
std::vector<ObjectInfo> mObjectsInfo;
|
||||||
|
|
||||||
|
bool mWasVisible;
|
||||||
|
|
||||||
bool mTestResult;
|
bool mTestResult;
|
||||||
|
|
||||||
|
@ -84,6 +92,8 @@ namespace MWRender
|
||||||
protected:
|
protected:
|
||||||
virtual void notifyRenderSingleObject(Ogre::Renderable* rend, const Ogre::Pass* pass, const Ogre::AutoParamDataSource* source,
|
virtual void notifyRenderSingleObject(Ogre::Renderable* rend, const Ogre::Pass* pass, const Ogre::AutoParamDataSource* source,
|
||||||
const Ogre::LightList* pLightList, bool suppressRenderStateChanges);
|
const Ogre::LightList* pLightList, bool suppressRenderStateChanges);
|
||||||
|
|
||||||
|
virtual void renderQueueEnded(Ogre::uint8 queueGroupId, const Ogre::String& invocation, bool& repeatThisInvocation);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -100,6 +100,7 @@ class RenderingManager: private RenderingInterface {
|
||||||
void sunDisable();
|
void sunDisable();
|
||||||
|
|
||||||
bool occlusionQuerySupported() { return mOcclusionQuery->supported(); };
|
bool occlusionQuerySupported() { return mOcclusionQuery->supported(); };
|
||||||
|
OcclusionQuery* getOcclusionQuery() { return mOcclusionQuery; };
|
||||||
|
|
||||||
void setGlare(bool glare);
|
void setGlare(bool glare);
|
||||||
void skyEnable ();
|
void skyEnable ();
|
||||||
|
|
|
@ -51,6 +51,33 @@ namespace MWWorld
|
||||||
return mEngine->rayTest(from,to);
|
return mEngine->rayTest(from,to);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector < std::pair <float, std::string> > PhysicsSystem::getFacedObjects ()
|
||||||
|
{
|
||||||
|
//get a ray pointing to the center of the viewport
|
||||||
|
Ray centerRay = mRender.getCamera()->getCameraToViewportRay(
|
||||||
|
mRender.getViewport()->getWidth()/2,
|
||||||
|
mRender.getViewport()->getHeight()/2);
|
||||||
|
//let's avoid the capsule shape of the player.
|
||||||
|
centerRay.setOrigin(centerRay.getOrigin() + 20*centerRay.getDirection());
|
||||||
|
btVector3 from(centerRay.getOrigin().x,-centerRay.getOrigin().z,centerRay.getOrigin().y);
|
||||||
|
btVector3 to(centerRay.getPoint(500).x,-centerRay.getPoint(500).z,centerRay.getPoint(500).y);
|
||||||
|
|
||||||
|
return mEngine->rayTest2(from,to);
|
||||||
|
}
|
||||||
|
|
||||||
|
btVector3 PhysicsSystem::getRayPoint(float extent)
|
||||||
|
{
|
||||||
|
//get a ray pointing to the center of the viewport
|
||||||
|
Ray centerRay = mRender.getCamera()->getCameraToViewportRay(
|
||||||
|
mRender.getViewport()->getWidth()/2,
|
||||||
|
mRender.getViewport()->getHeight()/2);
|
||||||
|
//let's avoid the capsule shape of the player.
|
||||||
|
centerRay.setOrigin(centerRay.getOrigin() + 20*centerRay.getDirection());
|
||||||
|
btVector3 from(centerRay.getOrigin().x,-centerRay.getOrigin().z,centerRay.getOrigin().y);
|
||||||
|
btVector3 to(centerRay.getPoint(500).x,-centerRay.getPoint(500).z,centerRay.getPoint(500).y);
|
||||||
|
return from * (1-extent) + to * extent;
|
||||||
|
}
|
||||||
|
|
||||||
bool PhysicsSystem::castRay(const Vector3& from, const Vector3& to)
|
bool PhysicsSystem::castRay(const Vector3& from, const Vector3& to)
|
||||||
{
|
{
|
||||||
btVector3 _from, _to;
|
btVector3 _from, _to;
|
||||||
|
|
|
@ -36,6 +36,10 @@ namespace MWWorld
|
||||||
|
|
||||||
std::pair<std::string, float> getFacedHandle (MWWorld::World& world);
|
std::pair<std::string, float> getFacedHandle (MWWorld::World& world);
|
||||||
|
|
||||||
|
btVector3 getRayPoint(float extent);
|
||||||
|
|
||||||
|
std::vector < std::pair <float, std::string> > getFacedObjects ();
|
||||||
|
|
||||||
// cast ray, return true if it hit something
|
// cast ray, return true if it hit something
|
||||||
bool castRay(const Ogre::Vector3& from, const Ogre::Vector3& to);
|
bool castRay(const Ogre::Vector3& from, const Ogre::Vector3& to);
|
||||||
|
|
||||||
|
|
|
@ -497,6 +497,8 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string World::getFacedHandle()
|
std::string World::getFacedHandle()
|
||||||
|
{
|
||||||
|
if (!mRendering->occlusionQuerySupported())
|
||||||
{
|
{
|
||||||
std::pair<std::string, float> result = mPhysics->getFacedHandle (*this);
|
std::pair<std::string, float> result = mPhysics->getFacedHandle (*this);
|
||||||
|
|
||||||
|
@ -506,6 +508,12 @@ namespace MWWorld
|
||||||
|
|
||||||
return result.first;
|
return result.first;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// updated every few frames in update()
|
||||||
|
return mFacedHandle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void World::deleteObject (Ptr ptr)
|
void World::deleteObject (Ptr ptr)
|
||||||
{
|
{
|
||||||
|
@ -715,6 +723,61 @@ namespace MWWorld
|
||||||
sun = Vector3(sun.x, -sun.z, sun.y);
|
sun = Vector3(sun.x, -sun.z, sun.y);
|
||||||
mRendering->getSkyManager()->setGlare(!mPhysics->castRay(Ogre::Vector3(p[0], p[1], p[2]), sun));
|
mRendering->getSkyManager()->setGlare(!mPhysics->castRay(Ogre::Vector3(p[0], p[1], p[2]), sun));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update faced handle (object the player is looking at)
|
||||||
|
// this uses a mixture of raycasts and occlusion queries.
|
||||||
|
else // if (mRendering->occlusionQuerySupported())
|
||||||
|
{
|
||||||
|
MWRender::OcclusionQuery* query = mRendering->getOcclusionQuery();
|
||||||
|
if (!query->occlusionTestPending())
|
||||||
|
{
|
||||||
|
// get result of last query
|
||||||
|
if (mNumFacing == 0) mFacedHandle = "";
|
||||||
|
else if (mNumFacing == 1)
|
||||||
|
{
|
||||||
|
bool result = query->getTestResult();
|
||||||
|
mFacedHandle = result ? mFaced1Name : "";
|
||||||
|
}
|
||||||
|
else if (mNumFacing == 2)
|
||||||
|
{
|
||||||
|
bool result = query->getTestResult();
|
||||||
|
mFacedHandle = result ? mFaced2Name : mFaced1Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
// send new query
|
||||||
|
// figure out which object we want to test against
|
||||||
|
std::vector < std::pair < float, std::string > > results = mPhysics->getFacedObjects();
|
||||||
|
|
||||||
|
if (results.size() == 0)
|
||||||
|
{
|
||||||
|
mNumFacing = 0;
|
||||||
|
}
|
||||||
|
else if (results.size() == 1)
|
||||||
|
{
|
||||||
|
mFaced1 = getPtrViaHandle(results.front().second);
|
||||||
|
mFaced1Name = results.front().second;
|
||||||
|
mNumFacing = 1;
|
||||||
|
|
||||||
|
btVector3 p = mPhysics->getRayPoint(results.front().first);
|
||||||
|
Ogre::Vector3 pos(p.x(), p.z(), -p.y());
|
||||||
|
Ogre::SceneNode* node = mFaced1.getRefData().getBaseNode();
|
||||||
|
query->occlusionTest(pos, node);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mFaced1Name = results.front().second;
|
||||||
|
mFaced2Name = results[1].second;
|
||||||
|
mFaced1 = getPtrViaHandle(results.front().second);
|
||||||
|
mFaced2 = getPtrViaHandle(results[1].second);
|
||||||
|
mNumFacing = 2;
|
||||||
|
|
||||||
|
btVector3 p = mPhysics->getRayPoint(results[1].first);
|
||||||
|
Ogre::Vector3 pos(p.x(), p.z(), -p.y());
|
||||||
|
Ogre::SceneNode* node = mFaced2.getRefData().getBaseNode();
|
||||||
|
query->occlusionTest(pos, node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool World::isCellExterior() const
|
bool World::isCellExterior() const
|
||||||
|
|
|
@ -93,6 +93,12 @@ namespace MWWorld
|
||||||
|
|
||||||
Ptr getPtrViaHandle (const std::string& handle, Ptr::CellStore& cellStore);
|
Ptr getPtrViaHandle (const std::string& handle, Ptr::CellStore& cellStore);
|
||||||
|
|
||||||
|
std::string mFacedHandle;
|
||||||
|
Ptr mFaced1;
|
||||||
|
Ptr mFaced2;
|
||||||
|
std::string mFaced1Name;
|
||||||
|
std::string mFaced2Name;
|
||||||
|
int mNumFacing;
|
||||||
|
|
||||||
int getDaysPerMonth (int month) const;
|
int getDaysPerMonth (int month) const;
|
||||||
|
|
||||||
|
|
|
@ -241,8 +241,8 @@ namespace Physic
|
||||||
|
|
||||||
static bool cmp( const std::pair<float, btCollisionObject*>& i, const std::pair<float, btCollisionObject*>& j )
|
static bool cmp( const std::pair<float, btCollisionObject*>& i, const std::pair<float, btCollisionObject*>& j )
|
||||||
{
|
{
|
||||||
if( i.first < j.first ) return false;
|
if( i.first > j.first ) return false;
|
||||||
if( j.first < i.first ) return true;
|
if( j.first > i.first ) return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue