📄 simplescenes_chain.h
字号:
/*
SimpleScenes_Chain.h
----------------------
A reimplementation of the ODE spherical chain demo
using Ogre and the OgreOde wrapper.
*/
#ifndef _SIMPLESCENESCHAIN_H_
#define _SIMPLESCENES_CHAIN_H_
/*
The chain test extends the base test class
*/
class SimpleScenes_Chain:public SimpleScenes
{
public:
// Standard constructor, creates everything in the demo
SimpleScenes_Chain()
{
// Set up the sizes of stuff
Real link_size = 0.4,geom_size = 0.4,adjust = 0.1;
OgreOde::Body* last_body = 0;
int num_links = 10;
_first_body = 0;
_force = 100;
// Create all the links in the chain
for(int i = num_links - 1;i >= 0;i--)
{
Real np = (Real)i * (link_size + adjust);
String name = String("Sphere_") + StringConverter::toString(i);
// Visuals
Entity* entity = _mgr->createEntity(name,"Ball.mesh");
entity->setNormaliseNormals(true);
entity->setCastShadows(true);
SceneNode* node = _mgr->getRootSceneNode()->createChildSceneNode(entity->getName());
node->attachObject(entity);
node->setScale(link_size * 0.2,link_size * 0.2,link_size * 0.2);
node->setPosition(Vector3(np,np + 0.4,np));
// Physicals
OgreOde::Body* body = OgreOde::MeshInformer::createSingleDynamicSphere(node,1.0,_space);
_bodies.push_back(body);
_geoms.push_back(body->getGeometry(0));
// Join the current body to the last one (if there was a last one)
if(!_first_body)
{
_last_node = node;
_first_body = body;
}
if(last_body)
{
OgreOde::BallJoint* joint = new OgreOde::BallJoint();
joint->attach(body,last_body);
Real ja = ((Real)i + 0.5) * (link_size + adjust);
joint->setAnchor(Vector3(ja,ja + 0.4,ja));
_joints.push_back(joint);
}
last_body = body;
}
// Create some static boxes to bump into
createBox(0,2,Vector3(4,1,4));
createBox(1,2,Vector3(-4,1,4));
createBox(2,2,Vector3(-4,1,-4));
createBox(3,2,Vector3(4,1,-4));
}
// Let the user throw the chain around
virtual void frameEnded(Real time,InputReader* input)
{
// Do default processing
SimpleScenes::frameEnded(time,input);
_force_to_apply = Vector3::ZERO;
// Up
if(input->isKeyDown(KC_Z)) _force_to_apply.y += _force;
// Along Z-axis
if(input->isKeyDown(KC_J)) _force_to_apply.z += _force;
if(input->isKeyDown(KC_L)) _force_to_apply.z -= _force;
// Along X-axis
if(input->isKeyDown(KC_K)) _force_to_apply.x += _force;
if(input->isKeyDown(KC_I)) _force_to_apply.x -= _force;
}
// Apply the forces before every time step
void addForcesAndTorques()
{
// Apply the force we calculated in the key handler
_first_body->addForce(_force_to_apply);
}
// Return our name for the test application to display
virtual const String& getName()
{
static String name = "Test Chain";
return name;
}
// Tell the user what keys they can use
virtual const String& getKeys()
{
static String keys = "J/L, I/K, Z - Throw the chain around";
return keys;
}
// Override the collision callback to set our own parameters
bool collision(OgreOde::Contact* contact)
{
// If the base class doesn't think the collision needs to
// happen then we won't do anything either
if(!SimpleScenes::collision(contact)) return false;
// Set the floor to be a bit slippy
contact->setCoulombFriction(10.0);
return true;
}
// Use the destructor to delete the crate scene nodes
// everything else gets deleted automatically
SimpleScenes_Chain::~SimpleScenes_Chain()
{
for(int i = 0;i < 4;i++)
{
if(i != 2)
{
String name = String("Crate_") + StringConverter::toString(i);
_mgr->destroySceneNode(name);
_mgr->removeEntity(name);
}
}
}
protected:
// Utility method to create a static box
void createBox(int id,Real size,const Vector3& position)
{
// Visual
String name = String("Crate_") + StringConverter::toString(id);
Entity* entity = _mgr->createEntity(name,"Crate.mesh");
entity->setNormaliseNormals(true);
entity->setCastShadows(true);
SceneNode* node = _mgr->getRootSceneNode()->createChildSceneNode(entity->getName());
node->attachObject(entity);
node->setScale(size * 0.1,size * 0.1,size * 0.1);
node->setPosition(position);
// Make one of them dynamic, the others are static
if((position.x < 0)&&(position.z < 0))
{
_box_body = OgreOde::MeshInformer::createSingleDynamicBox(node,2.0,_space);
_bodies.push_back(_box_body);
_geoms.push_back(_box_body->getGeometry(0));
}
else
{
// Collision geometry
_geoms.push_back(OgreOde::MeshInformer::createSingleStaticBox(node,_space));
}
}
protected:
// Keep track of the top of the chain so we can throw it around
OgreOde::Body *_first_body,*_box_body;
Real _force;
Vector3 _force_to_apply;
};
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -