oh I see, there is a problem.
It is one of the way Newton 4 does the collision.
basically newton 4 does not has narrow phase collision, instead is uses the distance test between two shapes. this is the function:
void ndScene::CalculateContacts(ndInt32 threadIndex, ndContact* const contact)
you can see that when two bodies are close enough, the engine calculates the minimum distance between the two collision shapes. if the distance is small, it means they are colliding.
is not, them in each subsequent update, in does an upper bound calculation of how much that distance will be reduced in each step.
them, is the reduction is below some critical values, it recalculates the distance again.
it keeps doing that until the bodies move far apart, in which case the broad phase will destroy the contact joint, or they move closer that they are colliding.
this algorithm trade more pairs, for more parallel execution and few fewer expensive low level calls to collision that will report not contacts.
for this to work, the update needs tow thing:
1-the update needs a time step.
2-the bodies should have velocity.
both are easy to solve.
the first one, all we need to do is to make CollisionUpdate() take a time step.
the secund, we need the bodies to have a velocity.
but that is very easy, in your side, when you are going to teleport a body.
you can calculate the velocity of that body as follows.
- Code: Select all
body->veloc = (body->posit - desired position) / timestep
them the call to update with the time step like CollisionUpdate(timestep)
should do the trick.
right now, what is happing is that the code that decreases the time step, is not decreasing the distance, the code below. as you can see if m_timestep is zero, the distant is never reduced.
- Code: Select all
void ndScene::CalculateContacts(ndInt32 threadIndex, ndContact* const contact)
{
const ndUnsigned32 lru = m_lru - D_CONTACT_DELAY_FRAMES;
ndVector deltaTime(m_timestep);
ndBodyKinematic* const body0 = contact->GetBody0();
ndBodyKinematic* const body1 = contact->GetBody1();
dAssert(!contact->m_isDead);
if (!(body0->m_equilibrium & body1->m_equilibrium))
{
bool active = contact->IsActive();
if (ValidateContactCache(contact, deltaTime))
{
contact->m_sceneLru = m_lru;
contact->m_timeOfImpact = ndFloat32(1.0e10f);
}
else
{
contact->SetActive(false);
contact->m_positAcc = ndVector::m_zero;
contact->m_rotationAcc = ndQuaternion();
ndFloat32 distance = contact->m_separationDistance;
if (distance >= D_NARROW_PHASE_DIST)
{
[color=#FF0040] const ndVector veloc0(body0->GetVelocity());
const ndVector veloc1(body1->GetVelocity());
const ndVector veloc(veloc1 - veloc0);
const ndVector omega0(body0->GetOmega());
const ndVector omega1(body1->GetOmega());
const ndShapeInstance* const collision0 = &body0->GetCollisionShape();
const ndShapeInstance* const collision1 = &body1->GetCollisionShape();
const ndVector scale(ndFloat32(1.0f), ndFloat32(3.5f) * collision0->GetBoxMaxRadius(), ndFloat32(3.5f) * collision1->GetBoxMaxRadius(), ndFloat32(0.0f));
const ndVector velocMag2(veloc.DotProduct(veloc).GetScalar(), omega0.DotProduct(omega0).GetScalar(), omega1.DotProduct(omega1).GetScalar(), ndFloat32(0.0f));
const ndVector velocMag(velocMag2.GetMax(ndVector::m_epsilon).InvSqrt() * velocMag2 * scale);
const ndFloat32 speed = velocMag.AddHorizontal().GetScalar() + ndFloat32(0.5f);
distance -= speed * m_timestep;
contact->m_separationDistance = distance;
}
if (distance < D_NARROW_PHASE_DIST)
[/color] {
CalculateJointContacts(threadIndex, contact);
as you can see, you can see that this new algorithm is very cost effective, is we have a scene when the objects are slow moving, then distance reduces very slowly and very few collisions call are made.
but if we have fast moving bodies, them they do more collisions as they should.
basically, it adapts to the scene, and is also deal naturally with continue collisions.
but as I expect there will be some tunning.
let us do this, you do the step two, setting the body velocities when teleporting, and I will do the Collision Update. for this I need to check in few places where the time step is use.