InnerScene.cs 41 KB

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