From 20a9bf08f51351e1e0a9de94f184ff56cd572665 Mon Sep 17 00:00:00 2001 From: Adam Frisby Date: Thu, 1 May 2008 18:04:42 +0000 Subject: * Rolled back a few changes. --- OpenSim/Region/Environment/Scenes/ScenePresence.cs | 3230 ++++++++++---------- 1 file changed, 1618 insertions(+), 1612 deletions(-) (limited to 'OpenSim/Region/Environment/Scenes/ScenePresence.cs') diff --git a/OpenSim/Region/Environment/Scenes/ScenePresence.cs b/OpenSim/Region/Environment/Scenes/ScenePresence.cs index 4cdf7f1..74e9cdc 100644 --- a/OpenSim/Region/Environment/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Environment/Scenes/ScenePresence.cs @@ -40,111 +40,117 @@ using OpenSim.Region.Physics.Manager; namespace OpenSim.Region.Environment.Scenes { - [Serializable] + [Serializable] public class ScenePresence : EntityBase, ISerializable { // ~ScenePresence() // { // System.Console.WriteLine("[ScenePresence] Destructor called"); // } - - #region Delegates - - public delegate void SignificantClientMovement(IClientAPI remote_client); - - #endregion - + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); public static AvatarAnimations Animations = new AvatarAnimations(); public static byte[] DefaultTexture; - private readonly Vector3[] Dir_Vectors = new Vector3[6]; - private readonly uint m_AgentControlFlags = 0; - private readonly List m_animations = new List(); - private readonly List m_animationSeqs = new List(); - private readonly List m_forcesList = new List(); - private readonly List m_knownChildRegions = new List(); - private readonly List m_knownPrimUUID = new List(); - private readonly UpdateQueue m_partsUpdateQueue = new UpdateQueue(); - private readonly byte m_state = 0; - private readonly Dictionary m_updateTimes = new Dictionary(); - protected ulong crossingFromRegion; public LLUUID currentParcelUUID = LLUUID.Zero; - private SignificantClientMovement handlerSignificantClientMovement; //OnSignificantClientMovement; + private List m_animations = new List(); + private List m_animationSeqs = new List(); + public Vector3 lastKnownAllowedPosition = new Vector3(); + public bool sentMessageAboutRestrictedParcelFlyingDown = false; + + private bool m_updateflag = false; + private byte m_movementflag = 0; + private readonly List m_forcesList = new List(); + private short m_updateCount = 0; + private uint m_requestedSitTargetID = 0; + private LLVector3 m_requestedSitOffset = new LLVector3(); + private float m_sitAvatarHeight = 2.0f; + private float m_godlevel = 0; + private LLVector3 m_LastChildAgentUpdatePosition = new LLVector3(); + + private int m_perfMonMS = 0; + + private bool m_setAlwaysRun = false; + + private Quaternion m_bodyRot; - public bool IsRestrictedToRegion; + public bool IsRestrictedToRegion = false; public string JID = string.Empty; - public Vector3 lastKnownAllowedPosition; // Agent moves with a PID controller causing a force to be exerted. - private LLVector3 lastPhysPos; - protected AvatarAppearance m_appearance; + private bool m_newForce = false; + private bool m_newCoarseLocations = true; + private bool m_gotAllObjectsInScene = false; - protected List m_attachments = new List(); + private LLVector3 m_lastVelocity = LLVector3.Zero; + + // Default AV Height private float m_avHeight = 127.0f; - private Quaternion m_bodyRot; + + protected RegionInfo m_regionInfo; + protected ulong crossingFromRegion = 0; + + private readonly Vector3[] Dir_Vectors = new Vector3[6]; + private LLVector3 lastPhysPos = new LLVector3(); // Position of agent's camera in world (region cordinates) + protected Vector3 m_CameraCenter = new Vector3(0, 0, 0); // Use these three vectors to figure out what the agent is looking at // Convert it to a Matrix and/or Quaternion protected Vector3 m_CameraAtAxis = new Vector3(0, 0, 0); - protected Vector3 m_CameraCenter = new Vector3(0, 0, 0); protected Vector3 m_CameraLeftAxis = new Vector3(0, 0, 0); protected Vector3 m_CameraUpAxis = new Vector3(0, 0, 0); - protected float m_DrawDistance; - private float m_godlevel; - private bool m_gotAllObjectsInScene; - private LLQuaternion m_headrotation; - private LLVector3 m_LastChildAgentUpdatePosition; - private LLVector3 m_lastVelocity = LLVector3.Zero; - private byte m_movementflag; - private bool m_newCoarseLocations = true; - private bool m_newForce; - private int m_perfMonMS; - protected RegionInfo m_regionInfo; - private LLVector3 m_requestedSitOffset; - private uint m_requestedSitTargetID; - private bool m_setAlwaysRun; - private float m_sitAvatarHeight = 2.0f; - private short m_updateCount; - private bool m_updateflag; + private uint m_AgentControlFlags = (uint) 0; + private LLQuaternion m_headrotation = new LLQuaternion(); + private byte m_state = (byte) 0; //Reuse the LLVector3 instead of creating a new one on the UpdateMovement method - private LLVector3 movementvector; + private LLVector3 movementvector = new LLVector3(); - /// - /// Position at which a significant movement was made - /// - private LLVector3 posLastSignificantMove; + private List m_knownPrimUUID = new List(); - public bool sentMessageAboutRestrictedParcelFlyingDown; + // Agent's Draw distance. + protected float m_DrawDistance = 0f; - #region Properties + protected AvatarAppearance m_appearance; - private readonly string m_firstname; - private readonly string m_lastname; - private readonly ulong m_regionHandle; - protected bool m_allowMovement = true; + protected List m_attachments = new List(); + + //neighbouring regions we have enabled a child agent in + private readonly List m_knownChildRegions = new List(); + + private SignificantClientMovement handlerSignificantClientMovement = null; //OnSignificantClientMovement; /// - /// This works out to be the ClientView object associated with this avatar, or it's UDP connection manager + /// Implemented Control Flags /// - private IClientAPI m_controllingClient; + private enum Dir_ControlFlags + { + DIR_CONTROL_FLAG_FORWARD = AgentManager.ControlFlags.AGENT_CONTROL_AT_POS, + DIR_CONTROL_FLAG_BACK = AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG, + DIR_CONTROL_FLAG_LEFT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS, + DIR_CONTROL_FLAG_RIGHT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG, + DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, + DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, + DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG + } /// - /// If this is true, agent doesn't have a representation in this scene. - /// this is an agent 'looking into' this scene from a nearby scene(region) - /// - /// if False, this agent has a representation in this scene + /// Position at which a significant movement was made /// - private bool m_isChildAgent = true; + private LLVector3 posLastSignificantMove = new LLVector3(); - private uint m_parentID; - protected LLVector3 m_parentPosition; - protected PhysicsActor m_physicsActor; + public delegate void SignificantClientMovement(IClientAPI remote_client); + + public event SignificantClientMovement OnSignificantClientMovement; + + private UpdateQueue m_partsUpdateQueue = new UpdateQueue(); + private Dictionary m_updateTimes = new Dictionary(); + + #region Properties /// /// Physical scene representation of this Avatar. @@ -161,6 +167,16 @@ namespace OpenSim.Region.Environment.Scenes get { return m_movementflag; } } + public bool KnownPrim(LLUUID primID) + { + if (m_knownPrimUUID.Contains(primID)) + { + return true; + } + m_knownPrimUUID.Add(primID); + return false; + } + public bool Updated { @@ -168,6 +184,8 @@ namespace OpenSim.Region.Environment.Scenes get { return m_updateflag; } } + private readonly ulong m_regionHandle; + public ulong RegionHandle { get { return m_regionHandle; } @@ -178,11 +196,15 @@ namespace OpenSim.Region.Environment.Scenes get { return m_CameraCenter; } } + private readonly string m_firstname; + public string Firstname { get { return m_firstname; } } + private readonly string m_lastname; + public string Lastname { get { return m_lastname; } @@ -193,18 +215,29 @@ namespace OpenSim.Region.Environment.Scenes get { return m_DrawDistance; } } + protected bool m_allowMovement = true; + public bool AllowMovement { get { return m_allowMovement; } set { m_allowMovement = value; } } + /// + /// This works out to be the ClientView object associated with this avatar, or it's UDP connection manager + /// + private IClientAPI m_controllingClient; + + protected PhysicsActor m_physicsActor; + public IClientAPI ControllingClient { get { return m_controllingClient; } set { m_controllingClient = value; } } + protected LLVector3 m_parentPosition = new LLVector3(); + /// /// Absolute position of this avatar in 'region cordinates' /// @@ -239,7 +272,7 @@ namespace OpenSim.Region.Environment.Scenes } m_pos = value; - m_parentPosition = new LLVector3(0, 0, 0); + m_parentPosition=new LLVector3(0, 0, 0); } } @@ -280,12 +313,22 @@ namespace OpenSim.Region.Environment.Scenes } } + /// + /// If this is true, agent doesn't have a representation in this scene. + /// this is an agent 'looking into' this scene from a nearby scene(region) + /// + /// if False, this agent has a representation in this scene + /// + private bool m_isChildAgent = true; + public bool IsChildAgent { get { return m_isChildAgent; } set { m_isChildAgent = value; } } + private uint m_parentID = 0; + public uint ParentID { get { return m_parentID; } @@ -300,16 +343,6 @@ namespace OpenSim.Region.Environment.Scenes get { return m_knownChildRegions; } } - public bool KnownPrim(LLUUID primID) - { - if (m_knownPrimUUID.Contains(primID)) - { - return true; - } - m_knownPrimUUID.Add(primID); - return false; - } - #endregion #region Constructor(s) @@ -387,1947 +420,1920 @@ namespace OpenSim.Region.Environment.Scenes #endregion - static ScenePresence() + /// + /// Add the part to the queue of parts for which we need to send an update to the client + /// + /// + public void QueuePartForUpdate(SceneObjectPart part) { - LLObject.TextureEntry textu = AvatarAppearance.GetDefaultTextureEntry(); - DefaultTexture = textu.ToBytes(); + //if (InterestList.Contains(part.ParentGroup)) + //{ + lock (m_partsUpdateQueue) + { + m_partsUpdateQueue.Enqueue(part); + } + // } } - public ScenePresence() + public uint GenerateClientFlags(LLUUID ObjectID) { -/* JB - if (Animations == null) - { - Animations = new AvatarAnimations(); - Animations.LoadAnims(); - } -*/ - if (DefaultTexture == null) - { - LLObject.TextureEntry textu = AvatarAppearance.GetDefaultTextureEntry(); - DefaultTexture = textu.ToBytes(); - } + return m_scene.PermissionsMngr.GenerateClientFlags(m_uuid, ObjectID); } - protected ScenePresence(SerializationInfo info, StreamingContext context) - : base(info, context) + /// + /// Send updates to the client about prims which have been placed on the update queue. We don't + /// necessarily send updates for all the parts on the queue, e.g. if an updates with a more recent + /// timestamp has already been sent. + /// + public void SendPrimUpdates() { - //System.Console.WriteLine("ScenePresence Deserialize BGN"); + // if (m_scene.QuadTree.GetNodeID(this.AbsolutePosition.X, this.AbsolutePosition.Y) != m_currentQuadNode) + //{ + // this.UpdateQuadTreeNode(); + //this.RefreshQuadObject(); + //} + m_perfMonMS = System.Environment.TickCount; - if (info == null) - { - throw new ArgumentNullException("info"); - } -/* JB - if (Animations == null) - { - Animations = new AvatarAnimations(); - Animations.LoadAnims(); - } -*/ - if (DefaultTexture == null) + if (!m_gotAllObjectsInScene) { - LLObject.TextureEntry textu = AvatarAppearance.GetDefaultTextureEntry(); - DefaultTexture = textu.ToBytes(); + if (!m_isChildAgent || m_scene.m_seeIntoRegionFromNeighbor) + { + m_scene.SendAllSceneObjectsToClient(this); + m_gotAllObjectsInScene = true; + } } - - List animations_work = (List) info.GetValue("m_animations", typeof (List)); - - foreach (Guid guid in animations_work) + + if (m_partsUpdateQueue.Count > 0) { - m_animations.Add(new LLUUID(guid)); - } - - m_animationSeqs = (List) info.GetValue("m_animationSeqs", typeof (List)); - m_updateflag = (bool) info.GetValue("m_updateflag", typeof (bool)); - m_movementflag = (byte) info.GetValue("m_movementflag", typeof (byte)); - m_forcesList = (List) info.GetValue("m_forcesList", typeof (List)); - m_updateCount = (short) info.GetValue("m_updateCount", typeof (short)); - m_requestedSitTargetID = (uint) info.GetValue("m_requestedSitTargetID", typeof (uint)); - - m_requestedSitOffset - = new LLVector3( - (float) info.GetValue("m_requestedSitOffset.X", typeof (float)), - (float) info.GetValue("m_requestedSitOffset.Y", typeof (float)), - (float) info.GetValue("m_requestedSitOffset.Z", typeof (float))); + bool runUpdate = true; + int updateCount = 0; + while (runUpdate) + { + SceneObjectPart part = m_partsUpdateQueue.Dequeue(); + if (m_updateTimes.ContainsKey(part.UUID)) + { + ScenePartUpdate update = m_updateTimes[part.UUID]; - m_sitAvatarHeight = (float) info.GetValue("m_sitAvatarHeight", typeof (float)); - m_godlevel = (float) info.GetValue("m_godlevel", typeof (float)); - m_setAlwaysRun = (bool) info.GetValue("m_setAlwaysRun", typeof (bool)); + // We deal with the possibility that two updates occur at the same unix time + // at the update point itself. + if (update.LastFullUpdateTime < part.TimeStampFull) + { +// m_log.DebugFormat( +// "[SCENE PRESENCE]: Fully updating prim {0}, {1} - part timestamp {2}", +// part.Name, part.UUID, part.TimeStampFull); + + part.SendFullUpdate(ControllingClient, GenerateClientFlags(part.UUID)); - m_bodyRot - = new Quaternion( - (float) info.GetValue("m_bodyRot.w", typeof (float)), - (float) info.GetValue("m_bodyRot.x", typeof (float)), - (float) info.GetValue("m_bodyRot.y", typeof (float)), - (float) info.GetValue("m_bodyRot.z", typeof (float))); + // We'll update to the part's timestamp rather than the current time to + // avoid the race condition whereby the next tick occurs while we are + // doing this update. If this happened, then subsequent updates which occurred + // on the same tick or the next tick of the last update would be ignored. + update.LastFullUpdateTime = part.TimeStampFull; - IsRestrictedToRegion = (bool) info.GetValue("IsRestrictedToRegion", typeof (bool)); - m_newForce = (bool) info.GetValue("m_newForce", typeof (bool)); - //m_newAvatar = (bool)info.GetValue("m_newAvatar", typeof(bool)); - m_newCoarseLocations = (bool) info.GetValue("m_newCoarseLocations", typeof (bool)); - m_gotAllObjectsInScene = (bool) info.GetValue("m_gotAllObjectsInScene", typeof (bool)); - m_avHeight = (float) info.GetValue("m_avHeight", typeof (float)); - crossingFromRegion = (ulong) info.GetValue("crossingFromRegion", typeof (ulong)); + updateCount++; + } + else if (update.LastTerseUpdateTime <= part.TimeStampTerse) + { +// m_log.DebugFormat( +// "[SCENE PRESENCE]: Tersely updating prim {0}, {1} - part timestamp {2}", +// part.Name, part.UUID, part.TimeStampTerse); + + part.SendTerseUpdate(ControllingClient); - List Dir_Vectors_work = (List) info.GetValue("Dir_Vectors", typeof (List)); - List Dir_Vectors_work2 = new List(); + update.LastTerseUpdateTime = part.TimeStampTerse; + updateCount++; + } + } + else + { + //never been sent to client before so do full update + part.SendFullUpdate(ControllingClient, GenerateClientFlags(part.UUID)); + ScenePartUpdate update = new ScenePartUpdate(); + update.FullID = part.UUID; + update.LastFullUpdateTime = part.TimeStampFull; + m_updateTimes.Add(part.UUID, update); + updateCount++; + } - foreach (float[] f3 in Dir_Vectors_work) - { - Dir_Vectors_work2.Add(new Vector3(f3[0], f3[1], f3[2])); + if (m_partsUpdateQueue.Count < 1 || updateCount > 60) + { + runUpdate = false; + } + } } - Dir_Vectors = Dir_Vectors_work2.ToArray(); - - lastPhysPos - = new LLVector3( - (float) info.GetValue("lastPhysPos.X", typeof (float)), - (float) info.GetValue("lastPhysPos.Y", typeof (float)), - (float) info.GetValue("lastPhysPos.Z", typeof (float))); + m_scene.AddAgentTime(System.Environment.TickCount - m_perfMonMS); + } - m_CameraCenter - = new Vector3( - (float) info.GetValue("m_CameraCenter.X", typeof (float)), - (float) info.GetValue("m_CameraCenter.Y", typeof (float)), - (float) info.GetValue("m_CameraCenter.Z", typeof (float))); + public void forceAvatarMovement(Vector3 position, Quaternion rotation) + { + AddNewMovement(position, rotation); + } - m_CameraAtAxis - = new Vector3( - (float) info.GetValue("m_CameraAtAxis.X", typeof (float)), - (float) info.GetValue("m_CameraAtAxis.Y", typeof (float)), - (float) info.GetValue("m_CameraAtAxis.Z", typeof (float))); + #region Status Methods - m_CameraLeftAxis - = new Vector3( - (float) info.GetValue("m_CameraLeftAxis.X", typeof (float)), - (float) info.GetValue("m_CameraLeftAxis.Y", typeof (float)), - (float) info.GetValue("m_CameraLeftAxis.Z", typeof (float))); - - m_CameraUpAxis - = new Vector3( - (float) info.GetValue("m_CameraUpAxis.X", typeof (float)), - (float) info.GetValue("m_CameraUpAxis.Y", typeof (float)), - (float) info.GetValue("m_CameraUpAxis.Z", typeof (float))); - - m_DrawDistance = (float) info.GetValue("m_DrawDistance", typeof (float)); - m_appearance = (AvatarAppearance) info.GetValue("m_appearance", typeof (AvatarAppearance)); - m_knownChildRegions = (List) info.GetValue("m_knownChildRegions", typeof (List)); + /// + /// This turns a child agent, into a root agent + /// This is called when an agent teleports into a region, or if an + /// agent crosses into this region from a neighbor over the border + /// + public void MakeRootAgent(LLVector3 pos, bool isFlying) + { +// m_log.DebugFormat( +// "[SCENEPRESENCE]: Upgrading child agent {0}, {1} to a root agent in {2}", +// Name, UUID, m_scene.RegionInfo.RegionName); + + m_isChildAgent = false; - posLastSignificantMove - = new LLVector3( - (float) info.GetValue("posLastSignificantMove.X", typeof (float)), - (float) info.GetValue("posLastSignificantMove.Y", typeof (float)), - (float) info.GetValue("posLastSignificantMove.Z", typeof (float))); + AbsolutePosition = pos; - // m_partsUpdateQueue = (UpdateQueue)info.GetValue("m_partsUpdateQueue", typeof(UpdateQueue)); + AddToPhysicalScene(); + m_physicsActor.Flying = isFlying; + SendAnimPack(); - /* - Dictionary updateTimes_work - = (Dictionary)info.GetValue("m_updateTimes", typeof(Dictionary)); + m_scene.SwapRootAgentCount(false); + m_scene.CommsManager.UserProfileCacheService.RequestInventoryForUser(m_uuid); + m_scene.AddCapsHandler(m_uuid); + //if (!m_gotAllObjectsInScene) + //{ + m_scene.SendAllSceneObjectsToClient(this); + m_scene.LandChannel.sendLandUpdate(this, true); + + //m_gotAllObjectsInScene = true; + //} + } - foreach (Guid id in updateTimes_work.Keys) + /// + /// This turns a root agent into a child agent + /// when an agent departs this region for a neighbor, this gets called. + /// + /// It doesn't get called for a teleport. Reason being, an agent that + /// teleports out may not be anywhere near this region + /// + public void MakeChildAgent() + { + if(m_animations.Count > 0) { - m_updateTimes.Add(new LLUUID(id), updateTimes_work[id]); - } - */ - m_regionHandle = (ulong) info.GetValue("m_regionHandle", typeof (ulong)); - m_firstname = (string) info.GetValue("m_firstname", typeof (string)); - m_lastname = (string) info.GetValue("m_lastname", typeof (string)); - m_allowMovement = (bool) info.GetValue("m_allowMovement", typeof (bool)); - m_parentPosition = new LLVector3((float) info.GetValue("m_parentPosition.X", typeof (float)), - (float) info.GetValue("m_parentPosition.Y", typeof (float)), - (float) info.GetValue("m_parentPosition.Z", typeof (float))); + LLUUID movement=m_animations[0]; - m_isChildAgent = (bool) info.GetValue("m_isChildAgent", typeof (bool)); - m_parentID = (uint) info.GetValue("m_parentID", typeof (uint)); + m_animations.Clear(); + m_animationSeqs.Clear(); -// for OpenSim_v0.5 - currentParcelUUID = new LLUUID((Guid) info.GetValue("currentParcelUUID", typeof (Guid))); + SetMovementAnimation(movement); + } +// m_log.DebugFormat( +// "[SCENEPRESENCE]: Downgrading child agent {0}, {1} to a root agent in {2}", +// Name, UUID, m_scene.RegionInfo.RegionName); + + Velocity = new LLVector3(0, 0, 0); + m_isChildAgent = true; + m_scene.SwapRootAgentCount(true); + RemoveFromPhysicalScene(); + m_scene.EventManager.TriggerOnMakeChildAgent(this); + //this.Pos = new LLVector3(128, 128, 70); + } - lastKnownAllowedPosition - = new Vector3( - (float) info.GetValue("lastKnownAllowedPosition.X", typeof (float)), - (float) info.GetValue("lastKnownAllowedPosition.Y", typeof (float)), - (float) info.GetValue("lastKnownAllowedPosition.Z", typeof (float))); + /// + /// Removes physics plugin scene representation of this agent if it exists. + /// + private void RemoveFromPhysicalScene() + { + if (PhysicsActor != null) + { + m_scene.PhysicsScene.RemoveAvatar(PhysicsActor); + m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; + m_physicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; + PhysicsActor = null; + } + } - sentMessageAboutRestrictedParcelFlyingDown = (bool) info.GetValue("sentMessageAboutRestrictedParcelFlyingDown", typeof (bool)); + /// + /// + /// + /// + public void Teleport(LLVector3 pos) + { + RemoveFromPhysicalScene(); + Velocity = new LLVector3(0, 0, 0); + AbsolutePosition = pos; + AddToPhysicalScene(); + SendTerseUpdateToAllClients(); + } - m_LastChildAgentUpdatePosition - = new LLVector3( - (float) info.GetValue("m_LastChildAgentUpdatePosition.X", typeof (float)), - (float) info.GetValue("m_LastChildAgentUpdatePosition.Y", typeof (float)), - (float) info.GetValue("m_LastChildAgentUpdatePosition.Z", typeof (float))); + /// + /// + /// + public void StopMovement() + { + } - m_perfMonMS = (int) info.GetValue("m_perfMonMS", typeof (int)); - m_AgentControlFlags = (uint) info.GetValue("m_AgentControlFlags", typeof (uint)); + public void StopFlying() + { + // It turns out to get the agent to stop flying, you have to feed it stop flying velocities + // and send a full object update. + // There's no message to send the client to tell it to stop flying - m_headrotation - = new LLQuaternion( - (float) info.GetValue("m_headrotation.W", typeof (float)), - (float) info.GetValue("m_headrotation.X", typeof (float)), - (float) info.GetValue("m_headrotation.Y", typeof (float)), - (float) info.GetValue("m_headrotation.Z", typeof (float))); + // Add 1/6 the avatar's height to it's position so it doesn't shoot into the air + // when the avatar stands up - m_state = (byte) info.GetValue("m_state", typeof (byte)); + if (m_avHeight != 127.0f) + { + AbsolutePosition = AbsolutePosition + new LLVector3(0, 0, (m_avHeight / 6)); + } + else + { + AbsolutePosition = AbsolutePosition + new LLVector3(0, 0, (1.56f / 6)); + } + SetMovementAnimation(Animations.AnimsLLUUID["LAND"]); + SendFullUpdateToAllClients(); + } - List knownPrimUUID_work = (List) info.GetValue("m_knownPrimUUID", typeof (List)); + public void AddNeighbourRegion(ulong regionHandle) + { + if (!m_knownChildRegions.Contains(regionHandle)) + { + m_knownChildRegions.Add(regionHandle); + } + } - foreach (Guid id in knownPrimUUID_work) + public void RemoveNeighbourRegion(ulong regionHandle) + { + if (!m_knownChildRegions.Contains(regionHandle)) { - m_knownPrimUUID.Add(new LLUUID(id)); + m_knownChildRegions.Remove(regionHandle); } + } - //System.Console.WriteLine("ScenePresence Deserialize END"); + public List GetKnownRegionList() + { + return m_knownChildRegions; } - #region ISerializable Members + #endregion - [SecurityPermission(SecurityAction.LinkDemand, - Flags = SecurityPermissionFlag.SerializationFormatter)] - public override void GetObjectData( - SerializationInfo info, StreamingContext context) + #region Event Handlers + + /// + /// Sets avatar height in the phyiscs plugin + /// + internal void SetHeight(float height) { - if (info == null) + m_avHeight = height; + if (PhysicsActor != null) { - throw new ArgumentNullException("info"); + PhysicsVector SetSize = new PhysicsVector(0.45f, 0.6f, m_avHeight); + PhysicsActor.Size = SetSize; } + } - base.GetObjectData(info, context); + /// + /// Complete Avatar's movement into the region + /// + public void CompleteMovement() + { + LLVector3 look = Velocity; + if ((look.X == 0) && (look.Y == 0) && (look.Z == 0)) + { + look = new LLVector3(0.99f, 0.042f, 0); + } - List animations_work = new List(); + m_controllingClient.MoveAgentIntoRegion(m_regionInfo, AbsolutePosition, look); - foreach (LLUUID uuid in m_animations) + if (m_isChildAgent) { - animations_work.Add(uuid.UUID); + m_isChildAgent = false; + + //this.m_scene.SendAllSceneObjectsToClient(this.ControllingClient); + MakeRootAgent(AbsolutePosition, false); } + } - info.AddValue("m_animations", animations_work); + /// + /// This is the event handler for client movement. If a client is moving, this event is triggering. + /// + public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdatePacket agentData) + { + //if (m_isChildAgent) + //{ + // // Console.WriteLine("DEBUG: HandleAgentUpdate: child agent"); + // return; + //} - info.AddValue("m_animationSeqs", m_animationSeqs); - info.AddValue("m_updateflag", m_updateflag); - info.AddValue("m_movementflag", m_movementflag); - info.AddValue("m_forcesList", m_forcesList); - info.AddValue("m_updateCount", m_updateCount); - info.AddValue("m_requestedSitTargetID", m_requestedSitTargetID); + // Must check for standing up even when PhysicsActor is null, + // since sitting currently removes avatar from physical scene - // LLVector3 - info.AddValue("m_requestedSitOffset.X", m_requestedSitOffset.X); - info.AddValue("m_requestedSitOffset.Y", m_requestedSitOffset.Y); - info.AddValue("m_requestedSitOffset.Z", m_requestedSitOffset.Z); + m_perfMonMS = System.Environment.TickCount; - info.AddValue("m_sitAvatarHeight", m_sitAvatarHeight); - info.AddValue("m_godlevel", m_godlevel); - info.AddValue("m_setAlwaysRun", m_setAlwaysRun); + uint flags = agentData.AgentData.ControlFlags; + LLQuaternion bodyRotation = agentData.AgentData.BodyRotation; - // Quaternion - info.AddValue("m_bodyRot.w", m_bodyRot.w); - info.AddValue("m_bodyRot.x", m_bodyRot.x); - info.AddValue("m_bodyRot.y", m_bodyRot.y); - info.AddValue("m_bodyRot.z", m_bodyRot.z); + // Camera location in world. We'll need to raytrace + // from this location from time to time. + m_CameraCenter.x = agentData.AgentData.CameraCenter.X; + m_CameraCenter.y = agentData.AgentData.CameraCenter.Y; + m_CameraCenter.z = agentData.AgentData.CameraCenter.Z; - info.AddValue("IsRestrictedToRegion", IsRestrictedToRegion); - info.AddValue("m_newForce", m_newForce); - //info.AddValue("m_newAvatar", m_newAvatar); - info.AddValue("m_newCoarseLocations", m_newCoarseLocations); - info.AddValue("m_gotAllObjectsInScene", m_gotAllObjectsInScene); - info.AddValue("m_avHeight", m_avHeight); + // Use these three vectors to figure out what the agent is looking at + // Convert it to a Matrix and/or Quaternion + m_CameraAtAxis.x = agentData.AgentData.CameraAtAxis.X; + m_CameraAtAxis.y = agentData.AgentData.CameraAtAxis.Y; + m_CameraAtAxis.z = agentData.AgentData.CameraAtAxis.Z; - // info.AddValue("m_regionInfo", m_regionInfo); + m_CameraLeftAxis.x = agentData.AgentData.CameraLeftAxis.X; + m_CameraLeftAxis.y = agentData.AgentData.CameraLeftAxis.Y; + m_CameraLeftAxis.z = agentData.AgentData.CameraLeftAxis.Z; - info.AddValue("crossingFromRegion", crossingFromRegion); + m_CameraUpAxis.x = agentData.AgentData.CameraUpAxis.X; + m_CameraUpAxis.y = agentData.AgentData.CameraUpAxis.Y; + m_CameraUpAxis.z = agentData.AgentData.CameraUpAxis.Z; - List Dir_Vectors_work = new List(); + // The Agent's Draw distance setting + m_DrawDistance = agentData.AgentData.Far; - foreach (Vector3 v3 in Dir_Vectors) + if ((flags & (uint) AgentManager.ControlFlags.AGENT_CONTROL_STAND_UP) != 0) { - Dir_Vectors_work.Add(new[] {v3.x, v3.y, v3.z}); + StandUp(); } - info.AddValue("Dir_Vectors", Dir_Vectors_work); + if (PhysicsActor == null) + { + return; + } - // LLVector3 - info.AddValue("lastPhysPos.X", lastPhysPos.X); - info.AddValue("lastPhysPos.Y", lastPhysPos.Y); - info.AddValue("lastPhysPos.Z", lastPhysPos.Z); + if ((flags & (uint) AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) + { + // TODO: This doesn't quite work yet -- probably a parent ID problem + // m_parentID = (what should this be?) + SetMovementAnimation(Animations.AnimsLLUUID["SIT_GROUND"]); + } + // In the future, these values might need to go global. + // Here's where you get them. - // Vector3 - info.AddValue("m_CameraCenter.X", m_CameraCenter.x); - info.AddValue("m_CameraCenter.Y", m_CameraCenter.y); - info.AddValue("m_CameraCenter.Z", m_CameraCenter.z); + // m_AgentControlFlags = flags; + // m_headrotation = agentData.AgentData.HeadRotation; + // m_state = agentData.AgentData.State; - // Vector3 - info.AddValue("m_CameraAtAxis.X", m_CameraAtAxis.x); - info.AddValue("m_CameraAtAxis.Y", m_CameraAtAxis.y); - info.AddValue("m_CameraAtAxis.Z", m_CameraAtAxis.z); + if (m_allowMovement) + { + int i = 0; + bool update_movementflag = false; + bool update_rotation = false; + bool DCFlagKeyPressed = false; + Vector3 agent_control_v3 = new Vector3(0, 0, 0); + Quaternion q = new Quaternion(bodyRotation.W, bodyRotation.X, bodyRotation.Y, bodyRotation.Z); + bool oldflying = PhysicsActor.Flying; - // Vector3 - info.AddValue("m_CameraLeftAxis.X", m_CameraLeftAxis.x); - info.AddValue("m_CameraLeftAxis.Y", m_CameraLeftAxis.y); - info.AddValue("m_CameraLeftAxis.Z", m_CameraLeftAxis.z); + PhysicsActor.Flying = ((flags & (uint) AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); + if (PhysicsActor.Flying != oldflying) + { + update_movementflag = true; + } - // Vector3 - info.AddValue("m_CameraUpAxis.X", m_CameraUpAxis.x); - info.AddValue("m_CameraUpAxis.Y", m_CameraUpAxis.y); - info.AddValue("m_CameraUpAxis.Z", m_CameraUpAxis.z); + if (q != m_bodyRot) + { + m_bodyRot = q; + update_rotation = true; + } - info.AddValue("m_DrawDistance", m_DrawDistance); - info.AddValue("m_appearance", m_appearance); - info.AddValue("m_knownChildRegions", m_knownChildRegions); + if (m_parentID == 0) + { + foreach (Dir_ControlFlags DCF in Enum.GetValues(typeof (Dir_ControlFlags))) + { + if ((flags & (uint) DCF) != 0) + { + DCFlagKeyPressed = true; + try + { + agent_control_v3 += Dir_Vectors[i]; + } + catch (IndexOutOfRangeException) + { + // Why did I get this? + } + if ((m_movementflag & (uint) DCF) == 0) + { + m_movementflag += (byte) (uint) DCF; + update_movementflag = true; + } + } + else + { + if ((m_movementflag & (uint) DCF) != 0) + { + m_movementflag -= (byte) (uint) DCF; + update_movementflag = true; + } + } + i++; + } + } + // Cause the avatar to stop flying if it's colliding + // with something with the down arrow pressed. - // LLVector3 - info.AddValue("posLastSignificantMove.X", posLastSignificantMove.X); - info.AddValue("posLastSignificantMove.Y", posLastSignificantMove.Y); - info.AddValue("posLastSignificantMove.Z", posLastSignificantMove.Z); + // Skip if there's no physicsactor + if (m_physicsActor != null) + { + // Only do this if we're flying + if (m_physicsActor.Flying) + { + // Are the landing controls requirements filled? + bool controlland = (((flags & (uint) AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || + ((flags & (uint) AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); - //info.AddValue("m_partsUpdateQueue", m_partsUpdateQueue); + // Are the collision requirements fulfilled? + bool colliding = (m_physicsActor.IsColliding == true); - /* - Dictionary updateTimes_work = new Dictionary(); + - foreach ( LLUUID id in m_updateTimes.Keys) + if (m_physicsActor.Flying && colliding && controlland) + { + StopFlying(); + } + } + } + if ((update_movementflag) || (update_rotation && DCFlagKeyPressed)) + { + AddNewMovement(agent_control_v3, q); + UpdateMovementAnimations(update_movementflag); + } + } + + m_scene.EventManager.TriggerOnClientMovement(this); + + m_scene.AddAgentTime(System.Environment.TickCount - m_perfMonMS); + } + + /// + /// Perform the logic necessary to stand the client up. This method also executes + /// the stand animation. + /// + public void StandUp() + { + if (m_parentID != 0) { - updateTimes_work.Add(id.UUID, m_updateTimes[id]); + SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); + if (part != null) + { + // Reset sit target. + if (part.GetAvatarOnSitTarget() == UUID) + part.SetAvatarOnSitTarget(LLUUID.Zero); + + m_parentPosition = part.GetWorldPosition(); + } + + if (m_physicsActor == null) + { + AddToPhysicalScene(); + } + + m_pos += m_parentPosition + new LLVector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); + m_parentPosition = new LLVector3(); + + m_parentID = 0; + SendFullUpdateToAllClients(); + + if (m_physicsActor != null) + { + SetHeight(m_avHeight); + } } - info.AddValue("m_updateTimes", updateTimes_work); - */ + SetMovementAnimation(Animations.AnimsLLUUID["STAND"]); + } - info.AddValue("m_regionHandle", m_regionHandle); - info.AddValue("m_firstname", m_firstname); - info.AddValue("m_lastname", m_lastname); - info.AddValue("m_allowMovement", m_allowMovement); - //info.AddValue("m_physicsActor", m_physicsActor); - info.AddValue("m_parentPosition.X", m_parentPosition.X); - info.AddValue("m_parentPosition.Y", m_parentPosition.Y); - info.AddValue("m_parentPosition.Z", m_parentPosition.Z); - info.AddValue("m_isChildAgent", m_isChildAgent); - info.AddValue("m_parentID", m_parentID); + private void SendSitResponse(IClientAPI remoteClient, LLUUID targetID, LLVector3 offset) + { + AvatarSitResponsePacket avatarSitResponse = new AvatarSitResponsePacket(); -// for OpenSim_v0.5 - info.AddValue("currentParcelUUID", currentParcelUUID.UUID); + avatarSitResponse.SitObject.ID = targetID; - info.AddValue("lastKnownAllowedPosition.X", lastKnownAllowedPosition.x); - info.AddValue("lastKnownAllowedPosition.Y", lastKnownAllowedPosition.y); - info.AddValue("lastKnownAllowedPosition.Z", lastKnownAllowedPosition.z); + bool autopilot = true; + LLVector3 pos = new LLVector3(); + LLQuaternion sitOrientation = new LLQuaternion(0, 0, 0, 1); - info.AddValue("sentMessageAboutRestrictedParcelFlyingDown", sentMessageAboutRestrictedParcelFlyingDown); + SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); + if (part != null) + { + // TODO: determine position to sit at based on scene geometry; don't trust offset from client + // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it - info.AddValue("m_LastChildAgentUpdatePosition.X", m_LastChildAgentUpdatePosition.X); - info.AddValue("m_LastChildAgentUpdatePosition.Y", m_LastChildAgentUpdatePosition.Y); - info.AddValue("m_LastChildAgentUpdatePosition.Z", m_LastChildAgentUpdatePosition.Z); + // Is a sit target available? + Vector3 avSitOffSet = part.GetSitTargetPosition(); + Quaternion avSitOrientation = part.GetSitTargetOrientation(); + LLUUID avOnTargetAlready = part.GetAvatarOnSitTarget(); - info.AddValue("m_perfMonMS", m_perfMonMS); - info.AddValue("m_AgentControlFlags", m_AgentControlFlags); + bool SitTargetUnOccupied = (!(avOnTargetAlready != LLUUID.Zero)); + bool SitTargetisSet = + (!(avSitOffSet.x == 0 && avSitOffSet.y == 0 && avSitOffSet.z == 0 && avSitOrientation.w == 0 && + avSitOrientation.x == 0 && avSitOrientation.y == 0 && avSitOrientation.z == 1)); - info.AddValue("m_headrotation.W", m_headrotation.W); - info.AddValue("m_headrotation.X", m_headrotation.X); - info.AddValue("m_headrotation.Y", m_headrotation.Y); - info.AddValue("m_headrotation.Z", m_headrotation.Z); + if (SitTargetisSet && SitTargetUnOccupied) + { + part.SetAvatarOnSitTarget(UUID); + offset = new LLVector3(avSitOffSet.x, avSitOffSet.y, avSitOffSet.z); + sitOrientation = + new LLQuaternion(avSitOrientation.w, avSitOrientation.x, avSitOrientation.y, avSitOrientation.z); + autopilot = false; + } - info.AddValue("m_state", m_state); + pos = part.AbsolutePosition + offset; - List knownPrimUUID_work = new List(); + if (m_physicsActor != null) + { + // If we're not using the client autopilot, we're immediately warping the avatar to the location + // We can remove the physicsActor until they stand up. + m_sitAvatarHeight = m_physicsActor.Size.Z; - foreach (LLUUID id in m_knownPrimUUID) - { - knownPrimUUID_work.Add(id.UUID); + if (autopilot) + { + if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) + { + autopilot = false; + + RemoveFromPhysicalScene(); + AbsolutePosition = pos + new LLVector3(0.0f, 0.0f, m_sitAvatarHeight); + } + } + else + { + RemoveFromPhysicalScene(); + } + } } - info.AddValue("m_knownPrimUUID", knownPrimUUID_work); - } + avatarSitResponse.SitTransform.AutoPilot = autopilot; + avatarSitResponse.SitTransform.SitPosition = offset; + avatarSitResponse.SitTransform.SitRotation = sitOrientation; - #endregion + remoteClient.OutPacket(avatarSitResponse, ThrottleOutPacketType.Task); - public event SignificantClientMovement OnSignificantClientMovement; + // This calls HandleAgentSit twice, once from here, and the client calls + // HandleAgentSit itself after it gets to the location + // It doesn't get to the location until we've moved them there though + // which happens in HandleAgentSit :P + if (!autopilot) + HandleAgentSit(remoteClient, UUID); + } - /// - /// Add the part to the queue of parts for which we need to send an update to the client - /// - /// - public void QueuePartForUpdate(SceneObjectPart part) + public void HandleAgentRequestSit(IClientAPI remoteClient, LLUUID agentID, LLUUID targetID, LLVector3 offset) { - //if (InterestList.Contains(part.ParentGroup)) - //{ - lock (m_partsUpdateQueue) + if (m_parentID != 0) { - m_partsUpdateQueue.Enqueue(part); + StandUp(); } - // } - } - public uint GenerateClientFlags(LLUUID ObjectID) - { - return m_scene.PermissionsMngr.GenerateClientFlags(m_uuid, ObjectID); - } - - /// - /// Send updates to the client about prims which have been placed on the update queue. We don't - /// necessarily send updates for all the parts on the queue, e.g. if an updates with a more recent - /// timestamp has already been sent. - /// - public void SendPrimUpdates() - { - // if (m_scene.QuadTree.GetNodeID(this.AbsolutePosition.X, this.AbsolutePosition.Y) != m_currentQuadNode) - //{ - // this.UpdateQuadTreeNode(); - //this.RefreshQuadObject(); - //} - m_perfMonMS = System.Environment.TickCount; + SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); - if (!m_gotAllObjectsInScene) + if (part != null) { - if (!m_isChildAgent || m_scene.m_seeIntoRegionFromNeighbor) - { - m_scene.SendAllSceneObjectsToClient(this); - m_gotAllObjectsInScene = true; - } + m_requestedSitTargetID = part.LocalId; + m_requestedSitOffset = offset; } - - if (m_partsUpdateQueue.Count > 0) + else { - bool runUpdate = true; - int updateCount = 0; - while (runUpdate) - { - SceneObjectPart part = m_partsUpdateQueue.Dequeue(); - if (m_updateTimes.ContainsKey(part.UUID)) - { - ScenePartUpdate update = m_updateTimes[part.UUID]; - - // We deal with the possibility that two updates occur at the same unix time - // at the update point itself. - if (update.LastFullUpdateTime < part.TimeStampFull) - { -// m_log.DebugFormat( -// "[SCENE PRESENCE]: Fully updating prim {0}, {1} - part timestamp {2}", -// part.Name, part.UUID, part.TimeStampFull); + m_log.Warn("Sit requested on unknown object: " + targetID.ToString()); + } + SendSitResponse(remoteClient, targetID, offset); + } - part.SendFullUpdate(ControllingClient, GenerateClientFlags(part.UUID)); + public void HandleAgentSit(IClientAPI remoteClient, LLUUID agentID) + { + SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID); - // We'll update to the part's timestamp rather than the current time to - // avoid the race condition whereby the next tick occurs while we are - // doing this update. If this happened, then subsequent updates which occurred - // on the same tick or the next tick of the last update would be ignored. - update.LastFullUpdateTime = part.TimeStampFull; + if (part != null) + { + if (part.GetAvatarOnSitTarget() == UUID) + { + Vector3 sitTargetPos = part.GetSitTargetPosition(); + Quaternion sitTargetOrient = part.GetSitTargetOrientation(); - updateCount++; - } - else if (update.LastTerseUpdateTime <= part.TimeStampTerse) - { -// m_log.DebugFormat( -// "[SCENE PRESENCE]: Tersely updating prim {0}, {1} - part timestamp {2}", -// part.Name, part.UUID, part.TimeStampTerse); + //Quaternion vq = new Quaternion(sitTargetPos.x, sitTargetPos.y+0.2f, sitTargetPos.z+0.2f, 0); + //Quaternion nq = new Quaternion(sitTargetOrient.w, -sitTargetOrient.x, -sitTargetOrient.y, -sitTargetOrient.z); - part.SendTerseUpdate(ControllingClient); + //Quaternion result = (sitTargetOrient * vq) * nq; - update.LastTerseUpdateTime = part.TimeStampTerse; - updateCount++; - } - } - else - { - //never been sent to client before so do full update - part.SendFullUpdate(ControllingClient, GenerateClientFlags(part.UUID)); - ScenePartUpdate update = new ScenePartUpdate(); - update.FullID = part.UUID; - update.LastFullUpdateTime = part.TimeStampFull; - m_updateTimes.Add(part.UUID, update); - updateCount++; - } + m_pos = new LLVector3(sitTargetPos.x, sitTargetPos.y, sitTargetPos.z); + m_bodyRot = sitTargetOrient; + //Rotation = sitTargetOrient; + m_parentPosition = part.AbsolutePosition; - if (m_partsUpdateQueue.Count < 1 || updateCount > 60) - { - runUpdate = false; - } + //SendTerseUpdateToAllClients(); + } + else + { + m_pos -= part.AbsolutePosition; + m_parentPosition = part.AbsolutePosition; } } - m_scene.AddAgentTime(System.Environment.TickCount - m_perfMonMS); - } + m_parentID = m_requestedSitTargetID; - public void forceAvatarMovement(Vector3 position, Quaternion rotation) - { - AddNewMovement(position, rotation); + Velocity = new LLVector3(0, 0, 0); + RemoveFromPhysicalScene(); + + SetMovementAnimation(Animations.AnimsLLUUID["SIT"]); + SendFullUpdateToAllClients(); + // This may seem stupid, but Our Full updates don't send avatar rotation :P + // So we're also sending a terse update (which has avatar rotation) + SendTerseUpdateToAllClients(); } /// - /// This allows the Sim owner the abiility to kick users from their sim currently. - /// It tells the client that the agent has permission to do so. + /// Event handler for the 'Always run' setting on the client + /// Tells the physics plugin to increase speed of movement. /// - public void GrantGodlikePowers(LLUUID agentID, LLUUID sessionID, LLUUID token, bool godStatus) + public void HandleSetAlwaysRun(IClientAPI remoteClient, bool SetAlwaysRun) { - GrantGodlikePowersPacket respondPacket = new GrantGodlikePowersPacket(); - GrantGodlikePowersPacket.GrantDataBlock gdb = new GrantGodlikePowersPacket.GrantDataBlock(); - GrantGodlikePowersPacket.AgentDataBlock adb = new GrantGodlikePowersPacket.AgentDataBlock(); - - adb.AgentID = agentID; - adb.SessionID = sessionID; // More security - - if (godStatus) - { - gdb.GodLevel = 250; - m_godlevel = 250; - } - else + m_setAlwaysRun = SetAlwaysRun; + if (PhysicsActor != null) { - gdb.GodLevel = 0; - m_godlevel = 0; + PhysicsActor.SetAlwaysRun = SetAlwaysRun; } - - gdb.Token = token; - //respondPacket.AgentData = (GrantGodlikePowersPacket.AgentDataBlock)ablock; - respondPacket.GrantData = gdb; - respondPacket.AgentData = adb; - ControllingClient.OutPacket(respondPacket, ThrottleOutPacketType.Task); } - /// - /// This updates important decision making data about a child agent - /// The main purpose is to figure out what objects to send to a child agent that's in a neighboring region - /// - public void ChildAgentDataUpdate(ChildAgentDataUpdate cAgentData, uint tRegionX, uint tRegionY, uint rRegionX, uint rRegionY) + public void AddAnimation(LLUUID animID) { - // - int shiftx = ((int) rRegionX - (int) tRegionX) * (int) Constants.RegionSize; - int shifty = ((int) rRegionY - (int) tRegionY) * (int) Constants.RegionSize; - - m_DrawDistance = cAgentData.drawdistance; - m_pos = new LLVector3(cAgentData.Position.x + shiftx, cAgentData.Position.y + shifty, cAgentData.Position.z); - - // It's hard to say here.. We can't really tell where the camera position is unless it's in world cordinates from the sending region - m_CameraCenter = - new Vector3(cAgentData.cameraPosition.x, cAgentData.cameraPosition.y, cAgentData.cameraPosition.z); - - - m_godlevel = cAgentData.godlevel; - SetHeight(cAgentData.AVHeight); - - ControllingClient.SetChildAgentThrottle(cAgentData.throttles); + if(m_isChildAgent) + return; + // Don't let this animation become the movement animation + if(m_animations.Count < 1) + SetMovementAnimation(Animations.AnimsLLUUID["STAND"]); - // Sends out the objects in the user's draw distance if m_sendTasksToChild is true. - if (m_scene.m_seeIntoRegionFromNeighbor) - m_scene.SendAllSceneObjectsToClient(this); - //cAgentData.AVHeight; - //cAgentData.regionHandle; - //m_velocity = cAgentData.Velocity; + if (!m_animations.Contains(animID)) + { + m_animations.Add(animID); + m_animationSeqs.Add(m_controllingClient.NextAnimationSequenceNumber); + SendAnimPack(); + } } - /// - /// Handles part of the PID controller function for moving an avatar. - /// - public override void UpdateMovement() + public void RemoveAnimation(LLUUID animID) { - m_newForce = false; - lock (m_forcesList) + if(m_isChildAgent) + return; + + if (m_animations.Contains(animID)) { - if (m_forcesList.Count > 0) + if (m_animations[0] == animID) { - for (int i = 0; i < m_forcesList.Count; i++) - { - NewForce force = m_forcesList[i]; + SetMovementAnimation(Animations.AnimsLLUUID["STAND"]); + } + else + { + // What a HACK!! Anim list really needs to be an object! + int idx; - m_updateflag = true; - try - { - movementvector.X = force.X; - movementvector.Y = force.Y; - movementvector.Z = force.Z; - Velocity = movementvector; - } - catch (NullReferenceException) + for(idx=0;idx < m_animations.Count;idx++) + { + if(m_animations[idx] == animID) { - // Under extreme load, this returns a NullReference Exception that we can ignore. - // Ignoring this causes no movement to be sent to the physics engine... - // which when the scene is moving at 1 frame every 10 seconds, it doesn't really matter! + int seq=m_animationSeqs[idx]; + + m_animations.Remove(animID); + m_animationSeqs.Remove(seq); + SendAnimPack(); + break; } - m_newForce = true; - } - for (int i = 0; i < m_forcesList.Count; i++) - { - m_forcesList.RemoveAt(0); } } } } - public override void SetText(string text, Vector3 color, double alpha) + public void HandleStartAnim(IClientAPI remoteClient, LLUUID animID) { - throw new Exception("Can't set Text on avatar."); + AddAnimation(animID); + } + + public void HandleStopAnim(IClientAPI remoteClient, LLUUID animID) + { + RemoveAnimation(animID); } /// - /// Adds a physical representation of the avatar to the Physics plugin + /// The movement animation is the first element of the animation list, + /// reserved for "main" animations that are mutually exclusive, + /// like flying and sitting, for example. /// - public void AddToPhysicalScene() + protected void SetMovementAnimation(LLUUID anim) { - PhysicsScene scene = m_scene.PhysicsScene; - - PhysicsVector pVec = - new PhysicsVector(AbsolutePosition.X, AbsolutePosition.Y, - AbsolutePosition.Z); - if (m_avHeight == 127.0f) + if(m_animations.Count < 1) { - m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec, new PhysicsVector(0, 0, 1.56f)); + m_animations.Add(Animations.AnimsLLUUID["STAND"]); + m_animationSeqs.Add(1); + + SendAnimPack(); } else { - m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec, new PhysicsVector(0, 0, m_avHeight)); - } - //m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; - m_physicsActor.OnCollisionUpdate += PhysicsCollisionUpdate; - m_physicsActor.LocalID = LocalId; - } - - // Event called by the physics plugin to tell the avatar about a collision. - private void PhysicsCollisionUpdate(EventArgs e) - { - bool isUserMoving = Velocity.X > 0 || Velocity.Y > 0; - UpdateMovementAnimations(isUserMoving); + try + { + if (m_animations[0] != anim) + { + m_animations[0] = anim; + m_animationSeqs[0] = m_controllingClient.NextAnimationSequenceNumber; + } + SendAnimPack(); + } + catch + { + m_log.Warn("[AVATAR]: SetMovementAnimation for avatar failed. Attempting recovery..."); + m_animations[0] = anim; + m_animationSeqs[0] = m_controllingClient.NextAnimationSequenceNumber; + SendAnimPack(); + } + } } - internal void Close() + /// + /// This method handles agent movement related animations + /// + protected void UpdateMovementAnimations(bool update_movementflag) { - lock (m_attachments) + + + if (update_movementflag) { - foreach (SceneObjectGroup grp in m_attachments) + // Are we moving? + if (m_movementflag != 0) { - // ControllingClient may be null at this point! - m_scene.m_innerScene.DetachSingleAttachmentToInv(grp.GetFromAssetID(), ControllingClient); + // We are moving + + if (m_physicsActor.Flying) + { + // We are flying + SetMovementAnimation(Animations.AnimsLLUUID["FLY"]); + } + else if (((m_movementflag & (uint) AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) && + PhysicsActor.IsColliding) + { + // Client is pressing the page down button and moving and is colliding with something + SetMovementAnimation(Animations.AnimsLLUUID["CROUCHWALK"]); + } + else if (!PhysicsActor.IsColliding && m_physicsActor.Velocity.Z < -6) + { + // Client is moving and falling at a velocity greater then 6 meters per unit + SetMovementAnimation(Animations.AnimsLLUUID["FALLDOWN"]); + } + else if (!PhysicsActor.IsColliding && Velocity.Z > 0 && + (m_movementflag & (uint) AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0) + { + // Client is moving, and colliding and pressing the page up button but isn't flying + try + { + SetMovementAnimation(Animations.AnimsLLUUID["JUMP"]); + } + catch (KeyNotFoundException) + { } + } + else if (m_setAlwaysRun) + { + // We are running + try + { + SetMovementAnimation(Animations.AnimsLLUUID["RUN"]); + } + catch (KeyNotFoundException) + { } + } + else + { + // We're moving, but we're not doing anything else.. so play the stand animation + try + { + SetMovementAnimation(Animations.AnimsLLUUID["WALK"]); + } + catch (KeyNotFoundException) + { } + + } + } + else + { + // Not moving + + if (((m_movementflag & (uint) AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) && + PhysicsActor.IsColliding) + { + // Client pressing the page down button + SetMovementAnimation(Animations.AnimsLLUUID["CROUCH"]); + } + else if (!PhysicsActor.IsColliding && m_physicsActor.Velocity.Z < -6 && !m_physicsActor.Flying) + { + // Not colliding and not flying, and we're falling at high speed + SetMovementAnimation(Animations.AnimsLLUUID["FALLDOWN"]); + } + else if (!PhysicsActor.IsColliding && Velocity.Z > 0 && !m_physicsActor.Flying && + (m_movementflag & (uint) AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0) + { + // This is the standing jump + SetMovementAnimation(Animations.AnimsLLUUID["JUMP"]); + } + else if (m_physicsActor.Flying) + { + // We're flying but not moving + SetMovementAnimation(Animations.AnimsLLUUID["HOVER"]); + } + else + { + // We're not moving.. and we're not doing anything.. so play the stand animation + try + { + + SetMovementAnimation(Animations.AnimsLLUUID["STAND"]); + } + catch (KeyNotFoundException) + { } + } } - m_attachments.Clear(); - } - lock (m_knownPrimUUID) - { - m_knownPrimUUID.Clear(); } - lock (m_knownChildRegions) + + } + + /// + /// Adds a new movement + /// + protected void AddNewMovement(Vector3 vec, Quaternion rotation) + { + if (m_isChildAgent) { - m_knownChildRegions.Clear(); + Console.WriteLine("DEBUG: AddNewMovement: child agent"); + return; } - lock (m_updateTimes) + + m_perfMonMS = System.Environment.TickCount; + + m_rotation = rotation; + NewForce newVelocity = new NewForce(); + Vector3 direc = rotation*vec; + direc.Normalize(); + + direc *= 0.03f*128f; + if (m_physicsActor.Flying) { - m_updateTimes.Clear(); + direc *= 4; + //bool controlland = (((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); + //bool colliding = (m_physicsActor.IsColliding==true); + //if (controlland) + // m_log.Info("[AGENT]: landCommand"); + //if (colliding ) + // m_log.Info("[AGENT]: colliding"); + //if (m_physicsActor.Flying && colliding && controlland) + //{ + // StopFlying(); + // m_log.Info("[AGENT]: Stop FLying"); + //} } - lock (m_partsUpdateQueue) + else { - m_partsUpdateQueue.Clear(); + if (!m_physicsActor.Flying && m_physicsActor.IsColliding) + { + //direc.z *= 40; + if (direc.z > 2.0f) + { + direc.z *= 3; + //System.Console.WriteLine("Jump"); + // PreJump and jump happen too quickly. Many times prejump gets ignored. + try + { + SetMovementAnimation(Animations.AnimsLLUUID["PREJUMP"]); + SetMovementAnimation(Animations.AnimsLLUUID["JUMP"]); + } + catch (KeyNotFoundException) + { } + } + } } - RemoveFromPhysicalScene(); - GC.Collect(); + newVelocity.X = direc.x; + newVelocity.Y = direc.y; + newVelocity.Z = direc.z; + m_forcesList.Add(newVelocity); + + m_scene.AddAgentTime(System.Environment.TickCount - m_perfMonMS); } - public void AddAttachment(SceneObjectGroup gobj) + #endregion + + #region Overridden Methods + + /// + /// + /// + public override void Update() { - lock (m_attachments) + SendPrimUpdates(); + + if (m_newCoarseLocations) { - m_attachments.Add(gobj); + SendCoarseLocations(); + m_newCoarseLocations = false; } - } - public void RemoveAttachment(SceneObjectGroup gobj) - { - lock (m_attachments) + if (m_isChildAgent == false) { - if (m_attachments.Contains(gobj)) + if (m_newForce) // user movement 'forces' (ie commands to move) { - m_attachments.Remove(gobj); + SendTerseUpdateToAllClients(); + m_updateCount = 0; } - } - } - - public void CrossAttachmentsIntoNewRegion(ulong regionHandle) - { - lock (m_attachments) - { - foreach (SceneObjectGroup gobj in m_attachments) + else if (m_movementflag != 0) // scripted movement (?) { - // If the prim group is null then something must have happened to it! - if (gobj != null) + m_updateCount++; + if (m_updateCount > 3) { - // Set the parent localID to 0 so it transfers over properly. - gobj.RootPart.SetParentLocalId(0); - gobj.RootPart.m_IsAttachment = false; - gobj.AbsolutePosition = gobj.RootPart.m_attachedPos; - gobj.RootPart.LastOwnerID = gobj.GetFromAssetID(); - m_scene.CrossPrimGroupIntoNewRegion(regionHandle, gobj); + SendTerseUpdateToAllClients(); + m_updateCount = 0; } } - m_attachments.Clear(); - } - } + else if ((Util.GetDistanceTo(lastPhysPos, AbsolutePosition) > 0.02) || (Util.GetDistanceTo(m_lastVelocity, m_velocity) > 0.02)) // physics-related movement + { - public void initializeScenePresence(IClientAPI client, RegionInfo region, Scene scene) - { - m_controllingClient = client; - m_regionInfo = region; - m_scene = scene; - RegisterToEvents(); + + // Send Terse Update to all clients updates lastPhysPos and m_lastVelocity + // doing the above assures us that we know what we sent the clients last + SendTerseUpdateToAllClients(); + m_updateCount = 0; + - /* - AbsolutePosition = client.StartPos; + + } - Animations = new AvatarAnimations(); - Animations.LoadAnims(); + // followed suggestion from mic bowman. reversed the two lines below. + CheckForBorderCrossing(); + CheckForSignificantMovement(); // sends update to the modules. + + } + } - m_animations = new List(); - m_animations.Add(Animations.AnimsLLUUID["STAND"]); - m_animationSeqs.Add(m_controllingClient.NextAnimationSequenceNumber); + #endregion - SetDirectionVectors(); - */ - } + #region Update Client(s) - #region Status Methods + /// + /// Sends a location update to the client connected to this scenePresence + /// + /// + public void SendTerseUpdateToClient(IClientAPI remoteClient) + { + m_perfMonMS = System.Environment.TickCount; + + LLVector3 pos = m_pos; + LLVector3 vel = Velocity; + LLQuaternion rot = new LLQuaternion(m_bodyRot.x, m_bodyRot.y, m_bodyRot.z, m_bodyRot.w); + remoteClient.SendAvatarTerseUpdate(m_regionHandle, (ushort)(m_scene.TimeDilation * (float)ushort.MaxValue), LocalId, new LLVector3(pos.X, pos.Y, pos.Z), + new LLVector3(vel.X, vel.Y, vel.Z), rot); + + m_scene.AddAgentTime(System.Environment.TickCount - m_perfMonMS); + m_scene.AddAgentUpdates(1); + } /// - /// This turns a child agent, into a root agent - /// This is called when an agent teleports into a region, or if an - /// agent crosses into this region from a neighbor over the border + /// Send a location/velocity/accelleration update to all agents in scene /// - public void MakeRootAgent(LLVector3 pos, bool isFlying) + public void SendTerseUpdateToAllClients() { -// m_log.DebugFormat( -// "[SCENEPRESENCE]: Upgrading child agent {0}, {1} to a root agent in {2}", -// Name, UUID, m_scene.RegionInfo.RegionName); + m_perfMonMS = System.Environment.TickCount; - m_isChildAgent = false; + m_scene.Broadcast(SendTerseUpdateToClient); - AbsolutePosition = pos; + m_lastVelocity = m_velocity; + lastPhysPos = AbsolutePosition; - AddToPhysicalScene(); - m_physicsActor.Flying = isFlying; - SendAnimPack(); + m_scene.AddAgentTime(System.Environment.TickCount - m_perfMonMS); + + } - m_scene.SwapRootAgentCount(false); - m_scene.CommsManager.UserProfileCacheService.RequestInventoryForUser(m_uuid); - m_scene.AddCapsHandler(m_uuid); - //if (!m_gotAllObjectsInScene) - //{ - m_scene.SendAllSceneObjectsToClient(this); - m_scene.LandChannel.sendLandUpdate(this, true); + public void SendCoarseLocations() + { + m_perfMonMS = System.Environment.TickCount; - //m_gotAllObjectsInScene = true; - //} + List CoarseLocations = new List(); + List avatars = m_scene.GetAvatars(); + for (int i = 0; i < avatars.Count; i++) + { + if (avatars[i] != this) + { + CoarseLocations.Add(avatars[i].m_pos); + } + } + + m_controllingClient.SendCoarseLocationUpdate(CoarseLocations); + + m_scene.AddAgentTime(System.Environment.TickCount - m_perfMonMS); + } + + public void CoarseLocationChange() + { + m_newCoarseLocations = true; } /// - /// This turns a root agent into a child agent - /// when an agent departs this region for a neighbor, this gets called. - /// - /// It doesn't get called for a teleport. Reason being, an agent that - /// teleports out may not be anywhere near this region + /// Tell other client about this avatar (The client previously didn't know or had outdated details about this avatar) /// - public void MakeChildAgent() + /// + public void SendFullUpdateToOtherClient(ScenePresence remoteAvatar) { - if (m_animations.Count > 0) - { - LLUUID movement = m_animations[0]; + remoteAvatar.m_controllingClient.SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_uuid, + LocalId, m_pos, m_appearance.TextureEntry.ToBytes(), + m_parentID); + m_scene.AddAgentUpdates(1); + } - m_animations.Clear(); - m_animationSeqs.Clear(); + /// + /// Tell *ALL* agents about this agent + /// + public void SendFullUpdateToAllClients() + { + m_perfMonMS = System.Environment.TickCount; - SetMovementAnimation(movement); + List avatars = m_scene.GetScenePresences(); + foreach (ScenePresence avatar in avatars) + { + SendFullUpdateToOtherClient(avatar); + if (avatar.LocalId != LocalId) + { + if (!avatar.m_isChildAgent || m_scene.m_seeIntoRegionFromNeighbor) + { + avatar.SendFullUpdateToOtherClient(this); + avatar.SendAppearanceToOtherAgent(this); + } + } } -// m_log.DebugFormat( -// "[SCENEPRESENCE]: Downgrading child agent {0}, {1} to a root agent in {2}", -// Name, UUID, m_scene.RegionInfo.RegionName); - - Velocity = new LLVector3(0, 0, 0); - m_isChildAgent = true; - m_scene.SwapRootAgentCount(true); - RemoveFromPhysicalScene(); - m_scene.EventManager.TriggerOnMakeChildAgent(this); - //this.Pos = new LLVector3(128, 128, 70); + m_scene.AddAgentUpdates(avatars.Count); + m_scene.AddAgentTime(System.Environment.TickCount - m_perfMonMS); } /// - /// Removes physics plugin scene representation of this agent if it exists. + /// /// - private void RemoveFromPhysicalScene() + public void SendInitialData() { - if (PhysicsActor != null) + m_controllingClient.SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_uuid, LocalId, + m_pos, m_appearance.TextureEntry.ToBytes(), m_parentID); + if (!m_isChildAgent) { - m_scene.PhysicsScene.RemoveAvatar(PhysicsActor); - m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; - m_physicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; - PhysicsActor = null; + m_scene.InformClientOfNeighbours(this); } + + SendFullUpdateToAllClients(); + SendAppearanceToAllOtherAgents(); } /// /// /// - /// - public void Teleport(LLVector3 pos) + /// + public void SendOwnAppearance() { - RemoveFromPhysicalScene(); - Velocity = new LLVector3(0, 0, 0); - AbsolutePosition = pos; - AddToPhysicalScene(); - SendTerseUpdateToAllClients(); + m_appearance.SendOwnWearables(ControllingClient); + + // TODO: remove this once the SunModule is slightly more tested + // m_controllingClient.SendViewerTime(m_scene.TimePhase); } /// /// /// - public void StopMovement() + public void SendAppearanceToAllOtherAgents() { + m_perfMonMS=System.Environment.TickCount; + + m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) + { + if (scenePresence.UUID != UUID) + { + m_appearance.SendAppearanceToOtherAgent(scenePresence); + } + }); + m_scene.AddAgentTime(System.Environment.TickCount - m_perfMonMS); } - public void StopFlying() + public void SendAppearanceToOtherAgent(ScenePresence avatar) { - // It turns out to get the agent to stop flying, you have to feed it stop flying velocities - // and send a full object update. - // There's no message to send the client to tell it to stop flying + m_appearance.SendAppearanceToOtherAgent(avatar); + } - // Add 1/6 the avatar's height to it's position so it doesn't shoot into the air - // when the avatar stands up + public void SetAppearance(byte[] texture, AgentSetAppearancePacket.VisualParamBlock[] visualParam) + { + m_appearance.SetAppearance(texture, visualParam); + SetHeight(m_appearance.AvatarHeight); - if (m_avHeight != 127.0f) - { - AbsolutePosition = AbsolutePosition + new LLVector3(0, 0, (m_avHeight / 6)); - } - else - { - AbsolutePosition = AbsolutePosition + new LLVector3(0, 0, (1.56f / 6)); - } - SetMovementAnimation(Animations.AnimsLLUUID["LAND"]); - SendFullUpdateToAllClients(); + SendAppearanceToAllOtherAgents(); } - public void AddNeighbourRegion(ulong regionHandle) + public void SetWearable(int wearableId, AvatarWearable wearable) { - if (!m_knownChildRegions.Contains(regionHandle)) - { - m_knownChildRegions.Add(regionHandle); - } + m_appearance.SetWearable(ControllingClient, wearableId, wearable); } - public void RemoveNeighbourRegion(ulong regionHandle) + /// + /// + /// + /// + /// + public void SendAnimPack(LLUUID[] animations, int[] seqs) { - if (!m_knownChildRegions.Contains(regionHandle)) - { - m_knownChildRegions.Remove(regionHandle); - } + if(m_isChildAgent) + return; + + m_scene.Broadcast( + delegate(IClientAPI client) { client.SendAnimations(animations, seqs, m_controllingClient.AgentId); }); } - public List GetKnownRegionList() + /// + /// + /// + public void SendAnimPack() { - return m_knownChildRegions; + SendAnimPack(m_animations.ToArray(), m_animationSeqs.ToArray()); } #endregion - #region Event Handlers + #region Significant Movement Method /// - /// Sets avatar height in the phyiscs plugin + /// This checks for a significant movement and sends a courselocationchange update /// - internal void SetHeight(float height) + protected void CheckForSignificantMovement() { - m_avHeight = height; - if (PhysicsActor != null) + if (Util.GetDistanceTo(AbsolutePosition, posLastSignificantMove) > 0.5) { - PhysicsVector SetSize = new PhysicsVector(0.45f, 0.6f, m_avHeight); - PhysicsActor.Size = SetSize; + posLastSignificantMove = AbsolutePosition; + handlerSignificantClientMovement = OnSignificantClientMovement; + if (handlerSignificantClientMovement != null) + { + handlerSignificantClientMovement(m_controllingClient); + m_scene.NotifyMyCoarseLocationChange(); + } } - } - /// - /// Complete Avatar's movement into the region - /// - public void CompleteMovement() - { - LLVector3 look = Velocity; - if ((look.X == 0) && (look.Y == 0) && (look.Z == 0)) + // Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m + if (Util.GetDistanceTo(AbsolutePosition,m_LastChildAgentUpdatePosition) > 32) { - look = new LLVector3(0.99f, 0.042f, 0); + ChildAgentDataUpdate cadu = new ChildAgentDataUpdate(); + cadu.ActiveGroupID=LLUUID.Zero.UUID; + cadu.AgentID = UUID.UUID; + cadu.alwaysrun = m_setAlwaysRun; + cadu.AVHeight = m_avHeight; + LLVector3 tempCameraCenter = new LLVector3(m_CameraCenter.x, m_CameraCenter.y, m_CameraCenter.z); + cadu.cameraPosition = new sLLVector3(tempCameraCenter); + cadu.drawdistance = m_DrawDistance; + cadu.godlevel = m_godlevel; + cadu.GroupAccess = 0; + cadu.Position = new sLLVector3(AbsolutePosition); + cadu.regionHandle = m_scene.RegionInfo.RegionHandle; + cadu.throttles = ControllingClient.GetThrottlesPacked(1f); + cadu.Velocity = new sLLVector3(Velocity); + m_scene.SendOutChildAgentUpdates(cadu,this); + m_LastChildAgentUpdatePosition.X = AbsolutePosition.X; + m_LastChildAgentUpdatePosition.Y = AbsolutePosition.Y; + m_LastChildAgentUpdatePosition.Z = AbsolutePosition.Z; } + } - m_controllingClient.MoveAgentIntoRegion(m_regionInfo, AbsolutePosition, look); + #endregion - if (m_isChildAgent) - { - m_isChildAgent = false; - - //this.m_scene.SendAllSceneObjectsToClient(this.ControllingClient); - MakeRootAgent(AbsolutePosition, false); - } - } + #region Border Crossing Methods /// - /// This is the event handler for client movement. If a client is moving, this event is triggering. + /// Checks to see if the avatar is in range of a border and calls CrossToNewRegion /// - public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdatePacket agentData) + protected void CheckForBorderCrossing() { - //if (m_isChildAgent) - //{ - // // Console.WriteLine("DEBUG: HandleAgentUpdate: child agent"); - // return; - //} - - // Must check for standing up even when PhysicsActor is null, - // since sitting currently removes avatar from physical scene - - m_perfMonMS = System.Environment.TickCount; + LLVector3 pos2 = AbsolutePosition; + LLVector3 vel = Velocity; - uint flags = agentData.AgentData.ControlFlags; - LLQuaternion bodyRotation = agentData.AgentData.BodyRotation; + 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); - // Camera location in world. We'll need to raytrace - // from this location from time to time. - m_CameraCenter.x = agentData.AgentData.CameraCenter.X; - m_CameraCenter.y = agentData.AgentData.CameraCenter.Y; - m_CameraCenter.z = agentData.AgentData.CameraCenter.Z; + if ((pos2.X < 0) || (pos2.X > Constants.RegionSize)) + { + CrossToNewRegion(); + } - // Use these three vectors to figure out what the agent is looking at - // Convert it to a Matrix and/or Quaternion - m_CameraAtAxis.x = agentData.AgentData.CameraAtAxis.X; - m_CameraAtAxis.y = agentData.AgentData.CameraAtAxis.Y; - m_CameraAtAxis.z = agentData.AgentData.CameraAtAxis.Z; + if ((pos2.Y < 0) || (pos2.Y > Constants.RegionSize)) + { + CrossToNewRegion(); + } + } - m_CameraLeftAxis.x = agentData.AgentData.CameraLeftAxis.X; - m_CameraLeftAxis.y = agentData.AgentData.CameraLeftAxis.Y; - m_CameraLeftAxis.z = agentData.AgentData.CameraLeftAxis.Z; + /// + /// Moves the agent outside the region bounds + /// Tells neighbor region that we're crossing to it + /// If the neighbor accepts, remove the agent's viewable avatar from this scene + /// set them to a child agent. + /// + protected void CrossToNewRegion() + { + LLVector3 pos = AbsolutePosition; + LLVector3 newpos = new LLVector3(pos.X, pos.Y, pos.Z); + uint neighbourx = m_regionInfo.RegionLocX; + uint neighboury = m_regionInfo.RegionLocY; - m_CameraUpAxis.x = agentData.AgentData.CameraUpAxis.X; - m_CameraUpAxis.y = agentData.AgentData.CameraUpAxis.Y; - m_CameraUpAxis.z = agentData.AgentData.CameraUpAxis.Z; + // distance to edge that will trigger crossing + const float boundaryDistance = 1.7f; - // The Agent's Draw distance setting - m_DrawDistance = agentData.AgentData.Far; + // distance into new region to place avatar + const float enterDistance = 0.1f; - if ((flags & (uint) AgentManager.ControlFlags.AGENT_CONTROL_STAND_UP) != 0) + if (pos.X < boundaryDistance) { - StandUp(); + neighbourx--; + newpos.X = Constants.RegionSize - enterDistance; } - - if (PhysicsActor == null) + else if (pos.X > Constants.RegionSize - boundaryDistance) { - return; + neighbourx++; + newpos.X = enterDistance; } - if ((flags & (uint) AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) + if (pos.Y < boundaryDistance) { - // TODO: This doesn't quite work yet -- probably a parent ID problem - // m_parentID = (what should this be?) - SetMovementAnimation(Animations.AnimsLLUUID["SIT_GROUND"]); + neighboury--; + newpos.Y = Constants.RegionSize - enterDistance; } - // In the future, these values might need to go global. - // Here's where you get them. - - // m_AgentControlFlags = flags; - // m_headrotation = agentData.AgentData.HeadRotation; - // m_state = agentData.AgentData.State; - - if (m_allowMovement) + else if (pos.Y > Constants.RegionSize - boundaryDistance) { - int i = 0; - bool update_movementflag = false; - bool update_rotation = false; - bool DCFlagKeyPressed = false; - Vector3 agent_control_v3 = new Vector3(0, 0, 0); - Quaternion q = new Quaternion(bodyRotation.W, bodyRotation.X, bodyRotation.Y, bodyRotation.Z); - bool oldflying = PhysicsActor.Flying; - - PhysicsActor.Flying = ((flags & (uint) AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); - if (PhysicsActor.Flying != oldflying) - { - update_movementflag = true; - } - - if (q != m_bodyRot) - { - m_bodyRot = q; - update_rotation = true; - } - - if (m_parentID == 0) - { - foreach (Dir_ControlFlags DCF in Enum.GetValues(typeof (Dir_ControlFlags))) - { - if ((flags & (uint) DCF) != 0) - { - DCFlagKeyPressed = true; - try - { - agent_control_v3 += Dir_Vectors[i]; - } - catch (IndexOutOfRangeException) - { - // Why did I get this? - } - if ((m_movementflag & (uint) DCF) == 0) - { - m_movementflag += (byte) (uint) DCF; - update_movementflag = true; - } - } - else - { - if ((m_movementflag & (uint) DCF) != 0) - { - m_movementflag -= (byte) (uint) DCF; - update_movementflag = true; - } - } - i++; - } - } - // Cause the avatar to stop flying if it's colliding - // with something with the down arrow pressed. - - // Skip if there's no physicsactor - if (m_physicsActor != null) - { - // Only do this if we're flying - if (m_physicsActor.Flying) - { - // Are the landing controls requirements filled? - bool controlland = (((flags & (uint) AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || - ((flags & (uint) AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); - - // Are the collision requirements fulfilled? - bool colliding = m_physicsActor.IsColliding; - - - if (m_physicsActor.Flying && colliding && controlland) - { - StopFlying(); - } - } - } - if ((update_movementflag) || (update_rotation && DCFlagKeyPressed)) - { - AddNewMovement(agent_control_v3, q); - UpdateMovementAnimations(update_movementflag); - } + neighboury++; + newpos.Y = enterDistance; } - m_scene.EventManager.TriggerOnClientMovement(this); - - m_scene.AddAgentTime(System.Environment.TickCount - m_perfMonMS); - } - - /// - /// Perform the logic necessary to stand the client up. This method also executes - /// the stand animation. - /// - public void StandUp() - { - if (m_parentID != 0) - { - SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); - if (part != null) - { - // Reset sit target. - if (part.GetAvatarOnSitTarget() == UUID) - part.SetAvatarOnSitTarget(LLUUID.Zero); - - m_parentPosition = part.GetWorldPosition(); - } + LLVector3 vel = m_velocity; + ulong neighbourHandle = Helpers.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); + SimpleRegionInfo neighbourRegion = m_scene.RequestNeighbouringRegionInfo(neighbourHandle); + if (neighbourRegion != null) + { + // When the neighbour is informed of the border crossing, it will set up CAPS handlers for the avatar + // This means we need to remove the current caps handler here and possibly compensate later, + // in case both scenes are being hosted on the same region server. Messy + m_scene.RemoveCapsHandler(UUID); + newpos = newpos + (vel); + bool res = + m_scene.InformNeighbourOfCrossing(neighbourHandle, m_controllingClient.AgentId, newpos, + m_physicsActor.Flying); + if (res) + { + AgentCircuitData circuitdata = m_controllingClient.RequestClientInfo(); - if (m_physicsActor == null) - { - AddToPhysicalScene(); + // TODO Should construct this behind a method + string capsPath = + "http://" + neighbourRegion.ExternalHostName + ":" + neighbourRegion.HttpPort + + "/CAPS/" + circuitdata.CapsPath + "0000/"; + + m_log.DebugFormat( + "[CAPS]: Sending new CAPS seed url {0} to client {1}", capsPath, m_uuid); + + m_controllingClient.CrossRegion(neighbourHandle, newpos, vel, neighbourRegion.ExternalEndPoint, + capsPath); + MakeChildAgent(); + CrossAttachmentsIntoNewRegion(neighbourHandle); + m_scene.SendKillObject(m_localId); + m_scene.NotifyMyCoarseLocationChange(); } - - m_pos += m_parentPosition + new LLVector3(0.0f, 0.0f, 2.0f * m_sitAvatarHeight); - m_parentPosition = new LLVector3(); - - m_parentID = 0; - SendFullUpdateToAllClients(); - - if (m_physicsActor != null) + else { - SetHeight(m_avHeight); + m_scene.AddCapsHandler(UUID); } } - - SetMovementAnimation(Animations.AnimsLLUUID["STAND"]); } - private void SendSitResponse(IClientAPI remoteClient, LLUUID targetID, LLVector3 offset) - { - AvatarSitResponsePacket avatarSitResponse = new AvatarSitResponsePacket(); - - avatarSitResponse.SitObject.ID = targetID; - - bool autopilot = true; - LLVector3 pos = new LLVector3(); - LLQuaternion sitOrientation = new LLQuaternion(0, 0, 0, 1); - - SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); - if (part != null) - { - // TODO: determine position to sit at based on scene geometry; don't trust offset from client - // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it - - // Is a sit target available? - Vector3 avSitOffSet = part.GetSitTargetPosition(); - Quaternion avSitOrientation = part.GetSitTargetOrientation(); - LLUUID avOnTargetAlready = part.GetAvatarOnSitTarget(); - - bool SitTargetUnOccupied = (!(avOnTargetAlready != LLUUID.Zero)); - bool SitTargetisSet = - (!(avSitOffSet.x == 0 && avSitOffSet.y == 0 && avSitOffSet.z == 0 && avSitOrientation.w == 0 && - avSitOrientation.x == 0 && avSitOrientation.y == 0 && avSitOrientation.z == 1)); - - if (SitTargetisSet && SitTargetUnOccupied) - { - part.SetAvatarOnSitTarget(UUID); - offset = new LLVector3(avSitOffSet.x, avSitOffSet.y, avSitOffSet.z); - sitOrientation = - new LLQuaternion(avSitOrientation.w, avSitOrientation.x, avSitOrientation.y, avSitOrientation.z); - autopilot = false; - } - - pos = part.AbsolutePosition + offset; - - if (m_physicsActor != null) - { - // If we're not using the client autopilot, we're immediately warping the avatar to the location - // We can remove the physicsActor until they stand up. - m_sitAvatarHeight = m_physicsActor.Size.Z; - - if (autopilot) - { - if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) - { - autopilot = false; - - RemoveFromPhysicalScene(); - AbsolutePosition = pos + new LLVector3(0.0f, 0.0f, m_sitAvatarHeight); - } - } - else - { - RemoveFromPhysicalScene(); - } - } - } - - avatarSitResponse.SitTransform.AutoPilot = autopilot; - avatarSitResponse.SitTransform.SitPosition = offset; - avatarSitResponse.SitTransform.SitRotation = sitOrientation; - - remoteClient.OutPacket(avatarSitResponse, ThrottleOutPacketType.Task); - - // This calls HandleAgentSit twice, once from here, and the client calls - // HandleAgentSit itself after it gets to the location - // It doesn't get to the location until we've moved them there though - // which happens in HandleAgentSit :P - if (!autopilot) - HandleAgentSit(remoteClient, UUID); - } - - public void HandleAgentRequestSit(IClientAPI remoteClient, LLUUID agentID, LLUUID targetID, LLVector3 offset) - { - if (m_parentID != 0) - { - StandUp(); - } - - SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); - - if (part != null) - { - m_requestedSitTargetID = part.LocalId; - m_requestedSitOffset = offset; - } - else - { - m_log.Warn("Sit requested on unknown object: " + targetID); - } - SendSitResponse(remoteClient, targetID, offset); - } - - public void HandleAgentSit(IClientAPI remoteClient, LLUUID agentID) - { - SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID); - - if (part != null) - { - if (part.GetAvatarOnSitTarget() == UUID) - { - Vector3 sitTargetPos = part.GetSitTargetPosition(); - Quaternion sitTargetOrient = part.GetSitTargetOrientation(); - - //Quaternion vq = new Quaternion(sitTargetPos.x, sitTargetPos.y+0.2f, sitTargetPos.z+0.2f, 0); - //Quaternion nq = new Quaternion(sitTargetOrient.w, -sitTargetOrient.x, -sitTargetOrient.y, -sitTargetOrient.z); - - //Quaternion result = (sitTargetOrient * vq) * nq; - - m_pos = new LLVector3(sitTargetPos.x, sitTargetPos.y, sitTargetPos.z); - m_bodyRot = sitTargetOrient; - //Rotation = sitTargetOrient; - m_parentPosition = part.AbsolutePosition; - - //SendTerseUpdateToAllClients(); - } - else - { - m_pos -= part.AbsolutePosition; - m_parentPosition = part.AbsolutePosition; - } - } - - m_parentID = m_requestedSitTargetID; - - Velocity = new LLVector3(0, 0, 0); - RemoveFromPhysicalScene(); - - SetMovementAnimation(Animations.AnimsLLUUID["SIT"]); - SendFullUpdateToAllClients(); - // This may seem stupid, but Our Full updates don't send avatar rotation :P - // So we're also sending a terse update (which has avatar rotation) - SendTerseUpdateToAllClients(); - } + #endregion /// - /// Event handler for the 'Always run' setting on the client - /// Tells the physics plugin to increase speed of movement. - /// - public void HandleSetAlwaysRun(IClientAPI remoteClient, bool SetAlwaysRun) - { - m_setAlwaysRun = SetAlwaysRun; - if (PhysicsActor != null) - { - PhysicsActor.SetAlwaysRun = SetAlwaysRun; - } - } - - public void AddAnimation(LLUUID animID) - { - if (m_isChildAgent) - return; - - // Don't let this animation become the movement animation - if (m_animations.Count < 1) - SetMovementAnimation(Animations.AnimsLLUUID["STAND"]); - - if (!m_animations.Contains(animID)) - { - m_animations.Add(animID); - m_animationSeqs.Add(m_controllingClient.NextAnimationSequenceNumber); - SendAnimPack(); - } - } - - public void RemoveAnimation(LLUUID animID) - { - if (m_isChildAgent) - return; - - if (m_animations.Contains(animID)) - { - if (m_animations[0] == animID) - { - SetMovementAnimation(Animations.AnimsLLUUID["STAND"]); - } - else - { - // What a HACK!! Anim list really needs to be an object! - int idx; - - for (idx = 0; idx < m_animations.Count; idx++) - { - if (m_animations[idx] == animID) - { - int seq = m_animationSeqs[idx]; - - m_animations.Remove(animID); - m_animationSeqs.Remove(seq); - SendAnimPack(); - break; - } - } - } - } - } - - public void HandleStartAnim(IClientAPI remoteClient, LLUUID animID) - { - AddAnimation(animID); - } - - public void HandleStopAnim(IClientAPI remoteClient, LLUUID animID) - { - RemoveAnimation(animID); - } - - /// - /// The movement animation is the first element of the animation list, - /// reserved for "main" animations that are mutually exclusive, - /// like flying and sitting, for example. - /// - protected void SetMovementAnimation(LLUUID anim) - { - if (m_animations.Count < 1) - { - m_animations.Add(Animations.AnimsLLUUID["STAND"]); - m_animationSeqs.Add(1); - - SendAnimPack(); - } - else - { - try - { - if (m_animations[0] != anim) - { - m_animations[0] = anim; - m_animationSeqs[0] = m_controllingClient.NextAnimationSequenceNumber; - } - SendAnimPack(); - } - catch - { - m_log.Warn("[AVATAR]: SetMovementAnimation for avatar failed. Attempting recovery..."); - m_animations[0] = anim; - m_animationSeqs[0] = m_controllingClient.NextAnimationSequenceNumber; - SendAnimPack(); - } - } - } - - /// - /// This method handles agent movement related animations + /// This allows the Sim owner the abiility to kick users from their sim currently. + /// It tells the client that the agent has permission to do so. /// - protected void UpdateMovementAnimations(bool update_movementflag) - { - if (update_movementflag) - { - // Are we moving? - if (m_movementflag != 0) - { - // We are moving - - if (m_physicsActor.Flying) - { - // We are flying - SetMovementAnimation(Animations.AnimsLLUUID["FLY"]); - } - else if (((m_movementflag & (uint) AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) && - PhysicsActor.IsColliding) - { - // Client is pressing the page down button and moving and is colliding with something - SetMovementAnimation(Animations.AnimsLLUUID["CROUCHWALK"]); - } - else if (!PhysicsActor.IsColliding && m_physicsActor.Velocity.Z < -6) - { - // Client is moving and falling at a velocity greater then 6 meters per unit - SetMovementAnimation(Animations.AnimsLLUUID["FALLDOWN"]); - } - else if (!PhysicsActor.IsColliding && Velocity.Z > 0 && - (m_movementflag & (uint) AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0) - { - // Client is moving, and colliding and pressing the page up button but isn't flying - try - { - SetMovementAnimation(Animations.AnimsLLUUID["JUMP"]); - } - catch (KeyNotFoundException) - { - } - } - else if (m_setAlwaysRun) - { - // We are running - try - { - SetMovementAnimation(Animations.AnimsLLUUID["RUN"]); - } - catch (KeyNotFoundException) - { - } - } - else - { - // We're moving, but we're not doing anything else.. so play the stand animation - try - { - SetMovementAnimation(Animations.AnimsLLUUID["WALK"]); - } - catch (KeyNotFoundException) - { - } - } - } - else - { - // Not moving - - if (((m_movementflag & (uint) AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) && - PhysicsActor.IsColliding) - { - // Client pressing the page down button - SetMovementAnimation(Animations.AnimsLLUUID["CROUCH"]); - } - else if (!PhysicsActor.IsColliding && m_physicsActor.Velocity.Z < -6 && !m_physicsActor.Flying) - { - // Not colliding and not flying, and we're falling at high speed - SetMovementAnimation(Animations.AnimsLLUUID["FALLDOWN"]); - } - else if (!PhysicsActor.IsColliding && Velocity.Z > 0 && !m_physicsActor.Flying && - (m_movementflag & (uint) AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0) - { - // This is the standing jump - SetMovementAnimation(Animations.AnimsLLUUID["JUMP"]); - } - else if (m_physicsActor.Flying) - { - // We're flying but not moving - SetMovementAnimation(Animations.AnimsLLUUID["HOVER"]); - } - else - { - // We're not moving.. and we're not doing anything.. so play the stand animation - try - { - SetMovementAnimation(Animations.AnimsLLUUID["STAND"]); - } - catch (KeyNotFoundException) - { - } - } - } + public void GrantGodlikePowers(LLUUID agentID, LLUUID sessionID, LLUUID token, bool godStatus) + { + GrantGodlikePowersPacket respondPacket = new GrantGodlikePowersPacket(); + GrantGodlikePowersPacket.GrantDataBlock gdb = new GrantGodlikePowersPacket.GrantDataBlock(); + GrantGodlikePowersPacket.AgentDataBlock adb = new GrantGodlikePowersPacket.AgentDataBlock(); + + adb.AgentID = agentID; + adb.SessionID = sessionID; // More security + + if (godStatus) + { + gdb.GodLevel = (byte)250; + m_godlevel = 250; + } + else + { + gdb.GodLevel = (byte)0; + m_godlevel = 0; } + + gdb.Token = token; + //respondPacket.AgentData = (GrantGodlikePowersPacket.AgentDataBlock)ablock; + respondPacket.GrantData = gdb; + respondPacket.AgentData = adb; + ControllingClient.OutPacket(respondPacket, ThrottleOutPacketType.Task); } /// - /// Adds a new movement + /// This updates important decision making data about a child agent + /// The main purpose is to figure out what objects to send to a child agent that's in a neighboring region /// - protected void AddNewMovement(Vector3 vec, Quaternion rotation) + public void ChildAgentDataUpdate(ChildAgentDataUpdate cAgentData, uint tRegionX, uint tRegionY, uint rRegionX, uint rRegionY) { - if (m_isChildAgent) - { - Console.WriteLine("DEBUG: AddNewMovement: child agent"); - return; - } + // + int shiftx = ((int)rRegionX - (int)tRegionX) * (int)Constants.RegionSize; + int shifty = ((int)rRegionY - (int)tRegionY) * (int)Constants.RegionSize; + + m_DrawDistance = cAgentData.drawdistance; + m_pos = new LLVector3(cAgentData.Position.x + shiftx, cAgentData.Position.y + shifty, cAgentData.Position.z); - m_perfMonMS = System.Environment.TickCount; + // It's hard to say here.. We can't really tell where the camera position is unless it's in world cordinates from the sending region + m_CameraCenter = + new Vector3(cAgentData.cameraPosition.x, cAgentData.cameraPosition.y, cAgentData.cameraPosition.z); + - m_rotation = rotation; - NewForce newVelocity = new NewForce(); - Vector3 direc = rotation * vec; - direc.Normalize(); + m_godlevel = cAgentData.godlevel; + SetHeight(cAgentData.AVHeight); - direc *= 0.03f * 128f; - if (m_physicsActor.Flying) - { - direc *= 4; - //bool controlland = (((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); - //bool colliding = (m_physicsActor.IsColliding==true); - //if (controlland) - // m_log.Info("[AGENT]: landCommand"); - //if (colliding ) - // m_log.Info("[AGENT]: colliding"); - //if (m_physicsActor.Flying && colliding && controlland) - //{ - // StopFlying(); - // m_log.Info("[AGENT]: Stop FLying"); - //} - } - else + ControllingClient.SetChildAgentThrottle(cAgentData.throttles); + + + + // Sends out the objects in the user's draw distance if m_sendTasksToChild is true. + if (m_scene.m_seeIntoRegionFromNeighbor) + m_scene.SendAllSceneObjectsToClient(this); + //cAgentData.AVHeight; + //cAgentData.regionHandle; + //m_velocity = cAgentData.Velocity; + } + + /// + /// Handles part of the PID controller function for moving an avatar. + /// + public override void UpdateMovement() + { + m_newForce = false; + lock (m_forcesList) { - if (!m_physicsActor.Flying && m_physicsActor.IsColliding) + if (m_forcesList.Count > 0) { - //direc.z *= 40; - if (direc.z > 2.0f) + for (int i = 0; i < m_forcesList.Count; i++) { - direc.z *= 3; - //System.Console.WriteLine("Jump"); - // PreJump and jump happen too quickly. Many times prejump gets ignored. + NewForce force = m_forcesList[i]; + + m_updateflag = true; try { - SetMovementAnimation(Animations.AnimsLLUUID["PREJUMP"]); - SetMovementAnimation(Animations.AnimsLLUUID["JUMP"]); + movementvector.X = force.X; + movementvector.Y = force.Y; + movementvector.Z = force.Z; + Velocity = movementvector; } - catch (KeyNotFoundException) + catch (NullReferenceException) { + // Under extreme load, this returns a NullReference Exception that we can ignore. + // Ignoring this causes no movement to be sent to the physics engine... + // which when the scene is moving at 1 frame every 10 seconds, it doesn't really matter! } + m_newForce = true; + } + for (int i = 0; i < m_forcesList.Count; i++) + { + m_forcesList.RemoveAt(0); } } } + } - newVelocity.X = direc.x; - newVelocity.Y = direc.y; - newVelocity.Z = direc.z; - m_forcesList.Add(newVelocity); - - m_scene.AddAgentTime(System.Environment.TickCount - m_perfMonMS); + static ScenePresence() + { + LLObject.TextureEntry textu = AvatarAppearance.GetDefaultTextureEntry(); + DefaultTexture = textu.ToBytes(); } - #endregion + [Serializable] + public class NewForce + { + public float X; + public float Y; + public float Z; - #region Overridden Methods + public NewForce() + { + } + } - /// - /// - /// - public override void Update() + [Serializable] + public class ScenePartUpdate : ISerializable { - SendPrimUpdates(); + public LLUUID FullID; + public uint LastFullUpdateTime; + public uint LastTerseUpdateTime; - if (m_newCoarseLocations) + public ScenePartUpdate() { - SendCoarseLocations(); - m_newCoarseLocations = false; + FullID = LLUUID.Zero; + LastFullUpdateTime = 0; + LastTerseUpdateTime = 0; } - if (m_isChildAgent == false) + protected ScenePartUpdate(SerializationInfo info, StreamingContext context) { - if (m_newForce) // user movement 'forces' (ie commands to move) - { - SendTerseUpdateToAllClients(); - m_updateCount = 0; - } - else if (m_movementflag != 0) // scripted movement (?) + //System.Console.WriteLine("ScenePartUpdate Deserialize BGN"); + + if (info == null) { - m_updateCount++; - if (m_updateCount > 3) - { - SendTerseUpdateToAllClients(); - m_updateCount = 0; - } + throw new ArgumentNullException("info"); } - else if ((Util.GetDistanceTo(lastPhysPos, AbsolutePosition) > 0.02) || (Util.GetDistanceTo(m_lastVelocity, m_velocity) > 0.02)) - // physics-related movement + + FullID = new LLUUID((Guid)info.GetValue("FullID", typeof(Guid))); + LastFullUpdateTime = (uint)info.GetValue("LastFullUpdateTime", typeof(uint)); + LastTerseUpdateTime = (uint)info.GetValue("LastTerseUpdateTime", typeof(uint)); + + //System.Console.WriteLine("ScenePartUpdate Deserialize END"); + } + + [SecurityPermission(SecurityAction.LinkDemand, + Flags = SecurityPermissionFlag.SerializationFormatter)] + public virtual void GetObjectData( + SerializationInfo info, StreamingContext context) + { + if (info == null) { - // Send Terse Update to all clients updates lastPhysPos and m_lastVelocity - // doing the above assures us that we know what we sent the clients last - SendTerseUpdateToAllClients(); - m_updateCount = 0; + throw new ArgumentNullException("info"); } - // followed suggestion from mic bowman. reversed the two lines below. - CheckForBorderCrossing(); - CheckForSignificantMovement(); // sends update to the modules. + info.AddValue("FullID", FullID.UUID); + info.AddValue("LastFullUpdateTime", LastFullUpdateTime); + info.AddValue("LastTerseUpdateTime", LastTerseUpdateTime); } } - #endregion - - #region Update Client(s) - - /// - /// Sends a location update to the client connected to this scenePresence - /// - /// - public void SendTerseUpdateToClient(IClientAPI remoteClient) + public override void SetText(string text, Vector3 color, double alpha) { - m_perfMonMS = System.Environment.TickCount; - - LLVector3 pos = m_pos; - LLVector3 vel = Velocity; - LLQuaternion rot = new LLQuaternion(m_bodyRot.x, m_bodyRot.y, m_bodyRot.z, m_bodyRot.w); - remoteClient.SendAvatarTerseUpdate(m_regionHandle, (ushort) (m_scene.TimeDilation * ushort.MaxValue), LocalId, new LLVector3(pos.X, pos.Y, pos.Z), - new LLVector3(vel.X, vel.Y, vel.Z), rot); - - m_scene.AddAgentTime(System.Environment.TickCount - m_perfMonMS); - m_scene.AddAgentUpdates(1); + throw new Exception("Can't set Text on avatar."); } /// - /// Send a location/velocity/accelleration update to all agents in scene + /// Adds a physical representation of the avatar to the Physics plugin /// - public void SendTerseUpdateToAllClients() + public void AddToPhysicalScene() { - m_perfMonMS = System.Environment.TickCount; - - m_scene.Broadcast(SendTerseUpdateToClient); - - m_lastVelocity = m_velocity; - lastPhysPos = AbsolutePosition; - - m_scene.AddAgentTime(System.Environment.TickCount - m_perfMonMS); + PhysicsScene scene = m_scene.PhysicsScene; + + PhysicsVector pVec = + new PhysicsVector(AbsolutePosition.X, AbsolutePosition.Y, + AbsolutePosition.Z); + if (m_avHeight == 127.0f) + { + m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec, new PhysicsVector(0, 0, 1.56f)); + } + else + { + m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec, new PhysicsVector(0, 0, m_avHeight)); + } + //m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; + m_physicsActor.OnCollisionUpdate += PhysicsCollisionUpdate; + m_physicsActor.LocalID = LocalId; } - public void SendCoarseLocations() + // Event called by the physics plugin to tell the avatar about a collision. + private void PhysicsCollisionUpdate(EventArgs e) { - m_perfMonMS = System.Environment.TickCount; + bool isUserMoving = Velocity.X > 0 || Velocity.Y > 0; + UpdateMovementAnimations(isUserMoving); + } - List CoarseLocations = new List(); - List avatars = m_scene.GetAvatars(); - for (int i = 0; i < avatars.Count; i++) + internal void Close() + { + lock (m_attachments) + { + foreach (SceneObjectGroup grp in m_attachments) + { + // ControllingClient may be null at this point! + m_scene.m_innerScene.DetachSingleAttachmentToInv(grp.GetFromAssetID(), ControllingClient); + } + m_attachments.Clear(); + } + lock (m_knownPrimUUID) + { + m_knownPrimUUID.Clear(); + } + lock (m_knownChildRegions) + { + m_knownChildRegions.Clear(); + } + lock (m_updateTimes) { - if (avatars[i] != this) - { - CoarseLocations.Add(avatars[i].m_pos); - } + m_updateTimes.Clear(); + } + lock (m_partsUpdateQueue) + { + m_partsUpdateQueue.Clear(); } - m_controllingClient.SendCoarseLocationUpdate(CoarseLocations); - - m_scene.AddAgentTime(System.Environment.TickCount - m_perfMonMS); + RemoveFromPhysicalScene(); + GC.Collect(); } - public void CoarseLocationChange() + public ScenePresence() { - m_newCoarseLocations = true; +/* JB + if (Animations == null) + { + Animations = new AvatarAnimations(); + Animations.LoadAnims(); + } +*/ + if (DefaultTexture == null) + { + LLObject.TextureEntry textu = AvatarAppearance.GetDefaultTextureEntry(); + DefaultTexture = textu.ToBytes(); + } } - - /// - /// Tell other client about this avatar (The client previously didn't know or had outdated details about this avatar) - /// - /// - public void SendFullUpdateToOtherClient(ScenePresence remoteAvatar) + public void AddAttachment(SceneObjectGroup gobj) { - remoteAvatar.m_controllingClient.SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_uuid, - LocalId, m_pos, m_appearance.TextureEntry.ToBytes(), - m_parentID); - m_scene.AddAgentUpdates(1); + lock (m_attachments) + { + m_attachments.Add(gobj); + } } - - /// - /// Tell *ALL* agents about this agent - /// - public void SendFullUpdateToAllClients() + public void RemoveAttachment(SceneObjectGroup gobj) { - m_perfMonMS = System.Environment.TickCount; - - List avatars = m_scene.GetScenePresences(); - foreach (ScenePresence avatar in avatars) + lock (m_attachments) { - SendFullUpdateToOtherClient(avatar); - if (avatar.LocalId != LocalId) + if (m_attachments.Contains(gobj)) { - if (!avatar.m_isChildAgent || m_scene.m_seeIntoRegionFromNeighbor) - { - avatar.SendFullUpdateToOtherClient(this); - avatar.SendAppearanceToOtherAgent(this); - } + m_attachments.Remove(gobj); } } - m_scene.AddAgentUpdates(avatars.Count); - m_scene.AddAgentTime(System.Environment.TickCount - m_perfMonMS); } - - /// - /// - /// - public void SendInitialData() + public void CrossAttachmentsIntoNewRegion(ulong regionHandle) { - m_controllingClient.SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_uuid, LocalId, - m_pos, m_appearance.TextureEntry.ToBytes(), m_parentID); - if (!m_isChildAgent) + lock (m_attachments) { - m_scene.InformClientOfNeighbours(this); + foreach (SceneObjectGroup gobj in m_attachments) + { + // If the prim group is null then something must have happened to it! + if (gobj != null) + { + // Set the parent localID to 0 so it transfers over properly. + gobj.RootPart.SetParentLocalId(0); + gobj.RootPart.m_IsAttachment = false; + gobj.AbsolutePosition = gobj.RootPart.m_attachedPos; + gobj.RootPart.LastOwnerID = gobj.GetFromAssetID(); + m_scene.CrossPrimGroupIntoNewRegion(regionHandle, gobj); + } + } + m_attachments.Clear(); } - SendFullUpdateToAllClients(); - SendAppearanceToAllOtherAgents(); } - - /// - /// - /// - /// - public void SendOwnAppearance() + public void initializeScenePresence(IClientAPI client, RegionInfo region, Scene scene) { - m_appearance.SendOwnWearables(ControllingClient); + m_controllingClient = client; + m_regionInfo = region; + m_scene = scene; + RegisterToEvents(); - // TODO: remove this once the SunModule is slightly more tested - // m_controllingClient.SendViewerTime(m_scene.TimePhase); - } + /* + AbsolutePosition = client.StartPos; - /// - /// - /// - public void SendAppearanceToAllOtherAgents() - { - m_perfMonMS = System.Environment.TickCount; + Animations = new AvatarAnimations(); + Animations.LoadAnims(); - m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) - { - if (scenePresence.UUID != UUID) - { - m_appearance.SendAppearanceToOtherAgent(scenePresence); - } - }); - m_scene.AddAgentTime(System.Environment.TickCount - m_perfMonMS); - } + m_animations = new List(); + m_animations.Add(Animations.AnimsLLUUID["STAND"]); + m_animationSeqs.Add(m_controllingClient.NextAnimationSequenceNumber); - public void SendAppearanceToOtherAgent(ScenePresence avatar) - { - m_appearance.SendAppearanceToOtherAgent(avatar); + SetDirectionVectors(); + */ } - public void SetAppearance(byte[] texture, AgentSetAppearancePacket.VisualParamBlock[] visualParam) + protected ScenePresence(SerializationInfo info, StreamingContext context) + : base (info, context) { - m_appearance.SetAppearance(texture, visualParam); - SetHeight(m_appearance.AvatarHeight); + //System.Console.WriteLine("ScenePresence Deserialize BGN"); - SendAppearanceToAllOtherAgents(); - } + if (info == null) + { + throw new ArgumentNullException("info"); + } +/* JB + if (Animations == null) + { + Animations = new AvatarAnimations(); + Animations.LoadAnims(); + } +*/ + if (DefaultTexture == null) + { + LLObject.TextureEntry textu = AvatarAppearance.GetDefaultTextureEntry(); + DefaultTexture = textu.ToBytes(); + } - public void SetWearable(int wearableId, AvatarWearable wearable) - { - m_appearance.SetWearable(ControllingClient, wearableId, wearable); - } + List animations_work = (List)info.GetValue("m_animations", typeof(List)); - /// - /// - /// - /// - /// - public void SendAnimPack(LLUUID[] animations, int[] seqs) - { - if (m_isChildAgent) - return; + foreach (Guid guid in animations_work) + { + m_animations.Add(new LLUUID(guid)); + } - m_scene.Broadcast( - delegate(IClientAPI client) { client.SendAnimations(animations, seqs, m_controllingClient.AgentId); }); - } + m_animationSeqs = (List)info.GetValue("m_animationSeqs", typeof(List)); + m_updateflag = (bool)info.GetValue("m_updateflag", typeof(bool)); + m_movementflag = (byte)info.GetValue("m_movementflag", typeof(byte)); + m_forcesList = (List)info.GetValue("m_forcesList", typeof(List)); + m_updateCount = (short)info.GetValue("m_updateCount", typeof(short)); + m_requestedSitTargetID = (uint)info.GetValue("m_requestedSitTargetID", typeof(uint)); - /// - /// - /// - public void SendAnimPack() - { - SendAnimPack(m_animations.ToArray(), m_animationSeqs.ToArray()); - } + m_requestedSitOffset + = new LLVector3( + (float)info.GetValue("m_requestedSitOffset.X", typeof(float)), + (float)info.GetValue("m_requestedSitOffset.Y", typeof(float)), + (float)info.GetValue("m_requestedSitOffset.Z", typeof(float))); - #endregion + m_sitAvatarHeight = (float)info.GetValue("m_sitAvatarHeight", typeof(float)); + m_godlevel = (float)info.GetValue("m_godlevel", typeof(float)); + m_setAlwaysRun = (bool)info.GetValue("m_setAlwaysRun", typeof(bool)); - #region Significant Movement Method + m_bodyRot + = new Quaternion( + (float)info.GetValue("m_bodyRot.w", typeof(float)), + (float)info.GetValue("m_bodyRot.x", typeof(float)), + (float)info.GetValue("m_bodyRot.y", typeof(float)), + (float)info.GetValue("m_bodyRot.z", typeof(float))); - /// - /// This checks for a significant movement and sends a courselocationchange update - /// - protected void CheckForSignificantMovement() - { - if (Util.GetDistanceTo(AbsolutePosition, posLastSignificantMove) > 0.5) + IsRestrictedToRegion = (bool)info.GetValue("IsRestrictedToRegion", typeof(bool)); + m_newForce = (bool)info.GetValue("m_newForce", typeof(bool)); + //m_newAvatar = (bool)info.GetValue("m_newAvatar", typeof(bool)); + m_newCoarseLocations = (bool)info.GetValue("m_newCoarseLocations", typeof(bool)); + m_gotAllObjectsInScene = (bool)info.GetValue("m_gotAllObjectsInScene", typeof(bool)); + m_avHeight = (float)info.GetValue("m_avHeight", typeof(float)); + crossingFromRegion = (ulong)info.GetValue("crossingFromRegion", typeof(ulong)); + + List Dir_Vectors_work = (List)info.GetValue("Dir_Vectors", typeof(List)); + List Dir_Vectors_work2 = new List(); + + foreach (float[] f3 in Dir_Vectors_work) { - posLastSignificantMove = AbsolutePosition; - handlerSignificantClientMovement = OnSignificantClientMovement; - if (handlerSignificantClientMovement != null) - { - handlerSignificantClientMovement(m_controllingClient); - m_scene.NotifyMyCoarseLocationChange(); - } + Dir_Vectors_work2.Add(new Vector3(f3[0], f3[1], f3[2])); } - // Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m - if (Util.GetDistanceTo(AbsolutePosition, m_LastChildAgentUpdatePosition) > 32) + Dir_Vectors = Dir_Vectors_work2.ToArray(); + + lastPhysPos + = new LLVector3( + (float)info.GetValue("lastPhysPos.X", typeof(float)), + (float)info.GetValue("lastPhysPos.Y", typeof(float)), + (float)info.GetValue("lastPhysPos.Z", typeof(float))); + + m_CameraCenter + = new Vector3( + (float)info.GetValue("m_CameraCenter.X", typeof(float)), + (float)info.GetValue("m_CameraCenter.Y", typeof(float)), + (float)info.GetValue("m_CameraCenter.Z", typeof(float))); + + m_CameraAtAxis + = new Vector3( + (float)info.GetValue("m_CameraAtAxis.X", typeof(float)), + (float)info.GetValue("m_CameraAtAxis.Y", typeof(float)), + (float)info.GetValue("m_CameraAtAxis.Z", typeof(float))); + + m_CameraLeftAxis + = new Vector3( + (float)info.GetValue("m_CameraLeftAxis.X", typeof(float)), + (float)info.GetValue("m_CameraLeftAxis.Y", typeof(float)), + (float)info.GetValue("m_CameraLeftAxis.Z", typeof(float))); + + m_CameraUpAxis + = new Vector3( + (float)info.GetValue("m_CameraUpAxis.X", typeof(float)), + (float)info.GetValue("m_CameraUpAxis.Y", typeof(float)), + (float)info.GetValue("m_CameraUpAxis.Z", typeof(float))); + + m_DrawDistance = (float)info.GetValue("m_DrawDistance", typeof(float)); + m_appearance = (AvatarAppearance)info.GetValue("m_appearance", typeof(AvatarAppearance)); + m_knownChildRegions = (List)info.GetValue("m_knownChildRegions", typeof(List)); + + posLastSignificantMove + = new LLVector3( + (float)info.GetValue("posLastSignificantMove.X", typeof(float)), + (float)info.GetValue("posLastSignificantMove.Y", typeof(float)), + (float)info.GetValue("posLastSignificantMove.Z", typeof(float))); + + // m_partsUpdateQueue = (UpdateQueue)info.GetValue("m_partsUpdateQueue", typeof(UpdateQueue)); + + /* + Dictionary updateTimes_work + = (Dictionary)info.GetValue("m_updateTimes", typeof(Dictionary)); + + foreach (Guid id in updateTimes_work.Keys) { - ChildAgentDataUpdate cadu = new ChildAgentDataUpdate(); - cadu.ActiveGroupID = LLUUID.Zero.UUID; - cadu.AgentID = UUID.UUID; - cadu.alwaysrun = m_setAlwaysRun; - cadu.AVHeight = m_avHeight; - LLVector3 tempCameraCenter = new LLVector3(m_CameraCenter.x, m_CameraCenter.y, m_CameraCenter.z); - cadu.cameraPosition = new sLLVector3(tempCameraCenter); - cadu.drawdistance = m_DrawDistance; - cadu.godlevel = m_godlevel; - cadu.GroupAccess = 0; - cadu.Position = new sLLVector3(AbsolutePosition); - cadu.regionHandle = m_scene.RegionInfo.RegionHandle; - cadu.throttles = ControllingClient.GetThrottlesPacked(1f); - cadu.Velocity = new sLLVector3(Velocity); - m_scene.SendOutChildAgentUpdates(cadu, this); - m_LastChildAgentUpdatePosition.X = AbsolutePosition.X; - m_LastChildAgentUpdatePosition.Y = AbsolutePosition.Y; - m_LastChildAgentUpdatePosition.Z = AbsolutePosition.Z; + m_updateTimes.Add(new LLUUID(id), updateTimes_work[id]); } - } + */ + m_regionHandle = (ulong)info.GetValue("m_regionHandle", typeof(ulong)); + m_firstname = (string)info.GetValue("m_firstname", typeof(string)); + m_lastname = (string)info.GetValue("m_lastname", typeof(string)); + m_allowMovement = (bool)info.GetValue("m_allowMovement", typeof(bool)); + m_parentPosition = new LLVector3((float)info.GetValue("m_parentPosition.X", typeof(float)), + (float)info.GetValue("m_parentPosition.Y", typeof(float)), + (float)info.GetValue("m_parentPosition.Z", typeof(float))); + + m_isChildAgent = (bool)info.GetValue("m_isChildAgent", typeof(bool)); + m_parentID = (uint)info.GetValue("m_parentID", typeof(uint)); + +// for OpenSim_v0.5 + currentParcelUUID = new LLUUID((Guid)info.GetValue("currentParcelUUID", typeof(Guid))); + + lastKnownAllowedPosition + = new Vector3( + (float)info.GetValue("lastKnownAllowedPosition.X", typeof(float)), + (float)info.GetValue("lastKnownAllowedPosition.Y", typeof(float)), + (float)info.GetValue("lastKnownAllowedPosition.Z", typeof(float))); + + sentMessageAboutRestrictedParcelFlyingDown = (bool)info.GetValue("sentMessageAboutRestrictedParcelFlyingDown", typeof(bool)); - #endregion + m_LastChildAgentUpdatePosition + = new LLVector3( + (float)info.GetValue("m_LastChildAgentUpdatePosition.X", typeof(float)), + (float)info.GetValue("m_LastChildAgentUpdatePosition.Y", typeof(float)), + (float)info.GetValue("m_LastChildAgentUpdatePosition.Z", typeof(float))); + + m_perfMonMS = (int)info.GetValue("m_perfMonMS", typeof(int)); + m_AgentControlFlags = (uint)info.GetValue("m_AgentControlFlags", typeof(uint)); - #region Border Crossing Methods + m_headrotation + = new LLQuaternion( + (float)info.GetValue("m_headrotation.W", typeof(float)), + (float)info.GetValue("m_headrotation.X", typeof(float)), + (float)info.GetValue("m_headrotation.Y", typeof(float)), + (float)info.GetValue("m_headrotation.Z", typeof(float))); - /// - /// Checks to see if the avatar is in range of a border and calls CrossToNewRegion - /// - protected void CheckForBorderCrossing() - { - LLVector3 pos2 = AbsolutePosition; - LLVector3 vel = Velocity; + m_state = (byte)info.GetValue("m_state", typeof(byte)); - 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); + List knownPrimUUID_work = (List)info.GetValue("m_knownPrimUUID", typeof(List)); - if ((pos2.X < 0) || (pos2.X > Constants.RegionSize)) + foreach (Guid id in knownPrimUUID_work) { - CrossToNewRegion(); + m_knownPrimUUID.Add(new LLUUID(id)); } - if ((pos2.Y < 0) || (pos2.Y > Constants.RegionSize)) - { - CrossToNewRegion(); - } + //System.Console.WriteLine("ScenePresence Deserialize END"); } - /// - /// Moves the agent outside the region bounds - /// Tells neighbor region that we're crossing to it - /// If the neighbor accepts, remove the agent's viewable avatar from this scene - /// set them to a child agent. - /// - protected void CrossToNewRegion() + [SecurityPermission(SecurityAction.LinkDemand, + Flags = SecurityPermissionFlag.SerializationFormatter)] + public override void GetObjectData( + SerializationInfo info, StreamingContext context) { - LLVector3 pos = AbsolutePosition; - LLVector3 newpos = new LLVector3(pos.X, pos.Y, pos.Z); - uint neighbourx = m_regionInfo.RegionLocX; - uint neighboury = m_regionInfo.RegionLocY; + if (info == null) + { + throw new ArgumentNullException("info"); + } - // distance to edge that will trigger crossing - const float boundaryDistance = 1.7f; + base.GetObjectData(info, context); - // distance into new region to place avatar - const float enterDistance = 0.1f; + List animations_work = new List(); - if (pos.X < boundaryDistance) - { - neighbourx--; - newpos.X = Constants.RegionSize - enterDistance; - } - else if (pos.X > Constants.RegionSize - boundaryDistance) + foreach (LLUUID uuid in m_animations) { - neighbourx++; - newpos.X = enterDistance; + animations_work.Add(uuid.UUID); } - if (pos.Y < boundaryDistance) - { - neighboury--; - newpos.Y = Constants.RegionSize - enterDistance; - } - else if (pos.Y > Constants.RegionSize - boundaryDistance) - { - neighboury++; - newpos.Y = enterDistance; - } + info.AddValue("m_animations", animations_work); - LLVector3 vel = m_velocity; - ulong neighbourHandle = Helpers.UIntsToLong((neighbourx * Constants.RegionSize), (neighboury * Constants.RegionSize)); - SimpleRegionInfo neighbourRegion = m_scene.RequestNeighbouringRegionInfo(neighbourHandle); - if (neighbourRegion != null) - { - // When the neighbour is informed of the border crossing, it will set up CAPS handlers for the avatar - // This means we need to remove the current caps handler here and possibly compensate later, - // in case both scenes are being hosted on the same region server. Messy - m_scene.RemoveCapsHandler(UUID); - newpos = newpos + (vel); - bool res = - m_scene.InformNeighbourOfCrossing(neighbourHandle, m_controllingClient.AgentId, newpos, - m_physicsActor.Flying); - if (res) - { - AgentCircuitData circuitdata = m_controllingClient.RequestClientInfo(); + info.AddValue("m_animationSeqs", m_animationSeqs); + info.AddValue("m_updateflag", m_updateflag); + info.AddValue("m_movementflag", m_movementflag); + info.AddValue("m_forcesList", m_forcesList); + info.AddValue("m_updateCount", m_updateCount); + info.AddValue("m_requestedSitTargetID", m_requestedSitTargetID); - // TODO Should construct this behind a method - string capsPath = - "http://" + neighbourRegion.ExternalHostName + ":" + neighbourRegion.HttpPort - + "/CAPS/" + circuitdata.CapsPath + "0000/"; + // LLVector3 + info.AddValue("m_requestedSitOffset.X", m_requestedSitOffset.X); + info.AddValue("m_requestedSitOffset.Y", m_requestedSitOffset.Y); + info.AddValue("m_requestedSitOffset.Z", m_requestedSitOffset.Z); - m_log.DebugFormat( - "[CAPS]: Sending new CAPS seed url {0} to client {1}", capsPath, m_uuid); + info.AddValue("m_sitAvatarHeight", m_sitAvatarHeight); + info.AddValue("m_godlevel", m_godlevel); + info.AddValue("m_setAlwaysRun", m_setAlwaysRun); + + // Quaternion + info.AddValue("m_bodyRot.w", m_bodyRot.w); + info.AddValue("m_bodyRot.x", m_bodyRot.x); + info.AddValue("m_bodyRot.y", m_bodyRot.y); + info.AddValue("m_bodyRot.z", m_bodyRot.z); - m_controllingClient.CrossRegion(neighbourHandle, newpos, vel, neighbourRegion.ExternalEndPoint, - capsPath); - MakeChildAgent(); - CrossAttachmentsIntoNewRegion(neighbourHandle); - m_scene.SendKillObject(m_localId); - m_scene.NotifyMyCoarseLocationChange(); - } - else - { - m_scene.AddCapsHandler(UUID); - } + info.AddValue("IsRestrictedToRegion", IsRestrictedToRegion); + info.AddValue("m_newForce", m_newForce); + //info.AddValue("m_newAvatar", m_newAvatar); + info.AddValue("m_newCoarseLocations", m_newCoarseLocations); + info.AddValue("m_gotAllObjectsInScene", m_gotAllObjectsInScene); + info.AddValue("m_avHeight", m_avHeight); + + // info.AddValue("m_regionInfo", m_regionInfo); + + info.AddValue("crossingFromRegion", crossingFromRegion); + + List Dir_Vectors_work = new List(); + + foreach (Vector3 v3 in Dir_Vectors) + { + Dir_Vectors_work.Add(new float[] { v3.x, v3.y, v3.z }); } - } - #endregion + info.AddValue("Dir_Vectors", Dir_Vectors_work); - #region Nested type: Dir_ControlFlags + // LLVector3 + info.AddValue("lastPhysPos.X", lastPhysPos.X); + info.AddValue("lastPhysPos.Y", lastPhysPos.Y); + info.AddValue("lastPhysPos.Z", lastPhysPos.Z); - /// - /// Implemented Control Flags - /// - private enum Dir_ControlFlags - { - DIR_CONTROL_FLAG_FORWARD = AgentManager.ControlFlags.AGENT_CONTROL_AT_POS, - DIR_CONTROL_FLAG_BACK = AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG, - DIR_CONTROL_FLAG_LEFT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS, - DIR_CONTROL_FLAG_RIGHT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG, - DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, - DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, - DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG - } + // Vector3 + info.AddValue("m_CameraCenter.X", m_CameraCenter.x); + info.AddValue("m_CameraCenter.Y", m_CameraCenter.y); + info.AddValue("m_CameraCenter.Z", m_CameraCenter.z); - #endregion + // Vector3 + info.AddValue("m_CameraAtAxis.X", m_CameraAtAxis.x); + info.AddValue("m_CameraAtAxis.Y", m_CameraAtAxis.y); + info.AddValue("m_CameraAtAxis.Z", m_CameraAtAxis.z); - #region Nested type: NewForce + // Vector3 + info.AddValue("m_CameraLeftAxis.X", m_CameraLeftAxis.x); + info.AddValue("m_CameraLeftAxis.Y", m_CameraLeftAxis.y); + info.AddValue("m_CameraLeftAxis.Z", m_CameraLeftAxis.z); - [Serializable] - public class NewForce - { - public float X; - public float Y; - public float Z; - } + // Vector3 + info.AddValue("m_CameraUpAxis.X", m_CameraUpAxis.x); + info.AddValue("m_CameraUpAxis.Y", m_CameraUpAxis.y); + info.AddValue("m_CameraUpAxis.Z", m_CameraUpAxis.z); - #endregion + info.AddValue("m_DrawDistance", m_DrawDistance); + info.AddValue("m_appearance", m_appearance); + info.AddValue("m_knownChildRegions", m_knownChildRegions); - #region Nested type: ScenePartUpdate + // LLVector3 + info.AddValue("posLastSignificantMove.X", posLastSignificantMove.X); + info.AddValue("posLastSignificantMove.Y", posLastSignificantMove.Y); + info.AddValue("posLastSignificantMove.Z", posLastSignificantMove.Z); - [Serializable] - public class ScenePartUpdate : ISerializable - { - public LLUUID FullID; - public uint LastFullUpdateTime; - public uint LastTerseUpdateTime; + //info.AddValue("m_partsUpdateQueue", m_partsUpdateQueue); - public ScenePartUpdate() + /* + Dictionary updateTimes_work = new Dictionary(); + + foreach ( LLUUID id in m_updateTimes.Keys) { - FullID = LLUUID.Zero; - LastFullUpdateTime = 0; - LastTerseUpdateTime = 0; + updateTimes_work.Add(id.UUID, m_updateTimes[id]); } - protected ScenePartUpdate(SerializationInfo info, StreamingContext context) - { - //System.Console.WriteLine("ScenePartUpdate Deserialize BGN"); + info.AddValue("m_updateTimes", updateTimes_work); + */ - if (info == null) - { - throw new ArgumentNullException("info"); - } + info.AddValue("m_regionHandle", m_regionHandle); + info.AddValue("m_firstname", m_firstname); + info.AddValue("m_lastname", m_lastname); + info.AddValue("m_allowMovement", m_allowMovement); + //info.AddValue("m_physicsActor", m_physicsActor); + info.AddValue("m_parentPosition.X", m_parentPosition.X); + info.AddValue("m_parentPosition.Y", m_parentPosition.Y); + info.AddValue("m_parentPosition.Z", m_parentPosition.Z); + info.AddValue("m_isChildAgent", m_isChildAgent); + info.AddValue("m_parentID", m_parentID); - FullID = new LLUUID((Guid) info.GetValue("FullID", typeof (Guid))); - LastFullUpdateTime = (uint) info.GetValue("LastFullUpdateTime", typeof (uint)); - LastTerseUpdateTime = (uint) info.GetValue("LastTerseUpdateTime", typeof (uint)); +// for OpenSim_v0.5 + info.AddValue("currentParcelUUID", currentParcelUUID.UUID); - //System.Console.WriteLine("ScenePartUpdate Deserialize END"); - } + info.AddValue("lastKnownAllowedPosition.X", lastKnownAllowedPosition.x); + info.AddValue("lastKnownAllowedPosition.Y", lastKnownAllowedPosition.y); + info.AddValue("lastKnownAllowedPosition.Z", lastKnownAllowedPosition.z); + + info.AddValue("sentMessageAboutRestrictedParcelFlyingDown", sentMessageAboutRestrictedParcelFlyingDown); - #region ISerializable Members + info.AddValue("m_LastChildAgentUpdatePosition.X", m_LastChildAgentUpdatePosition.X); + info.AddValue("m_LastChildAgentUpdatePosition.Y", m_LastChildAgentUpdatePosition.Y); + info.AddValue("m_LastChildAgentUpdatePosition.Z", m_LastChildAgentUpdatePosition.Z); - [SecurityPermission(SecurityAction.LinkDemand, - Flags = SecurityPermissionFlag.SerializationFormatter)] - public virtual void GetObjectData( - SerializationInfo info, StreamingContext context) - { - if (info == null) - { - throw new ArgumentNullException("info"); - } + info.AddValue("m_perfMonMS", m_perfMonMS); + info.AddValue("m_AgentControlFlags", m_AgentControlFlags); - info.AddValue("FullID", FullID.UUID); - info.AddValue("LastFullUpdateTime", LastFullUpdateTime); - info.AddValue("LastTerseUpdateTime", LastTerseUpdateTime); + info.AddValue("m_headrotation.W", m_headrotation.W); + info.AddValue("m_headrotation.X", m_headrotation.X); + info.AddValue("m_headrotation.Y", m_headrotation.Y); + info.AddValue("m_headrotation.Z", m_headrotation.Z); + + info.AddValue("m_state", m_state); + + List knownPrimUUID_work = new List(); + + foreach (LLUUID id in m_knownPrimUUID) + { + knownPrimUUID_work.Add(id.UUID); } - #endregion + info.AddValue("m_knownPrimUUID", knownPrimUUID_work); } - - #endregion } -} \ No newline at end of file +} -- cgit v1.1