diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
index a0ff151a92..22c89370a7 100644
--- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
@@ -110,7 +110,6 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
// client.OnAvatarNowWearing -= AvatarIsWearing;
}
-
public void SetAppearanceAssets(UUID userID, ref AvatarAppearance appearance)
{
IInventoryService invService = m_scene.InventoryService;
@@ -134,7 +133,10 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
}
else
{
- m_log.ErrorFormat("[APPEARANCE]: Can't find inventory item {0}, setting to default", appearance.Wearables[i].ItemID);
+ m_log.ErrorFormat(
+ "[APPEARANCE]: Can't find inventory item {0} for {1}, setting to default",
+ appearance.Wearables[i].ItemID, (WearableType)i);
+
appearance.Wearables[i].AssetID = def.Wearables[i].AssetID;
}
}
diff --git a/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs b/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs
index abcaf917bb..c289cdbaf6 100644
--- a/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs
+++ b/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs
@@ -43,10 +43,67 @@ namespace OpenSim.Region.Framework.Interfaces
int updateTimer, bool SetBlending, int disp, byte AlphaValue, int face);
UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data, string extraParams,
int updateTimer);
+
+ /// Apply a dynamically generated texture to all sides of the given prim. The texture is not persisted to the
+ /// asset service.
+ ///
+ /// The simulator in which the texture is being generated
+ /// The prim to which to apply the texture.
+ /// The content type to create. Current choices are "vector" to create a vector
+ /// based texture or "image" to create a texture from an image at a particular URL
+ /// The data for the generator
+ /// Parameters for the generator that don't form part of the main data.
+ /// If zero, the image is never updated after the first generation. If positive
+ /// the image is updated at the given interval. Not implemented for
+ ///
+ /// If true, the newly generated texture is blended with the appropriate existing ones on the prim
+ ///
+ ///
+ /// The alpha value of the generated texture.
+ ///
+ ///
+ /// The UUID of the texture updater, not the texture UUID. If you need the texture UUID then you will need
+ /// to obtain it directly from the SceneObjectPart. For instance, if ALL_SIDES is set then this texture
+ /// can be obtained as SceneObjectPart.Shape.Textures.DefaultTexture.TextureID
+ ///
UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data, string extraParams,
int updateTimer, bool SetBlending, byte AlphaValue);
- UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data, string extraParams,
- int updateTimer, bool SetBlending, int disp, byte AlphaValue, int face);
+
+ ///
+ /// Apply a dynamically generated texture to the given prim.
+ ///
+ /// The simulator in which the texture is being generated
+ /// The prim to which to apply the texture.
+ /// The content type to create. Current choices are "vector" to create a vector
+ /// based texture or "image" to create a texture from an image at a particular URL
+ /// The data for the generator
+ /// Parameters for the generator that don't form part of the main data.
+ /// If zero, the image is never updated after the first generation. If positive
+ /// the image is updated at the given interval. Not implemented for
+ ///
+ /// If true, the newly generated texture is blended with the appropriate existing ones on the prim
+ ///
+ ///
+ /// Display flags. If DISP_EXPIRE then the old texture is deleted if it is replaced by a
+ /// newer generated texture (may not currently be implemented). If DISP_TEMP then the asset is flagged as
+ /// temporary, which often means that it is not persisted to the database.
+ ///
+ ///
+ /// The alpha value of the generated texture.
+ ///
+ ///
+ /// The face of the prim on which to put the generated texture. If ALL_SIDES then all sides of the prim are
+ /// set
+ ///
+ ///
+ /// The UUID of the texture updater, not the texture UUID. If you need the texture UUID then you will need
+ /// to obtain it directly from the SceneObjectPart. For instance, if ALL_SIDES is set then this texture
+ /// can be obtained as SceneObjectPart.Shape.Textures.DefaultTexture.TextureID
+ ///
+ UUID AddDynamicTextureData(
+ UUID simID, UUID primID, string contentType, string data, string extraParams,
+ int updateTimer, bool SetBlending, int disp, byte AlphaValue, int face);
+
void GetDrawStringSize(string contentType, string text, string fontName, int fontSize,
out double xSize, out double ySize);
}
diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs
index 473920ee88..9f74b2a14c 100644
--- a/OpenSim/Region/Framework/Scenes/EventManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -205,6 +205,12 @@ namespace OpenSim.Region.Framework.Scenes
public delegate void OnMakeRootAgentDelegate(ScenePresence presence);
public event OnMakeRootAgentDelegate OnMakeRootAgent;
+ ///
+ /// Triggered when an object or attachment enters a scene
+ ///
+ public event OnIncomingSceneObjectDelegate OnIncomingSceneObject;
+ public delegate void OnIncomingSceneObjectDelegate(SceneObjectGroup so);
+
public delegate void NewInventoryItemUploadComplete(UUID avatarID, UUID assetID, string name, int userlevel);
public event NewInventoryItemUploadComplete OnNewInventoryItemUploadComplete;
@@ -407,7 +413,7 @@ namespace OpenSim.Region.Framework.Scenes
}
}
}
- }
+ }
public void TriggerGetScriptRunning(IClientAPI controllingClient, UUID objectID, UUID itemID)
{
@@ -1206,6 +1212,27 @@ namespace OpenSim.Region.Framework.Scenes
}
}
+ public void TriggerOnIncomingSceneObject(SceneObjectGroup so)
+ {
+ OnIncomingSceneObjectDelegate handlerIncomingSceneObject = OnIncomingSceneObject;
+ if (handlerIncomingSceneObject != null)
+ {
+ foreach (OnIncomingSceneObjectDelegate d in handlerIncomingSceneObject.GetInvocationList())
+ {
+ try
+ {
+ d(so);
+ }
+ catch (Exception e)
+ {
+ m_log.ErrorFormat(
+ "[EVENT MANAGER]: Delegate for TriggerOnIncomingSceneObject failed - continuing. {0} {1}",
+ e.Message, e.StackTrace);
+ }
+ }
+ }
+ }
+
public void TriggerOnRegisterCaps(UUID agentID, Caps caps)
{
RegisterCapsEvent handlerRegisterCaps = OnRegisterCaps;
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index f109589542..669720a464 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -2239,9 +2239,14 @@ namespace OpenSim.Region.Framework.Scenes
}
+ ///
+ /// Called when objects or attachments cross the border between regions.
+ ///
+ ///
+ ///
public bool IncomingCreateObject(ISceneObject sog)
{
- //m_log.Debug(" >>> IncomingCreateObject <<< " + ((SceneObjectGroup)sog).AbsolutePosition + " deleted? " + ((SceneObjectGroup)sog).IsDeleted);
+ //m_log.Debug(" >>> IncomingCreateObject(sog) <<< " + ((SceneObjectGroup)sog).AbsolutePosition + " deleted? " + ((SceneObjectGroup)sog).IsDeleted);
SceneObjectGroup newObject;
try
{
@@ -2258,7 +2263,12 @@ namespace OpenSim.Region.Framework.Scenes
m_log.DebugFormat("[SCENE]: Problem adding scene object {0} in {1} ", sog.UUID, RegionInfo.RegionName);
return false;
}
+
newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, 1);
+
+ // Do this as late as possible so that listeners have full access to the incoming object
+ EventManager.TriggerOnIncomingSceneObject(newObject);
+
return true;
}
@@ -2270,6 +2280,8 @@ namespace OpenSim.Region.Framework.Scenes
/// False
public virtual bool IncomingCreateObject(UUID userID, UUID itemID)
{
+ //m_log.DebugFormat(" >>> IncomingCreateObject(userID, itemID) <<< {0} {1}", userID, itemID);
+
ScenePresence sp = GetScenePresence(userID);
if (sp != null)
{
@@ -2307,7 +2319,7 @@ namespace OpenSim.Region.Framework.Scenes
foreach (SceneObjectPart p in sceneObject.Children.Values)
p.LocalId = 0;
- if ((sceneObject.RootPart.Shape.PCode == (byte)PCode.Prim) && (sceneObject.RootPart.Shape.State != 0)) // Attachment
+ if (sceneObject.IsAttachmentCheckFull()) // Attachment
{
sceneObject.RootPart.AddFlag(PrimFlags.TemporaryOnRez);
sceneObject.RootPart.AddFlag(PrimFlags.Phantom);
@@ -2332,29 +2344,23 @@ namespace OpenSim.Region.Framework.Scenes
//RootPrim.SetParentLocalId(parentLocalID);
- m_log.DebugFormat("[ATTACHMENT]: Received " +
- "attachment {0}, inworld asset id {1}",
- //grp.RootPart.LastOwnerID.ToString(),
- grp.GetFromItemID(),
- grp.UUID.ToString());
+ m_log.DebugFormat(
+ "[ATTACHMENT]: Received attachment {0}, inworld asset id {1}", grp.GetFromItemID(), grp.UUID);
//grp.SetFromAssetID(grp.RootPart.LastOwnerID);
- m_log.DebugFormat("[ATTACHMENT]: Attach " +
- "to avatar {0} at position {1}",
- sp.UUID.ToString(), grp.AbsolutePosition);
- AttachObject(sp.ControllingClient,
- grp.LocalId, (uint)0,
- grp.GroupRotation,
- grp.AbsolutePosition, false);
+ m_log.DebugFormat(
+ "[ATTACHMENT]: Attach to avatar {0} at position {1}", sp.UUID, grp.AbsolutePosition);
+
+ AttachObject(
+ sp.ControllingClient, grp.LocalId, (uint)0, grp.GroupRotation, grp.AbsolutePosition, false);
RootPrim.RemFlag(PrimFlags.TemporaryOnRez);
- grp.SendGroupFullUpdate();
+ grp.SendGroupFullUpdate();
}
else
{
RootPrim.RemFlag(PrimFlags.TemporaryOnRez);
RootPrim.AddFlag(PrimFlags.TemporaryOnRez);
}
-
}
else
{
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 8c568707aa..af466593bc 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -268,7 +268,16 @@ namespace OpenSim.Region.Framework.Scenes
}
}
- private bool IsAttachmentCheckFull()
+ ///
+ /// Check both the attachment property and the relevant properties of the underlying root part.
+ ///
+ /// This is necessary in some cases, particularly when a scene object has just crossed into a region and doesn't
+ /// have the IsAttachment property yet checked.
+ ///
+ /// FIXME: However, this should be fixed so that this property
+ /// propertly reflects the underlying status.
+ ///
+ public bool IsAttachmentCheckFull()
{
return (IsAttachment || (m_rootPart.Shape.PCode == 9 && m_rootPart.Shape.State != 0));
}
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 29f607bd9b..b8a937a303 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -104,6 +104,14 @@ namespace OpenSim.Region.Framework.Scenes
}
protected ScenePresenceAnimator m_animator;
+ ///
+ /// The scene objects attached to this avatar. Do not change this list directly - use methods such as
+ /// AddAttachment() and RemoveAttachment(). Lock this list when performing any read operations upon it.
+ ///
+ public List Attachments
+ {
+ get { return m_attachments; }
+ }
protected List m_attachments = new List();
private Dictionary scriptedcontrols = new Dictionary();
@@ -219,11 +227,6 @@ namespace OpenSim.Region.Framework.Scenes
protected AvatarAppearance m_appearance;
- public List Attachments
- {
- get { return m_attachments; }
- }
-
// neighbouring regions we have enabled a child agent in
// holds the seed cap for the child agent in that region
private Dictionary m_knownChildRegions = new Dictionary();
@@ -3210,8 +3213,7 @@ namespace OpenSim.Region.Framework.Scenes
m_physicsActor.OnCollisionUpdate += PhysicsCollisionUpdate;
m_physicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong
m_physicsActor.SubscribeEvents(500);
- m_physicsActor.LocalID = LocalId;
-
+ m_physicsActor.LocalID = LocalId;
}
private void OutOfBoundsCall(Vector3 pos)
@@ -3221,7 +3223,7 @@ namespace OpenSim.Region.Framework.Scenes
//AddToPhysicalScene(flying);
if (ControllingClient != null)
- ControllingClient.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.",true);
+ ControllingClient.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.", true);
}
// Event called by the physics plugin to tell the avatar about a collision.