Many scripted items use long lists of llSetLinkPrimitiveParams rules to make prims "teleport" or jump large distances. When teleporting to 10,000 meters, this results in 1,000 SetPos calls, which severely rapes the physics and update system. This change modifies this behaviour to only provide one update after all the rules have been executed.

avinationmerge
Tom 2011-03-28 13:28:59 -07:00
parent f7276dda02
commit c39b391b6a
1 changed files with 43 additions and 9 deletions

View File

@ -2113,13 +2113,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
return end;
}
protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos)
{
if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
return;
return fromPos;
// Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos)
LSL_Vector currentPos = GetPartLocalPos(part);
float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
@ -2128,14 +2128,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
if ((targetPos.z < ground) && disable_underground_movement && m_host.AttachmentPoint == 0)
targetPos.z = ground;
}
LSL_Vector real_vec = SetPosAdjust(fromPos, targetPos);
return real_vec;
}
protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
{
if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
return;
LSL_Vector currentPos = GetPartLocalPos(part);
LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
if (part.ParentGroup.RootPart == part)
{
SceneObjectGroup parent = part.ParentGroup;
LSL_Vector real_vec = SetPosAdjust(currentPos, targetPos);
parent.UpdateGroupPosition(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z));
parent.UpdateGroupPosition(new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z));
}
else
{
LSL_Vector rel_vec = SetPosAdjust(new LSL_Vector(part.OffsetPosition.X, part.OffsetPosition.Y, part.OffsetPosition.Z), targetPos);
part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z);
part.OffsetPosition = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z);
SceneObjectGroup parent = part.ParentGroup;
parent.HasGroupChanged = true;
parent.ScheduleGroupForTerseUpdate();
@ -7401,6 +7415,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
int idx = 0;
bool positionChanged = false;
LSL_Vector currentPosition = GetPartLocalPos(part);
while (idx < rules.Length)
{
int code = rules.GetLSLIntegerItem(idx++);
@ -7409,7 +7426,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
int face;
LSL_Vector v;
switch (code)
{
case (int)ScriptBaseClass.PRIM_POSITION:
@ -7417,7 +7434,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
return;
v=rules.GetVector3Item(idx++);
SetPos(part, v);
positionChanged = true;
currentPosition = GetSetPosTarget(part, v, currentPosition);
break;
case (int)ScriptBaseClass.PRIM_SIZE:
@ -7785,6 +7803,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
break;
}
}
if (positionChanged)
{
if (part.ParentGroup.RootPart == part)
{
SceneObjectGroup parent = part.ParentGroup;
parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
}
else
{
part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z);
SceneObjectGroup parent = part.ParentGroup;
parent.HasGroupChanged = true;
parent.ScheduleGroupForTerseUpdate();
}
}
}
public LSL_String llStringToBase64(string str)