simple collision problem
misterface
16-02-2006 20:56:24
Hi all,
I'm experimenting with OgreNewt. Al last I can compile the demos

Seems awsome! But not everything is 100% clear to me.
I will tell want I would like to do. I Have a level with non moving objects. (You can see the code below). I will import some other non moving entitys as well like chairs... and place them in that level as children.
Now I need OgreNewton (= I need your help

) I want my camera not the walk in my chairs, walls... so if the camera bumps against an object it has to stop. This is probably not hard to code as nothing has to move in my world exept the camera. Can anyone help me to implement this?
Thx
Some pure ogre code that maybe can help...
protected:
void createScene(void)
{
mCamera->setPosition(Vector3(0,0,0));
mSceneMgr->setAmbientLight( ColourValue( 1, 1, 1 ) );
mSceneMgr->setSkyDome( true, "Examples/CloudySky", 5, 8 );
Entity *ent = mSceneMgr->createEntity( "ent", "myworld.mesh" );
SceneNode *node = mSceneMgr->getRootSceneNode()->createChildSceneNode( "node" );
node->attachObject( ent )
}
};
Horizon
16-02-2006 22:15:27
I think you will want to create an OgreNewt Body for your camera without attaching an Ogre Entity. For example use an ellipsoid. For controlling the camera with the keyboard you will need to learn some things about applying forces though. You may want to look at a character controller demo from Newton.
misterface
16-02-2006 23:34:38
I thought this would work, but apparently not, I can walk true the walls, not good :/
please have a look at the camera stuff in the code below.
2 OgreNewt::Collision* col objects can't bump into each other right?
col (scene) and col2 (camera) do collide!
what do I don't get?
(my first day with ogrenewt

)
Entity *floor = mSceneMgr->createEntity( "floor", "levelmsvloer.mesh" );
floor->setNormaliseNormals(true);
floor->setCastShadows(false);
SceneNode *floornode = mSceneMgr->getRootSceneNode()->createChildSceneNode( "FloorNode" );
floornode->attachObject( floor );
// okay, the basic mesh is loaded. now let's decide the size of the object, and scale the node.
Ogre::Vector3 siz(1,1,1);
floornode->setScale(siz);
OgreNewt::Collision* col = new OgreNewt::CollisionPrimitives::TreeCollision( m_World, floornode, true );
OgreNewt::Body* bod = new OgreNewt::Body( m_World, col );
// now we "attach" the rigid body to the scene node that holds the visual object, and set it's
// original position and orientation. all rigid bodies default to mass=0 (static, immobile), so
// that's all we'll need to do for this object. dynamic objects have a few more steps, so look
// at the code in the FrameListener for more.
bod->attachToNode( floornode );
bod->setPositionOrientation( Ogre::Vector3(-60.0,-20.0,0.0), Ogre::Quaternion::IDENTITY );
// we`re done with the collision shape, we can delete it now.
delete col;
// position camera
msnCam = mSceneMgr->getRootSceneNode()->createChildSceneNode();
msnCam->attachObject( mCamera );
mCamera->setPosition(0.0, 0.0, 0.0);
msnCam->setPosition( 0.0, -10.0, 20.0);
// HELP !!!!!!!!!!!!!!!!!!!!!!!!
OgreNewt::Collision* col2 = new OgreNewt::CollisionPrimitives::Cylinder(m_World, 2.5, 5);
OgreNewt::Body* bod2 = new OgreNewt::Body( m_World, col2 );
delete col2;
bod2->attachToNode( msnCam );
bod2->setPositionOrientation( Ogre::Vector3(0.0,-10.0,0.0), Ogre::Quaternion::IDENTITY );
walaber
17-02-2006 00:13:23
i don't fully understand your problem from your post.
there are 2 ways to get what you want:
1. Make the static background objects into OgreNewt::Bodys. then make a dynamic object with small mass for the Camera sphere, and move this with forces, to move the camera around. it will not penetrate the world then.
2. instead of using physics, just use a OgreNewt::Collision for the camera, and test manually that it is now colliding with any bodies in the world (with the CollisionCollide() function). this allows more precise control over the movement of the camera, because you can simply modify its position however you want, checking for collision on your own.
after I finish my Trampoline game, and before starting on a new project, I will make some more demos that show some of these things, like FPS-style character control, and camera control styles, etc.
Another thing you might consider is that before setting a new camera position, raycast between that and the last camera position, if it hits, use the distance to determine correct new camera position.
misterface
17-02-2006 22:32:38
Another thing you might consider is that before setting a new camera position, raycast between that and the last camera position, if it hits, use the distance to determine correct new camera position.
looks good. but I have no experience with raycast unfortunatly
misterface
17-02-2006 22:33:09
after I finish my Trampoline game, and before starting on a new project, I will make some more demos that show some of these things, like FPS-style character control, and camera control styles, etc.
that would be great!
misterface
22-02-2006 00:10:21
ok, let's start over a bit
1)
Demo01_TheBasics is working 100% correctly! when I hit the space bar, it flies to the cilinder and bumps off....
2)
hitting F3 and I see beautifully the cilinder
3)
I replace
floor = mSceneMgr->createEntity("Floor", "cylinder.mesh" );
with
floor = mSceneMgr->createEntity("Floor", "levelmsvloer.mesh" );
4)
everything looks good! my personal level looks perfect
5)
I replace
OgreNewt::Collision* col = new OgreNewt::CollisionPrimitives::Cylinder(m_World, 2.5, 5);
with
OgreNewt::Collision* col = new OgreNewt::CollisionPrimitives::TreeCollision(( m_World, floornode, true );
everything looks good! my personal level looks perfect.
->> here the problems start:
a) when I hit F3 nothing happens; can't see those with stripes like I did with the cilinder.
b) when I hit the space bar, the object that is thrown stops in the air, after 1 second! when I walk a bit further in my level and throw again I see nothing, but when I walk back, I see the object that has been thrown.
I suspect I do do something wrong with the TreeCollision(..) I you want a screenshot, just ask...
walaber
22-02-2006 00:18:16
the OgreNewt::World defaults to a size of (-100,-100,-100) to (100,100,100).
if you want a bigger world (it sounds like your level is bigger), you need to set the world size with world->setWorldSize().
I'm not sure why the debug lines arent working for you...
misterface
22-02-2006 00:23:48
int size=100000;
m_World->setWorldSize(Ogre::AxisAlignedBox(-size,-size,-size,size,size,size));
now the thrown objects (space bar) fly thrue everything
walaber
22-02-2006 00:47:05
change the order in the demo.
for TreeCollision to work, you have to already have a mesh attached.
so the line that does
[code[floornode->attachObject( floor );
should be placed before you make the OgreNewt::Collision object.
this is also why you weren't getting any debug lines.
misterface
22-02-2006 17:07:57
That was already the case, it's in the right order I think.
thx for helping walaber
void OgreNewtonApplication::createScene()
{
// set world size
int size=100000;
m_World->setWorldSize(Ogre::AxisAlignedBox(-size,-size,-size,size,size,size));
// sky box.
mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox");
// this will be a static object that we can throw objects at. we'll use a simple cylinder primitive.
// first I load the visual mesh that represents it. I have some simple primitive shaped .mesh files in
// the "primitives" directory to make this simple... all of them have a basic size of "1" so that they
// can easily be scaled to fit any size primitive.
// -----Objecten importeren-----
Entity *floor = mSceneMgr->createEntity( "floor", "levelmsvloer.mesh" );
floor->setNormaliseNormals(true);
floor->setCastShadows(false);
// -----SceneNodes aanmaken-----
SceneNode *floornode = mSceneMgr->getRootSceneNode()->createChildSceneNode( "FloorNode" );
// -----Objecten aan de SceneNodes toekennen-----
floornode->attachObject( floor );
// okay, the basic mesh is loaded. now let's decide the size of the object, and scale the node.
Ogre::Vector3 siz(1,1,1);
floornode->setScale(siz);
OgreNewt::Collision* col = new OgreNewt::CollisionPrimitives::TreeCollision( m_World, floornode, true );
OgreNewt::Body* bod = new OgreNewt::Body( m_World, col );
// now we "attach" the rigid body to the scene node that holds the visual object, and set it's
// original position and orientation. all rigid bodies default to mass=0 (static, immobile), so
// that's all we'll need to do for this object. dynamic objects have a few more steps, so look
// at the code in the FrameListener for more.
bod->attachToNode( floornode );
bod->setPositionOrientation( Ogre::Vector3(-60.0,-20.0,0.0), Ogre::Quaternion::IDENTITY );
// we`re done with the collision shape, we can delete it now.
delete col;
// position camera
msnCam = mSceneMgr->getRootSceneNode()->createChildSceneNode();
msnCam->attachObject( mCamera );
mCamera->setPosition(0.0, 0.0, 0.0);
msnCam->setPosition( 0.0, -10.0, 20.0);
//make a light
Ogre::Light* light;
light = mSceneMgr->createLight( "Light1" );
light->setType( Ogre::Light::LightTypes::LT_POINT );
light->setPosition( Ogre::Vector3(0.0, 100.0, 100.0) );
}
void OgreNewtonApplication::createFrameListener()
{
// this is our custom frame listener for this app, that lets us shoot cylinders with the space bar, move
// the camera, etc.
mFrameListener = new OgreNewtonFrameListener( mWindow, mCamera, mSceneMgr, m_World, msnCam );
mRoot->addFrameListener(mFrameListener);
// this is a basic frame listener included with OgreNewt that does nothing but update the
// physics at a set framerate for you. complex project will want more control, but this
// works for simple demos like this. feel free to look at the source to see how it works.
mNewtonListener = new OgreNewt::BasicFrameListener( mWindow, mCamera, mSceneMgr, m_World, 120 );
mRoot->addFrameListener(mNewtonListener);
}
walaber
22-02-2006 18:39:02
hmm, you are right. it should work.... i'm not sure what is causing the problem.
misterface
22-02-2006 20:09:29
hmm, you are right. it should work.... i'm not sure what is causing the problem.
if somebody wants to test it and find the error:
open Demo01_TheBasics, OgreNewtonApplication.cpp
1) replace
floor = mSceneMgr->createEntity("Floor", "cylinder.mesh" );
with
floor = mSceneMgr->createEntity("Floor", "levelmsvloer.mesh" );
2) replace
OgreNewt::Collision* col = new OgreNewt::CollisionPrimitives::Cylinder(m_World, 2.5, 5);
with
OgreNewt::Collision* col = new OgreNewt::CollisionPrimitives::TreeCollision( m_World, floornode, true );
3) add
int size=100000;
m_World->setWorldSize(Ogre::AxisAlignedBox(-size,-size,-size,size,size,size));
the files you need:
http://www.dwimmo.be/levelmsvloer.mesh
http://www.dwimmo.be/levelmsvloer.material
misterface
23-02-2006 22:56:12
if somebody want to know...
it works
set my world bigger (now veeery big)
and the threecollision boolean I set to false.
now trying to make my camera a collision object:
OgreNewt::Collision* col2 = new OgreNewt::CollisionPrimitives::Cylinder(m_World, 2.5, 5);
OgreNewt::Body* bod2 = new OgreNewt::Body( m_World, col2 );
delete col2;
bod2->attachToNode( msnCam );
bod2->setPositionOrientation( Ogre::Vector3(0.0,-10.0,0.0), Ogre::Quaternion::IDENTITY );
that didn't work, too optimistic coding of me
so, taking walaber his advice:
1. make a dynamic object with small mass for the Camera sphere, and move this with forces, to move the camera around. it will not penetrate the world then.
2. instead of using physics, just use a OgreNewt::Collision for the camera, and test manually that it is now colliding with any bodies in the world (with the CollisionCollide() function). this allows more precise control over the movement of the camera, because you can simply modify its position however you want, checking for collision on your own.
1) first question: CollisionCollide() where can I find this? searched the api, didn't find.
2) second question: "make a dynamic object with small mass for the Camera sphere, and move this with forces, to move the camera around. it will not penetrate the world then." ok, I do:
Ogre::Vector3 rolstoelgrootte = Ogre::Vector3(20,20,20);
OgreNewt::Collision* col2 = new OgreNewt::CollisionPrimitives::Box( m_World, rolstoelgrootte );
OgreNewt::Body* bod2 = new OgreNewt::Body( m_World, col2 );
delete col2;
bod2->setPositionOrientation( Ogre::Vector3(0.0,-10.0,0.0), Ogre::Quaternion::IDENTITY );
bod2->setMassMatrix( 10.0, OgreNewt::MomentOfInertia::CalcSphereSolid( 10.0, 1.0 ) );
bod2->attachToNode(msnCam);
bod2->setStandardForceCallback();
but how do you move with force? the only way I know to move is:
if (mInputDevice->isKeyDown(Ogre::KC_UP))
msnCam->translate(trans);
if (mInputDevice->isKeyDown(Ogre::KC_DOWN))
msnCam->translate(trans * -1.0);
if (mInputDevice->isKeyDown(Ogre::KC_LEFT))
msnCam->translate(strafe * -1.0);
if (mInputDevice->isKeyDown(Ogre::KC_RIGHT))
msnCam->translate(strafe);
walaber
24-02-2006 01:57:49
1) the function is in the OgreNewt::CollisionTools namespace. there are lots of really cool functions in there.
2) to control an object with forces, you need to use a callback. have a look at some of the other posts in this forum to see how. the stuff at the
bottom of this thread is particularly helpful.
misterface
24-02-2006 19:12:41
thats it because this is a static function, you cannot access members so easily. I believe you can access static memebers though, so if you change it to static it will probably work.
otherwise the preferred way is to use the userData() function of rigid bodies. for example you make a simple class or all your physics bodies... something like this
Class PhysicsObject
{
public:
PhysicsObject();
~PhysicsObject();
void setForce( Ogre::Vector3 force ) { mForce = force; }
Ogre::Vector3 getForce() { return mForce; }
private:
OgreNewt::Body mBody;
Ogre::Vector3 mForce;
};
then in the initation of this class (when you create the body) you do this:
mBody->setUserData(this)
finally, back in that callback, you can do this:
PhysicsObject* obj = (PhysicsObject*)currentBody->getUserData();
currentBody->setForce( obj->getForce() );
having some trouble, I did everything like above (to make my camera a collision object that can't penetrate walls in my mesh), but a problem.
here is my code (see comments in code):
// position camera
msnCam = mSceneMgr->getRootSceneNode()->createChildSceneNode();
msnCam->attachObject( mCamera );
mCamera->setPosition(0.0, 0.0, 0.0);
msnCam->setPosition( 0.0, -10.0, 20.0);
// my code
Ogre::Vector3 size = Ogre::Vector3(20,20,20);
OgreNewt::Collision* col2 = new OgreNewt::CollisionPrimitives::Box(m_World, size);
OgreNewt::Body* bod2 = new OgreNewt::Body( m_World, col2 );
delete col2;
bod2->setPositionOrientation( Ogre::Vector3(0.0,-10.0,0.0), Ogre::Quaternion::IDENTITY );
bod2->setMassMatrix( 10.0, OgreNewt::MomentOfInertia::CalcSphereSolid( 10.0, 1.0 ) );
bod2->attachToNode(msnCam);
bod2->setStandardForceCallback();
bod2->setUserData(this); // help!!!
//bod2->setForce( Ogre::Vector3(10,10,10) ); // must be done in a registered callback, has this something to do with bod2->setUserData(this)?
PhysicsObject* obj = (PhysicsObject*)bod2->getUserData();
bod2->setForce( obj->getForce() );
I guess my problem is: bod2->setUserData(this)
maybe also other faults...
Error 3 error LNK2019: unresolved external symbol "public: class Ogre::Vector3 __thiscall PhysicsObject::getForce(void)" (?getForce@PhysicsObject@@QAE?AVVector3@Ogre@@XZ) referenced in function "protected: virtual void __thiscall OgreNewtonApplication::createScene(void)" (?createScene@OgreNewtonApplication@@MAEXXZ) OgreNewtonApplication.obj
Kerion
24-02-2006 19:33:14
thats it because this is a static function, you cannot access members so easily. I believe you can access static memebers though, so if you change it to static it will probably work.
otherwise the preferred way is to use the userData() function of rigid bodies. for example you make a simple class or all your physics bodies... something like this
Class PhysicsObject
{
public:
PhysicsObject();
~PhysicsObject();
void setForce( Ogre::Vector3 force ) { mForce = force; }
Ogre::Vector3 getForce() { return mForce; }
private:
OgreNewt::Body mBody;
Ogre::Vector3 mForce;
};
then in the initation of this class (when you create the body) you do this:
mBody->setUserData(this)
finally, back in that callback, you can do this:
PhysicsObject* obj = (PhysicsObject*)currentBody->getUserData();
currentBody->setForce( obj->getForce() );
having some trouble, I did everything like above (to make my camera a collision object that can't penetrate walls in my mesh), but a problem.
here is my code (see comments in code):
// position camera
msnCam = mSceneMgr->getRootSceneNode()->createChildSceneNode();
msnCam->attachObject( mCamera );
mCamera->setPosition(0.0, 0.0, 0.0);
msnCam->setPosition( 0.0, -10.0, 20.0);
// my code
Ogre::Vector3 size = Ogre::Vector3(20,20,20);
OgreNewt::Collision* col2 = new OgreNewt::CollisionPrimitives::Box(m_World, size);
OgreNewt::Body* bod2 = new OgreNewt::Body( m_World, col2 );
delete col2;
bod2->setPositionOrientation( Ogre::Vector3(0.0,-10.0,0.0), Ogre::Quaternion::IDENTITY );
bod2->setMassMatrix( 10.0, OgreNewt::MomentOfInertia::CalcSphereSolid( 10.0, 1.0 ) );
bod2->attachToNode(msnCam);
bod2->setStandardForceCallback();
bod2->setUserData(this); // help!!!
//bod2->setForce( Ogre::Vector3(10,10,10) ); // must be done in a registered callback, has this something to do with bod2->setUserData(this)?
PhysicsObject* obj = (PhysicsObject*)bod2->getUserData();
bod2->setForce( obj->getForce() );
I guess my problem is: bod2->setUserData(this)
maybe also other faults...
Error 3 error LNK2019: unresolved external symbol "public: class Ogre::Vector3 __thiscall PhysicsObject::getForce(void)" (?getForce@PhysicsObject@@QAE?AVVector3@Ogre@@XZ) referenced in function "protected: virtual void __thiscall OgreNewtonApplication::createScene(void)" (?createScene@OgreNewtonApplication@@MAEXXZ) OgreNewtonApplication.obj
You are attempting to use PhysicsObject as a concrete type, but it's missing a method implementation. Implement the getForce method (as in, give it a body) and that should go away. Or, if this is meant to be a base object with no implementation, make it pure virtual (virtual Ogre::Vector3 getForce() = 0). Also, as a tip, you may want to make that method const, as it doesn't change the state of the 'this' pointer in any way.
Such as:
virtual Ogre::Vector3 getForce() const { return vector; }
or
virtual Ogre::Vector3 getForce() const = 0;
to make it pure virtual (note, classes with pure virtual methods can't be instanciated or used as concrete types, you must subclass and implement the method at some level in the class hierarchy).
EDIT: I got to thinking, if you have the getForce method implemented, and it's implemented in-header, as part of the class decl, #include that header at the top of the source file that is going to actually use the type. Don't do a pre-declare and expect it to work. If you don't include that in the correct .cpp (or create a blank .cpp and do nothing but include that header), the method will never get compiled and linking will fail.
walaber
24-02-2006 20:03:21
my example was just an example not complete code. you need to create a new class called PhysicsObject (or whatever you want to name it) and implement the parts I mentioned along with anything else to make it work.
if you are not very comfortable making classes yet, take some time to study the subject, it's extremely important.
misterface
09-03-2006 23:22:38
I have a problem...
I want to play a sound when my car bumps into something.
sound and collision detection works fine!
but how do I know when something hits something.
My world is 1 mesh (body), the car is another mesh (body).
So in fact there is constantly a collission because the wheels hit the floor...
I want to detect bumping into the wall (same mesh).
I don't know if this can be achieved.
anyone?
I tried:
bool collide=false;
if (mCar->getChassisBody()->getCollision() != NULL) collide=true;
but the bool collide is ALWAYS true! strange
OvermindDL1
10-03-2006 01:33:23
Material callbacks?
walaber
10-03-2006 01:35:31
yup, this is a call for a material callback. they let you know when things slam into each other. Demo03 is a simple example of this, just ignore the part about making it into a conveyor belt, and focus on the material callback parts.
misterface
10-03-2006 16:37:10
thx

I will try that!
another question nothing to do with this...
My game runs perfectly on my pc, but when I export it to a slower pc, everything goes slower (fps drops to 20).
How do you make a game fps-independent?
OvermindDL1
10-03-2006 17:33:09
Using Ogre, just get the event's (through a framelistener) timeSinceLastFrame, and multiply it by everything that moves. Newton should do that automagically if you give it to it.
misterface
10-03-2006 17:43:15
interesting
but I don't get it 100%
Could you be more specific?
*update*
made seperate topic on this
OvermindDL1
11-03-2006 02:15:55
Not home right now so can't check. All the code you need to see will be in the demo newton framelistener; it is quite simple.
NHunter
19-03-2006 02:25:13
mental note to me: search forum,search....
XD