As an experiment I wanted to throw out any contacts that are generated with a impulse greater than a threshold, but the only function I can find to get the value of the normal impulse of a contact is "NewtonMaterialGetContactMaxNormalImpact" I'm not sure that's what I want because It says it is the "Max" impact. Basically I want to throw out contacts that have a high impact value so that the wheel jumps would be ignored. Better yet - instead of throwing out the contact, modifying the impact value to a lower value.
Julio, are these kind of functions possible - or do they even make sense to use?
that's not really possible with engines like newton, because contact are generated first then they are put together and the solver calculate the impulse.
anyway a couple of things on this problem.
This is a problem I have been struggling for many years and it is one more reason yet for not making rigid body cars using a rigid body solver.
the explanation is long for why this happen, but I can summarize like this.
-the wheel is a mall body that is sandwiched between two large bodies (the chassis and the ground)
-since the wheel is attached to the body with a spring joint along the vertical axis, this means that as the car and the wheel move horizontally they do not follow the same trajectory, the horizontal speed is the same but the vertical speed is different.
What happens is that for the chassis the motion appears to be small enough that any collision penetration in small relative to the body size.
To the wheel, she is moving with at least one contact touching the floor, for the most part, however each time the wheel loses that ground contact, now the solver see a body of small mass subjected to a very large force (the suspension) therefore in one step it acquire a very large velocity that make penetrate the ground by a significant value.
the higher the horizontal velocity the more likely the wheel trajectory diverge for the ground surface and it is inevitable that it will be air borne is some occasions.
basically it is a continue collision problem but along one direction of motion.
I have implemented many hacked solution over the years to combat this problem, one is the chamfered cylinder which is like a donought that generate only one contact, so the contact is almost always align to the wheel center. this solve the edge problem but not the airborne problem.
the only thing that can solve the airborne problem are all expensive and complicated.
1-continue collision (a bad idea for articulated bodies that move at high and low speed at the same time)
2-higher simulation rate (also a bad idea because the is a global setting)
3-a use define contact generation for generation for directional continue collision (this is the trick I am use now for the vehicle with mixed result)
for option 3 you can see how this is set up in the function
- Code: Select all
dCustomVehicleControllerManager::dCustomVehicleControllerManager(NewtonWorld* const world, int materialCount, int* const materialsList)
:dCustomControllerManager<dCustomVehicleController> (world, VEHICLE_PLUGIN_NAME)
,m_tireMaterial(NewtonMaterialCreateGroupID(world))
{
// create the normalized size tire shape
m_tireShapeTemplate = NewtonCreateChamferCylinder(world, 0.5f, 1.0f, 0, NULL);
m_tireShapeTemplateData = NewtonCollisionDataPointer(m_tireShapeTemplate);
// create a tire material and associate with the material the vehicle new to collide
for (int i = 0; i < materialCount; i ++) {
NewtonMaterialSetCallbackUserData (world, m_tireMaterial, materialsList[i], this);
if (m_tireMaterial != materialsList[i]) {
NewtonMaterialSetContactGenerationCallback (world, m_tireMaterial, materialsList[i], OnContactGeneration);
}
NewtonMaterialSetCollisionCallback(world, m_tireMaterial, materialsList[i], OnTireAabbOverlap, OnTireContactsProcess);
}
}
basically the vehicle implement this function,
void dCustomVehicleController::Collide(dWheelJoint* const tire, int threadIndex)
to calculate the tires collision at the beginning by using convex cast to determine if the tire will be airborne or not.
then it calculate the contacts and save them for each tire for later usage.
the contact callback simply look up the body and use the contacts generated by the vehicle.
it is like a ray cast but much better, because is a full collision.
this I found to be too complex, and when adding the other reasons why rigid body car are not a good idea, this is why I am making a new vehicle that is not raycast but that will do all these things by implementing an immediate mode physics solver that allow to do this things without tricking the generic solver.
here is something you can do to test is what I say is true or not, I am assuming you are running at 60 fps.
jack up the number of sub steps, say 4 or maybe 8, then you will see that the problem happen at higher vehicle speed, of course you can see why this is not a general solution.
My recommendation is that You and Dave be early adopters of the newer vehicle, It will be designed to cope with this issues, to be fast, accurate and fun to drive.
Because it will use the equations that govern vehicle dynamics which are some what more elaborated than simple right body physics.