in MREUnityRuntimeLib/Core/Physics/PredictionInterpolation.cs [171:359]
public void PredictAllRemoteBodiesWithOwnedBodies(
ref SortedList<Guid, RigidBodyPhysicsBridgeInfo> allRigidBodiesOfThePhysicsBridge,
PredictionTimeParameters timeInfo)
{
// clear here all the monitoring since we will re add them
_monitorCollisionInfo.Clear();
#if MRE_PHYSICS_DEBUG
Debug.Log(" ===================== ");
#endif
// test collisions of each owned body with each not owned body
foreach (var rb in allRigidBodiesOfThePhysicsBridge.Values)
{
if (rb.Ownership)
{
// test here all the remote-owned collisions and those should be turned to dynamic again.
foreach (var remoteBodyInfo in _switchCollisionInfos)
{
var remoteBody = allRigidBodiesOfThePhysicsBridge[remoteBodyInfo.rigidBodyId].RigidBody;
// if this is key framed then also on the remote side it will stay key framed
if (remoteBodyInfo.isKeyframed)
{
continue;
}
var comDist = (remoteBody.transform.position - rb.RigidBody.transform.position).magnitude;
var remoteHitPoint = remoteBody.ClosestPointOnBounds(rb.RigidBody.transform.position);
var ownedHitPoint = rb.RigidBody.ClosestPointOnBounds(remoteBody.transform.position);
var remoteRelativeHitP = (remoteHitPoint - remoteBody.transform.position);
var ownedRelativeHitP = (ownedHitPoint - rb.RigidBody.transform.position);
var radiousRemote = radiusExpansionFactor * remoteRelativeHitP.magnitude;
var radiusOwnedBody = radiusExpansionFactor * ownedRelativeHitP.magnitude;
var totalDistance = radiousRemote + radiusOwnedBody + 0.0001f; // avoid division by zero
// project the linear velocity of the body
var projectedOwnedBodyPos = rb.RigidBody.transform.position + rb.RigidBody.velocity * timeInfo.DT;
var projectedComDist = (remoteBody.transform.position - projectedOwnedBodyPos).magnitude;
var collisionMonitorInfo = remoteBodyInfo.monitorInfo;
float lastApproxDistance = Math.Min(comDist, projectedComDist);
collisionMonitorInfo.relativeDistance = lastApproxDistance / totalDistance;
bool addToMonitor = false;
bool isWithinCollisionRange = (projectedComDist < totalDistance || comDist < totalDistance);
float timeSinceCollisionStart = collisionMonitorInfo.timeFromStartCollision;
bool isAlreadyInMonitor = _monitorCollisionInfo.ContainsKey(remoteBodyInfo.rigidBodyId);
#if MRE_PHYSICS_DEBUG
//if (remoteBodyInfo.isKeyframed)
{
Debug.Log("prprojectedComDistoj: " + projectedComDist + " comDist:" + comDist
+ " totalDistance:" + totalDistance + " remote body pos:" + remoteBodyInfo.startPosition.ToString()
+ "input lin vel:" + remoteBodyInfo.linearVelocity + " radiousRemote:" + radiousRemote +
" radiusOwnedBody:" + radiusOwnedBody + " relative dist:" + collisionMonitorInfo.relativeDistance
+ " timeSinceCollisionStart:" + timeSinceCollisionStart + " isAlreadyInMonitor:" + isAlreadyInMonitor);
}
#endif
// unconditionally add to the monitor stream if this is a reasonable collision and we are only at the beginning
if (collisionMonitorInfo.timeFromStartCollision > timeInfo.halfDT &&
timeSinceCollisionStart <= startInterpolatingBack &&
collisionMonitorInfo.relativeDistance < inCollisionRangeRelativeDistanceFactor)
{
#if MRE_PHYSICS_DEBUG
//if (remoteBodyInfo.isKeyframed)
{
Debug.Log(" unconditionally add to collision stream time:" + timeSinceCollisionStart +
" relative dist:" + collisionMonitorInfo.relativeDistance);
}
#endif
addToMonitor = true;
}
// switch over smoothly to the key framing
if (!addToMonitor &&
timeSinceCollisionStart > 5 * timeInfo.DT && // some basic check for lower limit
//(!isAlreadyInMonitor || collisionMonitorInfo.relativeDistance > 1.2f) && // if this is already added then ignore large values
timeSinceCollisionStart <= endInterpolatingBack)
{
addToMonitor = true;
float oldVal = collisionMonitorInfo.keyframedInterpolationRatio;
// we might enter here before startInterpolatingBack
timeSinceCollisionStart = Math.Max(timeSinceCollisionStart, startInterpolatingBack + timeInfo.DT);
// progress the interpolation
collisionMonitorInfo.keyframedInterpolationRatio =
invInterpolationTimeWindows * (timeSinceCollisionStart - startInterpolatingBack);
#if MRE_PHYSICS_DEBUG
Debug.Log(" doing interpolation new:" + collisionMonitorInfo.keyframedInterpolationRatio +
" old:" + oldVal + " relative distance:" + collisionMonitorInfo.relativeDistance);
#endif
// stop interpolation
if (collisionMonitorInfo.relativeDistance < collisionRelDistLimit
&& collisionMonitorInfo.keyframedInterpolationRatio > limitCollisionInterpolation)
{
#if MRE_PHYSICS_DEBUG
Debug.Log(" Stop interpolation time with DT:" + timeInfo.DT +
" Ratio:" + collisionMonitorInfo.keyframedInterpolationRatio +
" relDist:" + collisionMonitorInfo.relativeDistance +
" t=" + collisionMonitorInfo.timeFromStartCollision);
#endif
// --- this is a different way to drop the percentage for key framing ---
//collisionMonitorInfo.timeFromStartCollision -=
// Math.Min( 4.0f, ( (1.0f/limitCollisionInterpolation) * collisionMonitorInfo.keyframedInterpolationRatio) )* DT;
// this version just drops the percentage back to the limit
collisionMonitorInfo.timeFromStartCollision = startInterpolatingBack
+ limitCollisionInterpolation * (endInterpolatingBack - startInterpolatingBack);
collisionMonitorInfo.keyframedInterpolationRatio = limitCollisionInterpolation;
}
}
// we add to the collision stream either when it is within range or
if (isWithinCollisionRange || addToMonitor)
{
// add to the monitor stream
if (isAlreadyInMonitor)
{
// if there is existent collision already with this remote body, then build the minimum
var existingMonitorInfo = _monitorCollisionInfo[remoteBodyInfo.rigidBodyId];
#if MRE_PHYSICS_DEBUG
Debug.Log(" START merge collision info: " + remoteBodyInfo.rigidBodyId.ToString() +
" r:" + existingMonitorInfo.keyframedInterpolationRatio + " d:" + existingMonitorInfo.relativeDistance);
#endif
existingMonitorInfo.timeFromStartCollision =
Math.Min(existingMonitorInfo.timeFromStartCollision, collisionMonitorInfo.timeFromStartCollision);
existingMonitorInfo.relativeDistance =
Math.Min(existingMonitorInfo.relativeDistance, collisionMonitorInfo.relativeDistance);
existingMonitorInfo.keyframedInterpolationRatio =
Math.Min(existingMonitorInfo.keyframedInterpolationRatio, collisionMonitorInfo.keyframedInterpolationRatio);
collisionMonitorInfo = existingMonitorInfo;
#if MRE_PHYSICS_DEBUG
// <todo> check why is this working sometimes weired.
_monitorCollisionInfo[remoteBodyInfo.rigidBodyId] = collisionMonitorInfo;
existingMonitorInfo = _monitorCollisionInfo[remoteBodyInfo.rigidBodyId];
Debug.Log(" merge collision info: " + remoteBodyInfo.rigidBodyId.ToString() +
" r:" + existingMonitorInfo.keyframedInterpolationRatio + " d:" + existingMonitorInfo.relativeDistance);
#endif
}
else
{
_monitorCollisionInfo.Add(remoteBodyInfo.rigidBodyId, collisionMonitorInfo);
#if MRE_PHYSICS_DEBUG
//if (remoteBodyInfo.isKeyframed)
{
var existingMonitorInfo = _monitorCollisionInfo[remoteBodyInfo.rigidBodyId];
Debug.Log(" Add collision info: " + remoteBodyInfo.rigidBodyId.ToString() +
" r:" + existingMonitorInfo.keyframedInterpolationRatio + " d:" + existingMonitorInfo.relativeDistance);
}
#endif
}
// this is a new collision
if (collisionMonitorInfo.timeFromStartCollision < timeInfo.halfDT)
{
// switch back to dynamic
remoteBody.isKinematic = false;
remoteBody.transform.position = remoteBodyInfo.startPosition;
remoteBody.transform.rotation = remoteBodyInfo.startOrientation;
remoteBody.velocity = remoteBodyInfo.linearVelocity;
remoteBody.angularVelocity = remoteBodyInfo.angularVelocity;
#if MRE_PHYSICS_DEBUG
//if (remoteBodyInfo.isKeyframed)
{
Debug.Log(" remote body velocity SWITCH to collision: " + remoteBody.velocity.ToString()
+ " start position:" + remoteBody.transform.position.ToString()
+ " linVel:" + remoteBody.velocity + " angVel:" + remoteBody.angularVelocity);
}
#endif
}
else
{
#if MRE_PHYSICS_DEBUG
// this is a previous collision so do nothing just leave dynamic
Debug.Log(" remote body velocity stay in collision: " + remoteBody.velocity.ToString() +
" start position:" + remoteBody.transform.position.ToString() +
" relative dist:" + collisionMonitorInfo.relativeDistance +
" Ratio:" + collisionMonitorInfo.keyframedInterpolationRatio );
#endif
}
}
}
}
} // end for each
} // end of PredictAllRemoteBodiesWithOwnedBodies