line 7949:
static bool doSubdiv = true;
static float subdiv = 0.2f;
float moveDist = prevPos.Distance(moveTrans.Position());
if(doSubdiv && moveDist > (subdiv + 0.01f))
{
const Time backupVCT = _vegCollisionTime;
const bool backupHPC = _highPriorityContact;
const bool backupPPC = _purePersonContact;
const bool backupOC = _objectContact;
ManVisualState collTest(moveTrans);
int nextIter = 0;
int numIter = intMax((int)ceilf(moveDist / subdiv), 2);
Vector3 endPos = moveTrans.Position();
for(int n = 0; n < numIter; n++)
{
collTest.SetPosition(prevPos.Lerp(endPos, (float)n / (numIter - 1)));
const float collVol = ValidatePotentialState(collTest);
// revert any side-effects on member variables
_vegCollisionTime = backupVCT;
_highPriorityContact = backupHPC;
_purePersonContact = backupPPC;
_objectContact = backupOC;
if (collVol > 0.f)
{
break;
}
nextIter = n;
//if (GetNetworkManager().IsClient())
//{
// //CYAN - collision validation on each subdivision
// enf::Shape::CreateSphere(collTest.Position() + 2.f*VUp, 0.03f, 0xff00ccff, enf::SS_ONCE|enf::SS_NOOUTLINE);
//}
}
const int NUM_CLOSE_SUBDIVS = 2; //number of first subdivs considered close
const bool isClientOnly(!GetNetworkManager().IsServerOwner());
bool canTeleport(isClientOnly && (nextIter < NUM_CLOSE_SUBDIVS) && (numIter > NUM_CLOSE_SUBDIVS + 1));
if (canTeleport && !_local)
{
const Vector3 localMoveDir = endPos - FutureVisualState().Position();
const Vector3 remotePosDir = _lastRemotePos - FutureVisualState().Position();
const float projDist = localMoveDir.DotProduct(remotePosDir);
const float sqDistToLocalPos = localMoveDir.SquareSize();
const float sqDistToRemotePos = remotePosDir.SquareSize();
canTeleport = (projDist > 0.f) && (sqDistToLocalPos <= sqDistToRemotePos);
}
if (canTeleport)
{
//if collision place is very close, jump straight to the last position
nextIter = numIter - 1;
}
else if (nextIter < NUM_CLOSE_SUBDIVS)
{
//advance to the next subdivision so that movement can be repaired
nextIter = intMin(nextIter + 1, numIter - 1);
}
float const iterRatio = (float)nextIter / (numIter - 1);
DoAssert(iterRatio > 0.f); // always advance on next iteration
moveTrans.SetPosition(prevPos.Lerp(endPos, iterRatio));
doCollision(deltaT * iterRatio);
}