Hi all,
I would like to jump a NxOgre body into my app but only if this one is on floor. You can't jump if you are always in the air
Today when i press space key i add "y" force to my body:
bool GameFrameListener::keyPressed(const OIS::KeyEvent &e) {
if(e.key == OIS::KC_SPACE) {
mForceVector.y = mForceApply; // int value : 20
}
return true;
}
Into Framestarted i had:
bool GameFrameListener::frameStarted(const FrameEvent& evt) {
mTimeController->advance(evt.timeSinceLastFrame);
if(mKeyboard)
mKeyboard->capture();
// Apply for on body
mBody->addForce(mForceVector);
return (true);
}
1 - How can perform a test which be able to say me: If body in the air then no force is applied. A raycast from body to plane will be able to do that? By getting the distance of the ray?
Thanks for your support,
Thomas
Druha
14-11-2009 15:02:17
Yes, raycast is exactly what you need to determine, whether your body is in the air or not.
Just use Scene::raycastClosestShape() pointing it straight down. And don't forget to correct its origin, that it doesn't hit your body, which position you are testing
betajaen
14-11-2009 15:25:04
that it doesn't hit your body
I believe you can cast within side a shape and that shape won't get reported, I think I did it with the Fake Camera Actor in Cake.
Makes things easier when working out ray origin positions.
I am trying for that:
bool GameFrameListener::keyPressed(const OIS::KeyEvent &e) {
if(e.key == OIS::KC_SPACE) {
NxOgre::Vec3 bodyPos = NxOgre::Vec3(mBody->getGlobalPosition());
mBodyRayHit = mScene->raycastClosestShape( NxOgre::Ray(bodyPos, NxOgre::Vec3(bodyPos.x, -10, bodyPos.z)),
NxOgre::Enums::ShapesType_Static);
if(mBodyRayHit.mDistance == 0) {
mForceVector.y = mForceApply;
LogManager::getSingletonPtr()->logMessage("IF zone");
} else {
LogManager::getSingletonPtr()->logMessage("ELSE zone");
}
}
}
I declared into my members the following variable:
NxOgre::RaycastHit mBodyRayHit;
Problem: i cannot jump the body. My "Ogre.log" file always write "ELSE zone" regarding to my log message on the first block of code i posted.
LogManager::getSingletonPtr()->logMessage("ELSE zone");
The body jump from a plane declared like this:
// Create floor plane (BloodyMess)
mScene->createSceneGeometry(new NxOgre::PlaneGeometry(0, NxOgre::Vec3(0, 1, 0)), Matrix44_Identity);
// Create floor plane (Ogre)
MovablePlane *plane = new MovablePlane("Plane");
plane->d = 0;
plane->normal = Vector3::UNIT_Y;
Ogre::MeshManager::getSingleton().createPlane("PlaneMesh",
ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
*plane, 120, 120, 1, 1, true, 1, 3, 3, Vector3::UNIT_Z);
Entity *planeEnt = mSceneManager->createEntity("PlaneEntity", "PlaneMesh");
planeEnt->setMaterialName("Examples/NxFloor");
planeEnt->setCastShadows(false);
Ogre::SceneNode* mPlaneNode = mSceneManager->getRootSceneNode()->createChildSceneNode();
mPlaneNode->attachObject(planeEnt);
1 - What's going wrong?
I believe you can cast within side a shape and that shape won't get reported
2 - i'am quite interested about this feature. How does it works? Which function i have to use?
Thanks for the support you bring to me,
Thomas (from france).
Druha
14-11-2009 16:13:20
Your object probably not at 0 distance from the ground. It may stay at 0.0001 for example, close enough, but not at zero. It's not a good idea to test float vars for equality to smth. Try to replace your condition for example with:
mBodyRayHit.mDistance < 0.1
To betajaen:
I have an expirience with raycasts, when my object start flying away exactly because it get reported as a query result. I had to change Shape type to NxOgre::Enums::ShapesType_Static to avoid false reports.
deshan
14-11-2009 16:15:39
I think the problem is in this line
if(mBodyRayHit.mDistance == 0)
because it may never reach to zero
I suggest you to print the mDistance value and check whether what is the it when the body is on the floor. Following is my code
void PlayerCharacter::jumpPlayer()
{
// ray casting
NxOgre::RaycastHit hit;
hit = gameEngData->mScene->raycastClosestShape(NxOgre::Ray(NxOgre::Vec3(characterNode->getPosition().x,characterNode->getPosition().y,characterNode->getPosition().z),NxOgre::Vec3(0,-1,0)),NxOgre::Enums::ShapesType_Static,1,40);
if(hit.mDistance < MINIMUM_FLOUR_TOUCH_LIMIT)
this->playerBody->addForce(NxOgre::Vec3(0,fpForceJumpPower,0), NxOgre::Enums::ForceMode_Force);
}
EDIT: Oh druha almost posted the code
Your object probably not at 0 distance from the ground. It may stay at 0.0001 for example, close enough, but not at zero. It's not a good idea to test float vars for equality to smth. Try to replace your condition for example with:
mBodyRayHit.mDistance < 0.1
Unfortunately it's not working with
mBodyRayHit.mDistance < 0.1
The definition of my ray is really correct? I use Vec3(mBody.x, -10, mBody.z) for the second vector of my ray:
mBodyRayHit = mScene->raycastClosestShape( NxOgre::Ray(bodyPos, NxOgre::Vec3(bodyPos.x, -10, bodyPos.z)),
NxOgre::Enums::ShapesType_Static);
Thanks for the support,
Thomas
Unfortunately it's not working with
mBodyRayHit.mDistance < 0.1
It Works with more greater value: 1 instead of 0.1
mBodyRayHit.mDistance < 1
1 - There is a way to debug raycast? To view on screen my ray? Which plane or actor, body does he hit?
Thanks all!
Thomas
Druha
14-11-2009 16:49:02
The definition of my ray is really correct? I use Vec3(mBody.x, -10, mBody.z) for the second vector of my ray:
mBodyRayHit = mScene->raycastClosestShape( NxOgre::Ray(bodyPos, NxOgre::Vec3(bodyPos.x, -10, bodyPos.z)),
NxOgre::Enums::ShapesType_Static);
The second vector in Ray constructor is a direction vector. In your case there should be NxOgre::Vec3(0,-1,0)
The one you are using now after normalisation may point in almost any direction, but not down
The definition of my ray is really correct? I use Vec3(mBody.x, -10, mBody.z) for the second vector of my ray:
mBodyRayHit = mScene->raycastClosestShape( NxOgre::Ray(bodyPos, NxOgre::Vec3(bodyPos.x, -10, bodyPos.z)),
NxOgre::Enums::ShapesType_Static);
The second vector in Ray constructor is a direction vector. In your case there should be NxOgre::Vec3(0,-1,0)
The one you are using now after normalisation may point in almost any direction, but not down 
Ok i understand and i correct. Thanks.
I ask again about the debug:
1 - There's a way to view Ray on the scene to debug?
2 - There is a to make a "surface ray" which describe a volume? This volume could intersec with other bodies, actor or static shape...
Thanks for support,
Thomas
betajaen
14-11-2009 19:28:17
1. No not really. Rays are preformed instantaneously, so they are to quick to be drawn. You can use an Ogre::ManualObject though to draw a line though.
2. Yep. You can use sweep testing if you like, it should be accessible via Scene.
However, I am really surprised how much difficulty you have had with this. Honestly it isn't hard to do.
I'll assume your player is 2 metres high, has a default skin width of 0.025:
float minFloorHeight = (2 * 0.5) + 0.025 + 0.05) // Half the height + skin width + 0.05 safety.
if (mScene->raycastAnyShape(NxOgre::Ray(bodyPos, NxOgre::Vec3(0,-1,0)), NxOgre::Enums::ShapesType_Static, INT_MAX, minFloorHeight)
; // On Floor
else
; // In air