Getting wrong position values

Djoef

26-07-2007 17:45:16

Hello,

I draw a wall and an movable object in Blender.
Sizes:
Wall 17x10 units
Movable object +/- 1.5x1.5 units

I never scale objects, just export them and import them in Ogre.

Once in Ogre have the main.cc script.
There you can see positions of the camera etc.

The movable object (Col from collisionobject) is connected to the joystick via OIS.
When cout-ing the positions of the movable object, these positions are correct, eg there are 5 units to the left before hitting the wall.

What I want to do is when hitting the wall, keep "driving" along the wall.
To do this i would like to have the normal of the current collided face (of the wall).
Then I can use this normal to choose the direction of motion for the movable object.

I now get values for the OgreOde contact->getPosition(), but those values are not incorrect. eg :
coltime : 3658
Position Vector3(0, 1.4013e-44, -1.80235e-05)
Position Vector3(0, 1.4013e-44, 6.13713e+17)

When asking for the Normal values i sometimes get a Segmentation Fault.
When i get a value, it is also an incorrect one, (not length 1).

Please help me out here, we have been looking at this problem with 2 or 3 people from the Ogre forum, but did not find any solution.
Any suggestions are welcome, they will be tried out, and I will post feedback.

thanks for helping!
Geoffrey.

printscreen from scene in blender :
http://perswww.kuleuven.be/~u0055189/blenderScreen.png

printscreen from terminal & Ogrewindow :
http://perswww.kuleuven.be/~u0055189/Screenshot-Terminal.png

Main.cc file:

#include "Ogre.h"
#include <iostream>

#include "OgreOde_Core.h"
#include "OgreOde_Prefab.h"
#include "OgreOde_Loader.h"

#include "OIS.h"
#include "OgreOdeCollision.h"

#include <vector>

//#define dTRIMESH_ENABLED 1

using namespace Ogre;
using namespace OgreOde;
using namespace OgreOde_Prefab;
using namespace OgreOde_Loader;

using std::cout;


class MyCollisionListener : public OgreOde::CollisionListener
{
public:
MyCollisionListener()
{
}

~MyCollisionListener()
{
}

bool collision(OgreOde::Contact* contact) {
contacts.push_back(contact);
return true;
}

std::vector<OgreOde::Contact*> &getContacts()
{
return contacts;
}

void clearContacts()
{
contacts.clear();
}

private:
std::vector<OgreOde::Contact*> contacts;

};


int main(int argc, char *argv[])
{
//je moet een alogfile maken
LogManager* logMgr = new LogManager;
Log *log = LogManager::getSingleton().createLog("mijnenlog2.log",true,true,false);

// maak root object aan, maar geen config files loaden.
Root *root = new Root("", "");

// plugins laden
root->loadPlugin("/usr/local/lib/OGRE/Plugin_CgProgramManager");
root->loadPlugin("/usr/local/lib/OGRE/Plugin_OctreeSceneManager");

//ResourceGroupManager & OpenGL Rendersysteem laden
try {
ResourceGroupManager::getSingleton().addResourceLocation("resources/objects","FileSystem","General");
ResourceGroupManager::getSingleton().addResourceLocation("resources/material","FileSystem","Materials");
root->loadPlugin("/usr/local/lib/OGRE/RenderSystem_GL");
}
catch (...) {}

try {
//uit de beschikbare rendersystemen kiezen we de OpenGL
RenderSystemList *rList = root->getAvailableRenderers();
RenderSystemList::iterator it = rList->begin();
RenderSystem *rSys = 0;
//lijst overlopen :
while (it != rList->end())
{
rSys = *(it++);
if (rSys->getName().find("GL")) {
root->setRenderSystem(rSys);
break;
}
}
// kijk of je nu effectief de OpenGL gevonden hebt, einde lijst en niets gevonden=fout
if (rSys == 0) {
delete root;
std::cerr << "No RenderSystem available, exiting..." << std::endl;
return -1;
}

root->initialise(false);// Root moet geen renderwindow maken voor ons
//alle opgegeven resources laden

// render window aanmaken :
RenderWindow *mwindow = root->createRenderWindow("Manual Ogre Window",1280,1024,true,0);
//RenderWindow *mwindow = rSys->createRenderWindow("Manual Ogre Window",1280,1024,false,0);
// window title, window width & height in pixels,fullscreen or not,0 = use defaults for all other values
ResourceGroupManager::getSingleton().initialiseAllResourceGroups();

//welke sceneManager (hangt af van gebruikte 3D omgeving)
SceneManager *mSceneMgr = root->createSceneManager(ST_GENERIC);

//camera maken
Camera *camera = mSceneMgr->createCamera("MainCam"); //Camera aanmaken
camera->setFarClipDistance(1000);
camera->setNearClipDistance(1);
camera->setAspectRatio(Real(1.333333)); // 4/3
camera->setPosition(Vector3(0,20,0)); //positie Z is neg -> naar u toe uit scherm
camera->lookAt(Vector3(0,0,-1)); // kijk naar ori
//camera->setProjectionType(PT_PERSPECTIVE);
Viewport *vp = mwindow->addViewport(camera);//viewport maken met die camera
vp->setBackgroundColour(ColourValue(0.8,0.8,0.8));//achtergrondkleur
mSceneMgr->setAmbientLight(ColourValue(0.8,0.8,0.8));//lichtkleur

cout<<"OIS INITIALISEREN\n";
OIS::ParamList pl; //typdef voor std::map (parameters doorgeven aan klasses)
size_t windowHnd =0; // om windowhandle te verkrijgen voor het renderwindow
std::ostringstream windowHndStr; //om size_t in string gieten
mwindow->getCustomAttribute("WINDOW", &windowHnd); //window handle in size_t steken
windowHndStr << windowHnd; //windowhandle in string gieten
pl.insert(std::make_pair(std::string("WINDOW"),windowHndStr.str()));
//string WINDOW in de parameter lijst steken met de string-handle

OIS::InputManager* inputManager = OIS::InputManager::createInputSystem(pl); //actually creates the OIS input system

OIS::JoyStick* m_joystick = static_cast<OIS::JoyStick*>(inputManager->createInputObject(OIS::OISJoyStick, false));
//m_keyboard, m_joystick en m_mouse zijn pointers naar OIS::Keyboard etc objecten
//dit static_cast zijn omdat OIS::InputManager een OIS::Object teruggeeft.
//die false is dat de objecten unbuffered zijn, moet buffered worden later (dus true)

//doorgeven aan OIS wat de schermafmetingen zijn :
unsigned int width, height, depth;
int top, left;
mwindow->getMetrics(width, height, depth, left, top);//get the renderwindow values

Entity *MuurL = mSceneMgr->createEntity("MuurL","MMuurL.mesh");
Entity *Col = mSceneMgr->createEntity("Col","MCol.mesh");

SceneNode* MLNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("MLNode",Vector3(0,0,0));
SceneNode* mMLNode = MLNode->createChildSceneNode("mMLNode");
mMLNode->attachObject(MuurL);
MuurL->setMaterialName("MuurL");

SceneNode* ColNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("ColNode",Vector3(0,0,0));
SceneNode* mColNode = ColNode->createChildSceneNode("mColNode");
mColNode->attachObject(Col);
Col->setMaterialName("Col");

OgreOde::World* _world = new OgreOde::World(mSceneMgr);
MyCollisionListener *Mcl = new MyCollisionListener; //make a collisionListener
//_world->setCollisionListener(Mcl);

Ogre::Matrix4 transforms_ML;
mColNode->getWorldTransforms(&transforms_ML);
OgreOde::EntityInformer* pEntityInfomer_ML = new OgreOde::EntityInformer( MuurL, transforms_ML );
OgreOde::TriangleMeshGeometry* pTriMesh_ML = pEntityInfomer_ML->createStaticTriangleMesh( _world );

Ogre::Matrix4 transforms_col;
mColNode->getWorldTransforms(&transforms_col);
OgreOde::EntityInformer* pEntityInfomer_col = new OgreOde::EntityInformer( Col, transforms_col );
OgreOde::TriangleMeshGeometry* pTriMesh_col = pEntityInfomer_col->createStaticTriangleMesh( _world );

Light *light;
light = mSceneMgr->createLight( "Light1" );
light->setType( Light::LT_DIRECTIONAL );
light->setPosition( Vector3(0, 15, 2) );

light->setDiffuseColour( ColourValue( 1.0, 1.0, 1.0 ) );
light->setSpecularColour( ColourValue( 1.0, 1.0, 1.0 ) );

Timer* mijnt = new Timer;
mijnt->reset();

bool renderLoop = true;
int b = 100;

while(renderLoop)
{

WindowEventUtilities::messagePump(); //dit moet er staan !

if(mijnt->getMilliseconds()<=b)
{
//cout<<"locatie : "<<mColNode->getPosition()<<"\n";
m_joystick->capture();
const OIS::JoyStickState &joy = m_joystick->getJoyStickState();

float joyLinksRechts = joy.mAxes[0].abs; //LinksRechts Links=-32K
float joyVoorAchter = joy.mAxes[1].abs; //VoorAchter Voor=-32K

float valVoorAchter = (joyVoorAchter/32000)/500;
float valLinksRechts = joyLinksRechts/128000;

/*
cout<<"joyVoor : "<<joyVoorAchter<<"\n";
cout<<"joyLinks: "<<joyLinksRechts<<"\n";

cout<<"valVoor : "<<valVoorAchter<<"\n";
cout<<"valLinks: "<<valLinksRechts<<"\n";
*/

if(pTriMesh_col->collide(pTriMesh_ML,Mcl)) //if there is a collision :
{
cout<<"coltime : "<<mijnt->getMilliseconds()<<"\n";

for(std::vector<OgreOde::Contact*>::iterator itr = (Mcl->getContacts()).begin(); itr != (Mcl->getContacts()).end(); itr++)
{
cout<<"\tPosition\t"<<(*itr)->getPosition()<<"\n";
//cout<<"\tNormal\t"<<(*itr)->getNormal()<<"\n";
//cout<<"\tDepth\t"<<(*itr)->getPenetrationDepth()<<"\n";
}
Mcl->clearContacts(); //clear the list for next use

if(joyLinksRechts>0) //if Jostick to right = turn right but slower
{
mColNode->yaw(Degree(-valLinksRechts/2));
}
else //else turn left
{
mColNode->yaw(Degree(valLinksRechts/2));
}
pTriMesh_col->setOrientation(mColNode->getOrientation());
mColNode->translate(mColNode->getOrientation()*Vector3(0,0,valVoorAchter/2)); //move slower
pTriMesh_col->setPosition(mColNode->getPosition());

}
else //just move normally
{
if(joyVoorAchter>250||joyVoorAchter<-250) //translate accoring to joystickvalues
{
mColNode->translate(mColNode->getOrientation()*Vector3(0,0,valVoorAchter));
pTriMesh_col->setPosition(mColNode->getPosition()); //dont forget to translate ODE trimesh
}
if(joyLinksRechts>200||joyLinksRechts<-200) //rotate according to joystickvalues
{
mColNode->yaw(Degree(-valLinksRechts));
pTriMesh_col->setOrientation(mColNode->getOrientation());
}
}

root->renderOneFrame(); //render 1 frame
renderLoop = true;
b+=50;
}
}
ResourceGroupManager::getSingleton().unloadResourceGroup("Materials",true);
}
catch (Exception &e) {
std::cerr << e.getFullDescription() << std::endl;
}
delete root;
return 0;
}

rewb0rn

26-07-2007 22:14:37

i have not checked your whole code, but your using of ogreode looks wrong to me. you do not use bodies, only geometries, these geometries are not attached anywhere, so how is the collision supposed to work? also your movable object should get a body. what are the values of your geometry positions?

Djoef

27-07-2007 09:36:49

How would you then use ogreOde ?
can you give a small example ?
(preferably the code as should be (i can find almost no clear & clean examples, but if you want, pseudo code is also ok)

The position of the geometry (well the moving part) is in the line of :
locatie : Vector3(-3.16254, 0, -6.35616)

meaning whole units, not e-10 fractions etc

(which could be expected looking at the units in blender.)

At least the collision detection works, and it works on the geometry (not boundig box) I can ask a position or normal so i was expecting that i was doing it the right way.
Thanks for the reply,
I hope you post a little example of how you think it should be done,

greetz,
geoffrey.

rewb0rn

28-07-2007 13:15:42

ok i was wrong with attaching geometries, thats not necessary, only for bodies... i have not a solution for you but maybe you should start with a standard setting, like one wall and a box or something, you will find codes for this in the ogreode demos.

in short its like this:

the wall or floor or whatever:
create ogreodeplane

create box:
create scenenode
create entity
attach entity to scenenode
create boxgeometry
create body
create boxmass
set mass at body
attach geometry to body
attach body to scenenode

simulate

Djoef

03-08-2007 21:54:29

I found the mistake, as explained in :
http://www.ogre3d.org/phpBB2/viewtopic.php?t=34678