Even with setVelocity there is no movement.

sdragou

27-03-2006 10:41:30

I am trying to make a character moving on a horizontal plane.

I've made an upvector joint and attached a cylindrical body to it.

In the frame listener I use setVelocity in order to move the body. But when they contact there is no movement.

here is some of the code:


Ogre::Quaternion quat=Ogre::Quaternion(Ogre::Math::Sqrt(0.5),0,0,Ogre::Math::Sqrt(0.5));

OgreNewt::Collision* col = new OgreNewt::CollisionPrimitives::Cylinder(m_World,30,170,quat,Vector3(0,85,0));

body = new OgreNewt::Body( m_World, col, 1 );
delete col;
assil_node->setPosition(500,12,300);
body->setPositionOrientation(assil_node->getPosition(),assil_node->getOrientation());
body->attachToNode(assil_node);
Ogre::Vector3 inertia = OgreNewt::MomentOfInertia::CalcCylinderSolid(100,30,170);
body->setMassMatrix(100.0f,inertia);
body->setStandardForceCallback();
OgreNewt::Joint *joint = new OgreNewt::BasicJoints::UpVector(m_World,body,Vector3(0,1,0));


After a while (due to gravity) the body reaches the ground and then it stops.

Here is the code for the ground
SceneNode *patnode = mSceneMgr->getRootSceneNode()->createChildSceneNode("patwma");
Entity *patwma=mRoot->getSceneManager("generic")->createEntity( "patwma", "patwma.mesh" );
patnode->attachObject(patwma);
patnode->setPosition(4000,0,4000);
patwma->setQueryFlags(FLOOR_MASK);

OgreNewt::Collision* pcol = new OgreNewt::CollisionPrimitives::TreeCollision( m_World, patnode, true );
OgreNewt::Body* pbod = new OgreNewt::Body( m_World, pcol );
pbod->setContinuousCollisionMode(1);


pbod->attachToNode( patnode );
pbod->setPositionOrientation(patnode->getPosition(),patnode->getOrientation());



and the framelistener framestarted method (a part of it)


m_World->update( evt.timeSinceLastFrame );
OgreNewt::Debugger::getSingleton().showLines( assil->m_World );
body->setVelocity(assil_node->getOrientation()*(-mDirection));




I also tryied to set friction to zero:

const OgreNewt::MaterialID* mMatDefault = m_World->getDefaultMaterialID();
const OgreNewt::MaterialID* mMatAssil = new OgreNewt::MaterialID( m_World );


OgreNewt::MaterialPair *mMatPairDefaultAssil = new OgreNewt::MaterialPair( m_World, mMatDefault, mMatAssil );
mMatPairDefaultAssil->setDefaultFriction( 0, 0 );
mMatPairDefaultAssil->setDefaultElasticity(0);
mMatPairDefaultAssil->setContinuousCollisionMode(1);
body->setMaterialGroupID(mMatAssil);


nothing.

Any Ideas?

BergBoy

27-03-2006 14:17:38

Are you using a force and torque callback? You need to apply force and torque in a callback. You havnt mentioned a callback and I cant see the code that moves the body so if you are not using a callback, then no force will happen. Thats my best guess at whats wrong.

sdragou

27-03-2006 16:28:44

I am not using force callback because I use setVelocity.

HexiDave

27-03-2006 20:11:09

Dig into the code to find the Body::setStandardForceCallback() function and see how it works - essentially find the actual callback function and implement your own into your code. Look [b]here[/b] on how to attach your callback function properly using makedelegate().

Now you can apply your forces properly - setting the velocity directly can lead to problems (at least that was my understanding of it.) Do a search on here for "applyForce" and read up on some of the callback code other people use.

sdragou

28-03-2006 12:56:39

I made a custom force callback


void FrameListener::customForceCallback( OgreNewt::Body* me){
Ogre::Real mass;
Ogre::Vector3 inertia;
Vector3 postition;
Quaternion orientation;
me->getMassMatrix(mass, inertia);
me->getPositionOrientation(postition,orientation);

Ogre::Vector3 force;
Vector3 V0 = me->getVelocity();
Vector3 V1=orientation*(-mDirection);
Ogre::Real deltatime = me->getWorld()->getTimeStep();
Vector3 acel ((V1 - V0) / deltatime);
force = (Vector3(acel.x,-981,acel.z))*mass;
me->addForce(force);

}


and called it from the FrameListener constructor
body->setCustomForceAndTorqueCallback(fastdelegate::MakeDelegate( this,customForceCallback) );


mDirection is set in the keypressed and keyreleased functions.

It works for a small period of time (3 seconds and it varies) and then it stops. After this period there is no movement.

I tried to set friction , elasticity and softness to zero. Nothing.

(btw the world size is big enough)

What I don't know is, if setting the orientation by setPostitionOrientation is causing the problem.

sdragou

28-03-2006 15:48:53

By using

body->setAutoFreeze(0)

The problem is solved.
Are there any sideeffects by this? (FPS decrease, ...)
What are the criteria that the callback stops responding?

pfo

29-03-2006 06:16:34

Newton freezes objects by default. Un-frozen objects have their force and torque callback called when NewtonUpdate is called. If you want to see a performance difference, make 100 boxes and then observe framerates with all of those boxes frozen and un-frozen. The ability to freeze stuff is a technique to squeeze some extra performance out of Newton by freezing bodies that you don't want (or need) active.What are the criteria that the callback stops responding?1) body is frozen
2) body has left world boundaries

sdragou

29-03-2006 10:07:22

I see. A frozen body has to be unfrozen manualy?

For example let's say that there is a wall which I made of 30 pieces in order to be able to break it. It is frozen (since the characer will reach it after 10 minutes)

If the character contacts the wall, the pieces will be unfrozen automaticaly or I have to make a custom contact callback and unfreeze the pieces in the userBegin method?

btw Is contactcallback called from a frozen body?

walaber

30-03-2006 03:26:51

frozen objects, when hit by other objects, come awake automatically.

only frozen objects you want to move manually must be awoken manually.