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

📄 simplescenes.cpp

📁 使用stl技术,(还没看,是听说的)
💻 CPP
字号:
/*
SimpleScenes.cpp
---------------
Code for the base scene class from which the specific scenes are derived
*/
#include "SimpleScenes.h"

const Real SimpleScenes::KEY_DELAY = 1.0;
const Real SimpleScenes::STEP_RATE = 0.01;

/*
Constructor; initailise stuff
*/
SimpleScenes::SimpleScenes()
{
	setInfoText(StringUtil::BLANK);

	_world = OgreOde::World::getSingletonPtr();
	_mgr = _world->getSceneManager();
	_world->setCollisionListener(this);
	_space = _world->getDefaultSpace();
	_key_delay = SimpleScenes::KEY_DELAY;
	_last_node = 0;
}

/*
Called by OgreOde whenever a collision occurs, so 
that we can modify the contact parameters
*/
bool SimpleScenes::collision(OgreOde::Contact* contact)
{
	// Check for collisions between things that are connected and ignore them
	OgreOde::Geometry* g1 = contact->getFirstGeometry();
	OgreOde::Geometry* g2 = contact->getSecondGeometry();

	if(g1 && g2)
	{
		OgreOde::Body* b1 = g1->getBody();
		OgreOde::Body* b2 = g2->getBody();
		if(b1 && b2) if(OgreOde::Joint::areConnected(b1,b2)) return false; 
	}

	// Set the friction at the contact
	contact->setCoulombFriction(OgreOde::Utility::Infinity);

	// Yes, this collision is valid
	return true;
}

/*
Handle key presses
*/
void SimpleScenes::frameEnded(Real time,InputReader* input)
{
	_key_delay += time;
}

/*
Utility method to set the information string in the UI
*/
void SimpleScenes::setInfoText(const String& text)
{
	GuiManager::getSingleton().getGuiElement("OgreOdeDemos/Info")->setCaption(String("Info: ") + text);
}

/*
Create a randomly sized box, sphere or capsule for dropping on things
*/
OgreOde::Body* SimpleScenes::createRandomObject(OgreOde::Geometry::Class objectClass)
{
	if(_key_delay < SimpleScenes::KEY_DELAY) return 0;

	String typeName = (objectClass == OgreOde::Geometry::Class_Box)?"Crate":
				      (objectClass == OgreOde::Geometry::Class_Sphere)?"Ball":
					  (objectClass == OgreOde::Geometry::Class_Capsule)?"Capsule":"unknown";

	// Create the visual representation (the Ogre entity and scene node)
	String name = typeName + StringConverter::toString((unsigned int)_bodies.size());
	Entity* entity = _mgr->createEntity(name, typeName + ".mesh");
	SceneNode* node = _mgr->getRootSceneNode()->createChildSceneNode(name);
	node->attachObject(entity);
	entity->setNormaliseNormals(true);
	entity->setCastShadows(true);

	// Pick a size
	Vector3 size((OgreOde::Utility::randomReal() * 0.5 + 0.1) * 2.0,(OgreOde::Utility::randomReal() * 0.5 + 0.1) * 2.0,(OgreOde::Utility::randomReal() * 0.5 + 0.1) * 2.0);

	// Create a body associated with the node we created
	OgreOde::Body* body = new OgreOde::Body();
	node->attachObject(body);

	// Set the mass and geometry to match the visual representation
	OgreOde::Geometry* geom = 0;
	switch(objectClass)
	{
		case OgreOde::Geometry::Class_Box:
		{
			size *= 1.75;

			OgreOde::BoxMass mass(1.0,size);
			mass.setDensity(5.0,size);
			
			geom = (OgreOde::Geometry*)new OgreOde::BoxGeometry(size,_space); 
			node->setScale(size.x * 0.1,size.y * 0.1,size.z * 0.1);
			body->setMass(mass);
		}
		break;

		case OgreOde::Geometry::Class_Sphere:
		{
			OgreOde::SphereMass mass(1.0,size.x);
			mass.setDensity(5.0,size.x);

			geom = (OgreOde::Geometry*)new OgreOde::SphereGeometry(size.x,_space);
			node->setScale(size.x * 0.2,size.x * 0.2,size.x * 0.2);
			body->setMass(mass);
		}
		break;

		case OgreOde::Geometry::Class_Capsule:
		{
			size.x *= 0.5;

			OgreOde::CapsuleMass mass(1.0,size.x,Vector3::UNIT_Z,size.y);
			mass.setDensity(5.0,size.x,Vector3::UNIT_Z,size.y);
			
			geom = (OgreOde::Geometry*)new OgreOde::CapsuleGeometry(size.x,size.y,_space);
			node->setScale(size.x,size.x,(size.y + (size.x * 2.0)) * 0.25);
			body->setMass(mass);
		}
		break;
	}

	// Tie the collision geometry to the physical body
	geom->setBody(body);

	// Keep track of the body
	_bodies.push_back(body);
	_geoms.push_back(geom);
	
	_key_delay = 0.0;

	// If we created something position and orient it randomly
	if(body)
	{
		body->setOrientation(Quaternion(Radian(OgreOde::Utility::randomReal() * 10.0 - 5.0),Vector3(OgreOde::Utility::randomReal() * 2.0 - 1.0,OgreOde::Utility::randomReal() * 2.0 - 1.0,OgreOde::Utility::randomReal() * 2.0 - 1.0)));
		body->setPosition(Vector3((OgreOde::Utility::randomReal() * 10.0) - 5.0,OgreOde::Utility::randomReal() + 5,(OgreOde::Utility::randomReal() * 10.0) - 5.0));

		// Set the last body we created to be looked at
		_last_node = static_cast<SceneNode*>(body->getParentNode());
	}

	return body;
}

/*
Destructor, delete everything we're keeping track of
*/
SimpleScenes::~SimpleScenes(void)
{
	// Stop listening for collisions
	if(_world->getCollisionListener() == this) _world->setCollisionListener(0);

	// Delete all the joints
	for(std::vector<OgreOde::Joint*>::iterator i = _joints.begin();i != _joints.end();i++)
	{
		delete (*i);
	}

	// Run through the list of bodies we're monitoring
	std::vector<MovableObject*> clearList;
	for(std::vector<OgreOde::Body*>::iterator i = _bodies.begin();i != _bodies.end();i++)
	{
		// Get the node this body controls
		SceneNode* node = static_cast<SceneNode*>((*i)->getParentNode());
		if(node)
		{
			// Get its name and remember all the things attached to it
			String name = node->getName();
			int num = node->numAttachedObjects();
			for(int cur = 0;cur < num;cur++)
			{
				MovableObject* obj = node->getAttachedObject(cur);
				if(obj->getMovableType() != OgreOde::Body::MovableType) clearList.push_back(obj);
			}

			// Destroy the node by name
			_mgr->getRootSceneNode()->removeAndDestroyChild(name);
		}

		// Delete the body
		delete (*i);
	}

	// Remove all the entities we found attached to scene nodes we're controlling
	for(std::vector<MovableObject*>::iterator i = clearList.begin();i != clearList.end();i++)
	{
		if((*i)->getMovableType() == "Entity") _mgr->removeEntity(static_cast<Entity*>(*i));
		else if((*i)->getMovableType() == "ParticleSystem") ParticleSystemManager::getSingleton().destroySystem(static_cast<ParticleSystem*>(*i));
	}

	// Delete all the collision geometries
	for(std::vector<OgreOde::Geometry*>::iterator i = _geoms.begin();i != _geoms.end();i++)
	{
		delete (*i);
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -