Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 71 additions & 38 deletions OpenSim/Region/Framework/Scenes/ScenePresence.cs
Original file line number Diff line number Diff line change
Expand Up @@ -138,14 +138,17 @@ public class ScenePresence : EntityBase

private Vector3 m_LastFinitePos;

// experimentally determined "fudge factor" to make sit-target positions
// the same as in SecondLife. Fudge factor was tested for 36 different
// test cases including prims of type box, sphere, cylinder, and torus,
// with varying parameters for sit target location, prim size, prim
// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis
// issue #1716
private bool ADJUST_SIT_TARGET = true; // do it the old OpenSim way for content compatibility
private static readonly Vector3 m_sitTargetCorrectionOffset = new Vector3(0.1f, 0.0f, 0.3f);
// Experimentally determined "fudge factor" to make sit-target positions the same as in SecondLife.
private Vector3 m_sitTargetCorrectionPrimSpaceOffset;
private Vector3 m_sitTargetCorrectionAgentSpaceOffset;
private enum SitTargetCorrectionMode
{
None,
SecondLife,
Legacy,
}
private readonly SitTargetCorrectionMode m_sitTargetCorrectionMode;

private float m_godlevel;

private bool m_invulnerable = true;
Expand Down Expand Up @@ -999,6 +1002,34 @@ private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo)
if (m_connection != null) // can be null for bots which don't have a LLCV
m_connection.ScenePresence = this;

var simulatorFeaturesConfig = world.Config.Configs["SimulatorFeatures"];
var sitTargetSystem = simulatorFeaturesConfig.GetString("SitTargetCompatibilityMode", "SecondLife");
switch (sitTargetSystem.Trim().Replace(" ", "").ToLower())
{
case "legacy":
// experimentally determined "fudge factor" to make sit-target positions
// the same as in SecondLife. Fudge factor was tested for 36 different
// test cases including prims of type box, sphere, cylinder, and torus,
// with varying parameters for sit target location, prim size, prim
// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis
// issue #1716

// Note from much farther in the future: the offsets from where this came from looked nothing like SL...

m_sitTargetCorrectionPrimSpaceOffset = new Vector3(0.1f, 0.0f, 0.3f);
m_sitTargetCorrectionAgentSpaceOffset = new Vector3(0.0f, 0.0f, 0.0f);
m_sitTargetCorrectionMode = SitTargetCorrectionMode.Legacy;
break;
case "secondlife":
m_sitTargetCorrectionPrimSpaceOffset = new Vector3(0.0f, 0.0f, 0.4f);
m_sitTargetCorrectionAgentSpaceOffset = new Vector3(0.0f, 0.0f, -0.05f);
m_sitTargetCorrectionMode = SitTargetCorrectionMode.SecondLife;
break;
default:
m_sitTargetCorrectionMode = SitTargetCorrectionMode.None;
break;
}

// Prime (cache) the user's group list.
m_scene.UserGroupsGet(this.UUID);
}
Expand Down Expand Up @@ -1318,7 +1349,7 @@ private void ContinueSitAsRootAgent(IClientAPI client, SceneObjectPart part, Vec
if (m_avatarMovesWithPart)
{
Vector3 newPos = sitInfo.Offset;
newPos += m_sitTargetCorrectionOffset;
newPos += m_sitTargetCorrectionPrimSpaceOffset + m_sitTargetCorrectionAgentSpaceOffset * sitInfo.Rotation;
m_bodyRot = sitInfo.Rotation;
//Rotation = sitTargetOrient;
SetAgentPositionInfo(null, true, newPos, part, part.AbsolutePosition, Vector3.Zero);
Expand Down Expand Up @@ -1564,7 +1595,7 @@ public void CompleteMovement()
if (AvatarMovesWithPart && (m_requestedSitTargetID != 0))
{
// now make it all consistent with updated parent ID while inside the lock
SetAgentPositionInfo(null, true, m_sitTargetCorrectionOffset, parent, pos, m_velocity);
SetAgentPositionInfo(null, true, m_sitTargetCorrectionPrimSpaceOffset, parent, pos, m_velocity);
}
}
}
Expand Down Expand Up @@ -2338,7 +2369,7 @@ public void StandUp(bool fromCrossing, bool recheckGroupForAutoreturn)
{
m_log.ErrorFormat("[SCENE PRESENCE]: StandUp for {0} with parentID={1} NOT FOUND in scene. Recovering position.", this.Name, (info.Parent == null) ? 0 : info.Parent.LocalId);
// Recover, by emulating a default sit, for the code below.
info.Position = m_sitTargetCorrectionOffset + m_LastRegionPosition;
info.Position = m_sitTargetCorrectionPrimSpaceOffset + m_LastRegionPosition;
}
else
{
Expand Down Expand Up @@ -2446,7 +2477,7 @@ public void StandUp(bool fromCrossing, bool recheckGroupForAutoreturn)
{
// Can't find the prim they were on so put them back where they
// were with the sit target on the poseball set with the offset.
newpos = partPos - (info.Position - m_sitTargetCorrectionOffset);
newpos = partPos - (info.Position - m_sitTargetCorrectionPrimSpaceOffset);
}

// And let's assume that the sit pos is roughly at vertical center of the avatar, and that when standing,
Expand Down Expand Up @@ -2574,7 +2605,7 @@ private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 off
SceneObjectPart rootPart = part.ParentGroup.RootPart;
vParentID = rootPart.UUID; // parentID to send to viewer, always the root prim
vPos = Vector3.Zero; // viewer position of avatar relative to root prim
vRot = Quaternion.Identity; // viewer rotation of avatar relative to root prim
vRot = m_sitTargetCorrectionMode == SitTargetCorrectionMode.SecondLife ? rootPart.RotationOffset : Quaternion.Identity; // viewer rotation of avatar relative to root prim
avSitPos = Vector3.Zero;
avSitRot = rootPart.RotationOffset;

Expand All @@ -2584,24 +2615,25 @@ private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 off
avSitRot *= part.RotationOffset;
}

// Viewer seems to draw the avatar based on the hip position.
// If you don't include HipOffset (which is raising the avatar
// since it's normally negative), then the viewer will draw
// the avatar walking with toes underground/inside prim.
// Full updates were missing this, so a rebake would reproduce it.
// This adjustment gives the viewer the position it expects.
vPos.Z -= m_appearance.HipOffset;
if (m_sitTargetCorrectionMode == SitTargetCorrectionMode.Legacy)
{
// Viewer seems to draw the avatar based on the hip position.
// If you don't include HipOffset (which is raising the avatar
// since it's normally negative), then the viewer will draw
// the avatar walking with toes underground/inside prim.
// Full updates were missing this, so a rebake would reproduce it.
// This adjustment gives the viewer the position it expects.
vPos.Z -= m_appearance.HipOffset;
}

if (sitInfo.IsActive)
{
avSitPos += sitInfo.Offset;
if (ADJUST_SIT_TARGET)
avSitPos += sitInfo.Offset + m_sitTargetCorrectionPrimSpaceOffset + m_sitTargetCorrectionAgentSpaceOffset * sitInfo.Rotation;
avSitRot *= sitInfo.Rotation;
if (m_sitTargetCorrectionMode == SitTargetCorrectionMode.SecondLife)
{
// If we want to support previous IW sit target offsets, rather than SL-accurate sit targets,
// we need to apply the OpenSim sit target correction adjustment.
avSitPos += m_sitTargetCorrectionOffset;
vPos += sitInfo.Offset + m_sitTargetCorrectionPrimSpaceOffset + m_sitTargetCorrectionAgentSpaceOffset * sitInfo.Rotation;
}
avSitRot *= sitInfo.Rotation;
vRot *= sitInfo.Rotation;
}
else
Expand Down Expand Up @@ -3338,13 +3370,16 @@ public void RecalcVisualPosition(out Vector3 vPos, out Quaternion vRot, out uint
return;
}

// Viewer seems to draw the avatar based on the hip position.
// If you don't include HipOffset (which is raising the avatar
// since it's normally negative), then the viewer will draw
// the avatar walking with toes underground/inside prim.
// Full updates were missing this, so a rebake would reproduce it.
// This adjustment gives the viewer the position it expects.
vPos.Z -= m_appearance.HipOffset;
if (m_sitTargetCorrectionMode == SitTargetCorrectionMode.Legacy)
{
// Viewer seems to draw the avatar based on the hip position.
// If you don't include HipOffset (which is raising the avatar
// since it's normally negative), then the viewer will draw
// the avatar walking with toes underground/inside prim.
// Full updates were missing this, so a rebake would reproduce it.
// This adjustment gives the viewer the position it expects.
vPos.Z -= m_appearance.HipOffset;
}

// Actual rotation is rootPart.RotationOffset * part.RotationOffset * part.SitTargetOrientation
// but we need to specify it relative to the root prim.
Expand All @@ -3357,13 +3392,11 @@ public void RecalcVisualPosition(out Vector3 vPos, out Quaternion vRot, out uint
if (sitInfo.Offset != Vector3.Zero)
{
vPos = sitInfo.Offset; // start with the sit target position
vPos.Z -= m_appearance.HipOffset; // reapply correction
if (ADJUST_SIT_TARGET)
if (m_sitTargetCorrectionMode == SitTargetCorrectionMode.Legacy)
{
// If we want to support previous IW sit target offsets, rather than SL-accurate sit targets,
// we need to apply the OpenSim sit target correction adjustment.
vPos += m_sitTargetCorrectionOffset;
vPos.Z -= m_appearance.HipOffset; // reapply correction
}
vPos += m_sitTargetCorrectionPrimSpaceOffset + m_sitTargetCorrectionAgentSpaceOffset * sitInfo.Rotation;

if (part != rootPart) // sitting on a child prim
{
Expand Down
7 changes: 7 additions & 0 deletions bin/Halcyon.sample.ini
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,13 @@
; Are mesh-based objects allowed on this region?
;MeshEnabled=true

; Which sit target offset calculation to use.
; "SecondLife" (Match SL as of Second Life Server 18.11.09.521593 and possibly much earlier.)
; "Legacy" (Match the way Halcyon used it in InWorldz)
; All other values cause the simulator to use no offsets at all.
; Default is "SecondLife"
;SitTargetCompatibilityMode="SecondLife"

[ChatLogModule]
; Enable or disable the serverside chat logging module as a whole. Unless a
; backend is set this doesn't do much.
Expand Down