📄 simplescenes.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 + -