diff --git a/OpenSim/Framework/ChildAgentDataUpdate.cs b/OpenSim/Framework/ChildAgentDataUpdate.cs index fe128744bf..e718aa6c47 100644 --- a/OpenSim/Framework/ChildAgentDataUpdate.cs +++ b/OpenSim/Framework/ChildAgentDataUpdate.cs @@ -229,12 +229,14 @@ namespace OpenSim.Framework public class ControllerData { + public UUID ObjectID; public UUID ItemID; public uint IgnoreControls; public uint EventControls; - public ControllerData(UUID item, uint ignore, uint ev) + public ControllerData(UUID obj, UUID item, uint ignore, uint ev) { + ObjectID = obj; ItemID = item; IgnoreControls = ignore; EventControls = ev; @@ -248,6 +250,7 @@ namespace OpenSim.Framework public OSDMap PackUpdateMessage() { OSDMap controldata = new OSDMap(); + controldata["object"] = OSD.FromUUID(ObjectID); controldata["item"] = OSD.FromUUID(ItemID); controldata["ignore"] = OSD.FromInteger(IgnoreControls); controldata["event"] = OSD.FromInteger(EventControls); @@ -258,6 +261,8 @@ namespace OpenSim.Framework public void UnpackUpdateMessage(OSDMap args) { + if (args["object"] != null) + ObjectID = args["object"].AsUUID(); if (args["item"] != null) ItemID = args["item"].AsUUID(); if (args["ignore"] != null) @@ -306,6 +311,7 @@ namespace OpenSim.Framework public AgentGroupData[] Groups; public Animation[] Anims; + public Animation DefaultAnim = null; public UUID GranterID; public UUID ParentPart; @@ -392,6 +398,11 @@ namespace OpenSim.Framework args["animations"] = anims; } + if (DefaultAnim != null) + { + args["default_animation"] = DefaultAnim.PackUpdateMessage(); + } + if (Appearance != null) args["packed_appearance"] = Appearance.Pack(); @@ -589,6 +600,18 @@ namespace OpenSim.Framework } } + if (args["default_animation"] != null) + { + try + { + DefaultAnim = new Animation((OSDMap)args["default_animation"]); + } + catch + { + DefaultAnim = null; + } + } + //if ((args["agent_textures"] != null) && (args["agent_textures"]).Type == OSDType.Array) //{ // OSDArray textures = (OSDArray)(args["agent_textures"]); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 42b6bc56ea..a6ce0e28be 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -465,7 +465,15 @@ namespace OpenSim.Region.Framework.Scenes { return (IsAttachment || (m_rootPart.Shape.PCode == 9 && m_rootPart.Shape.State != 0)); } - + + + + private struct avtocrossInfo + { + public ScenePresence av; + public uint ParentID; + } + /// /// The absolute position of this scene object in the scene /// @@ -517,15 +525,24 @@ namespace OpenSim.Region.Framework.Scenes { // We unparent the SP quietly so that it won't // be made to stand up + + List avsToCross = new List(); + foreach (ScenePresence av in m_linkedAvatars) { + avtocrossInfo avinfo = new avtocrossInfo(); SceneObjectPart parentPart = m_scene.GetSceneObjectPart(av.ParentID); if (parentPart != null) av.ParentUUID = parentPart.UUID; + avinfo.av = av; + avinfo.ParentID = av.ParentID; + avsToCross.Add(avinfo); + av.ParentID = 0; } +// m_linkedAvatars.Clear(); m_scene.CrossPrimGroupIntoNewRegion(val, this, true); // Normalize @@ -541,18 +558,37 @@ namespace OpenSim.Region.Framework.Scenes // If it's deleted, crossing was successful if (IsDeleted) { - foreach (ScenePresence av in m_linkedAvatars) + // foreach (ScenePresence av in m_linkedAvatars) + foreach (avtocrossInfo avinfo in avsToCross) { - m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar {0} to {1}", av.Name, val); + ScenePresence av = avinfo.av; + if (!av.IsInTransit) // just in case... + { + m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar {0} to {1}", av.Name, val); - av.IsInTransit = true; + av.IsInTransit = true; - CrossAgentToNewRegionDelegate d = entityTransfer.CrossAgentToNewRegionAsync; - d.BeginInvoke(av, val, x, y, destination, av.Flying, version, CrossAgentToNewRegionCompleted, d); + CrossAgentToNewRegionDelegate d = entityTransfer.CrossAgentToNewRegionAsync; + d.BeginInvoke(av, val, x, y, destination, av.Flying, version, CrossAgentToNewRegionCompleted, d); + } + else + m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar alreasy in transit {0} to {1}", av.Name, val); } - + avsToCross.Clear(); return; } + else // cross failed, put avas back ?? + { + foreach (avtocrossInfo avinfo in avsToCross) + { + ScenePresence av = avinfo.av; + av.ParentUUID = UUID.Zero; + av.ParentID = avinfo.ParentID; +// m_linkedAvatars.Add(av); + } + } + avsToCross.Clear(); + } else if (RootPart.PhysActor != null) { @@ -565,6 +601,7 @@ namespace OpenSim.Region.Framework.Scenes val.Z = Util.Clamp(oldp.Z, 0.5f, 4096.0f); } } + /* don't see the need but worse don't see where is restored to false if things stay in foreach (SceneObjectPart part in m_parts.GetArray()) { @@ -640,9 +677,12 @@ namespace OpenSim.Region.Framework.Scenes { agent.ParentPart = null; agent.ParentPosition = Vector3.Zero; + // agent.ParentUUID = UUID.Zero; } } + agent.ParentUUID = UUID.Zero; + // agent.Reset(); // else // Not successful // agent.RestoreInCurrentScene(); @@ -1779,15 +1819,14 @@ namespace OpenSim.Region.Framework.Scenes part.ClearUpdateSchedule(); if (part == m_rootPart) { - if (!IsAttachment || (AttachedAvatar == avatar.ControllingClient.AgentId) || + if (!IsAttachment || (AttachedAvatar == avatar.ControllingClient.AgentId) || (AttachmentPoint < 31) || (AttachmentPoint > 38)) avatar.ControllingClient.SendKillObject(m_regionHandle, new List { part.LocalId }); } } }); } - - + } public void AddScriptLPS(int count) @@ -2069,6 +2108,9 @@ namespace OpenSim.Region.Framework.Scenes dupe.m_isBackedUp = false; dupe.m_parts = new MapAndArray(); + // new group as no sitting avatars + dupe.m_linkedAvatars = new List(); + // Warning, The following code related to previousAttachmentStatus is needed so that clones of // attachments do not bordercross while they're being duplicated. This is hacktastic! // Normally, setting AbsolutePosition will bordercross a prim if it's outside the region! diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 5e275f6b66..5a6fb6cce3 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -63,6 +63,7 @@ namespace OpenSim.Region.Framework.Scenes struct ScriptControllers { + public UUID objectID; public UUID itemID; public ScriptControlled ignoreControls; public ScriptControlled eventControls; @@ -756,7 +757,13 @@ namespace OpenSim.Region.Framework.Scenes m_movementAnimationUpdateCounter = 0; if (Animator != null) { - if(ParentID == 0 && !SitGround) // skip it if sitting + // If the parentID == 0 we are not sitting + // if !SitGournd then we are not sitting on the ground + // Fairly straightforward, now here comes the twist + // if ParentUUID is NOT UUID.Zero, we are looking to + // be sat on an object that isn't there yet. Should + // be treated as if sat. + if(ParentID == 0 && !SitGround && ParentUUID == UUID.Zero) // skip it if sitting Animator.UpdateMovementAnimations(); } else @@ -923,7 +930,15 @@ namespace OpenSim.Region.Framework.Scenes } AbsolutePosition = pos; - AddToPhysicalScene(isFlying); + if (m_teleportFlags == TeleportFlags.Default) + { + Vector3 vel = Velocity; + AddToPhysicalScene(isFlying); + if (PhysicsActor != null) + PhysicsActor.SetMomentum(vel); + } + else + AddToPhysicalScene(isFlying); if (ForceFly) { @@ -974,6 +989,7 @@ namespace OpenSim.Region.Framework.Scenes // If we don't reset the movement flag here, an avatar that crosses to a neighbouring sim and returns will // stall on the border crossing since the existing child agent will still have the last movement // recorded, which stops the input from being processed. + MovementFlag = 0; m_scene.EventManager.TriggerOnMakeRootAgent(this); @@ -1014,6 +1030,8 @@ namespace OpenSim.Region.Framework.Scenes // as teleporting back TeleportFlags = TeleportFlags.Default; + MovementFlag = 0; + // It looks like Animator is set to null somewhere, and MakeChild // is called after that. Probably in aborted teleports. if (Animator == null) @@ -1021,6 +1039,7 @@ namespace OpenSim.Region.Framework.Scenes else Animator.ResetAnimations(); + // m_log.DebugFormat( // "[SCENE PRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}", // Name, UUID, m_scene.RegionInfo.RegionName); @@ -1047,9 +1066,9 @@ namespace OpenSim.Region.Framework.Scenes { // PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; PhysicsActor.OnOutOfBounds -= OutOfBoundsCall; - m_scene.PhysicsScene.RemoveAvatar(PhysicsActor); - PhysicsActor.UnSubscribeEvents(); PhysicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; + PhysicsActor.UnSubscribeEvents(); + m_scene.PhysicsScene.RemoveAvatar(PhysicsActor); PhysicsActor = null; } // else @@ -1885,6 +1904,8 @@ namespace OpenSim.Region.Framework.Scenes if (ParentID != 0) { SceneObjectPart part = ParentPart; + UnRegisterSeatControls(part.ParentGroup.UUID); + TaskInventoryDictionary taskIDict = part.TaskInventory; if (taskIDict != null) { @@ -3212,7 +3233,7 @@ namespace OpenSim.Region.Framework.Scenes foreach (ScriptControllers c in scriptedcontrols.Values) { - controls[i++] = new ControllerData(c.itemID, (uint)c.ignoreControls, (uint)c.eventControls); + controls[i++] = new ControllerData(c.objectID, c.itemID, (uint)c.ignoreControls, (uint)c.eventControls); } cAgent.Controllers = controls; } @@ -3223,6 +3244,7 @@ namespace OpenSim.Region.Framework.Scenes cAgent.Anims = Animator.Animations.ToArray(); } catch { } + cAgent.DefaultAnim = Animator.Animations.DefaultAnimation; // Attachment objects List attachments = GetAttachments(); @@ -3302,6 +3324,7 @@ namespace OpenSim.Region.Framework.Scenes foreach (ControllerData c in cAgent.Controllers) { ScriptControllers sc = new ScriptControllers(); + sc.objectID = c.ObjectID; sc.itemID = c.ItemID; sc.ignoreControls = (ScriptControlled)c.IgnoreControls; sc.eventControls = (ScriptControlled)c.EventControls; @@ -3316,6 +3339,8 @@ namespace OpenSim.Region.Framework.Scenes // FIXME: Why is this null check necessary? Where are the cases where we get a null Anims object? if (cAgent.Anims != null) Animator.Animations.FromArray(cAgent.Anims); + if (cAgent.DefaultAnim != null) + Animator.Animations.SetDefaultAnimation(cAgent.DefaultAnim.AnimID, cAgent.DefaultAnim.SequenceNum, UUID.Zero); if (cAgent.AttachmentObjects != null && cAgent.AttachmentObjects.Count > 0) { @@ -3791,10 +3816,15 @@ namespace OpenSim.Region.Framework.Scenes public void RegisterControlEventsToScript(int controls, int accept, int pass_on, uint Obj_localID, UUID Script_item_UUID) { + SceneObjectPart p = m_scene.GetSceneObjectPart(Obj_localID); + if (p == null) + return; + ScriptControllers obj = new ScriptControllers(); obj.ignoreControls = ScriptControlled.CONTROL_ZERO; obj.eventControls = ScriptControlled.CONTROL_ZERO; + obj.objectID = p.ParentGroup.UUID; obj.itemID = Script_item_UUID; if (pass_on == 0 && accept == 0) { @@ -3843,6 +3873,21 @@ namespace OpenSim.Region.Framework.Scenes ControllingClient.SendTakeControls(int.MaxValue, false, false); } + private void UnRegisterSeatControls(UUID obj) + { + List takers = new List(); + + foreach (ScriptControllers c in scriptedcontrols.Values) + { + if (c.objectID == obj) + takers.Add(c.itemID); + } + foreach (UUID t in takers) + { + UnRegisterControlEventsToScript(0, t); + } + } + public void UnRegisterControlEventsToScript(uint Obj_localID, UUID Script_item_UUID) { ScriptControllers takecontrols; diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs index 326fe97a77..b884b623b7 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs @@ -168,6 +168,10 @@ namespace OpenSim.Region.Physics.OdePlugin m_density = density; m_mass = 80f; // sure we have a default + // force lower density for testing + m_density = 3.0f; + + mu = parent_scene.AvatarFriction; walkDivisor = walk_divisor; @@ -1184,7 +1188,7 @@ namespace OpenSim.Region.Physics.OdePlugin // destroy avatar capsule and related ODE data AvatarGeomAndBodyDestroy(); } - + m_freemove = false; m_isPhysical = NewStatus; } } @@ -1236,7 +1240,7 @@ namespace OpenSim.Region.Physics.OdePlugin + (Amotor == IntPtr.Zero ? "Amotor " : "")); } } - + m_freemove = false; m_pidControllerActive = true; } else @@ -1250,6 +1254,7 @@ namespace OpenSim.Region.Physics.OdePlugin if (Body != IntPtr.Zero) d.BodySetPosition(Body, newPos.X, newPos.Y, newPos.Z); _position = newPos; + m_freemove = false; m_pidControllerActive = true; } @@ -1260,6 +1265,7 @@ namespace OpenSim.Region.Physics.OdePlugin private void changeVelocity(Vector3 newVel) { m_pidControllerActive = true; + m_freemove = false; _target_velocity = newVel; }