I am curious how you force an object to move with Newton... for example, if I press forward on my keyboard, it will move a ball within the program forward.
I have tried to look at the Character Controller tutorial that comes with Newton, but it is much too advanced for my current understanding and far too involved. It is also written with a 3D engine I am not familiar with, so I get even more confused.
Currently, I can create a ball by clicking the mouse button. This will throw the ball forward and it will bounce around for a while. After that, I tried to move the mesh with Irrlicht and adjust the corresponding matrix in Newton, but that results in no collision detection being done.
Have I got it backwards? Should I be moving the object with Newton and only then with Irrlicht in the callbacks? I tried setting the object's velocity, anticipating this would shoot the object forward, but it didn't do anything at all. Am I missing some sort of update function?
Any help with the order in which things should be done and what functions to look at would be very appreciated. A very simple example would be especially awsome.
Moving an object with Newton collision.
Yeah, you got it backwards. In the setTransformation callback, Newton tells us where the object is, and we are supposed to update the graphical representation. The physics comes first.
To push things forward and such, you should add a force to the body in the setForceAndTorque callback.
I'm not sure about the names of the callbacks, but it's something like that. Maybe i'll post a small tut on the wiki and show how it can be done.
To push things forward and such, you should add a force to the body in the setForceAndTorque callback.
I'm not sure about the names of the callbacks, but it's something like that. Maybe i'll post a small tut on the wiki and show how it can be done.
If you don't have anything nice to say, don't say anything at all.
Check this out. its my player controller using newton. updateMovement() is called every frame and it updates movement direction. Player_MeshTransform callback represents camera position lifted by 4 units above ground. Camera is surrounded by capsule by the way. So capsule do not care about cam torque and camera do not care about capsule torque. Torques are ignored. Player_ForceAndTorque takes user data of newton body which is my player object, as you see i have pointer to vector move and i can access it from callback. with tmp->node->getAbsoluteTransformation().rotateVect(dir); i rotate my direction vector move to point at the same forward position like camera (node). then all forces are applied. there is only one bug - when you are moving lets say forward speed is not constant, it is growing and growing. im not good at physics so i didnt make speed control yet
Code: Select all
void Player::updateMovement()
{
//vector3df move(0,0,0);
if(keysDown[KEY_KEY_W])
move->Z += MAX_SPD;
if(keysDown[KEY_KEY_S])
move->Z -= MAX_SPD;
if(keysDown[KEY_KEY_A])
move->X -= MAX_SPD;
if(keysDown[KEY_KEY_D])
move->X += MAX_SPD;
}
void _cdecl Player::Player_MeshTransform(const NewtonBody *body, const float *matrix)
{
// copy the matrix into an irrlicht matrix4
matrix4 mat;
memcpy(&mat, matrix, sizeof(float)*16);
// Retreive the user data attached to the newton body
Object *tmp = (Object*)NewtonBodyGetUserData(body);
if (tmp)
{
vector3df newPos = mat.getTranslation();
newPos.Y += 4;
// Position the node
tmp->node->setPosition(newPos); // set position
//tmp->node->setRotation(mat.getRotationDegrees()); // and rotation
}
}
void _cdecl Player::Player_ForceAndTorque(const NewtonBody* body)
{
float mass;
float Ixx;
float Iyy;
float Izz;
float force[3];
float torque[3];
Player *tmp = (Player*)NewtonBodyGetUserData(body);
vector3df dir;
dir.X = tmp->move->X;
dir.Y = tmp->move->Y;
dir.Z = tmp->move->Z;
tmp->node->getAbsoluteTransformation().rotateVect(dir);
/*tmp->node->setPosition(node->getAbsolutePosition() + move);*/
NewtonBodyGetMassMatrix (body, &mass, &Ixx, &Iyy, &Izz);
float currForce[3];
NewtonBodyGetForce(body, &currForce[0]);
force[0] = dir.X * mass;
force[1] = GRAVITY_Y * mass;
force[2] = dir.Z * mass;
tmp->move->X = 0;
tmp->move->Y = 0;
tmp->move->Z = 0;
torque[0] = 0.0f;
torque[1] = 0.0f;
torque[2] = 0.0f;
NewtonBodyAddForce (body, force);
NewtonBodyAddTorque (body, torque);
}
Hi again, thanks a lot for the replies! What roxaz posted is similar to what I thought had to happen. However, when I tried it, pushing forward doesn't do anything. It doesn't look like the callbacks are being called, although they are set correctly as they do get called when the object is added and falls to the ground.
I get the feeling I'm missing some key piece of the puzzle I'm too tired to see.
Do I need to tell Newton that it should be updating the object as a result of applied forces somehow? Currently, when I push forward, only where the object should be at is updated. For testing, it is currently just a universal variable, rather than being part of the character object. Does updating the user data result in Newton updating the body? I am not sure how it is supposed to work.
I get the feeling I'm missing some key piece of the puzzle I'm too tired to see.
Do I need to tell Newton that it should be updating the object as a result of applied forces somehow? Currently, when I push forward, only where the object should be at is updated. For testing, it is currently just a universal variable, rather than being part of the character object. Does updating the user data result in Newton updating the body? I am not sure how it is supposed to work.
it workls like this: you move newton bodies, they have their collision geometry and interact with each other. so all collision thing happens in newton. to see result you just design your mesh transform callback to update object mesh to look like newton body. check out my simple object mesh transform callback, maybe comments will make it clear for you.
Code: Select all
void _cdecl Object::Object_MeshTransform(const NewtonBody *body, const float *matrix)
{
// copy the matrix into an irrlicht matrix4
matrix4 mat;
memcpy(&mat, matrix, sizeof(float)*16);
// Retreive the user data attached to the newton body.
Object *tmp = (Object*)NewtonBodyGetUserData(body);
if (tmp)
{
// Position the node. mat.getTranslation() takes newton body position and tmp->node->setPosition() update our scene node position
tmp->node->setPosition(mat.getTranslation());
// mat.getRotationDegrees() gets current newton body rotation and tmp->node->setRotation() rotate our scene node just like newton body is rotated.
tmp->node->setRotation(mat.getRotationDegrees());
}
}
Thanks a lot for all of your help!
I finally figured out what I was doing wrong. Everything was working fine for my general shapes as they were not expected to be shifted by the user and only needed to react to collisions. Therefore, when they stopped moving, Newton didn't bother checking on them anymore.
My character now moves around and collides into things perfectly! Now, I just have to figure out how to make it stay upright.
Again, my thanks for your help.
I finally figured out what I was doing wrong. Everything was working fine for my general shapes as they were not expected to be shifted by the user and only needed to react to collisions. Therefore, when they stopped moving, Newton didn't bother checking on them anymore.
However, this needed to work differently for a character which had to respond to user input... Newton had to check on it consistently. So I made this happen by adding the following when I created my character.The Newton Engine does not call the NewtonApplyForceAndTorque callback function for bodies that are inactive or have reached a state of stable equilibrium.
Code: Select all
NewtonBodySetAutoFreeze(body, 0);
NewtonWorldUnfreezeBody(nWorld, body);
Again, my thanks for your help.
You can use a upvector constraint for that, like this
I think the newton sdk has a character controller example somewhere.
Code: Select all
vector3df upDirection (0.0f, 1.0f, 0.0f);
UpVector = NewtonConstraintCreateUpVector (World, &upDirection.X, Body);
If you don't have anything nice to say, don't say anything at all.