a few changes to physics new root avatar position height estimation

LSLKeyTest
UbitUmarov 2015-12-22 00:06:17 +00:00
parent 88a63ecc39
commit 6437a94388
1 changed files with 61 additions and 18 deletions

View File

@ -1123,6 +1123,10 @@ namespace OpenSim.Region.Framework.Scenes
/// delays that crossing. /// delays that crossing.
/// </remarks> /// </remarks>
// constants for physics position search
const float PhysSearchHeight = 600f;
const float PhysMinSkipGap = 50f;
const int PhysNumberCollisions = 30;
// only in use as part of completemovement // only in use as part of completemovement
// other uses need fix // other uses need fix
@ -1219,42 +1223,81 @@ namespace OpenSim.Region.Framework.Scenes
pos.Y = m_scene.RegionInfo.RegionSizeY - 0.5f; pos.Y = m_scene.RegionInfo.RegionSizeY - 0.5f;
} }
float groundHeight = m_scene.GetGroundHeight(pos.X, pos.Y) + .01f;
float physTestHeight;
if(PhysSearchHeight < groundHeight + 100f)
physTestHeight = groundHeight + 100f;
else
physTestHeight = PhysSearchHeight;
float localAVHalfHeight = 0.8f;
if (Appearance != null && Appearance.AvatarHeight > 0)
localAVHalfHeight = 0.5f * Appearance.AvatarHeight;
groundHeight += localAVHalfHeight;
if (groundHeight > pos.Z)
pos.Z = groundHeight;
bool checkPhysics = !positionChanged && bool checkPhysics = !positionChanged &&
m_scene.SupportsRayCastFiltered() && m_scene.SupportsRayCastFiltered() &&
pos.Z < physTestHeight &&
((m_teleportFlags & (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)) == ((m_teleportFlags & (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)) ==
(TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID) (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)
|| (m_teleportFlags & TeleportFlags.ViaLocation) != 0 || (m_teleportFlags & TeleportFlags.ViaLocation) != 0
|| (m_teleportFlags & TeleportFlags.ViaHGLogin) != 0); || (m_teleportFlags & TeleportFlags.ViaHGLogin) != 0);
float localAVHeight = 1.56f;
if (Appearance.AvatarHeight > 0)
localAVHeight = Appearance.AvatarHeight;
float newPosZ = m_scene.GetGroundHeight(pos.X, pos.Y) + .01f;
newPosZ += 0.5f * localAVHeight;
if (newPosZ > pos.Z)
pos.Z = newPosZ;
if(checkPhysics) if(checkPhysics)
{ {
// land check was done above // land check was done above
RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull; RayFilterFlags rayfilter = RayFilterFlags.BackFaceCull;
rayfilter |= RayFilterFlags.physical; rayfilter |= RayFilterFlags.physical;
rayfilter |= RayFilterFlags.nonphysical; rayfilter |= RayFilterFlags.nonphysical;
rayfilter |= RayFilterFlags.LSLPhantom; // ubODE will only see volume detectors rayfilter |= RayFilterFlags.LSLPhantom; // ubODE will only see volume detectors
int physcount = 25;
float dist = 1024f; int physcount = PhysNumberCollisions;
Vector3 direction = new Vector3(0f,0f,-1f);
float dist = physTestHeight - groundHeight + localAVHalfHeight;
Vector3 direction = new Vector3(0f, 0f, -1f);
Vector3 RayStart = pos; Vector3 RayStart = pos;
RayStart.Z += dist; RayStart.Z = physTestHeight;
List<ContactResult> physresults = List<ContactResult> physresults =
(List<ContactResult>)m_scene.RayCastFiltered(RayStart, direction, dist, physcount, rayfilter); (List<ContactResult>)m_scene.RayCastFiltered(RayStart, direction, dist, physcount, rayfilter);
if (physresults != null && physresults.Count > 0) if (physresults != null && physresults.Count > 0)
{ {
float d = physresults[0].Pos.Z + 0.5f * localAVHeight; float dest = physresults[0].Pos.Z;
if(d > pos.Z)
pos.Z = d; if(physresults.Count > 1)
{
physresults.Sort(delegate(ContactResult a, ContactResult b)
{
return a.Depth.CompareTo(b.Depth);
});
int sel = 0;
int count = physresults.Count;
float curd = physresults[0].Depth;
float nextd = curd + PhysMinSkipGap;
float maxDepth = dist - pos.Z;
for(int i = 1; i < count; i++)
{
curd = physresults[i].Depth;
if(curd >= nextd)
{
sel = i;
if(curd >= maxDepth)
break;
}
nextd = curd + PhysMinSkipGap;
}
dest = physresults[sel].Pos.Z;
}
dest += localAVHalfHeight;
if(dest > pos.Z)
pos.Z = dest;
} }
} }