⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ogrecollisionmanager.cpp

📁 opcode是功能强大
💻 CPP
📖 第 1 页 / 共 2 页
字号:
///////////////////////////////////////////////////////////////////////////////
///  @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 + -