Physics bugs under -2000
Posted: Sun Feb 19, 2012 12:00 pm
Hi everyone,
I found a strange behavior for the physics of kickables objects, which also affects markers.
It might explains why dynamic objects appear to be floating somewhere in the Age on the next link-in, and why some markers in a few places can't be collected.
I was not sure if it has already been found, so I thought it might be a good idea to post this here.
Recently I found something strange in my Simulation.0.elf log file:This immediately reminded me of a bug Diafero found and posted on another thread and I'm sure it is related:
I found it in the file plPXPhysical.cpp:... this part of code seems to be executed each time the physics of an object have to move. This test...:...was added to make sure an object that fell from the collision area won't fall forever. If the object falls under 2000 units (even though it is still on a collider), it will freeze (I assume it from "IEnable(false)"), and should be restored to its default position upon next link-in, which unfortunately isn't the case as it's floating somewhere else (I remember cones being stuck under the canyon bridge in the city). The second problem is that it seems to affect every physical that can move (animated or warped, as Markers), which we don't want.
I don't know if it can be fixed, but if it could freeze the physics of only kickables objects it would be great.
I found a strange behavior for the physics of kickables objects, which also affects markers.
It might explains why dynamic objects appear to be floating somewhere in the Age on the next link-in, and why some markers in a few places can't be collected.
I was not sure if it has already been found, so I thought it might be a good idea to post this here.
Recently I found something strange in my Simulation.0.elf log file:
Code: Select all
Physical JumpBlocker loaded out of range state. Forcing initial state to server.
[others]
Physical JumpBlocker fell to -2014.5 (-2000.0 is the max). Suppressing.
As this sounded quite strange to me, I looked for "is the max)" in the MOULa C++ files.Diafero wrote:Hans recently showed me a bug which I could now reproduce and narrow down: It seems that if you create a marker mission and add a marker of which the z coordinate is below -2000, it is not possible to collect that marker. When you play the mission, you can see it, but when you go through it, nothing happens. The only age I found that goes so deep is Vaiskor 2. I found a mountain there where you can easily walk across this invisible border, and indeed from a bunch of markers I placed there, all the ones below -2000 where non-collectable (-2007 did not work, -1991 worked). This happens both online and offline. Does anyone have any idea what this could be caused by? 2000 does not sound like a number overflow, and besides, markers in the outer scene of Gahreesen (which is at z value +10000) work fine.
Is there an UU version of Vaiskor 2, so one could verify if this is POTS-specific?
I found it in the file plPXPhysical.cpp:
Code: Select all
void plPXPhysical::SendNewLocation(hsBool synchTransform, hsBool isSynchUpdate)
{
// we only send if:
// - the body is active or forceUpdate is on
// - the mass is non-zero
// - the physical is not passive
hsBool bodyActive = !fActor->isSleeping();
hsBool dynamic = fActor->isDynamic();
if ((bodyActive || isSynchUpdate) && dynamic)// && fInitialTransform)
{
plProfile_Inc(MaySendLocation);
if (!GetProperty(plSimulationInterface::kPassive))
{
hsMatrix44 curl2w = fCachedLocal2World;
// we're going to cache the transform before sending so we can recognize if it comes back
IGetTransformGlobal(fCachedLocal2World);
if (!CompareMatrices(curl2w, fCachedLocal2World, .0001f))
{
plProfile_Inc(LocationsSent);
plProfile_BeginLap(PhysicsUpdates, GetKeyName());
// quick peek at the translation...last time it was corrupted because we applied a non-unit quaternion
// hsAssert(real_finite(fCachedLocal2World.fMap[0][3]) &&
// real_finite(fCachedLocal2World.fMap[1][3]) &&
// real_finite(fCachedLocal2World.fMap[2][3]), "Bad transform outgoing");
if (fCachedLocal2World.GetTranslate().fZ < kMaxNegativeZPos)
{
SimLog("Physical %s fell to %.1f (%.1f is the max). Suppressing.", GetKeyName(), fCachedLocal2World.GetTranslate().fZ, kMaxNegativeZPos);
// Since this has probably been falling for a while, and thus not getting any syncs,
// make sure to save it's current pos so we'll know to reset it later
DirtySynchState(kSDLPhysical, plSynchedObject::kBCastToClients);
IEnable(false);
}
hsMatrix44 w2l;
fCachedLocal2World.GetInverse(&w2l);
plCorrectionMsg *pCorrMsg = TRACKED_NEW plCorrectionMsg(GetObjectKey(), fCachedLocal2World, w2l, synchTransform);
pCorrMsg->Send();
if (fProxyGen)
fProxyGen->SetTransform(fCachedLocal2World, w2l);
plProfile_EndLap(PhysicsUpdates, GetKeyName());
}
}
}
}
Code: Select all
if (fCachedLocal2World.GetTranslate().fZ < kMaxNegativeZPos) // kMaxNegativeZPos has a value of -2000.0
{
SimLog("Physical %s fell to %.1f (%.1f is the max). Suppressing.", GetKeyName(), fCachedLocal2World.GetTranslate().fZ, kMaxNegativeZPos);
// Since this has probably been falling for a while, and thus not getting any syncs,
// make sure to save it's current pos so we'll know to reset it later
DirtySynchState(kSDLPhysical, plSynchedObject::kBCastToClients);
IEnable(false);
}
I don't know if it can be fixed, but if it could freeze the physics of only kickables objects it would be great.