mirror of
https://github.com/opensim/opensim.git
synced 2026-08-04 16:22:50 +08:00
Merge branch 'master' of ssh://opensimulator.org/var/git/opensim
This commit is contained in:
@@ -14,6 +14,9 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||
string GetUserHomeURL(UUID uuid);
|
||||
string GetUserUUI(UUID uuid);
|
||||
string GetUserServerURL(UUID uuid, string serverType);
|
||||
int GetUserFlags(UUID userID);
|
||||
int GetUserCreated(UUID userID);
|
||||
string GetUserTitle(UUID userID);
|
||||
|
||||
/// <summary>
|
||||
/// Add a user.
|
||||
@@ -48,5 +51,7 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||
/// <param name="firstName"></param>
|
||||
/// <param name="profileURL"></param>
|
||||
void AddUser(UUID uuid, string firstName, string lastName, string profileURL);
|
||||
|
||||
bool IsLocalGridUser(UUID uuid);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,7 +77,15 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// Controls whether physics can be applied to prims. Even if false, prims still have entries in a
|
||||
/// PhysicsScene in order to perform collision detection
|
||||
/// </summary>
|
||||
public bool m_physicalPrim;
|
||||
public bool PhysicalPrims { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Controls whether prims can be collided with.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If this is set to false then prims cannot be subject to physics either.
|
||||
/// </summary>
|
||||
public bool CollidablePrims { get; private set; }
|
||||
|
||||
public float m_maxNonphys = 256;
|
||||
public float m_maxPhys = 10;
|
||||
@@ -650,7 +658,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
//Animation states
|
||||
m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false);
|
||||
|
||||
m_physicalPrim = startupConfig.GetBoolean("physical_prim", true);
|
||||
PhysicalPrims = startupConfig.GetBoolean("physical_prim", true);
|
||||
CollidablePrims = startupConfig.GetBoolean("collidable_prim", true);
|
||||
|
||||
m_maxNonphys = startupConfig.GetFloat("NonPhysicalPrimMax", m_maxNonphys);
|
||||
if (RegionInfo.NonphysPrimMax > 0)
|
||||
@@ -701,7 +710,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
if (maptileRefresh != 0)
|
||||
{
|
||||
m_mapGenerationTimer.Interval = maptileRefresh * 1000;
|
||||
m_mapGenerationTimer.Elapsed += RegenerateMaptile;
|
||||
m_mapGenerationTimer.Elapsed += RegenerateMaptileAndReregister;
|
||||
m_mapGenerationTimer.AutoReset = true;
|
||||
m_mapGenerationTimer.Start();
|
||||
}
|
||||
@@ -1638,21 +1647,17 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
m_sceneGridService.SetScene(this);
|
||||
|
||||
//// Unfortunately this needs to be here and it can't be async.
|
||||
//// The map tile image is stored in RegionSettings, but it also needs to be
|
||||
//// stored in the GridService, because that's what the world map module uses
|
||||
//// to send the map image UUIDs (of other regions) to the viewer...
|
||||
if (m_generateMaptiles)
|
||||
RegenerateMaptile();
|
||||
|
||||
GridRegion region = new GridRegion(RegionInfo);
|
||||
string error = GridService.RegisterRegion(RegionInfo.ScopeID, region);
|
||||
if (error != String.Empty)
|
||||
{
|
||||
throw new Exception(error);
|
||||
}
|
||||
|
||||
// Generate the maptile asynchronously, because sometimes it can be very slow and we
|
||||
// don't want this to delay starting the region.
|
||||
if (m_generateMaptiles)
|
||||
{
|
||||
Util.FireAndForget(delegate {
|
||||
RegenerateMaptile(null, null);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -5023,13 +5028,24 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
public void RegenerateMaptile(object sender, ElapsedEventArgs e)
|
||||
private void RegenerateMaptile()
|
||||
{
|
||||
IWorldMapModule mapModule = RequestModuleInterface<IWorldMapModule>();
|
||||
if (mapModule != null)
|
||||
mapModule.GenerateMaptile();
|
||||
}
|
||||
|
||||
private void RegenerateMaptileAndReregister(object sender, ElapsedEventArgs e)
|
||||
{
|
||||
RegenerateMaptile();
|
||||
|
||||
// We need to propagate the new image UUID to the grid service
|
||||
// so that all simulators can retrieve it
|
||||
string error = GridService.RegisterRegion(RegionInfo.ScopeID, new GridRegion(RegionInfo));
|
||||
if (error != string.Empty)
|
||||
throw new Exception(error);
|
||||
}
|
||||
|
||||
// This method is called across the simulation connector to
|
||||
// determine if a given agent is allowed in this region
|
||||
// AS A ROOT AGENT. Returning false here will prevent them
|
||||
|
||||
@@ -333,7 +333,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
if (rot != null)
|
||||
sceneObject.UpdateGroupRotationR((Quaternion)rot);
|
||||
|
||||
//group.ApplyPhysics(m_physicalPrim);
|
||||
if (sceneObject.RootPart.PhysActor != null && sceneObject.RootPart.PhysActor.IsPhysical && vel != Vector3.Zero)
|
||||
{
|
||||
sceneObject.RootPart.ApplyImpulse((vel * sceneObject.GetMass()), false);
|
||||
|
||||
@@ -210,7 +210,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// </remarks>
|
||||
public bool UsesPhysics
|
||||
{
|
||||
get { return (RootPart.Flags & PrimFlags.TemporaryOnRez) != 0; }
|
||||
get { return (RootPart.Flags & PrimFlags.Physics) != 0; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -669,7 +669,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
//m_log.DebugFormat("[SCENE]: Given local id {0} to part {1}, linknum {2}, parent {3} {4}", part.LocalId, part.UUID, part.LinkNum, part.ParentID, part.ParentUUID);
|
||||
}
|
||||
|
||||
ApplyPhysics(m_scene.m_physicalPrim);
|
||||
ApplyPhysics();
|
||||
|
||||
// Don't trigger the update here - otherwise some client issues occur when multiple updates are scheduled
|
||||
// for the same object with very different properties. The caller must schedule the update.
|
||||
@@ -1239,8 +1239,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// <summary>
|
||||
/// Apply physics to this group
|
||||
/// </summary>
|
||||
/// <param name="m_physicalPrim"></param>
|
||||
public void ApplyPhysics(bool m_physicalPrim)
|
||||
public void ApplyPhysics()
|
||||
{
|
||||
// Apply physics to the root prim
|
||||
m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive);
|
||||
|
||||
@@ -1473,6 +1473,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// <param name="VolumeDetectActive"></param>
|
||||
public void ApplyPhysics(uint rootObjectFlags, bool VolumeDetectActive)
|
||||
{
|
||||
if (!ParentGroup.Scene.CollidablePrims)
|
||||
return;
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[SCENE OBJECT PART]: Applying physics to {0} {1}, m_physicalPrim {2}",
|
||||
// Name, LocalId, UUID, m_physicalPrim);
|
||||
@@ -1739,7 +1742,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// <param name="isNew"></param>
|
||||
public void DoPhysicsPropertyUpdate(bool UsePhysics, bool isNew)
|
||||
{
|
||||
if (!ParentGroup.Scene.m_physicalPrim && UsePhysics)
|
||||
if (!ParentGroup.Scene.PhysicalPrims && UsePhysics)
|
||||
return;
|
||||
|
||||
if (IsJoint())
|
||||
@@ -4318,7 +4321,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
if (ParentGroup.Scene == null)
|
||||
return;
|
||||
|
||||
if (PhysActor == null)
|
||||
if (ParentGroup.Scene.CollidablePrims && PhysActor == null)
|
||||
{
|
||||
// It's not phantom anymore. So make sure the physics engine get's knowledge of it
|
||||
PhysActor = ParentGroup.Scene.PhysicsScene.AddPrimShape(
|
||||
|
||||
@@ -118,7 +118,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// TODO: For some reason, we effectively have a list both here and in Appearance. Need to work out if this is
|
||||
/// necessary.
|
||||
/// </remarks>
|
||||
protected List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>();
|
||||
private List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>();
|
||||
|
||||
public Object AttachmentsSyncLock { get; private set; }
|
||||
|
||||
@@ -550,8 +550,12 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
}
|
||||
|
||||
m_pos = value;
|
||||
ParentPosition = Vector3.Zero;
|
||||
// Don't update while sitting
|
||||
if (ParentID == 0)
|
||||
{
|
||||
m_pos = value;
|
||||
ParentPosition = Vector3.Zero;
|
||||
}
|
||||
|
||||
//m_log.DebugFormat(
|
||||
// "[ENTITY BASE]: In {0} set AbsolutePosition of {1} to {2}",
|
||||
@@ -566,6 +570,15 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
public Vector3 OffsetPosition
|
||||
{
|
||||
get { return m_pos; }
|
||||
// Don't remove setter. It's not currently used in core but
|
||||
// upcoming Avination code needs it.
|
||||
set
|
||||
{
|
||||
// There is no offset position when not seated
|
||||
if (ParentID == 0)
|
||||
return;
|
||||
m_pos = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1161,10 +1174,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
public void CompleteMovement(IClientAPI client, bool openChildAgents)
|
||||
{
|
||||
// DateTime startTime = DateTime.Now;
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[SCENE PRESENCE]: Completing movement of {0} into region {1}",
|
||||
// client.Name, Scene.RegionInfo.RegionName);
|
||||
|
||||
m_log.DebugFormat(
|
||||
"[SCENE PRESENCE]: Completing movement of {0} into region {1} in position {2}",
|
||||
client.Name, Scene.RegionInfo.RegionName, AbsolutePosition);
|
||||
|
||||
Vector3 look = Velocity;
|
||||
if ((look.X == 0) && (look.Y == 0) && (look.Z == 0))
|
||||
@@ -2383,9 +2396,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
m_lastVelocity = Velocity;
|
||||
}
|
||||
|
||||
// followed suggestion from mic bowman. reversed the two lines below.
|
||||
if (ParentID == 0 && PhysicsActor != null || ParentID != 0) // Check that we have a physics actor or we're sitting on something
|
||||
CheckForBorderCrossing();
|
||||
CheckForBorderCrossing();
|
||||
|
||||
CheckForSignificantMovement(); // sends update to the modules.
|
||||
}
|
||||
@@ -2738,143 +2749,146 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// </remarks>
|
||||
protected void CheckForBorderCrossing()
|
||||
{
|
||||
if (IsChildAgent)
|
||||
// Check that we we are not a child
|
||||
if (IsChildAgent)
|
||||
return;
|
||||
|
||||
Vector3 pos2 = AbsolutePosition;
|
||||
Vector3 vel = Velocity;
|
||||
int neighbor = 0;
|
||||
int[] fix = new int[2];
|
||||
|
||||
float timeStep = 0.1f;
|
||||
pos2.X = pos2.X + (vel.X*timeStep);
|
||||
pos2.Y = pos2.Y + (vel.Y*timeStep);
|
||||
pos2.Z = pos2.Z + (vel.Z*timeStep);
|
||||
// If we don't have a PhysActor, we can't cross anyway
|
||||
// Also don't do this while sat, sitting avatars cross with the
|
||||
// object they sit on.
|
||||
if (ParentID != 0 || PhysicsActor == null)
|
||||
return;
|
||||
|
||||
if (!IsInTransit)
|
||||
{
|
||||
// Checks if where it's headed exists a region
|
||||
Vector3 pos2 = AbsolutePosition;
|
||||
Vector3 vel = Velocity;
|
||||
int neighbor = 0;
|
||||
int[] fix = new int[2];
|
||||
|
||||
bool needsTransit = false;
|
||||
if (m_scene.TestBorderCross(pos2, Cardinals.W))
|
||||
{
|
||||
if (m_scene.TestBorderCross(pos2, Cardinals.S))
|
||||
{
|
||||
needsTransit = true;
|
||||
neighbor = m_scene.HaveNeighbor(Cardinals.SW, ref fix);
|
||||
}
|
||||
else if (m_scene.TestBorderCross(pos2, Cardinals.N))
|
||||
{
|
||||
needsTransit = true;
|
||||
neighbor = m_scene.HaveNeighbor(Cardinals.NW, ref fix);
|
||||
}
|
||||
else
|
||||
{
|
||||
needsTransit = true;
|
||||
neighbor = m_scene.HaveNeighbor(Cardinals.W, ref fix);
|
||||
}
|
||||
}
|
||||
else if (m_scene.TestBorderCross(pos2, Cardinals.E))
|
||||
{
|
||||
if (m_scene.TestBorderCross(pos2, Cardinals.S))
|
||||
{
|
||||
needsTransit = true;
|
||||
neighbor = m_scene.HaveNeighbor(Cardinals.SE, ref fix);
|
||||
}
|
||||
else if (m_scene.TestBorderCross(pos2, Cardinals.N))
|
||||
{
|
||||
needsTransit = true;
|
||||
neighbor = m_scene.HaveNeighbor(Cardinals.NE, ref fix);
|
||||
}
|
||||
else
|
||||
{
|
||||
needsTransit = true;
|
||||
neighbor = m_scene.HaveNeighbor(Cardinals.E, ref fix);
|
||||
}
|
||||
}
|
||||
else if (m_scene.TestBorderCross(pos2, Cardinals.S))
|
||||
{
|
||||
needsTransit = true;
|
||||
neighbor = m_scene.HaveNeighbor(Cardinals.S, ref fix);
|
||||
}
|
||||
else if (m_scene.TestBorderCross(pos2, Cardinals.N))
|
||||
{
|
||||
needsTransit = true;
|
||||
neighbor = m_scene.HaveNeighbor(Cardinals.N, ref fix);
|
||||
}
|
||||
|
||||
// Makes sure avatar does not end up outside region
|
||||
if (neighbor <= 0)
|
||||
{
|
||||
if (needsTransit)
|
||||
{
|
||||
if (m_requestedSitTargetUUID == UUID.Zero)
|
||||
{
|
||||
bool isFlying = Flying;
|
||||
RemoveFromPhysicalScene();
|
||||
|
||||
Vector3 pos = AbsolutePosition;
|
||||
if (AbsolutePosition.X < 0)
|
||||
pos.X += Velocity.X * 2;
|
||||
else if (AbsolutePosition.X > Constants.RegionSize)
|
||||
pos.X -= Velocity.X * 2;
|
||||
if (AbsolutePosition.Y < 0)
|
||||
pos.Y += Velocity.Y * 2;
|
||||
else if (AbsolutePosition.Y > Constants.RegionSize)
|
||||
pos.Y -= Velocity.Y * 2;
|
||||
Velocity = Vector3.Zero;
|
||||
AbsolutePosition = pos;
|
||||
|
||||
// m_log.DebugFormat("[SCENE PRESENCE]: Prevented flyoff for {0} at {1}", Name, AbsolutePosition);
|
||||
|
||||
AddToPhysicalScene(isFlying);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (neighbor > 0)
|
||||
{
|
||||
if (!CrossToNewRegion())
|
||||
{
|
||||
if (m_requestedSitTargetUUID == UUID.Zero)
|
||||
{
|
||||
bool isFlying = Flying;
|
||||
RemoveFromPhysicalScene();
|
||||
|
||||
Vector3 pos = AbsolutePosition;
|
||||
if (AbsolutePosition.X < 0)
|
||||
pos.X += Velocity.X * 2;
|
||||
else if (AbsolutePosition.X > Constants.RegionSize)
|
||||
pos.X -= Velocity.X * 2;
|
||||
if (AbsolutePosition.Y < 0)
|
||||
pos.Y += Velocity.Y * 2;
|
||||
else if (AbsolutePosition.Y > Constants.RegionSize)
|
||||
pos.Y -= Velocity.Y * 2;
|
||||
Velocity = Vector3.Zero;
|
||||
AbsolutePosition = pos;
|
||||
|
||||
AddToPhysicalScene(isFlying);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// We must remove the agent from the physical scene if it has been placed in transit. If we don't,
|
||||
// then this method continues to be called from ScenePresence.Update() until the handover of the client between
|
||||
// regions is completed. Since this handover can take more than 1000ms (due to the 1000ms
|
||||
// event queue polling response from the server), this results in the avatar pausing on the border
|
||||
// for the handover period.
|
||||
RemoveFromPhysicalScene();
|
||||
|
||||
// This constant has been inferred from experimentation
|
||||
// I'm not sure what this value should be, so I tried a few values.
|
||||
timeStep = 0.04f;
|
||||
pos2 = AbsolutePosition;
|
||||
float timeStep = 0.1f;
|
||||
pos2.X = pos2.X + (vel.X * timeStep);
|
||||
pos2.Y = pos2.Y + (vel.Y * timeStep);
|
||||
pos2.Z = pos2.Z + (vel.Z * timeStep);
|
||||
m_pos = pos2;
|
||||
}
|
||||
|
||||
if (!IsInTransit)
|
||||
{
|
||||
// Checks if where it's headed exists a region
|
||||
bool needsTransit = false;
|
||||
if (m_scene.TestBorderCross(pos2, Cardinals.W))
|
||||
{
|
||||
if (m_scene.TestBorderCross(pos2, Cardinals.S))
|
||||
{
|
||||
needsTransit = true;
|
||||
neighbor = m_scene.HaveNeighbor(Cardinals.SW, ref fix);
|
||||
}
|
||||
else if (m_scene.TestBorderCross(pos2, Cardinals.N))
|
||||
{
|
||||
needsTransit = true;
|
||||
neighbor = m_scene.HaveNeighbor(Cardinals.NW, ref fix);
|
||||
}
|
||||
else
|
||||
{
|
||||
needsTransit = true;
|
||||
neighbor = m_scene.HaveNeighbor(Cardinals.W, ref fix);
|
||||
}
|
||||
}
|
||||
else if (m_scene.TestBorderCross(pos2, Cardinals.E))
|
||||
{
|
||||
if (m_scene.TestBorderCross(pos2, Cardinals.S))
|
||||
{
|
||||
needsTransit = true;
|
||||
neighbor = m_scene.HaveNeighbor(Cardinals.SE, ref fix);
|
||||
}
|
||||
else if (m_scene.TestBorderCross(pos2, Cardinals.N))
|
||||
{
|
||||
needsTransit = true;
|
||||
neighbor = m_scene.HaveNeighbor(Cardinals.NE, ref fix);
|
||||
}
|
||||
else
|
||||
{
|
||||
needsTransit = true;
|
||||
neighbor = m_scene.HaveNeighbor(Cardinals.E, ref fix);
|
||||
}
|
||||
}
|
||||
else if (m_scene.TestBorderCross(pos2, Cardinals.S))
|
||||
{
|
||||
needsTransit = true;
|
||||
neighbor = m_scene.HaveNeighbor(Cardinals.S, ref fix);
|
||||
}
|
||||
else if (m_scene.TestBorderCross(pos2, Cardinals.N))
|
||||
{
|
||||
needsTransit = true;
|
||||
neighbor = m_scene.HaveNeighbor(Cardinals.N, ref fix);
|
||||
}
|
||||
|
||||
// Makes sure avatar does not end up outside region
|
||||
if (neighbor <= 0)
|
||||
{
|
||||
if (needsTransit)
|
||||
{
|
||||
if (m_requestedSitTargetUUID == UUID.Zero)
|
||||
{
|
||||
bool isFlying = Flying;
|
||||
RemoveFromPhysicalScene();
|
||||
|
||||
Vector3 pos = AbsolutePosition;
|
||||
if (AbsolutePosition.X < 0)
|
||||
pos.X += Velocity.X * 2;
|
||||
else if (AbsolutePosition.X > Constants.RegionSize)
|
||||
pos.X -= Velocity.X * 2;
|
||||
if (AbsolutePosition.Y < 0)
|
||||
pos.Y += Velocity.Y * 2;
|
||||
else if (AbsolutePosition.Y > Constants.RegionSize)
|
||||
pos.Y -= Velocity.Y * 2;
|
||||
Velocity = Vector3.Zero;
|
||||
AbsolutePosition = pos;
|
||||
|
||||
// m_log.DebugFormat("[SCENE PRESENCE]: Prevented flyoff for {0} at {1}", Name, AbsolutePosition);
|
||||
|
||||
AddToPhysicalScene(isFlying);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (neighbor > 0)
|
||||
{
|
||||
if (!CrossToNewRegion())
|
||||
{
|
||||
if (m_requestedSitTargetUUID == UUID.Zero)
|
||||
{
|
||||
bool isFlying = Flying;
|
||||
RemoveFromPhysicalScene();
|
||||
|
||||
Vector3 pos = AbsolutePosition;
|
||||
if (AbsolutePosition.X < 0)
|
||||
pos.X += Velocity.X * 2;
|
||||
else if (AbsolutePosition.X > Constants.RegionSize)
|
||||
pos.X -= Velocity.X * 2;
|
||||
if (AbsolutePosition.Y < 0)
|
||||
pos.Y += Velocity.Y * 2;
|
||||
else if (AbsolutePosition.Y > Constants.RegionSize)
|
||||
pos.Y -= Velocity.Y * 2;
|
||||
Velocity = Vector3.Zero;
|
||||
AbsolutePosition = pos;
|
||||
|
||||
AddToPhysicalScene(isFlying);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// This constant has been inferred from experimentation
|
||||
// I'm not sure what this value should be, so I tried a few values.
|
||||
timeStep = 0.04f;
|
||||
pos2 = AbsolutePosition;
|
||||
pos2.X = pos2.X + (vel.X * timeStep);
|
||||
pos2.Y = pos2.Y + (vel.Y * timeStep);
|
||||
// Don't touch the Z
|
||||
m_pos = pos2;
|
||||
m_log.DebugFormat("[SCENE PRESENCE]: In transit m_pos={0}", m_pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -3104,30 +3118,28 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
catch { }
|
||||
|
||||
// Attachment objects
|
||||
lock (m_attachments)
|
||||
List<SceneObjectGroup> attachments = GetAttachments();
|
||||
if (attachments.Count > 0)
|
||||
{
|
||||
if (m_attachments.Count > 0)
|
||||
{
|
||||
cAgent.AttachmentObjects = new List<ISceneObject>();
|
||||
cAgent.AttachmentObjectStates = new List<string>();
|
||||
// IScriptModule se = m_scene.RequestModuleInterface<IScriptModule>();
|
||||
InTransitScriptStates.Clear();
|
||||
cAgent.AttachmentObjects = new List<ISceneObject>();
|
||||
cAgent.AttachmentObjectStates = new List<string>();
|
||||
// IScriptModule se = m_scene.RequestModuleInterface<IScriptModule>();
|
||||
InTransitScriptStates.Clear();
|
||||
|
||||
foreach (SceneObjectGroup sog in m_attachments)
|
||||
{
|
||||
// We need to make a copy and pass that copy
|
||||
// because of transfers withn the same sim
|
||||
ISceneObject clone = sog.CloneForNewScene();
|
||||
// Attachment module assumes that GroupPosition holds the offsets...!
|
||||
((SceneObjectGroup)clone).RootPart.GroupPosition = sog.RootPart.AttachedPos;
|
||||
((SceneObjectGroup)clone).IsAttachment = false;
|
||||
cAgent.AttachmentObjects.Add(clone);
|
||||
string state = sog.GetStateSnapshot();
|
||||
cAgent.AttachmentObjectStates.Add(state);
|
||||
InTransitScriptStates.Add(state);
|
||||
// Let's remove the scripts of the original object here
|
||||
sog.RemoveScriptInstances(true);
|
||||
}
|
||||
foreach (SceneObjectGroup sog in attachments)
|
||||
{
|
||||
// We need to make a copy and pass that copy
|
||||
// because of transfers withn the same sim
|
||||
ISceneObject clone = sog.CloneForNewScene();
|
||||
// Attachment module assumes that GroupPosition holds the offsets...!
|
||||
((SceneObjectGroup)clone).RootPart.GroupPosition = sog.RootPart.AttachedPos;
|
||||
((SceneObjectGroup)clone).IsAttachment = false;
|
||||
cAgent.AttachmentObjects.Add(clone);
|
||||
string state = sog.GetStateSnapshot();
|
||||
cAgent.AttachmentObjectStates.Add(state);
|
||||
InTransitScriptStates.Add(state);
|
||||
// Let's remove the scripts of the original object here
|
||||
sog.RemoveScriptInstances(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3535,26 +3547,29 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// <param name="args">The arguments for the event</param>
|
||||
public void SendScriptEventToAttachments(string eventName, Object[] args)
|
||||
{
|
||||
if (m_scriptEngines.Length == 0)
|
||||
return;
|
||||
|
||||
lock (m_attachments)
|
||||
Util.FireAndForget(delegate(object x)
|
||||
{
|
||||
foreach (SceneObjectGroup grp in m_attachments)
|
||||
{
|
||||
// 16384 is CHANGED_ANIMATION
|
||||
//
|
||||
// Send this to all attachment root prims
|
||||
//
|
||||
foreach (IScriptModule m in m_scriptEngines)
|
||||
{
|
||||
if (m == null) // No script engine loaded
|
||||
continue;
|
||||
if (m_scriptEngines.Length == 0)
|
||||
return;
|
||||
|
||||
m.PostObjectEvent(grp.RootPart.UUID, "changed", new Object[] { (int)Changed.ANIMATION });
|
||||
lock (m_attachments)
|
||||
{
|
||||
foreach (SceneObjectGroup grp in m_attachments)
|
||||
{
|
||||
// 16384 is CHANGED_ANIMATION
|
||||
//
|
||||
// Send this to all attachment root prims
|
||||
//
|
||||
foreach (IScriptModule m in m_scriptEngines)
|
||||
{
|
||||
if (m == null) // No script engine loaded
|
||||
continue;
|
||||
|
||||
m.PostObjectEvent(grp.RootPart.UUID, "changed", new Object[] { (int)Changed.ANIMATION });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
internal void PushForce(Vector3 impulse)
|
||||
|
||||
Reference in New Issue
Block a user