InnerScene.cs 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269
  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 OpenSim 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 Axiom.Math;
  30. using libsecondlife;
  31. using libsecondlife.Packets;
  32. using OpenSim.Framework;
  33. using OpenSim.Framework.Console;
  34. using OpenSim.Region.Environment.Types;
  35. using OpenSim.Region.Physics.Manager;
  36. namespace OpenSim.Region.Environment.Scenes
  37. {
  38. public delegate void PhysicsCrash();
  39. public class InnerScene
  40. {
  41. private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
  42. #region Events
  43. public event PhysicsCrash UnRecoverableError;
  44. private PhysicsCrash handlerPhysicsCrash = null;
  45. #endregion
  46. #region Fields
  47. public Dictionary<LLUUID, ScenePresence> ScenePresences;
  48. // SceneObjects is not currently populated or used.
  49. //public Dictionary<LLUUID, SceneObjectGroup> SceneObjects;
  50. public Dictionary<LLUUID, EntityBase> Entities;
  51. public Dictionary<LLUUID, ScenePresence> RestorePresences;
  52. public BasicQuadTreeNode QuadTree;
  53. protected RegionInfo m_regInfo;
  54. protected Scene m_parentScene;
  55. protected PermissionManager PermissionsMngr;
  56. protected List<EntityBase> m_updateList = new List<EntityBase>();
  57. protected int m_numRootAgents = 0;
  58. protected int m_numPrim = 0;
  59. protected int m_numChildAgents = 0;
  60. protected int m_physicalPrim = 0;
  61. protected int m_activeScripts = 0;
  62. protected int m_scriptLPS = 0;
  63. internal object m_syncRoot = new object();
  64. public PhysicsScene _PhyScene;
  65. #endregion
  66. public InnerScene(Scene parent, RegionInfo regInfo, PermissionManager permissionsMngr)
  67. {
  68. m_parentScene = parent;
  69. m_regInfo = regInfo;
  70. PermissionsMngr = permissionsMngr;
  71. QuadTree = new BasicQuadTreeNode(null, "/0/", 0, 0, (short)Constants.RegionSize, (short)Constants.RegionSize);
  72. QuadTree.Subdivide();
  73. QuadTree.Subdivide();
  74. }
  75. public PhysicsScene PhysicsScene
  76. {
  77. get { return _PhyScene; }
  78. set
  79. {
  80. // If we're not doing the initial set
  81. // Then we've got to remove the previous
  82. // event handler
  83. try
  84. {
  85. _PhyScene.OnPhysicsCrash -= physicsBasedCrash;
  86. }
  87. catch (NullReferenceException)
  88. {
  89. // This occurs when storing to _PhyScene the first time.
  90. // Is there a better way to check the event handler before
  91. // getting here
  92. // This can be safely ignored. We're setting the first inital
  93. // there are no event handler's registered.
  94. }
  95. _PhyScene = value;
  96. _PhyScene.OnPhysicsCrash += physicsBasedCrash;
  97. }
  98. }
  99. public void Close()
  100. {
  101. ScenePresences.Clear();
  102. //SceneObjects.Clear();
  103. Entities.Clear();
  104. }
  105. #region Update Methods
  106. internal void UpdatePreparePhysics()
  107. {
  108. // If we are using a threaded physics engine
  109. // grab the latest scene from the engine before
  110. // trying to process it.
  111. // PhysX does this (runs in the background).
  112. if (_PhyScene.IsThreaded)
  113. {
  114. _PhyScene.GetResults();
  115. }
  116. }
  117. internal void UpdateEntities()
  118. {
  119. List<EntityBase> updateEntities = GetEntities();
  120. foreach (EntityBase entity in updateEntities)
  121. {
  122. entity.Update();
  123. }
  124. }
  125. internal void UpdatePresences()
  126. {
  127. List<ScenePresence> updateScenePresences = GetScenePresences();
  128. foreach (ScenePresence pres in updateScenePresences)
  129. {
  130. pres.Update();
  131. }
  132. }
  133. internal float UpdatePhysics(double elapsed)
  134. {
  135. lock (m_syncRoot)
  136. {
  137. return _PhyScene.Simulate((float)elapsed);
  138. }
  139. }
  140. internal void UpdateEntityMovement()
  141. {
  142. List<EntityBase> moveEntities = GetEntities();
  143. foreach (EntityBase entity in moveEntities)
  144. {
  145. entity.UpdateMovement();
  146. }
  147. }
  148. #endregion
  149. #region Entity Methods
  150. public void AddEntityFromStorage(SceneObjectGroup sceneObject)
  151. {
  152. sceneObject.RegionHandle = m_regInfo.RegionHandle;
  153. sceneObject.SetScene(m_parentScene);
  154. foreach (SceneObjectPart part in sceneObject.Children.Values)
  155. {
  156. part.LocalId = m_parentScene.PrimIDAllocate();
  157. }
  158. sceneObject.UpdateParentIDs();
  159. AddEntity(sceneObject);
  160. }
  161. public void AddEntity(SceneObjectGroup sceneObject)
  162. {
  163. if (!Entities.ContainsKey(sceneObject.UUID))
  164. {
  165. // QuadTree.AddObject(sceneObject);
  166. lock (Entities)
  167. {
  168. Entities.Add(sceneObject.UUID, sceneObject);
  169. }
  170. m_numPrim++;
  171. }
  172. }
  173. /// <summary>
  174. /// Add an entity to the list of prims to process on the next update
  175. /// </summary>
  176. /// <param name="obj">
  177. /// A <see cref="EntityBase"/>
  178. /// </param>
  179. internal void AddToUpdateList(EntityBase obj)
  180. {
  181. lock (m_updateList)
  182. {
  183. if (!m_updateList.Contains(obj))
  184. {
  185. m_updateList.Add(obj);
  186. }
  187. }
  188. }
  189. /// <summary>
  190. /// Process all pending updates
  191. /// </summary>
  192. internal void ProcessUpdates()
  193. {
  194. lock (m_updateList)
  195. {
  196. for (int i = 0; i < m_updateList.Count; i++)
  197. {
  198. EntityBase entity = m_updateList[i];
  199. // Don't abort the whole update if one entity happens to give us an exception.
  200. try
  201. {
  202. m_updateList[i].Update();
  203. }
  204. catch (Exception e)
  205. {
  206. m_log.ErrorFormat("[INNER SCENE]: Failed to update {0}, - {1}", entity.Name, e);//entity.m_uuid
  207. }
  208. }
  209. m_updateList.Clear();
  210. }
  211. }
  212. public void AddPhysicalPrim(int number)
  213. {
  214. m_physicalPrim++;
  215. }
  216. public void RemovePhysicalPrim(int number)
  217. {
  218. m_physicalPrim--;
  219. }
  220. public void AddToScriptLPS(int number)
  221. {
  222. m_scriptLPS += number;
  223. }
  224. public void AddActiveScripts(int number)
  225. {
  226. m_activeScripts += number;
  227. }
  228. public void RemovePrim(uint localID, LLUUID avatar_deleter)
  229. {
  230. List<EntityBase> EntityList = GetEntities();
  231. foreach (EntityBase obj in EntityList)
  232. {
  233. if (obj is SceneObjectGroup)
  234. {
  235. if (((SceneObjectGroup)obj).LocalId == localID)
  236. {
  237. m_parentScene.RemoveEntity((SceneObjectGroup)obj);
  238. m_numPrim--;
  239. return;
  240. }
  241. }
  242. }
  243. }
  244. public void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, LLQuaternion rot)
  245. {
  246. System.Console.WriteLine("Attaching object " + objectLocalID + " to " + AttachmentPt);
  247. SceneObjectPart p = GetSceneObjectPart(objectLocalID);
  248. if (p != null)
  249. {
  250. ScenePresence av = null;
  251. if (TryGetAvatar(remoteClient.AgentId, out av))
  252. {
  253. ObjectUpdatePacket objupdate = new ObjectUpdatePacket();
  254. objupdate.RegionData.RegionHandle = m_regInfo.RegionHandle;
  255. objupdate.RegionData.TimeDilation = ushort.MaxValue;
  256. objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[2];
  257. // avatar stuff - horrible group copypaste
  258. objupdate.ObjectData[0] = new ObjectUpdatePacket.ObjectDataBlock();
  259. objupdate.ObjectData[0].PSBlock = new byte[0];
  260. objupdate.ObjectData[0].ExtraParams = new byte[1];
  261. objupdate.ObjectData[0].MediaURL = new byte[0];
  262. objupdate.ObjectData[0].NameValue = new byte[0];
  263. objupdate.ObjectData[0].Text = new byte[0];
  264. objupdate.ObjectData[0].TextColor = new byte[4];
  265. objupdate.ObjectData[0].JointAxisOrAnchor = new LLVector3(0, 0, 0);
  266. objupdate.ObjectData[0].JointPivot = new LLVector3(0, 0, 0);
  267. objupdate.ObjectData[0].Material = 4;
  268. objupdate.ObjectData[0].TextureAnim = new byte[0];
  269. objupdate.ObjectData[0].Sound = LLUUID.Zero;
  270. objupdate.ObjectData[0].State = 0;
  271. objupdate.ObjectData[0].Data = new byte[0];
  272. objupdate.ObjectData[0].ObjectData = new byte[76];
  273. objupdate.ObjectData[0].ObjectData[15] = 128;
  274. objupdate.ObjectData[0].ObjectData[16] = 63;
  275. objupdate.ObjectData[0].ObjectData[56] = 128;
  276. objupdate.ObjectData[0].ObjectData[61] = 102;
  277. objupdate.ObjectData[0].ObjectData[62] = 40;
  278. objupdate.ObjectData[0].ObjectData[63] = 61;
  279. objupdate.ObjectData[0].ObjectData[64] = 189;
  280. objupdate.ObjectData[0].UpdateFlags = 61 + (9 << 8) + (130 << 16) + (16 << 24);
  281. objupdate.ObjectData[0].PathCurve = 16;
  282. objupdate.ObjectData[0].ProfileCurve = 1;
  283. objupdate.ObjectData[0].PathScaleX = 100;
  284. objupdate.ObjectData[0].PathScaleY = 100;
  285. objupdate.ObjectData[0].ParentID = 0;
  286. objupdate.ObjectData[0].OwnerID = LLUUID.Zero;
  287. objupdate.ObjectData[0].Scale = new LLVector3(1, 1, 1);
  288. objupdate.ObjectData[0].PCode = (byte)PCode.Avatar;
  289. objupdate.ObjectData[0].TextureEntry = ScenePresence.DefaultTexture;
  290. objupdate.ObjectData[0].ID = av.LocalId;
  291. objupdate.ObjectData[0].FullID = remoteClient.AgentId;
  292. objupdate.ObjectData[0].ParentID = 0;
  293. objupdate.ObjectData[0].NameValue =
  294. Helpers.StringToField("FirstName STRING RW SV " + av.Firstname + "\nLastName STRING RW SV " + av.Lastname);
  295. LLVector3 pos2 = av.AbsolutePosition;
  296. // new LLVector3((float) Pos.X, (float) Pos.Y, (float) Pos.Z);
  297. byte[] pb = pos2.GetBytes();
  298. Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 16, pb.Length);
  299. // primitive part
  300. objupdate.ObjectData[1] = new ObjectUpdatePacket.ObjectDataBlock();
  301. // SetDefaultPrimPacketValues
  302. objupdate.ObjectData[1].PSBlock = new byte[0];
  303. objupdate.ObjectData[1].ExtraParams = new byte[1];
  304. objupdate.ObjectData[1].MediaURL = new byte[0];
  305. objupdate.ObjectData[1].NameValue = new byte[0];
  306. objupdate.ObjectData[1].Text = new byte[0];
  307. objupdate.ObjectData[1].TextColor = new byte[4];
  308. objupdate.ObjectData[1].JointAxisOrAnchor = new LLVector3(0, 0, 0);
  309. objupdate.ObjectData[1].JointPivot = new LLVector3(0, 0, 0);
  310. objupdate.ObjectData[1].Material = 3;
  311. objupdate.ObjectData[1].TextureAnim = new byte[0];
  312. objupdate.ObjectData[1].Sound = LLUUID.Zero;
  313. objupdate.ObjectData[1].State = 0;
  314. objupdate.ObjectData[1].Data = new byte[0];
  315. objupdate.ObjectData[1].ObjectData = new byte[60];
  316. objupdate.ObjectData[1].ObjectData[46] = 128;
  317. objupdate.ObjectData[1].ObjectData[47] = 63;
  318. // SetPrimPacketShapeData
  319. PrimitiveBaseShape primData = p.Shape;
  320. objupdate.ObjectData[1].TextureEntry = primData.TextureEntry;
  321. objupdate.ObjectData[1].PCode = primData.PCode;
  322. objupdate.ObjectData[1].State = (byte)(((byte)AttachmentPt) << 4);
  323. objupdate.ObjectData[1].PathBegin = primData.PathBegin;
  324. objupdate.ObjectData[1].PathEnd = primData.PathEnd;
  325. objupdate.ObjectData[1].PathScaleX = primData.PathScaleX;
  326. objupdate.ObjectData[1].PathScaleY = primData.PathScaleY;
  327. objupdate.ObjectData[1].PathShearX = primData.PathShearX;
  328. objupdate.ObjectData[1].PathShearY = primData.PathShearY;
  329. objupdate.ObjectData[1].PathSkew = primData.PathSkew;
  330. objupdate.ObjectData[1].ProfileBegin = primData.ProfileBegin;
  331. objupdate.ObjectData[1].ProfileEnd = primData.ProfileEnd;
  332. objupdate.ObjectData[1].Scale = primData.Scale;
  333. objupdate.ObjectData[1].PathCurve = primData.PathCurve;
  334. objupdate.ObjectData[1].ProfileCurve = primData.ProfileCurve;
  335. objupdate.ObjectData[1].ProfileHollow = primData.ProfileHollow;
  336. objupdate.ObjectData[1].PathRadiusOffset = primData.PathRadiusOffset;
  337. objupdate.ObjectData[1].PathRevolutions = primData.PathRevolutions;
  338. objupdate.ObjectData[1].PathTaperX = primData.PathTaperX;
  339. objupdate.ObjectData[1].PathTaperY = primData.PathTaperY;
  340. objupdate.ObjectData[1].PathTwist = primData.PathTwist;
  341. objupdate.ObjectData[1].PathTwistBegin = primData.PathTwistBegin;
  342. objupdate.ObjectData[1].ExtraParams = primData.ExtraParams;
  343. objupdate.ObjectData[1].UpdateFlags = 276957500; // flags; // ??
  344. objupdate.ObjectData[1].ID = p.LocalId;
  345. objupdate.ObjectData[1].FullID = p.UUID;
  346. objupdate.ObjectData[1].OwnerID = p.OwnerID;
  347. objupdate.ObjectData[1].Text = Helpers.StringToField(p.Text);
  348. objupdate.ObjectData[1].TextColor[0] = 255;
  349. objupdate.ObjectData[1].TextColor[1] = 255;
  350. objupdate.ObjectData[1].TextColor[2] = 255;
  351. objupdate.ObjectData[1].TextColor[3] = 128;
  352. objupdate.ObjectData[1].ParentID = objupdate.ObjectData[0].ID;
  353. //objupdate.ObjectData[1].PSBlock = particleSystem;
  354. //objupdate.ObjectData[1].ClickAction = clickAction;
  355. objupdate.ObjectData[1].Radius = 20;
  356. objupdate.ObjectData[1].NameValue =
  357. Helpers.StringToField("AttachItemID STRING RW SV " + p.UUID);
  358. LLVector3 pos = new LLVector3((float)0.0, (float)0.0, (float)0.0);
  359. pb = pos.GetBytes();
  360. Array.Copy(pb, 0, objupdate.ObjectData[1].ObjectData, 0, pb.Length);
  361. byte[] brot = rot.GetBytes();
  362. Array.Copy(brot, 0, objupdate.ObjectData[1].ObjectData, 36, brot.Length);
  363. remoteClient.OutPacket(objupdate, ThrottleOutPacketType.Task);
  364. }
  365. else
  366. {
  367. m_log.Info("[SCENE]: Avatar " + remoteClient.AgentId + " not found");
  368. }
  369. }
  370. else
  371. {
  372. m_log.Info("[SCENE]: Attempting to attach object; Object " + objectLocalID + "(localID) not found");
  373. }
  374. }
  375. public ScenePresence CreateAndAddScenePresence(IClientAPI client, bool child, AvatarAppearance appearance)
  376. {
  377. ScenePresence newAvatar = null;
  378. newAvatar = new ScenePresence(client, m_parentScene, m_regInfo, appearance);
  379. newAvatar.IsChildAgent = child;
  380. if (child)
  381. {
  382. m_numChildAgents++;
  383. m_log.Info("[SCENE]: " + m_regInfo.RegionName + ": Creating new child agent.");
  384. }
  385. else
  386. {
  387. m_numRootAgents++;
  388. m_log.Info("[SCENE]: " + m_regInfo.RegionName + ": Creating new root agent.");
  389. m_log.Info("[SCENE]: " + m_regInfo.RegionName + ": Adding Physical agent.");
  390. newAvatar.AddToPhysicalScene();
  391. }
  392. lock (Entities)
  393. {
  394. if (!Entities.ContainsKey(client.AgentId))
  395. {
  396. Entities.Add(client.AgentId, newAvatar);
  397. }
  398. else
  399. {
  400. Entities[client.AgentId] = newAvatar;
  401. }
  402. }
  403. lock (ScenePresences)
  404. {
  405. if (ScenePresences.ContainsKey(client.AgentId))
  406. {
  407. ScenePresences[client.AgentId] = newAvatar;
  408. }
  409. else
  410. {
  411. ScenePresences.Add(client.AgentId, newAvatar);
  412. }
  413. }
  414. return newAvatar;
  415. }
  416. public void AddScenePresence(ScenePresence presence)
  417. {
  418. bool child = presence.IsChildAgent;
  419. if (child)
  420. {
  421. m_numChildAgents++;
  422. m_log.Info("[SCENE]" + m_regInfo.RegionName + ": Creating new child agent.");
  423. }
  424. else
  425. {
  426. m_numRootAgents++;
  427. m_log.Info("[SCENE] " + m_regInfo.RegionName + ": Creating new root agent.");
  428. m_log.Info("[SCENE] " + m_regInfo.RegionName + ": Adding Physical agent.");
  429. presence.AddToPhysicalScene();
  430. }
  431. lock (Entities)
  432. {
  433. Entities[presence.UUID] = presence;
  434. }
  435. lock (ScenePresences)
  436. {
  437. ScenePresences[presence.UUID] = presence;
  438. }
  439. }
  440. public void SwapRootChildAgent(bool direction_RC_CR_T_F)
  441. {
  442. if (direction_RC_CR_T_F)
  443. {
  444. m_numRootAgents--;
  445. m_numChildAgents++;
  446. }
  447. else
  448. {
  449. m_numChildAgents--;
  450. m_numRootAgents++;
  451. }
  452. }
  453. public void removeUserCount(bool TypeRCTF)
  454. {
  455. if (TypeRCTF)
  456. {
  457. m_numRootAgents--;
  458. }
  459. else
  460. {
  461. m_numChildAgents--;
  462. }
  463. }
  464. public void RemoveAPrimCount()
  465. {
  466. m_numPrim--;
  467. }
  468. public void AddAPrimCount()
  469. {
  470. m_numPrim++;
  471. }
  472. public int GetChildAgentCount()
  473. {
  474. // some network situations come in where child agents get closed twice.
  475. if (m_numChildAgents < 0)
  476. {
  477. m_numChildAgents = 0;
  478. }
  479. return m_numChildAgents;
  480. }
  481. public int GetRootAgentCount()
  482. {
  483. return m_numRootAgents;
  484. }
  485. public int GetTotalObjects()
  486. {
  487. return m_numPrim;
  488. }
  489. public int GetActiveObjects()
  490. {
  491. return m_physicalPrim;
  492. }
  493. public int GetActiveScripts()
  494. {
  495. return m_activeScripts;
  496. }
  497. public int GetScriptLPS()
  498. {
  499. int returnval = m_scriptLPS;
  500. m_scriptLPS = 0;
  501. return returnval;
  502. }
  503. #endregion
  504. #region Get Methods
  505. /// <summary>
  506. /// Request a List of all m_scenePresences in this World
  507. /// </summary>
  508. /// <returns></returns>
  509. public List<ScenePresence> GetScenePresences()
  510. {
  511. List<ScenePresence> result;
  512. lock (ScenePresences)
  513. {
  514. result = new List<ScenePresence>(ScenePresences.Values);
  515. }
  516. return result;
  517. }
  518. public List<ScenePresence> GetAvatars()
  519. {
  520. List<ScenePresence> result =
  521. GetScenePresences(delegate(ScenePresence scenePresence) { return !scenePresence.IsChildAgent; });
  522. return result;
  523. }
  524. /// <summary>
  525. /// Request a filtered list of m_scenePresences in this World
  526. /// </summary>
  527. /// <returns></returns>
  528. public List<ScenePresence> GetScenePresences(FilterAvatarList filter)
  529. {
  530. List<ScenePresence> result = new List<ScenePresence>();
  531. List<ScenePresence> ScenePresencesList = GetScenePresences();
  532. foreach (ScenePresence avatar in ScenePresencesList)
  533. {
  534. if (filter(avatar))
  535. {
  536. result.Add(avatar);
  537. }
  538. }
  539. return result;
  540. }
  541. /// <summary>
  542. /// Request a Avatar by UUID
  543. /// </summary>
  544. /// <param name="avatarID"></param>
  545. /// <returns></returns>
  546. public ScenePresence GetScenePresence(LLUUID avatarID)
  547. {
  548. if (ScenePresences.ContainsKey(avatarID))
  549. {
  550. return ScenePresences[avatarID];
  551. }
  552. return null;
  553. }
  554. private SceneObjectGroup GetGroupByPrim(uint localID)
  555. {
  556. List<EntityBase> EntityList = GetEntities();
  557. foreach (EntityBase ent in EntityList)
  558. {
  559. if (ent is SceneObjectGroup)
  560. {
  561. if (((SceneObjectGroup)ent).HasChildPrim(localID))
  562. return (SceneObjectGroup)ent;
  563. }
  564. }
  565. return null;
  566. }
  567. private SceneObjectGroup GetGroupByPrim(LLUUID fullID)
  568. {
  569. List<EntityBase> EntityList = GetEntities();
  570. foreach (EntityBase ent in EntityList)
  571. {
  572. if (ent is SceneObjectGroup)
  573. {
  574. if (((SceneObjectGroup)ent).HasChildPrim(fullID))
  575. return (SceneObjectGroup)ent;
  576. }
  577. }
  578. return null;
  579. }
  580. public EntityIntersection GetClosestIntersectingPrim(Ray hray)
  581. {
  582. // Primitive Ray Tracing
  583. float closestDistance = 280f;
  584. EntityIntersection returnResult = new EntityIntersection();
  585. foreach (EntityBase ent in Entities.Values)
  586. {
  587. if (ent is SceneObjectGroup)
  588. {
  589. SceneObjectGroup reportingG = (SceneObjectGroup)ent;
  590. EntityIntersection result = reportingG.TestIntersection(hray);
  591. if (result.HitTF)
  592. {
  593. if (result.distance < closestDistance)
  594. {
  595. closestDistance = result.distance;
  596. returnResult = result;
  597. }
  598. }
  599. }
  600. }
  601. return returnResult;
  602. }
  603. public SceneObjectPart GetSceneObjectPart(uint localID)
  604. {
  605. SceneObjectGroup group = GetGroupByPrim(localID);
  606. if (group != null)
  607. return group.GetChildPart(localID);
  608. else
  609. return null;
  610. }
  611. public SceneObjectPart GetSceneObjectPart(LLUUID fullID)
  612. {
  613. SceneObjectGroup group = GetGroupByPrim(fullID);
  614. if (group != null)
  615. return group.GetChildPart(fullID);
  616. else
  617. return null;
  618. }
  619. internal bool TryGetAvatar(LLUUID avatarId, out ScenePresence avatar)
  620. {
  621. ScenePresence presence;
  622. if (ScenePresences.TryGetValue(avatarId, out presence))
  623. {
  624. if (!presence.IsChildAgent)
  625. {
  626. avatar = presence;
  627. return true;
  628. }
  629. else
  630. {
  631. m_log.WarnFormat(
  632. "[INNER SCENE]: Requested avatar {0} could not be found in scene {1} since it is only registered as a child agent!",
  633. avatarId, m_parentScene.RegionInfo.RegionName);
  634. }
  635. }
  636. avatar = null;
  637. return false;
  638. }
  639. internal bool TryGetAvatarByName(string avatarName, out ScenePresence avatar)
  640. {
  641. foreach (ScenePresence presence in ScenePresences.Values)
  642. {
  643. if (!presence.IsChildAgent)
  644. {
  645. string name = presence.ControllingClient.FirstName + " " + presence.ControllingClient.LastName;
  646. if (String.Compare(avatarName, name, true) == 0)
  647. {
  648. avatar = presence;
  649. return true;
  650. }
  651. }
  652. }
  653. avatar = null;
  654. return false;
  655. }
  656. public List<EntityBase> GetEntities()
  657. {
  658. List<EntityBase> result;
  659. lock (Entities)
  660. {
  661. result = new List<EntityBase>(Entities.Values);
  662. }
  663. return result;
  664. }
  665. #endregion
  666. #region Other Methods
  667. public void physicsBasedCrash()
  668. {
  669. handlerPhysicsCrash = UnRecoverableError;
  670. if (handlerPhysicsCrash != null)
  671. {
  672. handlerPhysicsCrash();
  673. }
  674. }
  675. public LLUUID ConvertLocalIDToFullID(uint localID)
  676. {
  677. SceneObjectGroup group = GetGroupByPrim(localID);
  678. if (group != null)
  679. return group.GetPartsFullID(localID);
  680. else
  681. return LLUUID.Zero;
  682. }
  683. public void SendAllSceneObjectsToClient(ScenePresence presence)
  684. {
  685. List<EntityBase> EntityList = GetEntities();
  686. foreach (EntityBase ent in EntityList)
  687. {
  688. if (ent is SceneObjectGroup)
  689. {
  690. // Only send child agents stuff in their draw distance.
  691. // This will need to be done for every agent once we figure out
  692. // what we're going to use to store prim that agents already got
  693. // the initial update for and what we'll use to limit the
  694. // space we check for new objects on movement.
  695. if (presence.IsChildAgent && m_parentScene.m_seeIntoRegionFromNeighbor)
  696. {
  697. LLVector3 oLoc = ((SceneObjectGroup)ent).AbsolutePosition;
  698. float distResult = (float)Util.GetDistanceTo(presence.AbsolutePosition, oLoc);
  699. //m_log.Info("[DISTANCE]: " + distResult.ToString());
  700. if (distResult < presence.DrawDistance)
  701. {
  702. // Send Only if we don't already know about it.
  703. // KnownPrim also makes the prim known when called.
  704. if (!presence.KnownPrim(((SceneObjectGroup)ent).UUID))
  705. ((SceneObjectGroup)ent).ScheduleFullUpdateToAvatar(presence);
  706. }
  707. }
  708. else
  709. {
  710. ((SceneObjectGroup)ent).ScheduleFullUpdateToAvatar(presence);
  711. }
  712. }
  713. }
  714. }
  715. internal void ForEachClient(Action<IClientAPI> action)
  716. {
  717. foreach (ScenePresence presence in ScenePresences.Values)
  718. {
  719. action(presence.ControllingClient);
  720. }
  721. }
  722. #endregion
  723. #region Client Event handlers
  724. /// <summary>
  725. ///
  726. /// </summary>
  727. /// <param name="localID"></param>
  728. /// <param name="scale"></param>
  729. /// <param name="remoteClient"></param>
  730. public void UpdatePrimScale(uint localID, LLVector3 scale, IClientAPI remoteClient)
  731. {
  732. SceneObjectGroup group = GetGroupByPrim(localID);
  733. if (group != null)
  734. {
  735. if (PermissionsMngr.CanEditObjectPosition(remoteClient.AgentId, group.UUID))
  736. {
  737. group.Resize(scale, localID);
  738. }
  739. }
  740. }
  741. /// <summary>
  742. /// This handles the nifty little tool tip that you get when you drag your mouse over an object
  743. /// Send to the Object Group to process. We don't know enough to service the request
  744. /// </summary>
  745. /// <param name="remoteClient"></param>
  746. /// <param name="AgentID"></param>
  747. /// <param name="RequestFlags"></param>
  748. /// <param name="ObjectID"></param>
  749. public void RequestObjectPropertiesFamily(IClientAPI remoteClient, LLUUID AgentID, uint RequestFlags,
  750. LLUUID ObjectID)
  751. {
  752. SceneObjectGroup group = GetGroupByPrim(ObjectID);
  753. if (group != null)
  754. {
  755. group.ServiceObjectPropertiesFamilyRequest(remoteClient, AgentID, RequestFlags);
  756. }
  757. }
  758. /// <summary>
  759. ///
  760. /// </summary>
  761. /// <param name="localID"></param>
  762. /// <param name="rot"></param>
  763. /// <param name="remoteClient"></param>
  764. public void UpdatePrimSingleRotation(uint localID, LLQuaternion rot, IClientAPI remoteClient)
  765. {
  766. SceneObjectGroup group = GetGroupByPrim(localID);
  767. if (group != null)
  768. {
  769. if (PermissionsMngr.CanEditObjectPosition(remoteClient.AgentId, group.UUID))
  770. {
  771. group.UpdateSingleRotation(rot, localID);
  772. }
  773. }
  774. }
  775. /// <summary>
  776. ///
  777. /// </summary>
  778. /// <param name="localID"></param>
  779. /// <param name="rot"></param>
  780. /// <param name="remoteClient"></param>
  781. public void UpdatePrimRotation(uint localID, LLQuaternion rot, IClientAPI remoteClient)
  782. {
  783. SceneObjectGroup group = GetGroupByPrim(localID);
  784. if (group != null)
  785. {
  786. if (PermissionsMngr.CanEditObjectPosition(remoteClient.AgentId, group.UUID))
  787. {
  788. group.UpdateGroupRotation(rot);
  789. }
  790. }
  791. }
  792. /// <summary>
  793. ///
  794. /// </summary>
  795. /// <param name="localID"></param>
  796. /// <param name="pos"></param>
  797. /// <param name="rot"></param>
  798. /// <param name="remoteClient"></param>
  799. public void UpdatePrimRotation(uint localID, LLVector3 pos, LLQuaternion rot, IClientAPI remoteClient)
  800. {
  801. SceneObjectGroup group = GetGroupByPrim(localID);
  802. if (group != null)
  803. {
  804. if (PermissionsMngr.CanEditObjectPosition(remoteClient.AgentId, group.UUID))
  805. {
  806. group.UpdateGroupRotation(pos, rot);
  807. }
  808. }
  809. }
  810. public void UpdatePrimSinglePosition(uint localID, LLVector3 pos, IClientAPI remoteClient)
  811. {
  812. SceneObjectGroup group = GetGroupByPrim(localID);
  813. if (group != null)
  814. {
  815. if (PermissionsMngr.CanEditObjectPosition(remoteClient.AgentId, group.UUID))
  816. {
  817. group.UpdateSinglePosition(pos, localID);
  818. }
  819. }
  820. }
  821. /// <summary>
  822. ///
  823. /// </summary>
  824. /// <param name="localID"></param>
  825. /// <param name="pos"></param>
  826. /// <param name="remoteClient"></param>
  827. public void UpdatePrimPosition(uint localID, LLVector3 pos, IClientAPI remoteClient)
  828. {
  829. SceneObjectGroup group = GetGroupByPrim(localID);
  830. if (group != null)
  831. {
  832. if (PermissionsMngr.CanEditObjectPosition(remoteClient.AgentId, group.UUID))
  833. {
  834. group.UpdateGroupPosition(pos);
  835. }
  836. }
  837. }
  838. /// <summary>
  839. ///
  840. /// </summary>
  841. /// <param name="localID"></param>
  842. /// <param name="texture"></param>
  843. /// <param name="remoteClient"></param>
  844. public void UpdatePrimTexture(uint localID, byte[] texture, IClientAPI remoteClient)
  845. {
  846. SceneObjectGroup group = GetGroupByPrim(localID);
  847. if (group != null)
  848. {
  849. if (PermissionsMngr.CanEditObjectPosition(remoteClient.AgentId, group.UUID))
  850. {
  851. group.UpdateTextureEntry(localID, texture);
  852. }
  853. }
  854. }
  855. /// <summary>
  856. ///
  857. /// </summary>
  858. /// <param name="localID"></param>
  859. /// <param name="packet"></param>
  860. /// <param name="remoteClient"></param>
  861. public void UpdatePrimFlags(uint localID, Packet packet, IClientAPI remoteClient)
  862. {
  863. SceneObjectGroup group = GetGroupByPrim(localID);
  864. if (group != null)
  865. {
  866. if (PermissionsMngr.CanEditObject(remoteClient.AgentId, group.UUID))
  867. {
  868. group.UpdatePrimFlags(localID, (ushort)packet.Type, true, packet.ToBytes());
  869. }
  870. }
  871. }
  872. public void MoveObject(LLUUID objectID, LLVector3 offset, LLVector3 pos, IClientAPI remoteClient)
  873. {
  874. SceneObjectGroup group = GetGroupByPrim(objectID);
  875. if (group != null)
  876. {
  877. if (PermissionsMngr.CanEditObjectPosition(remoteClient.AgentId, group.UUID))// && PermissionsMngr.)
  878. {
  879. group.GrabMovement(offset, pos, remoteClient);
  880. }
  881. // This is outside the above permissions condition
  882. // so that if the object is locked the client moving the object
  883. // get's it's position on the simulator even if it was the same as before
  884. // This keeps the moving user's client in sync with the rest of the world.
  885. group.SendGroupTerseUpdate();
  886. }
  887. }
  888. /// <summary>
  889. ///
  890. /// </summary>
  891. /// <param name="primLocalID"></param>
  892. /// <param name="description"></param>
  893. public void PrimName(IClientAPI remoteClient, uint primLocalID, string name)
  894. {
  895. SceneObjectGroup group = GetGroupByPrim(primLocalID);
  896. if (group != null)
  897. {
  898. if (PermissionsMngr.CanEditObject(remoteClient.AgentId, group.UUID))
  899. {
  900. group.SetPartName(Util.CleanString(name), primLocalID);
  901. }
  902. }
  903. }
  904. /// <summary>
  905. ///
  906. /// </summary>
  907. /// <param name="primLocalID"></param>
  908. /// <param name="description"></param>
  909. public void PrimDescription(IClientAPI remoteClient, uint primLocalID, string description)
  910. {
  911. SceneObjectGroup group = GetGroupByPrim(primLocalID);
  912. if (group != null)
  913. {
  914. if (PermissionsMngr.CanEditObject(remoteClient.AgentId, group.UUID))
  915. {
  916. group.SetPartDescription(Util.CleanString(description), primLocalID);
  917. }
  918. }
  919. }
  920. public void UpdateExtraParam(LLUUID agentID, uint primLocalID, ushort type, bool inUse, byte[] data)
  921. {
  922. SceneObjectGroup group = GetGroupByPrim(primLocalID);
  923. if (group != null)
  924. {
  925. if (PermissionsMngr.CanEditObject(agentID, group.UUID))
  926. {
  927. group.UpdateExtraParam(primLocalID, type, inUse, data);
  928. }
  929. }
  930. }
  931. /// <summary>
  932. ///
  933. /// </summary>
  934. /// <param name="primLocalID"></param>
  935. /// <param name="shapeBlock"></param>
  936. public void UpdatePrimShape(LLUUID agentID, uint primLocalID, ObjectShapePacket.ObjectDataBlock shapeBlock)
  937. {
  938. SceneObjectGroup group = GetGroupByPrim(primLocalID);
  939. if (group != null)
  940. {
  941. if (PermissionsMngr.CanEditObjectPosition(agentID, group.GetPartsFullID(primLocalID)))
  942. {
  943. group.UpdateShape(shapeBlock, primLocalID);
  944. }
  945. }
  946. }
  947. /// <summary>
  948. ///
  949. /// </summary>
  950. /// <param name="parentPrim"></param>
  951. /// <param name="childPrims"></param>
  952. public void LinkObjects(uint parentPrim, List<uint> childPrims)
  953. {
  954. List<EntityBase> EntityList = GetEntities();
  955. SceneObjectGroup parenPrim = null;
  956. foreach (EntityBase ent in EntityList)
  957. {
  958. if (ent is SceneObjectGroup)
  959. {
  960. if (((SceneObjectGroup)ent).LocalId == parentPrim)
  961. {
  962. parenPrim = (SceneObjectGroup)ent;
  963. break;
  964. }
  965. }
  966. }
  967. List<SceneObjectGroup> children = new List<SceneObjectGroup>();
  968. if (parenPrim != null)
  969. {
  970. for (int i = 0; i < childPrims.Count; i++)
  971. {
  972. foreach (EntityBase ent in EntityList)
  973. {
  974. if (ent is SceneObjectGroup)
  975. {
  976. if (((SceneObjectGroup)ent).LocalId == childPrims[i])
  977. {
  978. children.Add((SceneObjectGroup)ent);
  979. }
  980. }
  981. }
  982. }
  983. }
  984. foreach (SceneObjectGroup sceneObj in children)
  985. {
  986. parenPrim.LinkToGroup(sceneObj);
  987. }
  988. }
  989. /// <summary>
  990. /// Delink a linkset
  991. /// </summary>
  992. /// <param name="prims"></param>
  993. public void DelinkObjects(List<uint> primIds)
  994. {
  995. SceneObjectGroup parenPrim = null;
  996. // Need a list of the SceneObjectGroup local ids
  997. // XXX I'm anticipating that building this dictionary once is more efficient than
  998. // repeated scanning of the Entity.Values for a large number of primIds. However, it might
  999. // be more efficient yet to keep this dictionary permanently on hand.
  1000. Dictionary<uint, SceneObjectGroup> sceneObjects = new Dictionary<uint, SceneObjectGroup>();
  1001. List<EntityBase> EntitieList = GetEntities();
  1002. foreach (EntityBase ent in EntitieList)
  1003. {
  1004. if (ent is SceneObjectGroup)
  1005. {
  1006. SceneObjectGroup obj = (SceneObjectGroup)ent;
  1007. sceneObjects.Add(obj.LocalId, obj);
  1008. }
  1009. }
  1010. // Find the root prim among the prim ids we've been given
  1011. for (int i = 0; i < primIds.Count; i++)
  1012. {
  1013. if (sceneObjects.ContainsKey(primIds[i]))
  1014. {
  1015. parenPrim = sceneObjects[primIds[i]];
  1016. primIds.RemoveAt(i);
  1017. break;
  1018. }
  1019. }
  1020. if (parenPrim != null)
  1021. {
  1022. foreach (uint childPrimId in primIds)
  1023. {
  1024. parenPrim.DelinkFromGroup(childPrimId);
  1025. }
  1026. }
  1027. else
  1028. {
  1029. // If the first scan failed, we need to do a /deep/ scan of the linkages. This is /really/ slow
  1030. // We know that this is not the root prim now essentially, so we don't have to worry about remapping
  1031. // which one is the root prim
  1032. bool delinkedSomething = false;
  1033. for (int i = 0; i < primIds.Count; i++)
  1034. {
  1035. foreach (SceneObjectGroup grp in sceneObjects.Values)
  1036. {
  1037. SceneObjectPart gPart = grp.GetChildPart(primIds[i]);
  1038. if (gPart != null)
  1039. {
  1040. grp.DelinkFromGroup(primIds[i]);
  1041. delinkedSomething = true;
  1042. }
  1043. }
  1044. }
  1045. if (!delinkedSomething)
  1046. {
  1047. m_log.InfoFormat("[SCENE]: " +
  1048. "DelinkObjects(): Could not find a root prim out of {0} as given to a delink request!",
  1049. primIds);
  1050. }
  1051. }
  1052. }
  1053. /// <summary>
  1054. ///
  1055. /// </summary>
  1056. /// <param name="originalPrim"></param>
  1057. /// <param name="offset"></param>
  1058. /// <param name="flags"></param>
  1059. public void DuplicateObject(uint originalPrim, LLVector3 offset, uint flags, LLUUID AgentID, LLUUID GroupID)
  1060. {
  1061. List<EntityBase> EntityList = GetEntities();
  1062. SceneObjectGroup originPrim = null;
  1063. foreach (EntityBase ent in EntityList)
  1064. {
  1065. if (ent is SceneObjectGroup)
  1066. {
  1067. if (((SceneObjectGroup)ent).LocalId == originalPrim)
  1068. {
  1069. originPrim = (SceneObjectGroup)ent;
  1070. break;
  1071. }
  1072. }
  1073. }
  1074. if (originPrim != null)
  1075. {
  1076. if (PermissionsMngr.CanCopyObject(AgentID, originPrim.UUID))
  1077. {
  1078. SceneObjectGroup copy = originPrim.Copy(AgentID, GroupID);
  1079. copy.AbsolutePosition = copy.AbsolutePosition + offset;
  1080. copy.ResetIDs();
  1081. lock (Entities)
  1082. {
  1083. Entities.Add(copy.UUID, copy);
  1084. }
  1085. m_numPrim++;
  1086. copy.StartScripts();
  1087. copy.ScheduleGroupForFullUpdate();
  1088. }
  1089. }
  1090. else
  1091. {
  1092. m_log.WarnFormat("[SCENE]: Attempted to duplicate nonexistant prim id {0}", GroupID);
  1093. }
  1094. }
  1095. /// <summary>
  1096. /// Calculates the distance between two Vector3s
  1097. /// </summary>
  1098. /// <param name="v1"></param>
  1099. /// <param name="v2"></param>
  1100. /// <returns></returns>
  1101. public float Vector3Distance(Vector3 v1, Vector3 v2)
  1102. {
  1103. // We don't really need the double floating point precision...
  1104. // so casting it to a single
  1105. return
  1106. (float)
  1107. Math.Sqrt((v1.x - v2.x) * (v1.x - v2.x) + (v1.y - v2.y) * (v1.y - v2.y) + (v1.z - v2.z) * (v1.z - v2.z));
  1108. }
  1109. #endregion
  1110. }
  1111. }