SkilleR666
03-10-2010 17:19:16
Hi there
I started using Ogre with NxOgre, but i hate not open source library. So i switched to bullet/ogrebullet.
Actually, i have a terrain, a terrain shape, a .mesh, and a shape for the mesh. I update the simulation, the mesh follow the gravity, but not the collision.
Visual explanation -> http://tinypic.com/player.php?v=m9vq6e&s=7
Here, the main line (the textual :p) :
I started using Ogre with NxOgre, but i hate not open source library. So i switched to bullet/ogrebullet.
Actually, i have a terrain, a terrain shape, a .mesh, and a shape for the mesh. I update the simulation, the mesh follow the gravity, but not the collision.
Visual explanation -> http://tinypic.com/player.php?v=m9vq6e&s=7
Here, the main line (the textual :p) :
// m_GestionScene is a Ogre::SceneMgr
m_GestionScene = Jeu::getSingletonPtr()->m_Root->createSceneManager(
"TerrainSceneManager",
"LoginSceneMgr"
);
OgreBulletDynamics::DynamicsWorld *m_MondePhysique = new OgreBulletDynamics::DynamicsWorld(
m_GestionScene,
AxisAlignedBox(Ogre::Vector3 (-10000, -10000, -10000), Ogre::Vector3 (10000, 10000, 10000)),
Ogre::Vector3(0,-9.81,0),
true,
true,
10000);
m_GestionScene->setWorldGeometry("terrain.cfg");
unsigned page_size = Ogre::StringConverter::parseUnsignedInt(config["PageSize"].str());
Ogre::Vector3 terrainScale(
Ogre::StringConverter::parseReal( config["PageWorldX"].str() ) / (page_size-1),
Ogre::StringConverter::parseReal( config["MaxHeight"].str() ),
Ogre::StringConverter::parseReal( config["PageWorldZ"].str() ) / (page_size-1)
);
Ogre::String terrainfileName = config["Heightmap.image"].str();
float *heights = new float [page_size*page_size];
Ogre::Image terrainHeightMap;
terrainHeightMap.load("terrain.png", "Jeu");
for(unsigned y = 0; y < page_size; ++y)
{
for(unsigned x = 0; x < page_size; ++x)
{
Ogre::ColourValue color = terrainHeightMap.getColourAt(x, y, 0);
heights[x + y * page_size] = color.r;
}
}
OgreBulletCollisions::HeightmapCollisionShape *mTerrainShape = new OgreBulletCollisions
::HeightmapCollisionShape (
page_size,
page_size,
terrainScale,
heights,
true
);
OgreBulletDynamics::RigidBody *defaultTerrainBody = new OgreBulletDynamics::RigidBody(
"Terrain",
m_MondePhysique
);
const float terrainBodyRestitution = 0.1f;
const float terrainBodyFriction = 0.8f;
Ogre::Vector3 terrainShiftPos(
(terrainScale.x * (page_size - 1) / 2),
0,
(terrainScale.z * (page_size - 1) / 2)
);
terrainShiftPos.y = terrainScale.y / 2 * terrainScale.y;
Ogre::SceneNode* pTerrainNode = m_GestionScene->getRootSceneNode ()->createChildSceneNode ();
defaultTerrainBody->setStaticShape(
pTerrainNode,
mTerrainShape,
terrainBodyRestitution,
terrainBodyFriction,
terrainShiftPos);
Ogre::Entity *entity = m_GestionScene->createEntity(
"test",
"ellipsoid.mesh"
);
entity->setQueryFlags(GEOMETRY_QUERY_MASK);
entity->setCastShadows(true);
const float gStaticBodyRestitution = 0.1f;
const float gStaticBodyFriction = 0.8f;
const float gDynamicBodyRestitution = 0.6f;
const float gDynamicBodyFriction = 0.6f;
const float gDynamicBodyMass = 1.0f;
const Ogre::Real gSphereBodyBounds = 1.0f;
OgreBulletCollisions::SphereCollisionShape *sceneCubeShape = new OgreBulletCollisions::SphereCollisionShape(gSphereBodyBounds);
OgreBulletDynamics::RigidBody *defaultBody = new OgreBulletDynamics::RigidBody(
"defaultSphereRigid",
m_MondePhysique
);
pTerrainNode->attachObject (entity);
defaultBody->setShape (
node,
sceneCubeShape,
gDynamicBodyRestitution,
gDynamicBodyFriction,
gDynamicBodyMass,
Ogre::Vector3(1020,259,1220),
Ogre::Quaternion(0,0,0,1)
);
This code is formatted. In real, all physics part are store in Class "GestionPhysique". That's why the following code is called each update :
void GestionPhysique::miseAJour(const double tpsDepuisDerniereFrame)
{
// Mise à jour de la simulation physiques
m_MondePhysique->stepSimulation(tpsDepuisDerniereFrame);
}