[SOLVED] difference of terrains

emmanuel1359

24-02-2015 22:47:59

Hello,

after having compiled and linked under linux : ogre, bullet, and add OgreBullet to my project (could'nt link correctly OgreBullet), i've mixed up some of the tutorials:

the problem is that there is 2 terrain fro the same heightmap image, but they don't match !

i use the ogre basic framework, and the ogre bullet code at

when i throw a box with B, the behavior is good, on the green bullet terrain.

i wonder if it is not these lines:
Ogre::Vector3 terrainShiftPos(terrainScale.x/(page_size-1), 0, terrainScale.z/(page_size-1));
terrainShiftPos.y = terrainScale.y / 2 * terrainScale.y;

i don't understand what they do

must i read some bullet doc before ?

the result is:
[attachment=0]BOF_Screenshot_02242015_213717725.jpg[/attachment]


there my code:
#include "DemoApp.h"

#include "OgreBulletDynamics.h"
#include "OgreBulletCollisions.h"
#include "OgreBulletCollisionsShape.h"
#include "Shapes/OgreBulletCollisionsBoxShape.h" // for Boxes
#include "Shapes/OgreBulletCollisionsStaticPlaneShape.h" // for static planes
#include "Shapes/OgreBulletCollisionsCylinderShape.h" // for cylinders
#include "Shapes/OgreBulletCollisionsTerrainShape.h"

using namespace Ogre;

DemoApp::DemoApp()
{
mTerrainGroup = 0;
mTerrainGlobals = 0;
}

//|||||||||||||||||||||||||||||||||||||||||||||||

DemoApp::~DemoApp()
{
OGRE_DELETE mTerrainGroup;
OGRE_DELETE mTerrainGlobals;
OGRE_DELETE OgreFramework::getSingletonPtr();


// OgreBullet physic delete - RigidBodies
std::deque<OgreBulletDynamics::RigidBody *>::iterator itBody = mBodies.begin();
while (mBodies.end() != itBody)
{
OGRE_DELETE *itBody;
++itBody;
}
// OgreBullet physic delete - Shapes
std::deque<OgreBulletCollisions::CollisionShape *>::iterator itShape = mShapes.begin();
while (mShapes.end() != itShape)
{
OGRE_DELETE *itShape;
++itShape;
}
mBodies.clear();
mShapes.clear();
OGRE_DELETE mWorld->getDebugDrawer();
mWorld->setDebugDrawer(0);
OGRE_DELETE mWorld;

}


//-------------------------------------------------------------------------------------
void DemoApp::getTerrainImage(bool flipX, bool flipY, Ogre::Image& img)
{
img.load("terrain.png", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
if (flipX)
img.flipAroundY();
if (flipY)
img.flipAroundX();

}
//-------------------------------------------------------------------------------------
void DemoApp::defineTerrain(long x, long y)
{
Ogre::String filename = mTerrainGroup->generateFilename(x, y);
if (Ogre::ResourceGroupManager::getSingleton().resourceExists(mTerrainGroup->getResourceGroup(), filename))
{
mTerrainGroup->defineTerrain(x, y);
}
else
{
Ogre::Image img;
getTerrainImage(x % 2 != 0, y % 2 != 0, img);
mTerrainGroup->defineTerrain(x, y, &img);
mTerrainsImported = true;
}
}
//-------------------------------------------------------------------------------------
void DemoApp::initBlendMaps(Ogre::Terrain* terrain)
{

}
//-------------------------------------------------------------------------------------
void DemoApp::configureTerrainDefaults(Ogre::Light* light)
{
// Configure global
mTerrainGlobals->setMaxPixelError(8);
// testing composite map
mTerrainGlobals->setCompositeMapDistance(3000);

// Important to set these so that the terrain knows what to use for derived (non-realtime) data
mTerrainGlobals->setLightMapDirection(light->getDerivedDirection());
mTerrainGlobals->setCompositeMapAmbient(OgreFramework::getSingletonPtr()->m_pSceneMgr->getAmbientLight());
mTerrainGlobals->setCompositeMapDiffuse(light->getDiffuseColour());

// Configure default import settings for if we use imported image
Ogre::Terrain::ImportData& defaultimp = mTerrainGroup->getDefaultImportSettings();
defaultimp.terrainSize = 4000;
defaultimp.worldSize = 12000.0f;
defaultimp.inputScale = 600; // due terrain.png is 8 bpp
defaultimp.minBatchSize = 33;
defaultimp.maxBatchSize = 65;

// textures
defaultimp.layerList.resize(3);
defaultimp.layerList[0].worldSize = 100;
defaultimp.layerList[0].textureNames.push_back("grass_green-01_diffusespecular.dds");
defaultimp.layerList[0].textureNames.push_back("grass_green-01_normalheight.dds");
defaultimp.layerList[1].worldSize = 30;
defaultimp.layerList[1].textureNames.push_back("dirt_grayrocky_diffusespecular.dds");
defaultimp.layerList[1].textureNames.push_back("dirt_grayrocky_normalheight.dds");
defaultimp.layerList[2].worldSize = 200;
defaultimp.layerList[2].textureNames.push_back("growth_weirdfungus-03_diffusespecular.dds");
defaultimp.layerList[2].textureNames.push_back("growth_weirdfungus-03_normalheight.dds");

}




//-------------------------------------------------------------------------------------
void DemoApp::createGrassMesh(Ogre::String str)
{
const float width = 5.f;
const float height = 6.f;
Ogre::ManualObject mo(str);

Ogre::Vector3 vec(width/2, 0, 0);
Ogre::Quaternion rot;
rot.FromAngleAxis(Ogre::Degree(90), Ogre::Vector3::UNIT_Y);

mo.begin("myMaterials/"+str, Ogre::RenderOperation::OT_TRIANGLE_LIST);
for (int i = 0; i < 2; ++i)
{
mo.position(-vec.x, height, -vec.z);
mo.textureCoord(0, 0);

mo.position(vec.x, height, vec.z);
mo.textureCoord(1, 0);

mo.position(-vec.x, 0, -vec.z);
mo.textureCoord(0, 1);

mo.position(vec.x, 0, vec.z);
mo.textureCoord(1, 1);

int offset = i * 4;
mo.triangle(offset, offset+3, offset+1);
mo.triangle(offset, offset+2, offset+3);

vec = rot * vec;
}
mo.end();
mo.convertToMesh(str);
}


void DemoApp::createTerrain(Ogre::Light* light)
{
// terrain
mTerrainGlobals = OGRE_NEW Ogre::TerrainGlobalOptions();
mTerrainGroup = OGRE_NEW Ogre::TerrainGroup(OgreFramework::getSingletonPtr()->m_pSceneMgr, Ogre::Terrain::ALIGN_X_Z, 513, 12000.0f);
mTerrainGroup->setFilenameConvention(Ogre::String("TutorialTerrain"), Ogre::String("dat"));
mTerrainGroup->setOrigin(Ogre::Vector3::ZERO);
configureTerrainDefaults(light);

for (long x = 0; x <= 0; ++x)
for (long y = 0; y <= 0; ++y)
defineTerrain(x, y);

// sync load since we want everything in place when we start
mTerrainGroup->loadAllTerrains(true);

if (mTerrainsImported)
{
Ogre::TerrainGroup::TerrainIterator ti = mTerrainGroup->getTerrainIterator();
while(ti.hasMoreElements())
{
Ogre::Terrain* t = ti.getNext()->instance;
initBlendMaps(t);
}
}
mTerrainGroup->freeTemporaryResources();



// ground
const int nb_adventices = 8;
Ogre::String adventices[nb_adventices];
Ogre::Entity *E_adventice[nb_adventices];
adventices[0] = "Paturin";
adventices[1] = "Pissenlit";
adventices[2] = "Crocus";
adventices[3] = "Cigue";
adventices[4] = "Muguet";
adventices[5] = "Lavande";
adventices[6] = "Mauve";
adventices[7] = "Moutarde";
for (int i=0; i<nb_adventices; i++)
{
createGrassMesh(adventices);
E_adventice = OgreFramework::getSingletonPtr()->m_pSceneMgr->createEntity("e"+adventices, adventices);
}

// Ogre::InstanceManager *IM = OgreFramework::getSingletonPtr()->m_pSceneMgr->createInstanceManager("IM", "mesh_name", "group_name", Ogre::InstanceManager::ShaderBased, 1 );
// Ogre::InstanceManager::InstancingTechnique::HWInstancingBasic

// tree
// Ogre::SceneNode* headNode = OgreFramework::getSingletonPtr()->m_pSceneMgr->getRootSceneNode()->createChildSceneNode("HeadNode");
Ogre::Entity* maison = OgreFramework::getSingletonPtr()->m_pSceneMgr->createEntity("maison", "tudorhouse.mesh");
Ogre::Entity* tree = OgreFramework::getSingletonPtr()->m_pSceneMgr->createEntity("arbre", "column.mesh");

tree->setMaterialName("myMaterials/Bark");
// tree->setCastShadows(true);
// maison->setCastShadows(true);
// Ogre::Entity* tree = OgreFramework::getSingletonPtr()->m_pSceneMgr->createEntity("arbre", "StoneStatic.max");

// headNode->attachObject( tree );

// Ogre::InstancedGeometry *sg = OgreFramework::getSingletonPtr()->m_pSceneMgr->createInstancedGeometry("GroundArea");
Ogre::StaticGeometry *sg = OgreFramework::getSingletonPtr()->m_pSceneMgr->createStaticGeometry("GroundArea");

const int size = 1000;
const int rarete = 30;
sg->setRegionDimensions(Ogre::Vector3(size, size, size));
sg->setOrigin(Ogre::Vector3(-size/2, 0, -size/2));
for (int x = -size/2; x < size/2; x += rarete)
{
for (int z = -size/2; z < size/2; z += rarete)
{
Ogre::Real x1 = x + Ogre::Math::RangeRandom(-rarete/2, rarete/2);
Ogre::Real z1 = z + Ogre::Math::RangeRandom(-rarete/2, rarete/2);

// positionner au niveau du terrain
Ogre::Vector3 pos(x1, 0, z1);
long slotx;
long sloty;
mTerrainGroup->convertWorldPositionToTerrainSlot(pos, &slotx, &sloty);
Ogre::Terrain *terrain = mTerrainGroup->getTerrain(slotx, sloty);
pos.y = terrain->getHeightAtWorldPosition(pos);



Ogre::Vector3 scale(0.2f, Ogre::Math::RangeRandom(0.18f, 0.22f), 0.2f);
Ogre::Quaternion orientation;
orientation.FromAngleAxis(Ogre::Degree(Ogre::Math::RangeRandom(0, 359)), Ogre::Vector3::UNIT_Y);

float rand = Ogre::Math::RangeRandom(0.f, 100.f);
if (rand < 30)
sg->addEntity(E_adventice[0], pos, orientation, scale);
else if (rand < 60)
{
orientation.FromAngleAxis(Ogre::Degree(0), Ogre::Vector3::UNIT_X);
sg->addEntity(tree, pos, orientation, Ogre::Vector3(Ogre::Math::RangeRandom(0.01f, 0.1f)));
// orientation.FromAngleAxis(Ogre::Degree(-90), Ogre::Vector3::UNIT_X);
// sg->addEntity(tree, pos, orientation, Ogre::Vector3(Ogre::Math::RangeRandom(0.1f, 1.f)));
}
else if (rand < 65)
sg->addEntity(maison, pos+Ogre::Vector3(0, 10.f, 0), orientation, Ogre::Vector3(0.02f));
else if (rand < 70)
sg->addEntity(E_adventice[1], pos, orientation, scale);
else if (rand < 75)
sg->addEntity(E_adventice[2], pos, orientation, scale);
else if (rand < 80)
sg->addEntity(E_adventice[3], pos, orientation, scale);
else if (rand < 85)
sg->addEntity(E_adventice[4], pos, orientation, scale);
else if (rand < 90)
sg->addEntity(E_adventice[5], pos, orientation, scale);
else if (rand < 95)
sg->addEntity(E_adventice[6], pos, orientation, scale);
else
sg->addEntity(E_adventice[7], pos, orientation, scale);
}
}
sg->build();
}


//|||||||||||||||||||||||||||||||||||||||||||||||

void DemoApp::startDemo()
{
new OgreFramework();
if(!OgreFramework::getSingletonPtr()->initOgre("DemoApp v1.0", this, 0))
return;

m_bShutdown = false;

OgreFramework::getSingletonPtr()->m_pLog->logMessage("Demo initialized!");

setupDemoScene();
runDemo();
}




void DemoApp::initBullet()
{
// Start Bullet
mWorld = new OgreBulletDynamics::DynamicsWorld(
OgreFramework::getSingletonPtr()->m_pSceneMgr,
Ogre::AxisAlignedBox (
Ogre::Vector3 (-10000, -10000, -10000), //aligned box for Bullet
Ogre::Vector3 (10000, 10000, 10000)
),
Ogre::Vector3(0,-9.81f,0)
);
// add Debug info display tool
debugDrawer = new OgreBulletCollisions::DebugDrawer();
debugDrawer->setDrawWireframe(true); // we want to see the Bullet containers
mWorld->setDebugDrawer(debugDrawer);
mWorld->setShowDebugShapes(true); // enable it if you want to see the Bullet containers
Ogre::SceneNode *node = OgreFramework::getSingletonPtr()->m_pSceneMgr->getRootSceneNode()->createChildSceneNode("debugDrawer", Ogre::Vector3::ZERO);
node->attachObject(static_cast <SimpleRenderable *> (debugDrawer));


/*
// OGRE ENTITY : Define a floor plane mesh
Ogre::Entity *ent;
Ogre::Plane p;
p.normal = Ogre::Vector3(0,1,0); p.d = 0;
Ogre::MeshManager::getSingleton().createPlane(
"FloorPlane", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
p, 200000, 200000, 20, 20, true, 1, 9000, 9000, Ogre::Vector3::UNIT_Z
);
// Create an entity (the floor)
ent = OgreFramework::getSingletonPtr()->m_pSceneMgr->createEntity("floor", "FloorPlane");
ent->setMaterialName("Examples/BumpyMetal");
OgreFramework::getSingletonPtr()->m_pSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent);

// BULLET COLLISION SHAPE : collision shape
OgreBulletCollisions::CollisionShape *Shape;
Shape = new OgreBulletCollisions::StaticPlaneCollisionShape(Ogre::Vector3(0,1,0), 0); // (normal vector, distance)

OgreBulletDynamics::RigidBody *defaultPlaneBody = new OgreBulletDynamics::RigidBody("BasePlane", mWorld);
defaultPlaneBody->setStaticShape(Shape, 0.1f, 0.8f); // (shape, restitution, friction)

// push the created objects to the deques
mShapes.push_back(Shape);
mBodies.push_back(defaultPlaneBody);
*/



setTerrainPhysics();
}

void DemoApp::setTerrainPhysics()
{
// load the heightmap image
Ogre::Image img;
img.load("terrain.png", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);

// compute the height array
unsigned page_size = mTerrainGroup->getTerrainSize();
Ogre::Vector3 terrainScale(4096 / (page_size-1), 600, 4096 / (page_size-1));
float *heights = new float[page_size*page_size];
for(unsigned y = 0; y < page_size; ++y)
{
for(unsigned x = 0; x < page_size; ++x)
{
Ogre::ColourValue color = img.getColourAt(x, y, 0);
heights[x + y * page_size] = color.r;
}
}

// create the bullet shape and rigid body
OgreBulletCollisions::HeightmapCollisionShape *terrainShape = new OgreBulletCollisions::HeightmapCollisionShape(
page_size,
page_size,
terrainScale,
heights,
true
);
OgreBulletDynamics::RigidBody *terrainBody = new OgreBulletDynamics::RigidBody(
"Terrain",
mWorld
);


Ogre::Vector3 terrainShiftPos(terrainScale.x/(page_size-1), 0, terrainScale.z/(page_size-1));
terrainShiftPos.y = terrainScale.y / 2 * terrainScale.y;

Ogre::SceneNode *pTerrainNode = OgreFramework::getSingletonPtr()->m_pSceneMgr->getRootSceneNode()->createChildSceneNode();
terrainBody->setStaticShape(pTerrainNode, terrainShape, 0.0f, 0.8f, terrainShiftPos);
terrainBody->setPosition(terrainBody->getWorldPosition());

// push the created objects to the deques
mShapes.push_back(terrainShape);
mBodies.push_back(terrainBody);
}


//|||||||||||||||||||||||||||||||||||||||||||||||

void DemoApp::setupDemoScene()
{
// label tray
mInfoLabel = OgreFramework::getSingletonPtr()->m_pTrayMgr->createLabel(OgreBites::TL_TOP, "TInfo", "", 350);

// light
Ogre::Vector3 lightdir(0.55f, -0.3f, 0.75f);
lightdir.normalise();

Ogre::Light* light = OgreFramework::getSingletonPtr()->m_pSceneMgr->createLight("tstLight");
light->setType(Ogre::Light::LT_DIRECTIONAL);
light->setDirection(lightdir);
light->setDiffuseColour(Ogre::ColourValue::White);
light->setSpecularColour(Ogre::ColourValue(0.4f, 0.4f, 0.4f));


createTerrain(light);
initBullet();


OgreFramework::getSingletonPtr()->m_pSceneMgr->setSkyDome(true, "Examples/CloudySky", 5, 8);
OgreFramework::getSingletonPtr()->m_pSceneMgr->setAmbientLight(Ogre::ColourValue::White);

// OgreFramework::getSingletonPtr()->m_pSceneMgr->setShadowTechnique(Ogre::SHADOWTYPE_TEXTURE_MODULATIVE);

// OgreFramework::getSingletonPtr()->m_pSceneMgr->setFog(Ogre::FOG_LINEAR, Ogre::ColourValue(0.9, 0.9, 0.9), 0.0, 50, 500);
// OgreFramework::getSingletonPtr()->m_pSceneMgr->setFog(Ogre::FOG_EXP, Ogre::ColourValue(0.9, 0.9, 0.9), 0.005);
// OgreFramework::getSingletonPtr()->m_pSceneMgr->setFog(Ogre::FOG_EXP2, Ogre::ColourValue(0.9, 0.9, 0.9), 0.003);
}

//|||||||||||||||||||||||||||||||||||||||||||||||

void DemoApp::runDemo()
{
OgreFramework::getSingletonPtr()->m_pLog->logMessage("Start main loop...");

double startTime = 0;
m_timeSinceLastFrame = 0;

OgreFramework::getSingletonPtr()->m_pRenderWnd->resetStatistics();

while(!m_bShutdown && !OgreFramework::getSingletonPtr()->isOgreToBeShutDown())
{
if(OgreFramework::getSingletonPtr()->m_pRenderWnd->isClosed())m_bShutdown = true;

Ogre::WindowEventUtilities::messagePump();

if(OgreFramework::getSingletonPtr()->m_pRenderWnd->isActive())
{
startTime = OgreFramework::getSingletonPtr()->m_pTimer->getMillisecondsCPU();

OgreFramework::getSingletonPtr()->m_pKeyboard->capture();
OgreFramework::getSingletonPtr()->m_pMouse->capture();

OgreFramework::getSingletonPtr()->updateOgre(m_timeSinceLastFrame);

frameRenderingQueued(OgreFramework::getSingletonPtr()->getFrameEvent());



OgreFramework::getSingletonPtr()->m_pRoot->renderOneFrame();

m_timeSinceLastFrame = OgreFramework::getSingletonPtr()->m_pTimer->getMillisecondsCPU() - startTime;
}
else
{
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
Sleep(1000);
#else
sleep(1);
#endif
}
}

OgreFramework::getSingletonPtr()->m_pLog->logMessage("Main loop quit");
OgreFramework::getSingletonPtr()->m_pLog->logMessage("Shutdown OGRE...");
}

//|||||||||||||||||||||||||||||||||||||||||||||||

bool DemoApp::keyPressed(const OIS::KeyEvent &keyEventRef)
{
OgreFramework::getSingletonPtr()->keyPressed(keyEventRef);

static bool mMouseDown = false; // If a mouse button is depressed
static Ogre::Real mToggle = 0.5; // The time left until next toggle

bool currMouse = OgreFramework::getSingletonPtr()->m_pMouse->getMouseState().buttonDown(OIS::MB_Left);
if (currMouse && ! mMouseDown)
{
Ogre::Light* light2 = OgreFramework::getSingletonPtr()->m_pSceneMgr->getLight("tstLight");
light2->setVisible(! light2->isVisible());
}
mMouseDown = currMouse;

mToggle -= m_timeSinceLastFrame;

if ((mToggle < 0.0f ) && OgreFramework::getSingletonPtr()->m_pKeyboard->isKeyDown(OIS::KC_1))
{
mToggle = 0.5;
Ogre::Light* light = OgreFramework::getSingletonPtr()->m_pSceneMgr->getLight("tstLight");
light->setVisible(! light->isVisible());
}



// create and throw a box if 'B' is pressed
if(OgreFramework::getSingletonPtr()->m_pKeyboard->isKeyDown(OIS::KC_B) && mToggle <=0)
{
Vector3 size = Vector3::ZERO; // size of the box
// starting position of the box
Vector3 position = (OgreFramework::getSingletonPtr()->m_pCamera->getDerivedPosition() +
OgreFramework::getSingletonPtr()->m_pCamera->getDerivedDirection().normalisedCopy() * 10);
// create an ordinary, Ogre mesh with texture
Entity *entity = OgreFramework::getSingletonPtr()->m_pSceneMgr->createEntity(
"Box" + StringConverter::toString(mNumEntitiesInstanced),
"cube.mesh");
entity->setCastShadows(true);
// we need the bounding box of the box to be able to set the size of the Bullet-box
AxisAlignedBox boundingB = entity->getBoundingBox();
size = boundingB.getSize(); size /= 2.0f; // only the half needed
size *= 0.96f; // Bullet margin is a bit bigger so we need a smaller size
// (Bullet 2.76 Physics SDK Manual page 18)
entity->setMaterialName("Examples/BumpyMetal");
SceneNode *node = OgreFramework::getSingletonPtr()->m_pSceneMgr->getRootSceneNode()->createChildSceneNode();
node->attachObject(entity);
node->scale(0.05f, 0.05f, 0.05f); // the cube is too big for us
size *= 0.05f; // don't forget to scale down the Bullet-box too
// after that create the Bullet shape with the calculated size
OgreBulletCollisions::BoxCollisionShape *sceneBoxShape = new OgreBulletCollisions::BoxCollisionShape(size);
// and the Bullet rigid body
OgreBulletDynamics::RigidBody *defaultBody = new OgreBulletDynamics::RigidBody(
"defaultBoxRigid" + StringConverter::toString(mNumEntitiesInstanced),
mWorld);
defaultBody->setShape( node,
sceneBoxShape,
0.7f, // dynamic body restitution
0.6f, // dynamic body friction
1.0f, // dynamic bodymass
position, // starting position of the box
Quaternion(0,0,0,1));// orientation of the box
mNumEntitiesInstanced++;
defaultBody->setLinearVelocity(
OgreFramework::getSingletonPtr()->m_pCamera->getDerivedDirection().normalisedCopy() * 10.0f ); // shooting speed
// push the created objects to the deques
mShapes.push_back(sceneBoxShape);
mBodies.push_back(defaultBody);
mToggle = 0.5;
}

// create and throw a cylinder if 'C' is pressed
if(OgreFramework::getSingletonPtr()->m_pKeyboard->isKeyDown(OIS::KC_C) && mToggle <=0)
{
Vector3 size = Vector3::ZERO; // size of the box
// starting position of the box
Vector3 position = (OgreFramework::getSingletonPtr()->m_pCamera->getDerivedPosition() +
OgreFramework::getSingletonPtr()->m_pCamera->getDerivedDirection().normalisedCopy() * 10);
// create an ordinary, Ogre mesh with texture
Entity *entity = OgreFramework::getSingletonPtr()->m_pSceneMgr->createEntity(
"column" + StringConverter::toString(mNumEntitiesInstanced),
"column.mesh");
entity->setCastShadows(true);
// we need the bounding box of the box to be able to set the size of the Bullet-box
AxisAlignedBox boundingB = entity->getBoundingBox();
size = boundingB.getSize(); size /= 2.0f; // only the half needed
size *= 0.96f; // Bullet margin is a bit bigger so we need a smaller size
// (Bullet 2.76 Physics SDK Manual page 18)
entity->setMaterialName("Examples/BumpyMetal");
SceneNode *node = OgreFramework::getSingletonPtr()->m_pSceneMgr->getRootSceneNode()->createChildSceneNode();
node->attachObject(entity);
node->scale(0.05f, 0.05f, 0.05f); // the cube is too big for us
size *= 0.05f; // don't forget to scale down the Bullet-box too
// after that create the Bullet shape with the calculated size
OgreBulletCollisions::CylinderCollisionShape *sceneCylinderShape = new OgreBulletCollisions::CylinderCollisionShape(Ogre::Vector3(1, 10, 1), Ogre::Vector3::UNIT_Y);
// and the Bullet rigid body
OgreBulletDynamics::RigidBody *defaultBody = new OgreBulletDynamics::RigidBody(
"defaultBoxRigid" + StringConverter::toString(mNumEntitiesInstanced),
mWorld);


defaultBody->setShape( node,
sceneCylinderShape,
0.5f, // dynamic body restitution
0.7f, // dynamic body friction
1.0f, // dynamic bodymass
position, // starting position of the box
Quaternion(0, 0, 0, 1));// orientation of the box
mNumEntitiesInstanced++;
defaultBody->setLinearVelocity(
OgreFramework::getSingletonPtr()->m_pCamera->getDerivedDirection().normalisedCopy() * 10.0f ); // shooting speed
// push the created objects to the deques
mShapes.push_back(sceneCylinderShape);
mBodies.push_back(defaultBody);
mToggle = 0.5;
}



if(OgreFramework::getSingletonPtr()->m_pKeyboard->isKeyDown(OIS::KC_F))
{
//do something
}

return true;
}

//|||||||||||||||||||||||||||||||||||||||||||||||

bool DemoApp::keyReleased(const OIS::KeyEvent &keyEventRef)
{
OgreFramework::getSingletonPtr()->keyReleased(keyEventRef);

return true;
}

//|||||||||||||||||||||||||||||||||||||||||||||||



//-------------------------------------------------------------------------------------
void DemoApp::frameRenderingQueued(const Ogre::FrameEvent& evt)
{
if (mTerrainGroup)
{
if (mTerrainGroup->isDerivedDataUpdateInProgress())
{
OgreFramework::getSingletonPtr()->m_pTrayMgr->moveWidgetToTray(mInfoLabel, OgreBites::TL_TOP, 0);
mInfoLabel->show();
if (mTerrainsImported)
{
mInfoLabel->setCaption("Building terrain, please wait...");
}
else
{
mInfoLabel->setCaption("Updating textures, patience...");
}
}
else
{
OgreFramework::getSingletonPtr()->m_pTrayMgr->removeWidgetFromTray(mInfoLabel);
mInfoLabel->hide();
if (mTerrainsImported)
{
mTerrainGroup->saveAllTerrains(true);
mTerrainsImported = false;
}
}

// controle de l'altitude de la caméra = 1.8 m de la surface du sol
/* Ogre::Vector3 pos = OgreFramework::getSingletonPtr()->m_pCamera->getPosition();
pos.y = 1.8 + mTerrainGroup->getHeightAtWorldPosition(pos);
OgreFramework::getSingletonPtr()->m_pCamera->setPosition(pos);
*/ }

// update bullet
if (mWorld)
mWorld->stepSimulation(evt.timeSinceLastFrame); // update Bullet Physics animation
}




thanks

emmanuel1359

24-02-2015 22:55:49

sorry i'm so stupid sometimes !


just have to change 4096 to 12000 there:

void DemoApp::setTerrainPhysics()
{
...
Ogre::Vector3 terrainScale(12000 / (page_size-1), 600, 12000 / (page_size-1));

looks better:
[attachment=0]BOF_Screenshot_02242015_235249179.jpg[/attachment]

emmanuel1359

28-03-2015 09:18:01

a little modification to my code shown:


Ogre::Vector3 terrainScale(m_TerrainPageWorld / (page_size-1), m_TerrainMaxHeight, m_TerrainPageWorld / (page_size-1));

void DemoApp::createTerrain(Ogre::Light* light)
{
// terrain
// How large is a page of tiles (in vertices)? Must be (2^n)+1
m_TerrainPageSize = 513;
// The size of a terrain page, in world units
m_TerrainPageWorld=12000.0f;
// Maximum height of the terrain
m_TerrainMaxHeight=600.f;



is better to avoid bad rounding from float to int (the edge of the bullet map was not exactly in the ogre mesh)

my repository:
https://bitbucket.org/emmanuel1359