Key release problem

kintaro

10-03-2006 18:42:38

Hi, I am working on demo7 of ogrenewt, and I had put the camera inside in an elipsoid primitive, so the camera can collide with others objects. To movethe elpsoid around, when I press arrows keys, its set a velocity to the boby (elipsoid). Till here, every thing works perfectly. The question, is that when I release some key, want to set body velocity to zero, but not freeze it. So I created a function called keyRelease, but it is not working. It not give erros, only don't work. What am I doing wrong?

The code below, is OgreNewtonFrameListener.cpp, that I changed a bit.

#include ".\ogrenewtonframelistener.h"



OgreNewtonFrameListener::OgreNewtonFrameListener(RenderWindow* win, Camera* cam, SceneManager* mgr, OgreNewt::World* W, SceneNode* ncam, OgreNewt::Body* camera_body) :
ExampleFrameListener(win,cam)
{
m_World = W;
msnCam = ncam;
mSceneMgr = mgr;
cam_body = camera_body;

}

OgreNewtonFrameListener::~OgreNewtonFrameListener(void)
{
}

void OgreNewtonFrameListener::keyReleased(KeyEvent *e)
{
Vector3 trans, strafe, vec;
Quaternion quat;

quat = msnCam->getOrientation();

vec = Vector3(0.0,0.0,-0.5);
trans = quat * vec;

vec = Vector3(0.5,0.0,0.0);
strafe = quat * vec;

cam_body->setVelocity( (trans * 0) );

cam_body->setVelocity( (strafe * 0) );

}

void OgreNewtonFrameListener::keyPressed(KeyEvent *e)
{
}

void OgreNewtonFrameListener::keyClicked(KeyEvent *e)
{
}


bool OgreNewtonFrameListener::frameStarted(const FrameEvent &evt)
{
Vector3 trans, strafe, vec;
Quaternion quat;

quat = msnCam->getOrientation();

vec = Vector3(0.0,0.0,-0.5);
trans = quat * vec;

vec = Vector3(0.5,0.0,0.0);
strafe = quat * vec;

mInputDevice->capture();

//msnCam->pitch( Degree(mInputDevice->getMouseRelativeY() * -0.5) );
//msnCam->yaw( Degree(mInputDevice->getMouseRelativeX() * -0.5), SceneNode::TS_WORLD );

bool up_enable;

up_enable = true;


if (mInputDevice->isKeyDown(Ogre::KC_UP) || mInputDevice->isKeyDown(Ogre::KC_W))
{
cam_body->setVelocity( (trans * 6.0) );
}




if (mInputDevice->isKeyDown(Ogre::KC_DOWN) || mInputDevice->isKeyDown(Ogre::KC_S))
{
cam_body->unFreeze();
cam_body->setVelocity( (trans * -1 * 6.0) );
}

if (mInputDevice->isKeyDown(Ogre::KC_LEFT) || mInputDevice->isKeyDown(Ogre::KC_A))
{
cam_body->unFreeze();
cam_body->setVelocity( (strafe * -1 * 6.0) );
}

if (mInputDevice->isKeyDown(Ogre::KC_RIGHT) || mInputDevice->isKeyDown(Ogre::KC_D))
{
cam_body->unFreeze();
cam_body->setVelocity( (strafe * 6.0) );
}

if (mInputDevice->isKeyDown(Ogre::KC_PGDOWN))
{
Ogre::Vector3 dir(0,-1,0);
cam_body->setVelocity( (dir * 6.0) );
}

if (mInputDevice->isKeyDown(Ogre::KC_PGUP))
{
Ogre::Vector3 dir(0,1,0);
cam_body->setVelocity( (dir * 6.0) );
}

if (mInputDevice->isKeyDown(Ogre::KC_SPACE))
{
if (timer <= 0.0)
{
Ogre::Vector3 dir, vec;
Ogre::Quaternion camorient = msnCam->getWorldOrientation();
vec = Ogre::Vector3(0,0,-1);

dir = camorient * vec;

Entity* ent;
SceneNode* node;
Ogre::String name;
Ogre::Vector3 pos = msnCam->getWorldPosition();

name = "Body "+Ogre::StringConverter::toString( count++ );

ent = mSceneMgr->createEntity( name, "ellipsoid.mesh" );
node = mSceneMgr->getRootSceneNode()->createChildSceneNode( name );
node->attachObject( ent );

ent->setMaterialName( "Simple/dirt01" );
ent->setNormaliseNormals(true);

OgreNewt::Collision* col = new OgreNewt::CollisionPrimitives::Ellipsoid( m_World, Ogre::Vector3(1,1,1) );
OgreNewt::Body* body = new OgreNewt::Body( m_World, col );

Ogre::Vector3 inertia = OgreNewt::MomentOfInertia::CalcSphereSolid( 10 , 1.0 );
body->setMassMatrix( 10 , inertia );
body->attachToNode( node );
body->setStandardForceCallback();
body->setPositionOrientation( pos, camorient );
body->setVelocity( (dir * 50.0) );

timer = 0.2;
}
}

timer -= evt.timeSinceLastFrame;


if (mInputDevice->isKeyDown(Ogre::KC_ESCAPE))
return false;



return true;
}



Thanks for help.

Epimetheus

11-03-2006 10:49:51

is the keyreleased even called?

kintaro

16-03-2006 18:13:33

You're right, I forgot to call the events. I am still learning. The keyrelease event is working now.

Thanks a lot.

czechow

05-05-2006 19:44:28

You're right, I forgot to call the events. I am still learning. The keyrelease event is working now.

Thanks a lot.



could you explain how to call the keyrelease event, and give me some code examples or codes from other files from aplication Demo7? Thanks for any answer.

kintaro

05-05-2006 21:49:40

OK, I'll try to explain.

First a keyrelease event is part of KeyListener, and to use KeyListener you have to set true to BufferedInput for keyboard and or mouse (it's up to your application) on the ExampleFrameListener input, like:

ExampleFrameListener(win,cam, true, true)

It comes from:

ExampleFrameListener(RenderWindow* win, Camera* cam, bool useBufferedInputKeys = false, bool useBufferedInputMouse = false)

Here is a example how you call a KeyRelease function:

void OgreNewtonFrameListener::keyReleased(KeyEvent *e)
{
//your code//
}


Below there is the code files from Demo7 that I made some changes, the result is a green ninja that has gravity, and when you press key_up or w key, the ninja walk in front. Remenber to run this code your have to put all media file of ninja in the correct media sub folders.

FILES:

OgreNewtonApplication.cpp

/*
OgreNewt library - connecting Ogre and Newton!

Demo02_Joints - basic demo that shows how to connect rigid bodies via joints.
*/

#include ".\OgreNewtonApplication.h"
#include ".\OgreNewtonFrameListener.h"
#include ".\MyCustomBallSocket.h"

#include <OgreNewt.h>



OgreNewtonApplication::OgreNewtonApplication(void)
{
// create OgreNewt world.
m_World = new OgreNewt::World();

mEntityCount = 0;

}

OgreNewtonApplication::~OgreNewtonApplication(void)
{
// destroy world.
delete m_World;
}



void OgreNewtonApplication::createScene()
{
// sky box.
mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox");

// shadows on!
mSceneMgr->setShadowTechnique( Ogre::SHADOWTYPE_STENCIL_ADDITIVE );


// floor object!
Entity* floor;
SceneNode* floornode;
floor = mSceneMgr->createEntity("Floor", "simple_terrain.mesh" );
floornode = mSceneMgr->getRootSceneNode()->createChildSceneNode( "FloorNode" );
floornode->attachObject( floor );
floor->setMaterialName( "Simple/BeachStones" );

floor->setCastShadows( false );

//Ogre::Vector3 siz(100.0, 10.0, 100.0);
OgreNewt::Collision* col = new OgreNewt::CollisionPrimitives::TreeCollision( m_World, floornode, true );
OgreNewt::Body* bod = new OgreNewt::Body( m_World, col );
delete col;

//floornode->setScale( siz );
bod->attachToNode( floornode );
bod->setPositionOrientation( Ogre::Vector3(0.0,-20.0,0.0), Ogre::Quaternion::IDENTITY );



// make a simple rope.
Ogre::Vector3 size(3,1.5,1.5);
Ogre::Vector3 pos(0,3,0);
Ogre::Quaternion orient = Ogre::Quaternion::IDENTITY;

// loop through, making bodies and connecting them.
OgreNewt::Body* parent = NULL;
OgreNewt::Body* child = NULL;

for (int x=0;x<5;x++)
{
// make the next box.
child = makeSimpleBox(size, pos, orient);

// now make a new joint connecting this to the last box.
OgreNewt::Joint* joint;

// make the joint right between the bodies...


if (parent)
{
joint = new MyCustomBallSocket(child, parent, pos-Ogre::Vector3(size.x/2,0,0), Ogre::Vector3(Ogre::Vector3::UNIT_X) );
}
else
{
// no parent, this is the first joint, so just pass NULL as the parent, to stick it to the "world"
joint = new MyCustomBallSocket(child, NULL, pos-Ogre::Vector3(size.x/2,0,0), Ogre::Vector3(Ogre::Vector3::UNIT_X) );
}

// offset pos a little more.
pos += Ogre::Vector3(size.x,0,0);

// save the last body for the next loop!
parent = child;
}


//MY IMPLEMENTATION

//ninja collision

mEntity = mSceneMgr->createEntity( "Ninja", "ninja.mesh" );

msnEnt_Body = mSceneMgr->getRootSceneNode()->createChildSceneNode();

msnEnt_Body->setPosition( 0.0, -3.0, 25.0);

msnCam = msnEnt_Body->createChildSceneNode( Vector3( 0 , 0 , 0 ) );

msnCam->attachObject( mCamera );

mCamera->setPosition(0.0, 0.0, 25.0);

msnEnt = msnEnt_Body->createChildSceneNode( "Entity_node", Vector3( 0 , -5 , 0 ) );

msnEnt->attachObject( mEntity );

msnEnt->scale( 0.05, 0.05 , 0.05 );

OgreNewt::Collision* ent_col = new OgreNewt::CollisionPrimitives::Box( m_World, Ogre::Vector3( 2 , 10 , 2) );

ent_body = new OgreNewt::Body( m_World, ent_col );

Ogre::Vector3 ent_inertia = OgreNewt::MomentOfInertia::CalcBoxSolid( 10, Ogre::Vector3( 2 , 10 , 2) );

ent_body->setMassMatrix( 10 , ent_inertia );

ent_body->attachToNode( msnEnt_Body );

Ogre::Vector3 Up_Direction_1( 0 , 1 , 0 );

OgreNewt::BasicJoints::UpVector* Up_Vector_1;

Up_Vector_1 = new OgreNewt::BasicJoints::UpVector( m_World, ent_body, Up_Direction_1 );

Ogre::Vector3 Up_Direction_2 ( 1 , 0 , 0 );

OgreNewt::BasicJoints::UpVector* Up_Vector_2;

Up_Vector_2 = new OgreNewt::BasicJoints::UpVector( m_World, ent_body, Up_Direction_2 );

ent_body->setStandardForceCallback();

delete ent_col;
//~ninja collision

mAnimationState = mEntity->getAnimationState( "Idle1" );
mAnimationState->setLoop( true );
mAnimationState->setEnabled( true );

//~MY IMPLEMENTATION


//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()
{
mFrameListener = new OgreNewtonFrameListener( mWindow, mCamera, mSceneMgr, m_World, msnCam, ent_body, msnEnt, mEntity, mAnimationState );
mRoot->addFrameListener(mFrameListener);

mNewtonListener = new OgreNewt::BasicFrameListener( mWindow, mCamera, mSceneMgr, m_World, 60 );
mRoot->addFrameListener(mNewtonListener);
}


OgreNewt::Body* OgreNewtonApplication::makeSimpleBox( Ogre::Vector3& size, Ogre::Vector3& pos, Ogre::Quaternion& orient )
{
// base mass on the size of the object.
Ogre::Real mass = size.x * size.y * size.z * 2.5;

// calculate the inertia based on box formula and mass
Ogre::Vector3 inertia = OgreNewt::MomentOfInertia::CalcBoxSolid( mass, size );


Entity* box1;
SceneNode* box1node;

box1 = mSceneMgr->createEntity( "Entity"+Ogre::StringConverter::toString(mEntityCount++), "box.mesh" );
box1node = mSceneMgr->getRootSceneNode()->createChildSceneNode();
box1node->attachObject( box1 );
box1node->setScale( size );
box1->setNormaliseNormals(true);

OgreNewt::Collision* col = new OgreNewt::CollisionPrimitives::Box( m_World, size );
OgreNewt::Body* bod = new OgreNewt::Body( m_World, col );
delete col;

bod->attachToNode( box1node );
bod->setMassMatrix( mass, inertia );
bod->setStandardForceCallback();

box1->setMaterialName( "Simple/BumpyMetal" );


bod->setPositionOrientation( pos, orient );

return bod;
}



OgreNewtonFrameListener.cpp

In this file there is the keyrelease function.

#include ".\ogrenewtonframelistener.h"



OgreNewtonFrameListener::OgreNewtonFrameListener(RenderWindow* win, Camera* cam, SceneManager* mgr, OgreNewt::World* W, SceneNode* ncam, OgreNewt::Body* entity_body, SceneNode* nent, Entity* mEntity_buffer, AnimationState *mAnimationState_buffer) :
ExampleFrameListener(win,cam, true, true)
{
m_World = W;
msnCam = ncam;
mSceneMgr = mgr;
ent_body = entity_body;
msnEnt = nent;
mEntity = mEntity_buffer;
mAnimationState = mAnimationState_buffer;

mEventProcessor->addKeyListener( this );

}

OgreNewtonFrameListener::~OgreNewtonFrameListener(void)
{
}

void OgreNewtonFrameListener::keyReleased(KeyEvent *e)
{
Vector3 trans, strafe, vec;
Quaternion quat;

quat = msnEnt->getOrientation();

vec = Vector3(0.0,0.0,-0.5);
trans = quat * vec;

vec = Vector3(0.5,0.0,0.0);
strafe = quat * vec;

ent_body->setVelocity( (trans * 0) );

ent_body->setVelocity( (strafe * 0) );

if( mAnimationState->getAnimationName() == "Walk" )
{
mAnimationState->setTimePosition( 0.0f );
mAnimationState->setEnabled( false );
}

mAnimationState = mEntity->getAnimationState( "Idle1" );

mAnimationState->setLoop( true );

mAnimationState->setEnabled( true );

}

void OgreNewtonFrameListener::keyPressed(KeyEvent *e)
{
}

void OgreNewtonFrameListener::keyClicked(KeyEvent *e)
{
}


bool OgreNewtonFrameListener::frameStarted(const FrameEvent &evt)
{

mAnimationState->addTime( evt.timeSinceLastFrame );

Vector3 trans, strafe, vec;
Quaternion quat;

quat = msnEnt->getOrientation();

vec = Vector3(0.0,0.0,-0.5);
trans = quat * vec;

vec = Vector3(0.5,0.0,0.0);
strafe = quat * vec;

mInputDevice->capture();

msnCam->pitch( Degree(mInputDevice->getMouseRelativeY() * -0.5) );
msnCam->yaw( Degree(mInputDevice->getMouseRelativeX() * -0.5), SceneNode::TS_WORLD );

ent_body->unFreeze();

Ogre::Vector3 cur_vel = ent_body->getVelocity();

//Ogre::Vector3 cur_pos = ent_body->getPositionOrientation();


if (mInputDevice->isKeyDown(Ogre::KC_UP) || mInputDevice->isKeyDown(Ogre::KC_W))
{
// in your movement code
Ogre::Vector3 vel = trans * 1 * 10.0;
vel.y = cur_vel.y;

ent_body->setVelocity( vel );

// Set walking animation
if( mAnimationState->getAnimationName() == "Idle1" )
{
mAnimationState->setTimePosition( 0.0f );
mAnimationState->setEnabled( false );
}
mAnimationState = mEntity->getAnimationState( "Walk" );
mAnimationState->setLoop( true );
mAnimationState->setEnabled( true );
}

if (mInputDevice->isKeyDown(Ogre::KC_DOWN) || mInputDevice->isKeyDown(Ogre::KC_S))
{
//ent_body->setVelocity( (trans * -1 * 10.0) );
//ent_body->setPositionOrientation();

//ent_body->getOgreNode()->yaw( Ogre::Degree 90 );

// in your movement code
Ogre::Vector3 vel = trans * -1 * 10.0;
vel.y = cur_vel.y;

ent_body->setVelocity( vel );

// Set walking animation
if( mAnimationState->getAnimationName() == "Idle1" )
{
mAnimationState->setTimePosition( 0.0f );
mAnimationState->setEnabled( false );
}
mAnimationState = mEntity->getAnimationState( "Walk" );
mAnimationState->setLoop( true );
mAnimationState->setEnabled( true );
}

if (mInputDevice->isKeyDown(Ogre::KC_LEFT) || mInputDevice->isKeyDown(Ogre::KC_A))
{
ent_body->setVelocity( (strafe * -1 * 10.0) );
}

if (mInputDevice->isKeyDown(Ogre::KC_RIGHT) || mInputDevice->isKeyDown(Ogre::KC_D))
{
ent_body->setVelocity( (strafe * 10.0) );
}

if (mInputDevice->isKeyDown(Ogre::KC_PGDOWN))
{
Ogre::Vector3 dir(0,-1,0);
ent_body->setVelocity( (dir * 10.0) );
}

if (mInputDevice->isKeyDown(Ogre::KC_PGUP))
{
Ogre::Vector3 dir(0,1,0);
ent_body->setVelocity( (dir * 10.0) );
}

if (mInputDevice->isKeyDown(Ogre::KC_SPACE))
{
if (timer <= 0.0)
{
Ogre::Vector3 dir, vec;
Ogre::Quaternion camorient = msnCam->getWorldOrientation();
vec = Ogre::Vector3(0,0,-1);

dir = camorient * vec;

Entity* ent;
SceneNode* node;
Ogre::String name;
Ogre::Vector3 pos = msnCam->getWorldPosition();

name = "Body "+Ogre::StringConverter::toString( count++ );

ent = mSceneMgr->createEntity( name, "ellipsoid.mesh" );
node = mSceneMgr->getRootSceneNode()->createChildSceneNode( name );
node->attachObject( ent );

ent->setMaterialName( "Simple/dirt01" );
ent->setNormaliseNormals(true);

OgreNewt::Collision* col = new OgreNewt::CollisionPrimitives::Ellipsoid( m_World, Ogre::Vector3(1,1,1) );
OgreNewt::Body* body = new OgreNewt::Body( m_World, col );

Ogre::Vector3 inertia = OgreNewt::MomentOfInertia::CalcSphereSolid( 10 , 1.0 );
body->setMassMatrix( 10 , inertia );
body->attachToNode( node );
body->setStandardForceCallback();
body->setPositionOrientation( pos, camorient );
body->setVelocity( (dir * 50.0) );

timer = 0.2;
}
}

timer -= evt.timeSinceLastFrame;

mAnimationState->getEnabled();


if (mInputDevice->isKeyDown(Ogre::KC_ESCAPE))
return false;

return true;
}


OgreNewtonApplication.h

#pragma once
#include <ExampleApplication.h>

#include <OgreNewt.h>


class OgreNewtonApplication :
public ExampleApplication
{
public:
OgreNewtonApplication(void);
~OgreNewtonApplication(void);

protected:
void createFrameListener();
void createScene();

// our custom function to simplify making simpe dynamics rigid body boxes.
OgreNewt::Body* makeSimpleBox( Ogre::Vector3& size, Ogre::Vector3& pos, Ogre::Quaternion& orient );

private:
OgreNewt::World* m_World;

Ogre::SceneNode* msnCam;

Ogre::SceneNode* msnEnt;

Ogre::SceneNode* msnEnt_Body;

Ogre::FrameListener* mNewtonListener;

int mEntityCount;

OgreNewt::Body* cam_body;

OgreNewt::Body* ent_body;

Ogre::Entity* mEntity;

AnimationState* mAnimationState;

};



OgreNewtonFrameListener.h

#pragma once
#include "ExampleFrameListener.h"

#include <OgreNewt.h>


class OgreNewtonFrameListener :
public ExampleFrameListener
{
protected:
OgreNewt::World* m_World;
SceneNode* msnCam;
Ogre::SceneNode* msnEnt;
SceneManager* mSceneMgr;
int count;
float timer;

OgreNewt::Body* ent_body; /*MY IMPLEMENTATION*/

OgreNewt::Collision* ent_col; /*MY IMPLEMENTATION*/

AnimationState* mAnimationState; /*MY IMPLEMENTATION*/

//AnimationState* mAnimationState_buffer; /*MY IMPLEMENTATION*/

Entity* mEntity; /*MY IMPLEMENTATION*/

//Entity* mEntity_buffer; /*MY IMPLEMENTATION*/



public:
OgreNewtonFrameListener(RenderWindow* win, Camera* cam, SceneManager* mgr, OgreNewt::World* W, SceneNode* ncam, OgreNewt::Body* entity_body, SceneNode* nent, Entity* mEntity_buffer, AnimationState* mAnimationState_buffer);
~OgreNewtonFrameListener(void);

bool frameStarted(const FrameEvent &evt);

void keyReleased( KeyEvent *e );

void keyPressed(KeyEvent *e);

void keyClicked(KeyEvent *e);
};


I hope this would help. I'm not a professional programmer, I am still learning, but any doubt with this app, you can ask that I'll try to help you.

czechow

08-05-2006 10:43:42

I'd like to thank you, your answer was really helpful and everything is working correctlty now
I've got one more question, have you ever tried to attach mouse control to it?? If you happen to know how to do it I'ii be grateful for any help

kintaro

09-05-2006 20:14:41

Yes, I had been working on control something with the mouse. There is more than one way to do it.

One example:

mInputDevice->getMouseRelativeX()

This comand returns the amount that you moved the mouse in x axis. In the same way:

mInputDevice->getMouseRelativeY()

To catch the right mouse button you can use:

mInputDevice->getMouseButton( 1 )

Where 1 is the right mouse button. If I remember well, 0 is the left button and 2 is the midle button, I'm not sure about that.

Suppose the code below inside a frame listener:

Radian mRotX, mRotY;
Vector3 mTranslateVector;
InputReader* mInputDevice;


if( mInputDevice->getMouseButton( 1 ) )
{
mTranslateVector.x += mInputDevice->getMouseRelativeX() * 0.13;
mTranslateVector.y -= mInputDevice->getMouseRelativeY() * 0.13;
}
else
{
mRotX = Degree(-mInputDevice->getMouseRelativeX() * 0.13);
mRotY = Degree(-mInputDevice->getMouseRelativeY() * 0.13);
}

mCamera->yaw(mRotX);
mCamera->pitch(mRotY);
mCamera->moveRelative(mTranslateVector);


This peace of code is a resume of what ExampleFrameListener do with the camera. You will see that is when you move the mouse without press any mouse button, the camera will rotate in the proportional amount of mouse dislocation. And if you press the right mouse button and move mouse, the camera will translate and not rotate in the proportion of mouse dislocation.

You can do similar things you a SceneNode, in this case a scenenode does not have moveRelative(). You can use the peace of code below in place of "mCamera->moveRelative(mTranslateVector);":

mEntity_node->translate(mEntityTranslateVector, Ogre::Node::TransformSpace::TS_LOCAL );
mTranslateVector= Vector3(0,0,0);


This will tranlate scenenode while you're moving the mouse.

I think this would help you. Any doubt feel free to ask.

czechow

16-05-2006 20:31:34

HI!!
I'd tried to do what you advised me but it doesn't working. It strarts but after pressing any key the program stops working. if you could give me the easiest properly working aplication that uses camera control closed in ellipsoid with use of mouse and keyboard I'd be grateful.