📄 ogrecollisionmanager.cpp
字号:
///////////////////////////////////////////////////////////////////////////////
/// @file OgreCollisionManager.cpp
/// @brief <TODO: insert file description here>
///
/// @author The OgreOpcode Team
///
/// This file is part of OgreOpcode.
///
/// A lot of the code is based on the Nebula Opcode Collision module, see docs/Nebula_license.txt
///
/// OgreOpcode is free software; you can redistribute it and/or
/// modify it under the terms of the GNU Lesser General Public
/// License as published by the Free Software Foundation; either
/// version 2.1 of the License, or (at your option) any later version.
///
/// OgreOpcode is distributed in the hope that it will be useful,
/// but WITHOUT ANY WARRANTY; without even the implied warranty of
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
/// Lesser General Public License for more details.
///
/// You should have received a copy of the GNU Lesser General Public
/// License along with OgreOpcode; if not, write to the Free Software
/// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
///
///////////////////////////////////////////////////////////////////////////////
#include "OgreCollisionManager.h"
#include "OgreCollisionReporter.h"
#include "OgreMeshCollisionShape.h"
#include "OgreEntityCollisionShape.h"
#include "OgrePtrCollisionShape.h"
#include "OgreBoxCollisionShape.h"
#include "OgreCapsuleMeshCollisionShape.h"
#include "OgreSphereMeshCollisionShape.h"
#include "OgreTerrainCollisionShape.h"
#include "OgreCapsuleMeshCollisionShape.h"
using namespace Ogre;
using namespace OgreOpcode::Details;
template<> OgreOpcode::CollisionManager* Ogre::Singleton<OgreOpcode::CollisionManager>::ms_Singleton = 0;
namespace OgreOpcode
{
CollisionManager* CollisionManager::getSingletonPtr(void)
{
return ms_Singleton;
}
CollisionManager& CollisionManager::getSingleton(void)
{
assert( ms_Singleton ); return ( *ms_Singleton );
}
CollisionManager::CollisionManager(SceneManager* sMgr)
{
mSceneMgr = sMgr;
unique_id = 0;
default_context = 0;
Opcode::InitOpcode();
// setup the tree collider
opcTreeCollider.SetFirstContact(false); // report all contacts
opcTreeCollider.SetFullBoxBoxTest(false); // use coarse BV-BV tests
opcTreeCollider.SetFullPrimBoxTest(false); // use coarse primitive-BV tests
opcTreeCollider.SetTemporalCoherence(false); // don't use temporal coherence
// setup the ray collider
opcRayCollider.SetFirstContact(false); // report all contacts
opcRayCollider.SetTemporalCoherence(false); // no temporal coherence
opcRayCollider.SetClosestHit(false); // all hits
opcRayCollider.SetCulling(true); // with backface culling
opcRayCollider.SetMaxDist(100000.0f); // max dist 100 km
opcRayCollider.SetDestination(&(opcFaceCache)); // detected hits go here
// setup the sphere collider
opcSphereCollider.SetFirstContact(false); // report all contacts
opcSphereCollider.SetTemporalCoherence(false); // no temporal coherence
// setup the planes collider
opcPlanesCollider.SetFirstContact(false); // report all contacts
opcPlanesCollider.SetTemporalCoherence(false); // no temporal coherence
// setup the LSS collider
opcSweptSphereCollider.SetFirstContact(false);
opcSweptSphereCollider.SetTemporalCoherence(false); // no temporal coherence
}
CollisionManager::~CollisionManager()
{
/// release collision type definitions
collclass_list.clear();
colltype_table.clear();
/// release any shapes and contexts that may still be around...
ContextList::iterator ctxIter;
for (ctxIter = context_list.begin(); ctxIter != context_list.end(); ++ctxIter)
{
if(ctxIter->second)
delete ctxIter->second;
}
context_list.clear();
ShapeList::iterator shpIter;
for (shpIter = shape_list.begin(); shpIter != shape_list.end(); ++shpIter)
{
if(shpIter->second)
delete shpIter->second;
}
shape_list.clear();
Opcode::CloseOpcode();
}
CollisionContext *CollisionManager::createContext(const Ogre::String& contextName)
{
ContextIterator i = context_list.find(contextName);
if (i != context_list.end())
{
// Warning! Context already exsists. Return the exsisting one.
return i->second;
}
CollisionContext *cc = new CollisionContext(contextName);
context_list.insert(ContextList::value_type(contextName,cc));
return cc;
}
/// Create a new, possibly shared shape object.
ICollisionShape *CollisionManager::createShape(const Ogre::String& id, const ShapeType shpType)
{
// assert(id);
Ogre::String new_id = getResourceID(id);
ShapeIterator i = shape_list.find(new_id);
if (i != shape_list.end())
{
// Warning! Shape already exsists. Return the exsisting one, if the pointer is valid
// otherwise: delete the new_id shape from the shape list.
if(i->second)
{
return i->second;
} else
{
shape_list.erase(i->first);
}
}
if(shpType == SHAPETYPE_ENTITY)
{
EntityCollisionShape* cs = new EntityCollisionShape(new_id);
shape_list.insert(ShapeList::value_type(new_id,cs));
return cs;
}
if(shpType == SHAPETYPE_MESH)
{
MeshCollisionShape* cs = new MeshCollisionShape(new_id);
shape_list.insert(ShapeList::value_type(new_id,cs));
return cs;
}
if(shpType == SHAPETYPE_PTR)
{
PtrCollisionShape* cs = new PtrCollisionShape(new_id);
shape_list.insert(ShapeList::value_type(new_id,cs));
return cs;
}
if(shpType == SHAPETYPE_BOX)
{
BoxCollisionShape* cs = new BoxCollisionShape(new_id);
shape_list.insert(ShapeList::value_type(new_id,cs));
return cs;
}
if(shpType == SHAPETYPE_CAPSULE)
{
CapsuleMeshCollisionShape* cs = new CapsuleMeshCollisionShape(new_id);
shape_list.insert(ShapeList::value_type(new_id,cs));
return cs;
}
if(shpType == SHAPETYPE_SPHERE)
{
SphereMeshCollisionShape* cs = new SphereMeshCollisionShape(new_id);
shape_list.insert(ShapeList::value_type(new_id,cs));
return cs;
}
if(shpType == SHAPETYPE_TERRAIN)
{
TerrainCollisionShape* cs = new TerrainCollisionShape(new_id);
shape_list.insert(ShapeList::value_type(new_id,cs));
return cs;
}
// hacky way of returning a default ..
EntityCollisionShape* cs = new EntityCollisionShape(new_id);
shape_list.insert(ShapeList::value_type(new_id,cs));
return cs;
}
MeshCollisionShape* CollisionManager::createMeshCollisionShape(const Ogre::String& name)
{
return static_cast<MeshCollisionShape*>(createShape(name, SHAPETYPE_MESH));
}
EntityCollisionShape* CollisionManager::createEntityCollisionShape(const Ogre::String& name)
{
return static_cast<EntityCollisionShape*>(createShape(name, SHAPETYPE_ENTITY));
}
BoxCollisionShape* CollisionManager::createBoxCollisionShape(const Ogre::String& name)
{
return static_cast<BoxCollisionShape*>(createShape(name, SHAPETYPE_BOX));
}
CapsuleMeshCollisionShape* CollisionManager::createCapsuleMeshCollisionShape(const Ogre::String& name)
{
return static_cast<CapsuleMeshCollisionShape*>(createShape(name, SHAPETYPE_CAPSULE));
}
SphereMeshCollisionShape* CollisionManager::createSphereMeshCollisionShape(const Ogre::String& name)
{
return static_cast<SphereMeshCollisionShape*>(createShape(name, SHAPETYPE_SPHERE));
}
PtrCollisionShape* CollisionManager::createPtrCollisionShape(const Ogre::String& name)
{
return static_cast<PtrCollisionShape*>(createShape(name, SHAPETYPE_PTR));
}
TerrainCollisionShape* CollisionManager::createTerrainCollisionShape(const Ogre::String& name)
{
return static_cast<TerrainCollisionShape*>(createShape(name, SHAPETYPE_TERRAIN));
}
void CollisionManager::attachContext(CollisionContext *cc)
{
Ogre::String contextName = cc->getName();
ContextIterator i = context_list.find(contextName);
if (i != context_list.end())
{
// Warning! Context already exsists.
// If the pointer is 0 : Return without touching anything.
if(i->second)
return;
// Just remove the context from the list
context_list.erase(i->first);
}
context_list.insert(ContextList::value_type(contextName,cc));
}
void CollisionManager::detachContext(CollisionContext *cc)
{
assert(cc);
ContextIterator i, iend;
iend = context_list.end();
for (i = context_list.begin(); i != iend; ++i)
{
if (i->second == cc)
{
context_list.erase(i->first);
break;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -