PageRenderTime 66ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 1ms

/OpenSim/Region/Framework/Scenes/ScenePresence.cs

https://gitlab.com/N3X15/VoxelSim
C# | 3751 lines | 2378 code | 522 blank | 851 comment | 532 complexity | 7f20658cddec888950a40227101fff65 MD5 | raw file
Possible License(s): BSD-3-Clause

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. * Copyright (c) Contributors, http://opensimulator.org/
  3. * See CONTRIBUTORS.TXT for a full list of copyright holders.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. * * Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * * Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * * Neither the name of the OpenSimulator Project nor the
  13. * names of its contributors may be used to endorse or promote products
  14. * derived from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
  17. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19. * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
  20. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  21. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  22. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  23. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  25. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. using System;
  28. using System.Collections.Generic;
  29. using System.Reflection;
  30. using System.Timers;
  31. using OpenMetaverse;
  32. using log4net;
  33. using OpenSim.Framework;
  34. using OpenSim.Framework.Client;
  35. using OpenSim.Region.Framework.Interfaces;
  36. using OpenSim.Region.Framework.Scenes.Animation;
  37. using OpenSim.Region.Framework.Scenes.Types;
  38. using OpenSim.Region.Physics.Manager;
  39. using GridRegion = OpenSim.Services.Interfaces.GridRegion;
  40. using OpenSim.Services.Interfaces;
  41. namespace OpenSim.Region.Framework.Scenes
  42. {
  43. enum ScriptControlled : uint
  44. {
  45. CONTROL_ZERO = 0,
  46. CONTROL_FWD = 1,
  47. CONTROL_BACK = 2,
  48. CONTROL_LEFT = 4,
  49. CONTROL_RIGHT = 8,
  50. CONTROL_UP = 16,
  51. CONTROL_DOWN = 32,
  52. CONTROL_ROT_LEFT = 256,
  53. CONTROL_ROT_RIGHT = 512,
  54. CONTROL_LBUTTON = 268435456,
  55. CONTROL_ML_LBUTTON = 1073741824
  56. }
  57. struct ScriptControllers
  58. {
  59. public UUID itemID;
  60. public ScriptControlled ignoreControls;
  61. public ScriptControlled eventControls;
  62. }
  63. public delegate void SendCourseLocationsMethod(UUID scene, ScenePresence presence, List<Vector3> coarseLocations, List<UUID> avatarUUIDs);
  64. public class ScenePresence : EntityBase, ISceneEntity
  65. {
  66. // ~ScenePresence()
  67. // {
  68. // m_log.Debug("[ScenePresence] Destructor called");
  69. // }
  70. private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
  71. // private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes();
  72. private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags));
  73. private static readonly Vector3 HEAD_ADJUSTMENT = new Vector3(0f, 0f, 0.3f);
  74. /// <summary>
  75. /// Experimentally determined "fudge factor" to make sit-target positions
  76. /// the same as in SecondLife. Fudge factor was tested for 36 different
  77. /// test cases including prims of type box, sphere, cylinder, and torus,
  78. /// with varying parameters for sit target location, prim size, prim
  79. /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis
  80. /// issue #1716
  81. /// </summary>
  82. private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f);
  83. public UUID currentParcelUUID = UUID.Zero;
  84. private ISceneViewer m_sceneViewer;
  85. /// <value>
  86. /// The animator for this avatar
  87. /// </value>
  88. public ScenePresenceAnimator Animator
  89. {
  90. get { return m_animator; }
  91. }
  92. protected ScenePresenceAnimator m_animator;
  93. /// <value>
  94. /// The scene objects attached to this avatar. Do not change this list directly - use methods such as
  95. /// AddAttachment() and RemoveAttachment(). Lock this list when performing any read operations upon it.
  96. /// </value>
  97. public List<SceneObjectGroup> Attachments
  98. {
  99. get { return m_attachments; }
  100. }
  101. protected List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>();
  102. private Dictionary<UUID, ScriptControllers> scriptedcontrols = new Dictionary<UUID, ScriptControllers>();
  103. private ScriptControlled IgnoredControls = ScriptControlled.CONTROL_ZERO;
  104. private ScriptControlled LastCommands = ScriptControlled.CONTROL_ZERO;
  105. private bool MouseDown = false;
  106. private SceneObjectGroup proxyObjectGroup;
  107. //private SceneObjectPart proxyObjectPart = null;
  108. public Vector3 lastKnownAllowedPosition;
  109. public bool sentMessageAboutRestrictedParcelFlyingDown;
  110. public Vector4 CollisionPlane = Vector4.UnitW;
  111. private Vector3 m_lastPosition;
  112. private Quaternion m_lastRotation;
  113. private Vector3 m_lastVelocity;
  114. //private int m_lastTerseSent;
  115. private bool m_updateflag;
  116. private byte m_movementflag;
  117. private Vector3? m_forceToApply;
  118. private uint m_requestedSitTargetID;
  119. private UUID m_requestedSitTargetUUID;
  120. public bool SitGround = false;
  121. private SendCourseLocationsMethod m_sendCourseLocationsMethod;
  122. //private Vector3 m_requestedSitOffset = new Vector3();
  123. private Vector3 m_LastFinitePos;
  124. private float m_sitAvatarHeight = 2.0f;
  125. private int m_godLevel;
  126. private int m_userLevel;
  127. private bool m_invulnerable = true;
  128. private Vector3 m_lastChildAgentUpdatePosition;
  129. private Vector3 m_lastChildAgentUpdateCamPosition;
  130. private int m_perfMonMS;
  131. private bool m_setAlwaysRun;
  132. private bool m_forceFly;
  133. private bool m_flyDisabled;
  134. private float m_speedModifier = 1.0f;
  135. private Quaternion m_bodyRot= Quaternion.Identity;
  136. private Quaternion m_bodyRotPrevious = Quaternion.Identity;
  137. private const int LAND_VELOCITYMAG_MAX = 12;
  138. public bool IsRestrictedToRegion;
  139. public string JID = String.Empty;
  140. private float m_health = 100f;
  141. protected RegionInfo m_regionInfo;
  142. protected ulong crossingFromRegion;
  143. private readonly Vector3[] Dir_Vectors = new Vector3[9];
  144. // Position of agent's camera in world (region cordinates)
  145. protected Vector3 m_CameraCenter;
  146. protected Vector3 m_lastCameraCenter;
  147. protected Timer m_reprioritization_timer;
  148. protected bool m_reprioritizing;
  149. protected bool m_reprioritization_called;
  150. // Use these three vectors to figure out what the agent is looking at
  151. // Convert it to a Matrix and/or Quaternion
  152. protected Vector3 m_CameraAtAxis;
  153. protected Vector3 m_CameraLeftAxis;
  154. protected Vector3 m_CameraUpAxis;
  155. private AgentManager.ControlFlags m_AgentControlFlags;
  156. private Quaternion m_headrotation = Quaternion.Identity;
  157. private byte m_state;
  158. //Reuse the Vector3 instead of creating a new one on the UpdateMovement method
  159. // private Vector3 movementvector;
  160. private bool m_autopilotMoving;
  161. private Vector3 m_autoPilotTarget;
  162. private bool m_sitAtAutoTarget;
  163. private string m_nextSitAnimation = String.Empty;
  164. //PauPaw:Proper PID Controler for autopilot************
  165. private bool m_moveToPositionInProgress;
  166. private Vector3 m_moveToPositionTarget;
  167. private bool m_followCamAuto;
  168. private int m_movementUpdateCount;
  169. private const int NumMovementsBetweenRayCast = 5;
  170. private bool CameraConstraintActive;
  171. //private int m_moveToPositionStateStatus;
  172. //*****************************************************
  173. // Agent's Draw distance.
  174. protected float m_DrawDistance;
  175. protected AvatarAppearance m_appearance;
  176. // neighbouring regions we have enabled a child agent in
  177. // holds the seed cap for the child agent in that region
  178. private Dictionary<ulong, string> m_knownChildRegions = new Dictionary<ulong, string>();
  179. /// <summary>
  180. /// Implemented Control Flags
  181. /// </summary>
  182. private enum Dir_ControlFlags
  183. {
  184. DIR_CONTROL_FLAG_FORWARD = AgentManager.ControlFlags.AGENT_CONTROL_AT_POS,
  185. DIR_CONTROL_FLAG_BACK = AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG,
  186. DIR_CONTROL_FLAG_LEFT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS,
  187. DIR_CONTROL_FLAG_RIGHT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG,
  188. DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
  189. DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
  190. DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS,
  191. DIR_CONTROL_FLAG_BACKWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
  192. DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
  193. }
  194. /// <summary>
  195. /// Position at which a significant movement was made
  196. /// </summary>
  197. private Vector3 posLastSignificantMove;
  198. // For teleports and crossings callbacks
  199. string m_callbackURI;
  200. UUID m_originRegionID;
  201. ulong m_rootRegionHandle;
  202. /// <value>
  203. /// Script engines present in the scene
  204. /// </value>
  205. private IScriptModule[] m_scriptEngines;
  206. #region Properties
  207. /// <summary>
  208. /// Physical scene representation of this Avatar.
  209. /// </summary>
  210. public PhysicsActor PhysicsActor
  211. {
  212. set { m_physicsActor = value; }
  213. get { return m_physicsActor; }
  214. }
  215. public byte MovementFlag
  216. {
  217. set { m_movementflag = value; }
  218. get { return m_movementflag; }
  219. }
  220. public bool Updated
  221. {
  222. set { m_updateflag = value; }
  223. get { return m_updateflag; }
  224. }
  225. public bool Invulnerable
  226. {
  227. set { m_invulnerable = value; }
  228. get { return m_invulnerable; }
  229. }
  230. public int UserLevel
  231. {
  232. get { return m_userLevel; }
  233. }
  234. public int GodLevel
  235. {
  236. get { return m_godLevel; }
  237. }
  238. public ulong RegionHandle
  239. {
  240. get { return m_rootRegionHandle; }
  241. }
  242. public Vector3 CameraPosition
  243. {
  244. get { return m_CameraCenter; }
  245. }
  246. public Quaternion CameraRotation
  247. {
  248. get { return Util.Axes2Rot(m_CameraAtAxis, m_CameraLeftAxis, m_CameraUpAxis); }
  249. }
  250. public Vector3 CameraAtAxis
  251. {
  252. get { return m_CameraAtAxis; }
  253. }
  254. public Vector3 CameraLeftAxis
  255. {
  256. get { return m_CameraLeftAxis; }
  257. }
  258. public Vector3 CameraUpAxis
  259. {
  260. get { return m_CameraUpAxis; }
  261. }
  262. public Vector3 Lookat
  263. {
  264. get
  265. {
  266. Vector3 a = new Vector3(m_CameraAtAxis.X, m_CameraAtAxis.Y, 0);
  267. if (a == Vector3.Zero)
  268. return a;
  269. return Util.GetNormalizedVector(a);
  270. }
  271. }
  272. private readonly string m_firstname;
  273. public string Firstname
  274. {
  275. get { return m_firstname; }
  276. }
  277. private readonly string m_lastname;
  278. public string Lastname
  279. {
  280. get { return m_lastname; }
  281. }
  282. private string m_grouptitle;
  283. public string Grouptitle
  284. {
  285. get { return m_grouptitle; }
  286. set { m_grouptitle = value; }
  287. }
  288. public float DrawDistance
  289. {
  290. get { return m_DrawDistance; }
  291. }
  292. protected bool m_allowMovement = true;
  293. public bool AllowMovement
  294. {
  295. get { return m_allowMovement; }
  296. set { m_allowMovement = value; }
  297. }
  298. public bool SetAlwaysRun
  299. {
  300. get
  301. {
  302. if (PhysicsActor != null)
  303. {
  304. return PhysicsActor.SetAlwaysRun;
  305. }
  306. else
  307. {
  308. return m_setAlwaysRun;
  309. }
  310. }
  311. set
  312. {
  313. m_setAlwaysRun = value;
  314. if (PhysicsActor != null)
  315. {
  316. PhysicsActor.SetAlwaysRun = value;
  317. }
  318. }
  319. }
  320. public byte State
  321. {
  322. get { return m_state; }
  323. set { m_state = value; }
  324. }
  325. public uint AgentControlFlags
  326. {
  327. get { return (uint)m_AgentControlFlags; }
  328. set { m_AgentControlFlags = (AgentManager.ControlFlags)value; }
  329. }
  330. /// <summary>
  331. /// This works out to be the ClientView object associated with this avatar, or it's client connection manager
  332. /// </summary>
  333. private IClientAPI m_controllingClient;
  334. protected PhysicsActor m_physicsActor;
  335. /// <value>
  336. /// The client controlling this presence
  337. /// </value>
  338. public IClientAPI ControllingClient
  339. {
  340. get { return m_controllingClient; }
  341. }
  342. public IClientCore ClientView
  343. {
  344. get { return (IClientCore) m_controllingClient; }
  345. }
  346. protected Vector3 m_parentPosition;
  347. public Vector3 ParentPosition
  348. {
  349. get { return m_parentPosition; }
  350. set { m_parentPosition = value; }
  351. }
  352. /// <summary>
  353. /// Position of this avatar relative to the region the avatar is in
  354. /// </summary>
  355. public override Vector3 AbsolutePosition
  356. {
  357. get
  358. {
  359. PhysicsActor actor = m_physicsActor;
  360. if (actor != null)
  361. m_pos = actor.Position;
  362. return m_parentPosition + m_pos;
  363. }
  364. set
  365. {
  366. PhysicsActor actor = m_physicsActor;
  367. if (actor != null)
  368. {
  369. try
  370. {
  371. lock (m_scene.SyncRoot)
  372. m_physicsActor.Position = value;
  373. }
  374. catch (Exception e)
  375. {
  376. m_log.Error("[SCENEPRESENCE]: ABSOLUTE POSITION " + e.Message);
  377. }
  378. }
  379. m_pos = value;
  380. m_parentPosition = Vector3.Zero;
  381. }
  382. }
  383. public Vector3 OffsetPosition
  384. {
  385. get { return m_pos; }
  386. set { m_pos = value; }
  387. }
  388. /// <summary>
  389. /// Current velocity of the avatar.
  390. /// </summary>
  391. public override Vector3 Velocity
  392. {
  393. get
  394. {
  395. PhysicsActor actor = m_physicsActor;
  396. if (actor != null)
  397. m_velocity = actor.Velocity;
  398. return m_velocity;
  399. }
  400. set
  401. {
  402. PhysicsActor actor = m_physicsActor;
  403. if (actor != null)
  404. {
  405. try
  406. {
  407. lock (m_scene.SyncRoot)
  408. actor.Velocity = value;
  409. }
  410. catch (Exception e)
  411. {
  412. m_log.Error("[SCENEPRESENCE]: VELOCITY " + e.Message);
  413. }
  414. }
  415. m_velocity = value;
  416. }
  417. }
  418. public Quaternion Rotation
  419. {
  420. get { return m_bodyRot; }
  421. set { m_bodyRot = value; }
  422. }
  423. public Quaternion PreviousRotation
  424. {
  425. get { return m_bodyRotPrevious; }
  426. set { m_bodyRotPrevious = value; }
  427. }
  428. /// <summary>
  429. /// If this is true, agent doesn't have a representation in this scene.
  430. /// this is an agent 'looking into' this scene from a nearby scene(region)
  431. ///
  432. /// if False, this agent has a representation in this scene
  433. /// </summary>
  434. private bool m_isChildAgent = true;
  435. public bool IsChildAgent
  436. {
  437. get { return m_isChildAgent; }
  438. set { m_isChildAgent = value; }
  439. }
  440. private uint m_parentID;
  441. public uint ParentID
  442. {
  443. get { return m_parentID; }
  444. set { m_parentID = value; }
  445. }
  446. public float Health
  447. {
  448. get { return m_health; }
  449. set { m_health = value; }
  450. }
  451. /// <summary>
  452. /// These are the region handles known by the avatar.
  453. /// </summary>
  454. public List<ulong> KnownChildRegionHandles
  455. {
  456. get
  457. {
  458. if (m_knownChildRegions.Count == 0)
  459. return new List<ulong>();
  460. else
  461. return new List<ulong>(m_knownChildRegions.Keys);
  462. }
  463. }
  464. public Dictionary<ulong, string> KnownRegions
  465. {
  466. get { return m_knownChildRegions; }
  467. set
  468. {
  469. m_knownChildRegions = value;
  470. }
  471. }
  472. public ISceneViewer SceneViewer
  473. {
  474. get { return m_sceneViewer; }
  475. }
  476. public void AdjustKnownSeeds()
  477. {
  478. Dictionary<ulong, string> seeds;
  479. if (Scene.CapsModule != null)
  480. seeds = Scene.CapsModule.GetChildrenSeeds(UUID);
  481. else
  482. seeds = new Dictionary<ulong, string>();
  483. List<ulong> old = new List<ulong>();
  484. foreach (ulong handle in seeds.Keys)
  485. {
  486. uint x, y;
  487. Utils.LongToUInts(handle, out x, out y);
  488. x = x / Constants.RegionSize;
  489. y = y / Constants.RegionSize;
  490. if (Util.IsOutsideView(x, Scene.RegionInfo.RegionLocX, y, Scene.RegionInfo.RegionLocY))
  491. {
  492. old.Add(handle);
  493. }
  494. }
  495. DropOldNeighbours(old);
  496. if (Scene.CapsModule != null)
  497. Scene.CapsModule.SetChildrenSeed(UUID, seeds);
  498. KnownRegions = seeds;
  499. //m_log.Debug(" ++++++++++AFTER+++++++++++++ ");
  500. //DumpKnownRegions();
  501. }
  502. public void DumpKnownRegions()
  503. {
  504. m_log.Info("================ KnownRegions "+Scene.RegionInfo.RegionName+" ================");
  505. foreach (KeyValuePair<ulong, string> kvp in KnownRegions)
  506. {
  507. uint x, y;
  508. Utils.LongToUInts(kvp.Key, out x, out y);
  509. x = x / Constants.RegionSize;
  510. y = y / Constants.RegionSize;
  511. m_log.Info(" >> "+x+", "+y+": "+kvp.Value);
  512. }
  513. }
  514. private bool m_inTransit;
  515. private bool m_mouseLook;
  516. private bool m_leftButtonDown;
  517. public bool IsInTransit
  518. {
  519. get { return m_inTransit; }
  520. set { m_inTransit = value; }
  521. }
  522. public float SpeedModifier
  523. {
  524. get { return m_speedModifier; }
  525. set { m_speedModifier = value; }
  526. }
  527. public bool ForceFly
  528. {
  529. get { return m_forceFly; }
  530. set { m_forceFly = value; }
  531. }
  532. public bool FlyDisabled
  533. {
  534. get { return m_flyDisabled; }
  535. set { m_flyDisabled = value; }
  536. }
  537. public string Viewer
  538. {
  539. get { return m_scene.AuthenticateHandler.GetAgentCircuitData(ControllingClient.CircuitCode).Viewer; }
  540. }
  541. #endregion
  542. #region Constructor(s)
  543. public ScenePresence()
  544. {
  545. m_sendCourseLocationsMethod = SendCoarseLocationsDefault;
  546. CreateSceneViewer();
  547. m_animator = new ScenePresenceAnimator(this);
  548. }
  549. private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) : this()
  550. {
  551. m_rootRegionHandle = reginfo.RegionHandle;
  552. m_controllingClient = client;
  553. m_firstname = m_controllingClient.FirstName;
  554. m_lastname = m_controllingClient.LastName;
  555. m_name = String.Format("{0} {1}", m_firstname, m_lastname);
  556. m_scene = world;
  557. m_uuid = client.AgentId;
  558. m_regionInfo = reginfo;
  559. m_localId = m_scene.AllocateLocalId();
  560. UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid);
  561. if (account != null)
  562. m_userLevel = account.UserLevel;
  563. IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>();
  564. if (gm != null)
  565. m_grouptitle = gm.GetGroupTitle(m_uuid);
  566. m_scriptEngines = m_scene.RequestModuleInterfaces<IScriptModule>();
  567. AbsolutePosition = posLastSignificantMove = m_CameraCenter =
  568. m_lastCameraCenter = m_controllingClient.StartPos;
  569. m_reprioritization_timer = new Timer(world.ReprioritizationInterval);
  570. m_reprioritization_timer.Elapsed += new ElapsedEventHandler(Reprioritize);
  571. m_reprioritization_timer.AutoReset = false;
  572. AdjustKnownSeeds();
  573. // TODO: I think, this won't send anything, as we are still a child here...
  574. Animator.TrySetMovementAnimation("STAND");
  575. // we created a new ScenePresence (a new child agent) in a fresh region.
  576. // Request info about all the (root) agents in this region
  577. // Note: This won't send data *to* other clients in that region (children don't send)
  578. // MIC: This gets called again in CompleteMovement
  579. SendInitialFullUpdateToAllClients();
  580. RegisterToEvents();
  581. SetDirectionVectors();
  582. }
  583. public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, AvatarAppearance appearance)
  584. : this(client, world, reginfo)
  585. {
  586. m_appearance = appearance;
  587. }
  588. private void CreateSceneViewer()
  589. {
  590. m_sceneViewer = new SceneViewer(this);
  591. }
  592. public void RegisterToEvents()
  593. {
  594. m_controllingClient.OnCompleteMovementToRegion += CompleteMovement;
  595. //m_controllingClient.OnCompleteMovementToRegion += SendInitialData;
  596. m_controllingClient.OnAgentUpdate += HandleAgentUpdate;
  597. m_controllingClient.OnAgentRequestSit += HandleAgentRequestSit;
  598. m_controllingClient.OnAgentSit += HandleAgentSit;
  599. m_controllingClient.OnSetAlwaysRun += HandleSetAlwaysRun;
  600. m_controllingClient.OnStartAnim += HandleStartAnim;
  601. m_controllingClient.OnStopAnim += HandleStopAnim;
  602. m_controllingClient.OnForceReleaseControls += HandleForceReleaseControls;
  603. m_controllingClient.OnAutoPilotGo += DoAutoPilot;
  604. m_controllingClient.AddGenericPacketHandler("autopilot", DoMoveToPosition);
  605. // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange);
  606. // ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement);
  607. }
  608. private void SetDirectionVectors()
  609. {
  610. Dir_Vectors[0] = Vector3.UnitX; //FORWARD
  611. Dir_Vectors[1] = -Vector3.UnitX; //BACK
  612. Dir_Vectors[2] = Vector3.UnitY; //LEFT
  613. Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
  614. Dir_Vectors[4] = Vector3.UnitZ; //UP
  615. Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
  616. Dir_Vectors[8] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
  617. Dir_Vectors[6] = Vector3.UnitX*2; //FORWARD
  618. Dir_Vectors[7] = -Vector3.UnitX; //BACK
  619. }
  620. private Vector3[] GetWalkDirectionVectors()
  621. {
  622. Vector3[] vector = new Vector3[9];
  623. vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD
  624. vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
  625. vector[2] = Vector3.UnitY; //LEFT
  626. vector[3] = -Vector3.UnitY; //RIGHT
  627. vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP
  628. vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN
  629. vector[8] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge
  630. vector[6] = (new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z) * 2); //FORWARD Nudge
  631. vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK Nudge
  632. return vector;
  633. }
  634. #endregion
  635. public uint GenerateClientFlags(UUID ObjectID)
  636. {
  637. return m_scene.Permissions.GenerateClientFlags(m_uuid, ObjectID);
  638. }
  639. /// <summary>
  640. /// Send updates to the client about prims which have been placed on the update queue. We don't
  641. /// necessarily send updates for all the parts on the queue, e.g. if an updates with a more recent
  642. /// timestamp has already been sent.
  643. /// </summary>
  644. public void SendPrimUpdates()
  645. {
  646. m_perfMonMS = Util.EnvironmentTickCount();
  647. m_sceneViewer.SendPrimUpdates();
  648. m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
  649. }
  650. #region Status Methods
  651. /// <summary>
  652. /// This turns a child agent, into a root agent
  653. /// This is called when an agent teleports into a region, or if an
  654. /// agent crosses into this region from a neighbor over the border
  655. /// </summary>
  656. public void MakeRootAgent(Vector3 pos, bool isFlying)
  657. {
  658. m_log.DebugFormat(
  659. "[SCENE]: Upgrading child to root agent for {0} in {1}",
  660. Name, m_scene.RegionInfo.RegionName);
  661. //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count);
  662. IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>();
  663. if (gm != null)
  664. m_grouptitle = gm.GetGroupTitle(m_uuid);
  665. m_rootRegionHandle = m_scene.RegionInfo.RegionHandle;
  666. m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene);
  667. // Moved this from SendInitialData to ensure that m_appearance is initialized
  668. // before the inventory is processed in MakeRootAgent. This fixes a race condition
  669. // related to the handling of attachments
  670. //m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance);
  671. if (m_scene.TestBorderCross(pos, Cardinals.E))
  672. {
  673. Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E);
  674. pos.X = crossedBorder.BorderLine.Z - 1;
  675. }
  676. if (m_scene.TestBorderCross(pos, Cardinals.N))
  677. {
  678. Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N);
  679. pos.Y = crossedBorder.BorderLine.Z - 1;
  680. }
  681. if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
  682. {
  683. m_log.WarnFormat(
  684. "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping",
  685. pos, Name, UUID);
  686. if (pos.X < 0f) pos.X = 0f;
  687. if (pos.Y < 0f) pos.Y = 0f;
  688. if (pos.Z < 0f) pos.Z = 0f;
  689. }
  690. float localAVHeight = 1.56f;
  691. if (m_appearance != null)
  692. {
  693. if (m_appearance.AvatarHeight > 0)
  694. localAVHeight = m_appearance.AvatarHeight;
  695. }
  696. {
  697. if(m_scene.Voxels.IsInsideTerrain(pos))
  698. {
  699. Vector3 newPos=m_scene.Voxels.FindNearestAirVoxel(pos,true);
  700. newPos.Z+=localAVHeight / 2;
  701. pos=newPos;
  702. }
  703. }
  704. float posZLimit = 0;
  705. AbsolutePosition = pos;
  706. if (m_appearance != null)
  707. {
  708. if (m_appearance.AvatarHeight > 0)
  709. SetHeight(m_appearance.AvatarHeight);
  710. }
  711. else
  712. {
  713. m_log.ErrorFormat("[SCENE PRESENCE]: null appearance in MakeRoot in {0}", Scene.RegionInfo.RegionName);
  714. // emergency; this really shouldn't happen
  715. m_appearance = new AvatarAppearance(UUID);
  716. }
  717. AddToPhysicalScene(isFlying);
  718. if (m_appearance != null)
  719. {
  720. if (m_appearance.AvatarHeight > 0)
  721. SetHeight(m_appearance.AvatarHeight);
  722. }
  723. if (m_forceFly)
  724. {
  725. m_physicsActor.Flying = true;
  726. }
  727. else if (m_flyDisabled)
  728. {
  729. m_physicsActor.Flying = false;
  730. }
  731. // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying
  732. // avatar to return to the standing position in mid-air. On login it looks like this is being sent
  733. // elsewhere anyway
  734. // Animator.SendAnimPack();
  735. m_scene.SwapRootAgentCount(false);
  736. //CachedUserInfo userInfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(m_uuid);
  737. //if (userInfo != null)
  738. // userInfo.FetchInventory();
  739. //else
  740. // m_log.ErrorFormat("[SCENE]: Could not find user info for {0} when making it a root agent", m_uuid);
  741. // On the next prim update, all objects will be sent
  742. //
  743. m_sceneViewer.Reset();
  744. m_isChildAgent = false;
  745. // send the animations of the other presences to me
  746. m_scene.ForEachScenePresence(delegate(ScenePresence presence)
  747. {
  748. if (presence != this)
  749. presence.Animator.SendAnimPackToClient(ControllingClient);
  750. });
  751. m_scene.EventManager.TriggerOnMakeRootAgent(this);
  752. }
  753. /// <summary>
  754. /// This turns a root agent into a child agent
  755. /// when an agent departs this region for a neighbor, this gets called.
  756. ///
  757. /// It doesn't get called for a teleport. Reason being, an agent that
  758. /// teleports out may not end up anywhere near this region
  759. /// </summary>
  760. public void MakeChildAgent()
  761. {
  762. // It looks like m_animator is set to null somewhere, and MakeChild
  763. // is called after that. Probably in aborted teleports.
  764. if (m_animator == null)
  765. m_animator = new ScenePresenceAnimator(this);
  766. else
  767. Animator.ResetAnimations();
  768. // m_log.DebugFormat(
  769. // "[SCENEPRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}",
  770. // Name, UUID, m_scene.RegionInfo.RegionName);
  771. // Don't zero out the velocity since this can cause problems when an avatar is making a region crossing,
  772. // depending on the exact timing. This shouldn't matter anyway since child agent positions are not updated.
  773. //Velocity = new Vector3(0, 0, 0);
  774. m_isChildAgent = true;
  775. m_scene.SwapRootAgentCount(true);
  776. RemoveFromPhysicalScene();
  777. // FIXME: Set m_rootRegionHandle to the region handle of the scene this agent is moving into
  778. m_scene.EventManager.TriggerOnMakeChildAgent(this);
  779. }
  780. /// <summary>
  781. /// Removes physics plugin scene representation of this agent if it exists.
  782. /// </summary>
  783. private void RemoveFromPhysicalScene()
  784. {
  785. if (PhysicsActor != null)
  786. {
  787. m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients;
  788. m_physicsActor.OnOutOfBounds -= OutOfBoundsCall;
  789. m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
  790. m_physicsActor.UnSubscribeEvents();
  791. m_physicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate;
  792. PhysicsActor = null;
  793. }
  794. }
  795. /// <summary>
  796. ///
  797. /// </summary>
  798. /// <param name="pos"></param>
  799. public void Teleport(Vector3 pos)
  800. {
  801. bool isFlying = false;
  802. if (m_physicsActor != null)
  803. isFlying = m_physicsActor.Flying;
  804. RemoveFromPhysicalScene();
  805. Velocity = Vector3.Zero;
  806. AbsolutePosition = pos;
  807. AddToPhysicalScene(isFlying);
  808. if (m_appearance != null)
  809. {
  810. if (m_appearance.AvatarHeight > 0)
  811. SetHeight(m_appearance.AvatarHeight);
  812. }
  813. SendTerseUpdateToAllClients();
  814. }
  815. public void TeleportWithMomentum(Vector3 pos)
  816. {
  817. bool isFlying = false;
  818. if (m_physicsActor != null)
  819. isFlying = m_physicsActor.Flying;
  820. RemoveFromPhysicalScene();
  821. AbsolutePosition = pos;
  822. AddToPhysicalScene(isFlying);
  823. if (m_appearance != null)
  824. {
  825. if (m_appearance.AvatarHeight > 0)
  826. SetHeight(m_appearance.AvatarHeight);
  827. }
  828. SendTerseUpdateToAllClients();
  829. }
  830. /// <summary>
  831. ///
  832. /// </summary>
  833. public void StopMovement()
  834. {
  835. }
  836. public void StopFlying()
  837. {
  838. ControllingClient.StopFlying(this);
  839. }
  840. public void AddNeighbourRegion(ulong regionHandle, string cap)
  841. {
  842. lock (m_knownChildRegions)
  843. {
  844. if (!m_knownChildRegions.ContainsKey(regionHandle))
  845. {
  846. uint x, y;
  847. Utils.LongToUInts(regionHandle, out x, out y);
  848. m_knownChildRegions.Add(regionHandle, cap);
  849. }
  850. }
  851. }
  852. public void RemoveNeighbourRegion(ulong regionHandle)
  853. {
  854. lock (m_knownChildRegions)
  855. {
  856. if (m_knownChildRegions.ContainsKey(regionHandle))
  857. {
  858. m_knownChildRegions.Remove(regionHandle);
  859. //m_log.Debug(" !!! removing known region {0} in {1}. Count = {2}", regionHandle, Scene.RegionInfo.RegionName, m_knownChildRegions.Count);
  860. }
  861. }
  862. }
  863. public void DropOldNeighbours(List<ulong> oldRegions)
  864. {
  865. foreach (ulong handle in oldRegions)
  866. {
  867. RemoveNeighbourRegion(handle);
  868. Scene.CapsModule.DropChildSeed(UUID, handle);
  869. }
  870. }
  871. public List<ulong> GetKnownRegionList()
  872. {
  873. return new List<ulong>(m_knownChildRegions.Keys);
  874. }
  875. #endregion
  876. #region Event Handlers
  877. /// <summary>
  878. /// Sets avatar height in the phyiscs plugin
  879. /// </summary>
  880. public void SetHeight(float height)
  881. {
  882. if (PhysicsActor != null && !IsChildAgent)
  883. {
  884. Vector3 SetSize = new Vector3(0.45f, 0.6f, height);
  885. PhysicsActor.Size = SetSize;
  886. }
  887. }
  888. /// <summary>
  889. /// Complete Avatar's movement into the region.
  890. /// This is called upon a very important packet sent from the client,
  891. /// so it's client-controlled. Never call this method directly.
  892. /// </summary>
  893. public void CompleteMovement(IClientAPI client)
  894. {
  895. DateTime startTime = DateTime.Now;
  896. m_log.DebugFormat(
  897. "[SCENE PRESENCE]: Completing movement of {0} into region {1}",
  898. client.Name, Scene.RegionInfo.RegionName);
  899. Vector3 look = Velocity;
  900. if ((look.X == 0) && (look.Y == 0) && (look.Z == 0))
  901. {
  902. look = new Vector3(0.99f, 0.042f, 0);
  903. }
  904. // Prevent teleporting to an underground location
  905. // (may crash client otherwise)
  906. //
  907. Vector3 pos = AbsolutePosition;
  908. float ground = m_scene.GetGroundHeight(pos.X, pos.Y);
  909. if (pos.Z < ground + 1.5f)
  910. {
  911. pos.Z = ground + 1.5f;
  912. AbsolutePosition = pos;
  913. }
  914. m_isChildAgent = false;
  915. bool m_flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
  916. MakeRootAgent(AbsolutePosition, m_flying);
  917. if ((m_callbackURI != null) && !m_callbackURI.Equals(""))
  918. {
  919. m_log.DebugFormat("[SCENE PRESENCE]: Releasing agent in URI {0}", m_callbackURI);
  920. Scene.SimulationService.ReleaseAgent(m_originRegionID, UUID, m_callbackURI);
  921. m_callbackURI = null;
  922. }
  923. //m_log.DebugFormat("Completed movement");
  924. m_controllingClient.MoveAgentIntoRegion(m_regionInfo, AbsolutePosition, look);
  925. SendInitialData();
  926. // Create child agents in neighbouring regions
  927. if (!m_isChildAgent)
  928. {
  929. IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();
  930. if (m_agentTransfer != null)
  931. m_agentTransfer.EnableChildAgents(this);
  932. else
  933. m_log.DebugFormat("[SCENE PRESENCE]: Unable to create child agents in neighbours, because AgentTransferModule is not active");
  934. IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>();
  935. if (friendsModule != null)
  936. friendsModule.SendFriendsOnlineIfNeeded(ControllingClient);
  937. }
  938. m_log.DebugFormat(
  939. "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms",
  940. client.Name, Scene.RegionInfo.RegionName, (DateTime.Now - startTime).Milliseconds);
  941. }
  942. /// <summary>
  943. /// Callback for the Camera view block check. Gets called with the results of the camera view block test
  944. /// hitYN is true when there's something in the way.
  945. /// </summary>
  946. /// <param name="hitYN"></param>
  947. /// <param name="collisionPoint"></param>
  948. /// <param name="localid"></param>
  949. /// <param name="distance"></param>
  950. public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 pNormal)
  951. {
  952. const float POSITION_TOLERANCE = 0.02f;
  953. const float VELOCITY_TOLERANCE = 0.02f;
  954. const float ROTATION_TOLERANCE = 0.02f;
  955. if (m_followCamAuto)
  956. {
  957. if (hitYN)
  958. {
  959. CameraConstraintActive = true;
  960. //m_log.DebugFormat("[RAYCASTRESULT]: {0}, {1}, {2}, {3}", hitYN, collisionPoint, localid, distance);
  961. Vector3 normal = Vector3.Normalize(new Vector3(0f, 0f, collisionPoint.Z) - collisionPoint);
  962. ControllingClient.SendCameraConstraint(new Vector4(normal.X, normal.Y, normal.Z, -1 * Vector3.Distance(new Vector3(0,0,collisionPoint.Z),collisionPoint)));
  963. }
  964. else
  965. {
  966. if (!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) ||
  967. !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) ||
  968. !m_bodyRot.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE))
  969. {
  970. if (CameraConstraintActive)
  971. {
  972. ControllingClient.SendCameraConstraint(new Vector4(0f, 0.5f, 0.9f, -3000f));
  973. CameraConstraintActive = false;
  974. }
  975. }
  976. }
  977. }
  978. }
  979. /// <summary>
  980. /// This is the event handler for client movement. If a client is moving, this event is triggering.
  981. /// </summary>
  982. public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
  983. {
  984. //if (m_isChildAgent)
  985. //{
  986. // // m_log.Debug("DEBUG: HandleAgentUpdate: child agent");
  987. // return;
  988. //}
  989. m_perfMonMS = Util.EnvironmentTickCount();
  990. ++m_movementUpdateCount;
  991. if (m_movementUpdateCount < 1)
  992. m_movementUpdateCount = 1;
  993. #region Sanity Checking
  994. // This is irritating. Really.
  995. if (!AbsolutePosition.IsFinite())
  996. {
  997. RemoveFromPhysicalScene();
  998. m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902");
  999. m_pos = m_LastFinitePos;
  1000. if (!m_pos.IsFinite())
  1001. {
  1002. m_pos.X = 127f;
  1003. m_pos.Y = 127f;
  1004. m_pos.Z = 127f;
  1005. m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999903");
  1006. }
  1007. AddToPhysicalScene(false);
  1008. }
  1009. else
  1010. {
  1011. m_LastFinitePos = m_pos;
  1012. }
  1013. #endregion Sanity Checking
  1014. #region Inputs
  1015. AgentManager.ControlFlags flags = (AgentManager.ControlFlags)agentData.ControlFlags;
  1016. Quaternion bodyRotation = agentData.BodyRotation;
  1017. // Camera location in world. We'll need to raytrace
  1018. // from this location from time to time.
  1019. m_CameraCenter = agentData.CameraCenter;
  1020. if (Vector3.Distance(m_lastCameraCenter, m_CameraCenter) >= Scene.RootReprioritizationDistance)
  1021. {
  1022. ReprioritizeUpdates();
  1023. m_lastCameraCenter = m_CameraCenter;
  1024. }
  1025. // Use these three vectors to figure out what the agent is looking at
  1026. // Convert it to a Matrix and/or Quaternion
  1027. m_CameraAtAxis = agentData.CameraAtAxis;
  1028. m_CameraLeftAxis = agentData.CameraLeftAxis;
  1029. m_CameraUpAxis = agentData.CameraUpAxis;
  1030. // The Agent's Draw distance setting
  1031. m_DrawDistance = agentData.Far;
  1032. // Check if Client has camera in 'follow cam' or 'build' mode.
  1033. Vector3 camdif = (Vector3.One * m_bodyRot - Vector3.One * CameraRotation);
  1034. m_followCamAuto = ((m_CameraUpAxis.Z > 0.959f && m_CameraUpAxis.Z < 0.98f)
  1035. && (Math.Abs(camdif.X) < 0.4f && Math.Abs(camdif.Y) < 0.4f)) ? true : false;
  1036. m_mouseLook = (flags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0;
  1037. m_leftButtonDown = (flags & AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0;
  1038. #endregion Inputs
  1039. if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_STAND_UP) != 0)
  1040. {
  1041. StandUp();
  1042. }
  1043. //m_log.DebugFormat("[FollowCam]: {0}", m_followCamAuto);
  1044. // Raycast from the avatar's head to the camera to see if there's anything blocking the view
  1045. if ((m_movementUpdateCount % NumMovementsBetweenRayCast) == 0 && m_scene.PhysicsScene.SupportsRayCast())
  1046. {
  1047. if (m_followCamAuto)
  1048. {
  1049. Vector3 posAdjusted = m_pos + HEAD_ADJUSTMENT;
  1050. m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
  1051. }
  1052. }
  1053. lock (scriptedcontrols)
  1054. {
  1055. if (scriptedcontrols.Count > 0)
  1056. {
  1057. SendControlToScripts((uint)flags);
  1058. flags = RemoveIgnoredControls(flags, IgnoredControls);
  1059. }
  1060. }
  1061. if (m_autopilotMoving)
  1062. CheckAtSitTarget();
  1063. if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
  1064. {
  1065. // TODO: This doesn't prevent the user from walking yet.
  1066. // Setting parent ID would fix this, if we knew what value
  1067. // to use. Or we could add a m_isSitting variable.
  1068. //Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
  1069. SitGround = true;
  1070. }
  1071. // In the future, these values might need to go global.
  1072. // Here's where you get them.
  1073. m_AgentControlFlags = flags;
  1074. m_headrotation = agentData.HeadRotation;
  1075. m_state = agentData.State;
  1076. PhysicsActor actor = PhysicsActor;
  1077. if (actor == null)
  1078. {
  1079. return;
  1080. }
  1081. bool update_movementflag = false;
  1082. if (m_allowMovement && !SitGround)
  1083. {
  1084. if (agentData.UseClientAgentPosition)
  1085. {
  1086. m_moveToPositionInProgress = (agentData.ClientAgentPosition - AbsolutePosition).Length() > 0.2f;
  1087. m_moveToPositionTarget = agentData.ClientAgentPosition;
  1088. }
  1089. int i = 0;
  1090. bool update_rotation = false;
  1091. bool DCFlagKeyPressed = false;
  1092. Vector3 agent_control_v3 = Vector3.Zero;
  1093. Quaternion q = bodyRotation;
  1094. bool oldflying = PhysicsActor.Flying;
  1095. if (m_forceFly)
  1096. actor.Flying = true;
  1097. else if (m_flyDisabled)
  1098. actor.Flying = false;
  1099. else
  1100. actor.Flying = ((flags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
  1101. if (actor.Flying != oldflying)
  1102. update_movementflag = true;
  1103. if (q != m_bodyRot)
  1104. {
  1105. m_bodyRot = q;
  1106. update_rotation = true;
  1107. }
  1108. if (m_parentID == 0)
  1109. {
  1110. bool bAllowUpdateMoveToPosition = false;
  1111. bool bResetMoveToPosition = false;
  1112. Vector3[] dirVectors;
  1113. // use camera up angle when in mouselook and not flying or when holding the left mouse button down and not flying
  1114. // this prevents 'jumping' in inappropriate situations.
  1115. if ((m_mouseLook && !m_physicsActor.Flying) || (m_leftButtonDown && !m_physicsActor.Flying))
  1116. dirVectors = GetWalkDirectionVectors();
  1117. else
  1118. dirVectors = Dir_Vectors;
  1119. // The fact that m_movementflag is a byte needs to be fixed
  1120. // it really should be a uint
  1121. uint nudgehack = 250;
  1122. foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
  1123. {
  1124. if (((uint)flags & (uint)DCF) != 0)
  1125. {
  1126. bResetMoveToPosition = true;
  1127. DCFlagKeyPressed = true;
  1128. try
  1129. {
  1130. agent_control_v3 += dirVectors[i];
  1131. //m_log.DebugFormat("[Motion]: {0}, {1}",i, dirVectors[i]);
  1132. }
  1133. catch (IndexOutOfRangeException)
  1134. {
  1135. // Why did I get this?
  1136. }
  1137. if ((m_movementflag & (byte)(uint)DCF) == 0)
  1138. {
  1139. if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
  1140. {
  1141. m_movementflag |= (byte)nudgehack;
  1142. }
  1143. m_movementflag += (byte)(uint)DCF;
  1144. update_movementflag = true;
  1145. }
  1146. }
  1147. else
  1148. {
  1149. if ((m_movementflag & (byte)(uint)DCF) != 0 ||
  1150. ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
  1151. && ((m_movementflag & (byte)nudgehack) == nudgehack))
  1152. ) // This or is for Nudge forward
  1153. {
  1154. m_movementflag -= ((byte)(uint)DCF);
  1155. update_movementflag = true;

Large files files are truncated, but you can click here to view the full file