SceneObjectGroup.cs 61 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781
  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 System.Drawing;
  31. using System.IO;
  32. using System.Text;
  33. using System.Xml;
  34. using Axiom.Math;
  35. using libsecondlife;
  36. using libsecondlife.Packets;
  37. using OpenSim.Framework;
  38. using OpenSim.Framework.Console;
  39. using OpenSim.Region.Environment.Interfaces;
  40. using OpenSim.Region.Physics.Manager;
  41. namespace OpenSim.Region.Environment.Scenes
  42. {
  43. public delegate void PrimCountTaintedDelegate();
  44. public partial class SceneObjectGroup : EntityBase
  45. {
  46. private Encoding enc = Encoding.ASCII;
  47. protected SceneObjectPart m_rootPart;
  48. protected Dictionary<LLUUID, SceneObjectPart> m_parts = new Dictionary<LLUUID, SceneObjectPart>();
  49. protected ulong m_regionHandle;
  50. public event PrimCountTaintedDelegate OnPrimCountTainted;
  51. /// <summary>
  52. /// Signal whether the non-inventory attributes of any prims in the group have changed
  53. /// since the group's last persistent backup
  54. /// </summary>
  55. public bool HasGroupChanged = false;
  56. private LLVector3 lastPhysGroupPos;
  57. private LLQuaternion lastPhysGroupRot;
  58. #region Properties
  59. /// <summary>
  60. ///
  61. /// </summary>
  62. public int PrimCount
  63. {
  64. get { return m_parts.Count; }
  65. }
  66. public LLQuaternion GroupRotation
  67. {
  68. get { return m_rootPart.RotationOffset; }
  69. }
  70. public LLUUID GroupID
  71. {
  72. get { return m_rootPart.GroupID; }
  73. set { m_rootPart.GroupID = value; }
  74. }
  75. /// <summary>
  76. ///
  77. /// </summary>
  78. public LLVector3 GroupCentrePoint
  79. {
  80. get { return new LLVector3(0, 0, 0); }
  81. }
  82. public Dictionary<LLUUID, SceneObjectPart> Children
  83. {
  84. get { return m_parts; }
  85. set { m_parts = value; }
  86. }
  87. public SceneObjectPart RootPart
  88. {
  89. get { return m_rootPart; }
  90. set { m_rootPart = value; }
  91. }
  92. public ulong RegionHandle
  93. {
  94. get { return m_regionHandle; }
  95. set
  96. {
  97. m_regionHandle = value;
  98. lock (m_parts)
  99. {
  100. foreach (SceneObjectPart part in m_parts.Values)
  101. {
  102. part.RegionHandle = m_regionHandle;
  103. }
  104. }
  105. }
  106. }
  107. public override LLVector3 AbsolutePosition
  108. {
  109. get { return m_rootPart.GroupPosition; }
  110. set
  111. {
  112. LLVector3 val = value;
  113. if (val.X > 257f || val.X < -1f || val.Y > 257f || val.Y < -1f)
  114. {
  115. m_scene.CrossPrimGroupIntoNewRegion(val, this);
  116. }
  117. lock (m_parts)
  118. {
  119. foreach (SceneObjectPart part in m_parts.Values)
  120. {
  121. part.GroupPosition = val;
  122. }
  123. }
  124. //if (m_rootPart.PhysActor != null)
  125. //{
  126. //m_rootPart.PhysActor.Position =
  127. //new PhysicsVector(m_rootPart.GroupPosition.X, m_rootPart.GroupPosition.Y,
  128. //m_rootPart.GroupPosition.Z);
  129. //m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor);
  130. //}
  131. }
  132. }
  133. public override uint LocalId
  134. {
  135. get { return m_rootPart.LocalID; }
  136. set { m_rootPart.LocalID = value; }
  137. }
  138. public override LLUUID UUID
  139. {
  140. get { return m_rootPart.UUID; }
  141. set { m_rootPart.UUID = value; }
  142. }
  143. public LLUUID OwnerID
  144. {
  145. get { return m_rootPart.OwnerID; }
  146. set { m_rootPart.OwnerID = value; }
  147. }
  148. public Color Color
  149. {
  150. get { return m_rootPart.Color; }
  151. set { m_rootPart.Color = value; }
  152. }
  153. public string Text
  154. {
  155. get { return m_rootPart.Text; }
  156. set { m_rootPart.Text = value; }
  157. }
  158. /// <summary>
  159. /// Added because the Parcel code seems to use it
  160. /// but not sure a object should have this
  161. /// as what does it tell us? that some avatar has selected it (but not what Avatar/user)
  162. /// think really there should be a list (or whatever) in each scenepresence
  163. /// saying what prim(s) that user has selected.
  164. /// </summary>
  165. protected bool m_isSelected = false;
  166. protected virtual bool InSceneBackup
  167. {
  168. get { return true; }
  169. }
  170. public bool IsSelected
  171. {
  172. get { return m_isSelected; }
  173. set {
  174. m_isSelected = value;
  175. // Tell physics engine that group is selected
  176. if (m_rootPart.PhysActor != null)
  177. {
  178. m_rootPart.PhysActor.Selected = value;
  179. }
  180. }
  181. }
  182. // The UUID for the Region this Object is in.
  183. public LLUUID RegionUUID
  184. {
  185. get
  186. {
  187. if (m_scene != null)
  188. {
  189. return m_scene.RegionInfo.RegionID;
  190. }
  191. return LLUUID.Zero;
  192. }
  193. }
  194. #endregion
  195. #region Constructors
  196. /// <summary>
  197. ///
  198. /// </summary>
  199. public SceneObjectGroup()
  200. {
  201. }
  202. /// <summary>
  203. /// This constructor creates a SceneObjectGroup using a pre-existing SceneObjectPart.
  204. /// The original SceneObjectPart will be used rather than a copy, preserving
  205. /// its existing localID and UUID.
  206. /// </summary>
  207. public SceneObjectGroup(Scene scene, ulong regionHandle, SceneObjectPart part)
  208. {
  209. m_scene = scene;
  210. part.SetParent(this);
  211. part.ParentID = 0;
  212. part.LinkNum = 0;
  213. m_parts.Add(part.UUID, part);
  214. SetPartAsRoot(part);
  215. RegionHandle = regionHandle;
  216. AttachToBackup();
  217. ApplyPhysics(scene.m_physicalPrim);
  218. ScheduleGroupForFullUpdate();
  219. }
  220. /// <summary>
  221. ///
  222. /// </summary>
  223. public SceneObjectGroup(Scene scene, ulong regionHandle, string xmlData)
  224. {
  225. m_scene = scene;
  226. m_regionHandle = regionHandle;
  227. StringReader sr = new StringReader(xmlData);
  228. XmlTextReader reader = new XmlTextReader(sr);
  229. reader.Read();
  230. reader.ReadStartElement("SceneObjectGroup");
  231. reader.ReadStartElement("RootPart");
  232. m_rootPart = SceneObjectPart.FromXml(reader);
  233. AddPart(m_rootPart);
  234. reader.ReadEndElement();
  235. while (reader.Read())
  236. {
  237. switch (reader.NodeType)
  238. {
  239. case XmlNodeType.Element:
  240. if (reader.Name == "Part")
  241. {
  242. reader.Read();
  243. SceneObjectPart part = SceneObjectPart.FromXml(reader);
  244. part.LocalID = m_scene.PrimIDAllocate();
  245. AddPart(part);
  246. part.RegionHandle = m_regionHandle;
  247. part.TrimPermissions();
  248. }
  249. break;
  250. case XmlNodeType.EndElement:
  251. break;
  252. }
  253. }
  254. reader.Close();
  255. sr.Close();
  256. m_rootPart.LocalID = m_scene.PrimIDAllocate();
  257. m_rootPart.ParentID = 0;
  258. m_rootPart.RegionHandle = m_regionHandle;
  259. UpdateParentIDs();
  260. AttachToBackup();
  261. ApplyPhysics(scene.m_physicalPrim);
  262. ScheduleGroupForFullUpdate();
  263. }
  264. /// <summary>
  265. ///
  266. /// </summary>
  267. public SceneObjectGroup(string xmlData)
  268. {
  269. StringReader sr = new StringReader(xmlData);
  270. XmlTextReader reader = new XmlTextReader(sr);
  271. reader.Read();
  272. reader.ReadStartElement("SceneObjectGroup");
  273. m_rootPart = SceneObjectPart.FromXml(reader);
  274. m_rootPart.SetParent(this);
  275. m_parts.Add(m_rootPart.UUID, m_rootPart);
  276. m_rootPart.ParentID = 0;
  277. m_rootPart.LinkNum = 0;
  278. reader.Read();
  279. bool more = true;
  280. while (more)
  281. {
  282. switch (reader.NodeType)
  283. {
  284. case XmlNodeType.Element:
  285. if (reader.Name == "SceneObjectPart")
  286. {
  287. SceneObjectPart Part = SceneObjectPart.FromXml(reader);
  288. AddPart(Part);
  289. }
  290. else
  291. {
  292. Console.WriteLine("found unexpected element: " + reader.Name);
  293. reader.Read();
  294. }
  295. break;
  296. case XmlNodeType.EndElement:
  297. reader.Read();
  298. break;
  299. }
  300. more = !reader.EOF;
  301. }
  302. reader.Close();
  303. sr.Close();
  304. UpdateParentIDs();
  305. ScheduleGroupForFullUpdate();
  306. }
  307. private void AttachToBackup()
  308. {
  309. if (InSceneBackup)
  310. {
  311. m_scene.EventManager.OnBackup += ProcessBackup;
  312. }
  313. }
  314. public EntityIntersection TestIntersection(Ray hRay)
  315. {
  316. // We got a request from the inner_scene to raytrace along the Ray hRay
  317. // We're going to check all of the prim in this group for intersection with the ray
  318. // If we get a result, we're going to find the closest result to the origin of the ray
  319. // and send back the intersection information back to the innerscene.
  320. EntityIntersection returnresult = new EntityIntersection();
  321. foreach (SceneObjectPart part in m_parts.Values)
  322. {
  323. // Temporary commented to stop compiler warning
  324. //Vector3 partPosition =
  325. // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z);
  326. Quaternion parentrotation =
  327. new Quaternion(GroupRotation.W, GroupRotation.X, GroupRotation.Y, GroupRotation.Z);
  328. // Telling the prim to raytrace.
  329. EntityIntersection inter = part.TestIntersection(hRay, parentrotation);
  330. // This may need to be updated to the maximum draw distance possible..
  331. // We might (and probably will) be checking for prim creation from other sims
  332. // when the camera crosses the border.
  333. float idist = (float)Constants.RegionSize;
  334. if (inter.HitTF)
  335. {
  336. // We need to find the closest prim to return to the testcaller along the ray
  337. if (inter.distance < idist)
  338. {
  339. idist = inter.distance;
  340. returnresult.HitTF = true;
  341. returnresult.ipoint = inter.ipoint;
  342. returnresult.obj = part;
  343. returnresult.normal = inter.normal;
  344. returnresult.distance = inter.distance;
  345. }
  346. }
  347. }
  348. return returnresult;
  349. }
  350. /// <summary>
  351. ///
  352. /// </summary>
  353. public SceneObjectGroup(Scene scene, ulong regionHandle, LLUUID ownerID, uint localID, LLVector3 pos,
  354. LLQuaternion rot, PrimitiveBaseShape shape)
  355. {
  356. m_regionHandle = regionHandle;
  357. m_scene = scene;
  358. // this.Pos = pos;
  359. LLVector3 rootOffset = new LLVector3(0, 0, 0);
  360. SceneObjectPart newPart =
  361. new SceneObjectPart(m_regionHandle, this, ownerID, localID, shape, pos, rot, rootOffset);
  362. newPart.LinkNum = m_parts.Count;
  363. m_parts.Add(newPart.UUID, newPart);
  364. SetPartAsRoot(newPart);
  365. AttachToBackup();
  366. //ApplyPhysics(scene.m_physicalPrim);
  367. }
  368. /// <summary>
  369. ///
  370. /// </summary>
  371. public SceneObjectGroup(Scene scene, ulong regionHandle, LLUUID ownerID, uint localID, LLVector3 pos,
  372. PrimitiveBaseShape shape)
  373. : this(scene, regionHandle, ownerID, localID, pos, LLQuaternion.Identity, shape)
  374. {
  375. }
  376. #endregion
  377. public string ToXmlString()
  378. {
  379. using (StringWriter sw = new StringWriter())
  380. {
  381. using (XmlTextWriter writer = new XmlTextWriter(sw))
  382. {
  383. ToXml(writer);
  384. }
  385. return sw.ToString();
  386. }
  387. }
  388. public void ToXml(XmlTextWriter writer)
  389. {
  390. writer.WriteStartElement(String.Empty, "SceneObjectGroup", String.Empty);
  391. writer.WriteStartElement(String.Empty, "RootPart", String.Empty);
  392. m_rootPart.ToXml(writer);
  393. writer.WriteEndElement();
  394. writer.WriteStartElement(String.Empty, "OtherParts", String.Empty);
  395. foreach (SceneObjectPart part in m_parts.Values)
  396. {
  397. if (part.UUID != m_rootPart.UUID)
  398. {
  399. writer.WriteStartElement(String.Empty, "Part", String.Empty);
  400. part.ToXml(writer);
  401. writer.WriteEndElement();
  402. }
  403. }
  404. writer.WriteEndElement();
  405. writer.WriteEndElement();
  406. }
  407. public string ToXmlString2()
  408. {
  409. using (StringWriter sw = new StringWriter())
  410. {
  411. using (XmlTextWriter writer = new XmlTextWriter(sw))
  412. {
  413. ToXml2(writer);
  414. }
  415. return sw.ToString();
  416. }
  417. }
  418. public void ToXml2(XmlTextWriter writer)
  419. {
  420. writer.WriteStartElement(String.Empty, "SceneObjectGroup", String.Empty);
  421. m_rootPart.ToXml(writer);
  422. writer.WriteStartElement(String.Empty, "OtherParts", String.Empty);
  423. foreach (SceneObjectPart part in m_parts.Values)
  424. {
  425. if (part.UUID != m_rootPart.UUID)
  426. {
  427. part.ToXml(writer);
  428. }
  429. }
  430. writer.WriteEndElement();
  431. writer.WriteEndElement();
  432. }
  433. #region Copying
  434. /// <summary>
  435. ///
  436. /// </summary>
  437. /// <returns></returns>
  438. public SceneObjectGroup Copy(LLUUID cAgentID, LLUUID cGroupID)
  439. {
  440. SceneObjectGroup dupe = (SceneObjectGroup) MemberwiseClone();
  441. dupe.m_parts = new Dictionary<LLUUID, SceneObjectPart>();
  442. dupe.m_parts.Clear();
  443. //dupe.OwnerID = AgentID;
  444. //dupe.GroupID = GroupID;
  445. dupe.AbsolutePosition = new LLVector3(AbsolutePosition.X, AbsolutePosition.Y, AbsolutePosition.Z);
  446. dupe.m_scene = m_scene;
  447. dupe.m_regionHandle = m_regionHandle;
  448. dupe.CopyRootPart(m_rootPart, OwnerID, GroupID);
  449. dupe.m_rootPart.TrimPermissions();
  450. /// may need to create a new Physics actor.
  451. if (dupe.RootPart.PhysActor != null)
  452. {
  453. PrimitiveBaseShape pbs = dupe.RootPart.Shape;
  454. dupe.RootPart.PhysActor = m_scene.PhysicsScene.AddPrimShape(
  455. dupe.RootPart.Name,
  456. pbs,
  457. new PhysicsVector(dupe.RootPart.AbsolutePosition.X, dupe.RootPart.AbsolutePosition.Y,
  458. dupe.RootPart.AbsolutePosition.Z),
  459. new PhysicsVector(dupe.RootPart.Scale.X, dupe.RootPart.Scale.Y, dupe.RootPart.Scale.Z),
  460. new Quaternion(dupe.RootPart.RotationOffset.W, dupe.RootPart.RotationOffset.X,
  461. dupe.RootPart.RotationOffset.Y, dupe.RootPart.RotationOffset.Z),
  462. dupe.RootPart.PhysActor.IsPhysical);
  463. dupe.RootPart.DoPhysicsPropertyUpdate(dupe.RootPart.PhysActor.IsPhysical, true);
  464. }
  465. // Now we've made a copy that replaces this one, we need to
  466. // switch the owner to the person who did the copying
  467. // Second Life copies an object and duplicates the first one in it's place
  468. // So, we have to make a copy of this one, set it in it's place then set the owner on this one
  469. SetRootPartOwner(m_rootPart, cAgentID, cGroupID);
  470. m_rootPart.ScheduleFullUpdate();
  471. List<SceneObjectPart> partList = new List<SceneObjectPart>(m_parts.Values);
  472. foreach (SceneObjectPart part in partList)
  473. {
  474. if (part.UUID != m_rootPart.UUID)
  475. {
  476. dupe.CopyPart(part, OwnerID, GroupID);
  477. SetPartOwner(part, cAgentID, cGroupID);
  478. part.ScheduleFullUpdate();
  479. }
  480. }
  481. dupe.UpdateParentIDs();
  482. dupe.AttachToBackup();
  483. ScheduleGroupForFullUpdate();
  484. return dupe;
  485. }
  486. /// <summary>
  487. ///
  488. /// </summary>
  489. /// <param name="part"></param>
  490. public void CopyRootPart(SceneObjectPart part, LLUUID cAgentID, LLUUID cGroupID)
  491. {
  492. SceneObjectPart newPart = part.Copy(m_scene.PrimIDAllocate(), OwnerID, GroupID, m_parts.Count);
  493. newPart.SetParent(this);
  494. m_parts.Add(newPart.UUID, newPart);
  495. SetPartAsRoot(newPart);
  496. }
  497. public void applyImpulse(PhysicsVector impulse)
  498. {
  499. // We check if rootpart is null here because scripts don't delete if you delete the host.
  500. // This means that unfortunately, we can pass a null physics actor to Simulate!
  501. // Make sure we don't do that!
  502. SceneObjectPart rootpart = m_rootPart;
  503. if (rootpart != null)
  504. {
  505. if (rootpart.PhysActor != null)
  506. {
  507. rootpart.PhysActor.AddForce(impulse);
  508. m_scene.PhysicsScene.AddPhysicsActorTaint(rootpart.PhysActor);
  509. }
  510. }
  511. }
  512. public void SetRootPartOwner(SceneObjectPart part, LLUUID cAgentID, LLUUID cGroupID)
  513. {
  514. part.LastOwnerID = part.OwnerID;
  515. part.OwnerID = cAgentID;
  516. part.GroupID = cGroupID;
  517. if (part.OwnerID != cAgentID)
  518. {
  519. // Apply Next Owner Permissions if we're not bypassing permissions
  520. if (!m_scene.PermissionsMngr.BypassPermissions)
  521. m_rootPart.ApplyNextOwnerPermissions();
  522. }
  523. part.ScheduleFullUpdate();
  524. }
  525. /// <summary>
  526. ///
  527. /// </summary>
  528. /// <param name="part"></param>
  529. public void CopyPart(SceneObjectPart part, LLUUID cAgentID, LLUUID cGroupID)
  530. {
  531. SceneObjectPart newPart = part.Copy(m_scene.PrimIDAllocate(), OwnerID, GroupID, m_parts.Count);
  532. newPart.SetParent(this);
  533. m_parts.Add(newPart.UUID, newPart);
  534. SetPartAsNonRoot(newPart);
  535. }
  536. /// <summary>
  537. /// Reset the LLUUIDs for all the prims that make up this group.
  538. ///
  539. /// This is called by methods which want to add a new group to an existing scene, in order
  540. /// to ensure that there are no clashes with groups already present.
  541. /// </summary>
  542. public void ResetIDs()
  543. {
  544. List<SceneObjectPart> partsList = new List<SceneObjectPart>(m_parts.Values);
  545. m_parts.Clear();
  546. foreach (SceneObjectPart part in partsList)
  547. {
  548. part.ResetIDs(m_parts.Count);
  549. m_parts.Add(part.UUID, part);
  550. }
  551. }
  552. /// <summary>
  553. ///
  554. /// </summary>
  555. /// <param name="part"></param>
  556. public void ServiceObjectPropertiesFamilyRequest(IClientAPI remoteClient, LLUUID AgentID, uint RequestFlags)
  557. {
  558. //RootPart.ServiceObjectPropertiesFamilyRequest(remoteClient, AgentID, RequestFlags);
  559. ObjectPropertiesFamilyPacket objPropFamilyPack = (ObjectPropertiesFamilyPacket) PacketPool.Instance.GetPacket(PacketType.ObjectPropertiesFamily);
  560. // TODO: don't create new blocks if recycling an old packet
  561. ObjectPropertiesFamilyPacket.ObjectDataBlock objPropDB = new ObjectPropertiesFamilyPacket.ObjectDataBlock();
  562. objPropDB.RequestFlags = RequestFlags;
  563. objPropDB.ObjectID = RootPart.UUID;
  564. objPropDB.OwnerID = RootPart.ObjectOwner;
  565. objPropDB.GroupID = RootPart.GroupID;
  566. objPropDB.BaseMask = RootPart.BaseMask;
  567. objPropDB.OwnerMask = RootPart.OwnerMask;
  568. objPropDB.GroupMask = RootPart.GroupMask;
  569. objPropDB.EveryoneMask = RootPart.EveryoneMask;
  570. objPropDB.NextOwnerMask = RootPart.NextOwnerMask;
  571. // TODO: More properties are needed in SceneObjectPart!
  572. objPropDB.OwnershipCost = RootPart.OwnershipCost;
  573. objPropDB.SaleType = RootPart.ObjectSaleType;
  574. objPropDB.SalePrice = RootPart.SalePrice;
  575. objPropDB.Category = RootPart.Category;
  576. objPropDB.LastOwnerID = RootPart.CreatorID;
  577. objPropDB.Name = Helpers.StringToField(RootPart.Name);
  578. objPropDB.Description = Helpers.StringToField(RootPart.Description);
  579. objPropFamilyPack.ObjectData = objPropDB;
  580. remoteClient.OutPacket(objPropFamilyPack, ThrottleOutPacketType.Task);
  581. }
  582. public void SetPartOwner(SceneObjectPart part, LLUUID cAgentID, LLUUID cGroupID)
  583. {
  584. part.OwnerID = cAgentID;
  585. part.GroupID = cGroupID;
  586. }
  587. #endregion
  588. #region Scheduling
  589. /// <summary>
  590. ///
  591. /// </summary>
  592. public override void Update()
  593. {
  594. if (Util.GetDistanceTo(lastPhysGroupPos, AbsolutePosition) > 0.02)
  595. {
  596. foreach (SceneObjectPart part in m_parts.Values)
  597. {
  598. if (part.UpdateFlag == 0) part.UpdateFlag = 1;
  599. }
  600. lastPhysGroupPos = AbsolutePosition;
  601. }
  602. if ((Math.Abs(lastPhysGroupRot.W - GroupRotation.W) > 0.1)
  603. || (Math.Abs(lastPhysGroupRot.X - GroupRotation.X) > 0.1)
  604. || (Math.Abs(lastPhysGroupRot.Y - GroupRotation.Y) > 0.1)
  605. || (Math.Abs(lastPhysGroupRot.Z - GroupRotation.Z) > 0.1))
  606. {
  607. foreach (SceneObjectPart part in m_parts.Values)
  608. {
  609. if (part.UpdateFlag == 0) part.UpdateFlag = 1;
  610. }
  611. lastPhysGroupRot = GroupRotation;
  612. }
  613. foreach (SceneObjectPart part in m_parts.Values)
  614. {
  615. part.SendScheduledUpdates();
  616. }
  617. }
  618. public void ScheduleFullUpdateToAvatar(ScenePresence presence)
  619. {
  620. foreach (SceneObjectPart part in m_parts.Values)
  621. {
  622. part.AddFullUpdateToAvatar(presence);
  623. }
  624. }
  625. public void ScheduleTerseUpdateToAvatar(ScenePresence presence)
  626. {
  627. foreach (SceneObjectPart part in m_parts.Values)
  628. {
  629. part.AddTerseUpdateToAvatar(presence);
  630. }
  631. }
  632. /// <summary>
  633. ///
  634. /// </summary>
  635. public void ScheduleGroupForFullUpdate()
  636. {
  637. HasGroupChanged = true;
  638. foreach (SceneObjectPart part in m_parts.Values)
  639. {
  640. part.ScheduleFullUpdate();
  641. }
  642. }
  643. /// <summary>
  644. ///
  645. /// </summary>
  646. public void ScheduleGroupForTerseUpdate()
  647. {
  648. HasGroupChanged = true;
  649. foreach (SceneObjectPart part in m_parts.Values)
  650. {
  651. part.ScheduleTerseUpdate();
  652. }
  653. }
  654. /// <summary>
  655. ///
  656. /// </summary>
  657. public void SendGroupFullUpdate()
  658. {
  659. HasGroupChanged = true;
  660. foreach (SceneObjectPart part in m_parts.Values)
  661. {
  662. part.SendFullUpdateToAllClients();
  663. }
  664. }
  665. /// <summary>
  666. ///
  667. /// </summary>
  668. public void SendGroupTerseUpdate()
  669. {
  670. HasGroupChanged = true;
  671. foreach (SceneObjectPart part in m_parts.Values)
  672. {
  673. part.SendTerseUpdateToAllClients();
  674. }
  675. }
  676. #endregion
  677. #region SceneGroupPart Methods
  678. /// <summary>
  679. /// Get the child part by LinkNum
  680. /// </summary>
  681. /// <param name="linknum"></param>
  682. /// <returns>null if no child part with that linknum or child part</returns>
  683. public SceneObjectPart GetLinkNumPart(int linknum)
  684. {
  685. foreach (SceneObjectPart part in m_parts.Values)
  686. {
  687. if (part.LinkNum == linknum)
  688. {
  689. return part;
  690. }
  691. }
  692. return null;
  693. }
  694. /// <summary>
  695. /// Get a child part with a given UUID
  696. /// </summary>
  697. /// <param name="primID"></param>
  698. /// <returns>null if a child part with the primID was not found</returns>
  699. public SceneObjectPart GetChildPart(LLUUID primID)
  700. {
  701. SceneObjectPart childPart = null;
  702. if (m_parts.ContainsKey(primID))
  703. {
  704. childPart = m_parts[primID];
  705. }
  706. return childPart;
  707. }
  708. /// <summary>
  709. /// Get a child part with a given local ID
  710. /// </summary>
  711. /// <param name="localID"></param>
  712. /// <returns>null if a child part with the local ID was not found</returns>
  713. public SceneObjectPart GetChildPart(uint localID)
  714. {
  715. foreach (SceneObjectPart part in m_parts.Values)
  716. {
  717. if (part.LocalID == localID)
  718. {
  719. return part;
  720. }
  721. }
  722. return null;
  723. }
  724. /// <summary>
  725. /// Does this group contain the child prim
  726. /// should be able to remove these methods once we have a entity index in scene
  727. /// </summary>
  728. /// <param name="primID"></param>
  729. /// <returns></returns>
  730. public bool HasChildPrim(LLUUID primID)
  731. {
  732. if (m_parts.ContainsKey(primID))
  733. {
  734. return true;
  735. }
  736. return false;
  737. }
  738. /// <summary>
  739. /// Does this group contain the child prim
  740. /// should be able to remove these methods once we have a entity index in scene
  741. /// </summary>
  742. /// <param name="localID"></param>
  743. /// <returns></returns>
  744. public bool HasChildPrim(uint localID)
  745. {
  746. foreach (SceneObjectPart part in m_parts.Values)
  747. {
  748. if (part.LocalID == localID)
  749. {
  750. return true;
  751. }
  752. }
  753. return false;
  754. }
  755. #endregion
  756. #region Packet Handlers
  757. /// <summary>
  758. /// Link the prims in a given group to this group
  759. /// </summary>
  760. /// <param name="objectGroup">The group of prims which should be linked to this group</param>
  761. public void LinkToGroup(SceneObjectGroup objectGroup)
  762. {
  763. SceneObjectPart linkPart = objectGroup.m_rootPart;
  764. Vector3 oldGroupPosition =
  765. new Vector3(linkPart.GroupPosition.X, linkPart.GroupPosition.Y, linkPart.GroupPosition.Z);
  766. Quaternion oldRootRotation =
  767. new Quaternion(linkPart.RotationOffset.W, linkPart.RotationOffset.X, linkPart.RotationOffset.Y,
  768. linkPart.RotationOffset.Z);
  769. linkPart.OffsetPosition = linkPart.GroupPosition - AbsolutePosition;
  770. linkPart.GroupPosition = AbsolutePosition;
  771. Vector3 axPos = new Vector3(linkPart.OffsetPosition.X, linkPart.OffsetPosition.Y, linkPart.OffsetPosition.Z);
  772. Quaternion parentRot =
  773. new Quaternion(m_rootPart.RotationOffset.W, m_rootPart.RotationOffset.X, m_rootPart.RotationOffset.Y,
  774. m_rootPart.RotationOffset.Z);
  775. axPos = parentRot.Inverse()*axPos;
  776. linkPart.OffsetPosition = new LLVector3(axPos.x, axPos.y, axPos.z);
  777. Quaternion oldRot =
  778. new Quaternion(linkPart.RotationOffset.W, linkPart.RotationOffset.X, linkPart.RotationOffset.Y,
  779. linkPart.RotationOffset.Z);
  780. Quaternion newRot = parentRot.Inverse()*oldRot;
  781. linkPart.RotationOffset = new LLQuaternion(newRot.x, newRot.y, newRot.z, newRot.w);
  782. linkPart.ParentID = m_rootPart.LocalID;
  783. linkPart.LinkNum = m_parts.Count;
  784. m_parts.Add(linkPart.UUID, linkPart);
  785. linkPart.SetParent(this);
  786. //if (linkPart.PhysActor != null)
  787. //{
  788. // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor);
  789. //linkPart.PhysActor = null;
  790. //}
  791. //TODO: rest of parts
  792. foreach (SceneObjectPart part in objectGroup.Children.Values)
  793. {
  794. if (part.UUID != objectGroup.m_rootPart.UUID)
  795. {
  796. LinkNonRootPart(part, oldGroupPosition, oldRootRotation);
  797. }
  798. }
  799. DetachFromBackup(objectGroup);
  800. m_scene.DeleteEntity(objectGroup.UUID);
  801. objectGroup.DeleteParts();
  802. AbsolutePosition = AbsolutePosition;
  803. ScheduleGroupForFullUpdate();
  804. }
  805. /// <summary>
  806. /// Delink the given prim from this group. The delinked prim is established as
  807. /// an independent SceneObjectGroup.
  808. /// </summary>
  809. /// <param name="partID"></param>
  810. public void DelinkFromGroup(uint partID)
  811. {
  812. SceneObjectPart linkPart = GetChildPart(partID);
  813. if (null != linkPart)
  814. {
  815. LLQuaternion worldRot = linkPart.GetWorldRotation();
  816. // Remove the part from this object
  817. m_parts.Remove(linkPart.UUID);
  818. linkPart.ParentID = 0;
  819. if (linkPart.PhysActor != null)
  820. {
  821. m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor);
  822. }
  823. // We need to reset the child part's position
  824. // ready for life as a separate object after being a part of another object
  825. Quaternion parentRot
  826. = new Quaternion(
  827. m_rootPart.RotationOffset.W,
  828. m_rootPart.RotationOffset.X,
  829. m_rootPart.RotationOffset.Y,
  830. m_rootPart.RotationOffset.Z);
  831. Vector3 axPos
  832. = new Vector3(
  833. linkPart.OffsetPosition.X,
  834. linkPart.OffsetPosition.Y,
  835. linkPart.OffsetPosition.Z);
  836. axPos = parentRot*axPos;
  837. linkPart.OffsetPosition = new LLVector3(axPos.x, axPos.y, axPos.z);
  838. linkPart.GroupPosition = AbsolutePosition + linkPart.OffsetPosition;
  839. linkPart.OffsetPosition = new LLVector3(0, 0, 0);
  840. linkPart.RotationOffset = worldRot;
  841. // This chunk is probably unnecesary now - delete later on
  842. /*
  843. Quaternion oldRot
  844. = new Quaternion(
  845. linkPart.RotationOffset.W,
  846. linkPart.RotationOffset.X,
  847. linkPart.RotationOffset.Y,
  848. linkPart.RotationOffset.Z);
  849. Quaternion newRot = parentRot*oldRot;
  850. linkPart.RotationOffset = new LLQuaternion(newRot.x, newRot.y, newRot.z, newRot.w);
  851. */
  852. // Add physics information back to delinked part if appropriate
  853. // XXX This is messy and should be refactorable with the similar section in
  854. // SceneObjectPart.UpdatePrimFlags()
  855. //if (m_rootPart.PhysActor != null)
  856. //{
  857. //linkPart.PhysActor = m_scene.PhysicsScene.AddPrimShape(
  858. //linkPart.Name,
  859. //linkPart.Shape,
  860. //new PhysicsVector(linkPart.AbsolutePosition.X, linkPart.AbsolutePosition.Y,
  861. //linkPart.AbsolutePosition.Z),
  862. //new PhysicsVector(linkPart.Scale.X, linkPart.Scale.Y, linkPart.Scale.Z),
  863. //new Quaternion(linkPart.RotationOffset.W, linkPart.RotationOffset.X,
  864. //linkPart.RotationOffset.Y, linkPart.RotationOffset.Z),
  865. //m_rootPart.PhysActor.IsPhysical);
  866. //m_rootPart.DoPhysicsPropertyUpdate(m_rootPart.PhysActor.IsPhysical, true);
  867. //}
  868. SceneObjectGroup objectGroup = new SceneObjectGroup(m_scene, m_regionHandle, linkPart);
  869. m_scene.AddEntity(objectGroup);
  870. ScheduleGroupForFullUpdate();
  871. }
  872. else
  873. {
  874. m_log.InfoFormat("[SCENE]: " +
  875. "DelinkFromGroup(): Child prim local id {0} not found in object with root prim id {1}",
  876. partID, LocalId);
  877. }
  878. }
  879. private void DetachFromBackup(SceneObjectGroup objectGroup)
  880. {
  881. m_scene.EventManager.OnBackup -= objectGroup.ProcessBackup;
  882. }
  883. private void LinkNonRootPart(SceneObjectPart part, Vector3 oldGroupPosition, Quaternion oldGroupRotation)
  884. {
  885. part.SetParent(this);
  886. part.ParentID = m_rootPart.LocalID;
  887. part.LinkNum = m_parts.Count;
  888. m_parts.Add(part.UUID, part);
  889. Vector3 axiomOldPos = new Vector3(part.OffsetPosition.X, part.OffsetPosition.Y, part.OffsetPosition.Z);
  890. axiomOldPos = oldGroupRotation*axiomOldPos;
  891. axiomOldPos += oldGroupPosition;
  892. LLVector3 oldAbsolutePosition = new LLVector3(axiomOldPos.x, axiomOldPos.y, axiomOldPos.z);
  893. part.OffsetPosition = oldAbsolutePosition - AbsolutePosition;
  894. Quaternion axiomRootRotation =
  895. new Quaternion(m_rootPart.RotationOffset.W, m_rootPart.RotationOffset.X, m_rootPart.RotationOffset.Y,
  896. m_rootPart.RotationOffset.Z);
  897. Vector3 axiomPos = new Vector3(part.OffsetPosition.X, part.OffsetPosition.Y, part.OffsetPosition.Z);
  898. axiomPos = axiomRootRotation.Inverse()*axiomPos;
  899. part.OffsetPosition = new LLVector3(axiomPos.x, axiomPos.y, axiomPos.z);
  900. Quaternion axiomPartRotation =
  901. new Quaternion(part.RotationOffset.W, part.RotationOffset.X, part.RotationOffset.Y,
  902. part.RotationOffset.Z);
  903. axiomPartRotation = oldGroupRotation*axiomPartRotation;
  904. axiomPartRotation = axiomRootRotation.Inverse()*axiomPartRotation;
  905. part.RotationOffset =
  906. new LLQuaternion(axiomPartRotation.x, axiomPartRotation.y, axiomPartRotation.z, axiomPartRotation.w);
  907. }
  908. /// <summary>
  909. /// If object is physical, apply force to move it around
  910. /// If object is not physical, just put it at the resulting location
  911. /// </summary>
  912. /// <param name="offset">Always seems to be 0,0,0, so ignoring</param>
  913. /// <param name="pos">New position. We do the math here to turn it into a force</param>
  914. /// <param name="remoteClient"></param>
  915. public void GrabMovement(LLVector3 offset, LLVector3 pos, IClientAPI remoteClient)
  916. {
  917. if (m_scene.EventManager.TriggerGroupMove(UUID, pos))
  918. {
  919. if (m_rootPart.PhysActor != null)
  920. {
  921. if (m_rootPart.PhysActor.IsPhysical)
  922. {
  923. LLVector3 llmoveforce = pos - AbsolutePosition;
  924. PhysicsVector grabforce = new PhysicsVector(llmoveforce.X, llmoveforce.Y, llmoveforce.Z);
  925. grabforce = (grabforce / 10) * m_rootPart.PhysActor.Mass;
  926. m_rootPart.PhysActor.AddForce(grabforce);
  927. m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor);
  928. }
  929. else
  930. {
  931. NonPhysicalGrabMovement(pos);
  932. }
  933. }
  934. else
  935. {
  936. NonPhysicalGrabMovement(pos);
  937. }
  938. }
  939. }
  940. public void NonPhysicalGrabMovement(LLVector3 pos)
  941. {
  942. AbsolutePosition = pos;
  943. m_rootPart.SendTerseUpdateToAllClients();
  944. }
  945. /// <summary>
  946. ///
  947. /// </summary>
  948. /// <param name="client"></param>
  949. public void GetProperties(IClientAPI client)
  950. {
  951. ObjectPropertiesPacket proper = (ObjectPropertiesPacket) PacketPool.Instance.GetPacket(PacketType.ObjectProperties);
  952. // TODO: don't create new blocks if recycling an old packet
  953. proper.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[1];
  954. proper.ObjectData[0] = new ObjectPropertiesPacket.ObjectDataBlock();
  955. proper.ObjectData[0].ItemID = LLUUID.Zero;
  956. proper.ObjectData[0].CreationDate = (ulong) m_rootPart.CreationDate;
  957. proper.ObjectData[0].CreatorID = m_rootPart.CreatorID;
  958. proper.ObjectData[0].FolderID = LLUUID.Zero;
  959. proper.ObjectData[0].FromTaskID = LLUUID.Zero;
  960. proper.ObjectData[0].GroupID = LLUUID.Zero;
  961. proper.ObjectData[0].InventorySerial = (short) m_rootPart.InventorySerial;
  962. proper.ObjectData[0].LastOwnerID = m_rootPart.LastOwnerID;
  963. proper.ObjectData[0].ObjectID = UUID;
  964. proper.ObjectData[0].OwnerID = m_rootPart.OwnerID;
  965. proper.ObjectData[0].TouchName = Helpers.StringToField(m_rootPart.TouchName);
  966. proper.ObjectData[0].TextureID = new byte[0];
  967. proper.ObjectData[0].SitName = Helpers.StringToField(m_rootPart.SitName);
  968. proper.ObjectData[0].Name = Helpers.StringToField(m_rootPart.Name);
  969. proper.ObjectData[0].Description = Helpers.StringToField(m_rootPart.Description);
  970. proper.ObjectData[0].OwnerMask = m_rootPart.OwnerMask;
  971. proper.ObjectData[0].NextOwnerMask = m_rootPart.NextOwnerMask;
  972. proper.ObjectData[0].GroupMask = m_rootPart.GroupMask;
  973. proper.ObjectData[0].EveryoneMask = m_rootPart.EveryoneMask;
  974. proper.ObjectData[0].BaseMask = m_rootPart.BaseMask;
  975. client.OutPacket(proper, ThrottleOutPacketType.Task);
  976. }
  977. /// <summary>
  978. /// Set the name of a prim
  979. /// </summary>
  980. /// <param name="name"></param>
  981. /// <param name="localID"></param>
  982. public void SetPartName(string name, uint localID)
  983. {
  984. SceneObjectPart part = GetChildPart(localID);
  985. if (part != null)
  986. {
  987. part.Name = name;
  988. }
  989. }
  990. public void SetPartDescription(string des, uint localID)
  991. {
  992. SceneObjectPart part = GetChildPart(localID);
  993. if (part != null)
  994. {
  995. part.Description = des;
  996. }
  997. }
  998. public void SetPartText(string text, uint localID)
  999. {
  1000. SceneObjectPart part = GetChildPart(localID);
  1001. if (part != null)
  1002. {
  1003. part.Text = text;
  1004. }
  1005. }
  1006. public void SetPartText(string text, LLUUID partID)
  1007. {
  1008. SceneObjectPart part = GetChildPart(partID);
  1009. if (part != null)
  1010. {
  1011. part.Text = text;
  1012. }
  1013. }
  1014. public string GetPartName(uint localID)
  1015. {
  1016. SceneObjectPart part = GetChildPart(localID);
  1017. if (part != null)
  1018. {
  1019. return part.Name;
  1020. }
  1021. return String.Empty;
  1022. }
  1023. public string GetPartDescription(uint localID)
  1024. {
  1025. SceneObjectPart part = GetChildPart(localID);
  1026. if (part != null)
  1027. {
  1028. return part.Description;
  1029. }
  1030. return String.Empty;
  1031. }
  1032. /// <summary>
  1033. ///
  1034. /// </summary>
  1035. /// <param name="localID"></param>
  1036. /// <param name="type"></param>
  1037. /// <param name="inUse"></param>
  1038. /// <param name="data"></param>
  1039. ///
  1040. public void UpdatePrimFlags(uint localID, ushort type, bool inUse, byte[] data)
  1041. {
  1042. SceneObjectPart part = GetChildPart(localID);
  1043. if (part != null)
  1044. {
  1045. // If we have children
  1046. if (m_parts.Count > 1)
  1047. {
  1048. foreach (SceneObjectPart parts in m_parts.Values)
  1049. {
  1050. parts.UpdatePrimFlags(type, inUse, data);
  1051. }
  1052. }
  1053. else
  1054. {
  1055. part.UpdatePrimFlags(type, inUse, data);
  1056. }
  1057. }
  1058. }
  1059. public void UpdateExtraParam(uint localID, ushort type, bool inUse, byte[] data)
  1060. {
  1061. SceneObjectPart part = GetChildPart(localID);
  1062. if (part != null)
  1063. {
  1064. part.UpdateExtraParam(type, inUse, data);
  1065. }
  1066. }
  1067. public SceneObjectPart[] GetParts()
  1068. {
  1069. int numParts = Children.Count;
  1070. SceneObjectPart[] partArray = new SceneObjectPart[numParts];
  1071. Children.Values.CopyTo(partArray, 0);
  1072. return partArray;
  1073. }
  1074. /// <summary>
  1075. ///
  1076. /// </summary>
  1077. /// <param name="localID"></param>
  1078. /// <param name="textureEntry"></param>
  1079. public void UpdateTextureEntry(uint localID, byte[] textureEntry)
  1080. {
  1081. SceneObjectPart part = GetChildPart(localID);
  1082. if (part != null)
  1083. {
  1084. part.UpdateTextureEntry(textureEntry);
  1085. }
  1086. }
  1087. public void UpdatePermissions(LLUUID AgentID, byte field, uint localID, uint mask, byte addRemTF)
  1088. {
  1089. SceneObjectPart updatePart = GetChildPart(localID);
  1090. updatePart.UpdatePermissions(AgentID, field, localID, mask, addRemTF);
  1091. }
  1092. #endregion
  1093. #region Shape
  1094. /// <summary>
  1095. ///
  1096. /// </summary>
  1097. /// <param name="shapeBlock"></param>
  1098. public void UpdateShape(ObjectShapePacket.ObjectDataBlock shapeBlock, uint localID)
  1099. {
  1100. SceneObjectPart part = GetChildPart(localID);
  1101. if (part != null)
  1102. {
  1103. part.UpdateShape(shapeBlock);
  1104. if (part.PhysActor != null)
  1105. m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor);
  1106. }
  1107. }
  1108. #endregion
  1109. #region Resize
  1110. /// <summary>
  1111. ///
  1112. /// </summary>
  1113. /// <param name="scale"></param>
  1114. /// <param name="localID"></param>
  1115. public void Resize(LLVector3 scale, uint localID)
  1116. {
  1117. SceneObjectPart part = GetChildPart(localID);
  1118. if (part != null)
  1119. {
  1120. part.Resize(scale);
  1121. if (part.PhysActor != null)
  1122. {
  1123. part.PhysActor.Size =
  1124. new PhysicsVector(scale.X, scale.Y, scale.Z);
  1125. m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor);
  1126. }
  1127. if (part.UUID != m_rootPart.UUID)
  1128. ScheduleGroupForFullUpdate();
  1129. //if (part.UUID == m_rootPart.UUID)
  1130. //{
  1131. //if (m_rootPart.PhysActor != null)
  1132. //{
  1133. //m_rootPart.PhysActor.Size =
  1134. //new PhysicsVector(m_rootPart.Scale.X, m_rootPart.Scale.Y, m_rootPart.Scale.Z);
  1135. //m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor);
  1136. //}
  1137. //}
  1138. }
  1139. }
  1140. #endregion
  1141. #region Position
  1142. /// <summary>
  1143. ///
  1144. /// </summary>
  1145. /// <param name="pos"></param>
  1146. public void UpdateGroupPosition(LLVector3 pos)
  1147. {
  1148. if (m_scene.EventManager.TriggerGroupMove(UUID, pos))
  1149. {
  1150. AbsolutePosition = pos;
  1151. }
  1152. //we need to do a terse update even if the move wasn't allowed
  1153. // so that the position is reset in the client (the object snaps back)
  1154. ScheduleGroupForTerseUpdate();
  1155. }
  1156. /// <summary>
  1157. ///
  1158. /// </summary>
  1159. /// <param name="pos"></param>
  1160. /// <param name="localID"></param>
  1161. public void UpdateSinglePosition(LLVector3 pos, uint localID)
  1162. {
  1163. SceneObjectPart part = GetChildPart(localID);
  1164. if (part != null)
  1165. {
  1166. if (part.UUID == m_rootPart.UUID)
  1167. {
  1168. UpdateRootPosition(pos);
  1169. }
  1170. else
  1171. {
  1172. part.UpdateOffSet(pos);
  1173. }
  1174. }
  1175. }
  1176. /// <summary>
  1177. ///
  1178. /// </summary>
  1179. /// <param name="pos"></param>
  1180. private void UpdateRootPosition(LLVector3 pos)
  1181. {
  1182. LLVector3 newPos = new LLVector3(pos.X, pos.Y, pos.Z);
  1183. LLVector3 oldPos =
  1184. new LLVector3(AbsolutePosition.X + m_rootPart.OffsetPosition.X,
  1185. AbsolutePosition.Y + m_rootPart.OffsetPosition.Y,
  1186. AbsolutePosition.Z + m_rootPart.OffsetPosition.Z);
  1187. LLVector3 diff = oldPos - newPos;
  1188. Vector3 axDiff = new Vector3(diff.X, diff.Y, diff.Z);
  1189. Quaternion partRotation =
  1190. new Quaternion(m_rootPart.RotationOffset.W, m_rootPart.RotationOffset.X, m_rootPart.RotationOffset.Y,
  1191. m_rootPart.RotationOffset.Z);
  1192. axDiff = partRotation.Inverse()*axDiff;
  1193. diff.X = axDiff.x;
  1194. diff.Y = axDiff.y;
  1195. diff.Z = axDiff.z;
  1196. foreach (SceneObjectPart obPart in m_parts.Values)
  1197. {
  1198. if (obPart.UUID != m_rootPart.UUID)
  1199. {
  1200. obPart.OffsetPosition = obPart.OffsetPosition + diff;
  1201. }
  1202. }
  1203. AbsolutePosition = newPos;
  1204. ScheduleGroupForTerseUpdate();
  1205. }
  1206. public void OffsetForNewRegion(LLVector3 offset)
  1207. {
  1208. m_rootPart.GroupPosition = offset;
  1209. }
  1210. #endregion
  1211. #region Rotation
  1212. /// <summary>
  1213. ///
  1214. /// </summary>
  1215. /// <param name="rot"></param>
  1216. public void UpdateGroupRotation(LLQuaternion rot)
  1217. {
  1218. m_rootPart.UpdateRotation(rot);
  1219. if (m_rootPart.PhysActor != null)
  1220. {
  1221. m_rootPart.PhysActor.Orientation =
  1222. new Quaternion(m_rootPart.RotationOffset.W, m_rootPart.RotationOffset.X, m_rootPart.RotationOffset.Y,
  1223. m_rootPart.RotationOffset.Z);
  1224. m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor);
  1225. }
  1226. ScheduleGroupForTerseUpdate();
  1227. }
  1228. /// <summary>
  1229. ///
  1230. /// </summary>
  1231. /// <param name="pos"></param>
  1232. /// <param name="rot"></param>
  1233. public void UpdateGroupRotation(LLVector3 pos, LLQuaternion rot)
  1234. {
  1235. m_rootPart.UpdateRotation(rot);
  1236. if (m_rootPart.PhysActor != null)
  1237. {
  1238. m_rootPart.PhysActor.Orientation =
  1239. new Quaternion(m_rootPart.RotationOffset.W, m_rootPart.RotationOffset.X, m_rootPart.RotationOffset.Y,
  1240. m_rootPart.RotationOffset.Z);
  1241. m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor);
  1242. }
  1243. AbsolutePosition = pos;
  1244. ScheduleGroupForTerseUpdate();
  1245. }
  1246. /// <summary>
  1247. ///
  1248. /// </summary>
  1249. /// <param name="rot"></param>
  1250. /// <param name="localID"></param>
  1251. public void UpdateSingleRotation(LLQuaternion rot, uint localID)
  1252. {
  1253. SceneObjectPart part = GetChildPart(localID);
  1254. if (part != null)
  1255. {
  1256. if (part.UUID == m_rootPart.UUID)
  1257. {
  1258. UpdateRootRotation(rot);
  1259. }
  1260. else
  1261. {
  1262. part.UpdateRotation(rot);
  1263. }
  1264. }
  1265. }
  1266. /// <summary>
  1267. ///
  1268. /// </summary>
  1269. /// <param name="rot"></param>
  1270. private void UpdateRootRotation(LLQuaternion rot)
  1271. {
  1272. Quaternion axRot = new Quaternion(rot.W, rot.X, rot.Y, rot.Z);
  1273. Quaternion oldParentRot =
  1274. new Quaternion(m_rootPart.RotationOffset.W, m_rootPart.RotationOffset.X, m_rootPart.RotationOffset.Y,
  1275. m_rootPart.RotationOffset.Z);
  1276. m_rootPart.UpdateRotation(rot);
  1277. if (m_rootPart.PhysActor != null)
  1278. {
  1279. m_rootPart.PhysActor.Orientation =
  1280. new Quaternion(m_rootPart.RotationOffset.W, m_rootPart.RotationOffset.X, m_rootPart.RotationOffset.Y,
  1281. m_rootPart.RotationOffset.Z);
  1282. m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor);
  1283. }
  1284. foreach (SceneObjectPart prim in m_parts.Values)
  1285. {
  1286. if (prim.UUID != m_rootPart.UUID)
  1287. {
  1288. Vector3 axPos = new Vector3(prim.OffsetPosition.X, prim.OffsetPosition.Y, prim.OffsetPosition.Z);
  1289. axPos = oldParentRot*axPos;
  1290. axPos = axRot.Inverse()*axPos;
  1291. prim.OffsetPosition = new LLVector3(axPos.x, axPos.y, axPos.z);
  1292. Quaternion primsRot =
  1293. new Quaternion(prim.RotationOffset.W, prim.RotationOffset.X, prim.RotationOffset.Y,
  1294. prim.RotationOffset.Z);
  1295. Quaternion newRot = oldParentRot*primsRot;
  1296. newRot = axRot.Inverse()*newRot;
  1297. prim.RotationOffset = new LLQuaternion(newRot.x, newRot.y, newRot.z, newRot.w);
  1298. prim.ScheduleTerseUpdate();
  1299. }
  1300. }
  1301. m_rootPart.ScheduleTerseUpdate();
  1302. }
  1303. #endregion
  1304. /// <summary>
  1305. ///
  1306. /// </summary>
  1307. /// <param name="part"></param>
  1308. private void SetPartAsRoot(SceneObjectPart part)
  1309. {
  1310. m_rootPart = part;
  1311. }
  1312. /// <summary>
  1313. ///
  1314. /// </summary>
  1315. /// <param name="part"></param>
  1316. private void SetPartAsNonRoot(SceneObjectPart part)
  1317. {
  1318. part.ParentID = m_rootPart.LocalID;
  1319. }
  1320. /// <summary>
  1321. ///
  1322. /// </summary>
  1323. /// <returns></returns>
  1324. public List<ScenePresence> GetScenePresences()
  1325. {
  1326. return m_scene.GetScenePresences();
  1327. }
  1328. #region Events
  1329. /// <summary>
  1330. ///
  1331. /// </summary>
  1332. public void TriggerTainted()
  1333. {
  1334. if (OnPrimCountTainted != null)
  1335. {
  1336. OnPrimCountTainted();
  1337. }
  1338. }
  1339. /// <summary>
  1340. /// Processes backup
  1341. /// </summary>
  1342. /// <param name="datastore"></param>
  1343. public void ProcessBackup(IRegionDataStore datastore)
  1344. {
  1345. if (HasGroupChanged)
  1346. {
  1347. datastore.StoreObject(this, m_scene.RegionInfo.RegionID);
  1348. HasGroupChanged = false;
  1349. }
  1350. ForEachPart(delegate(SceneObjectPart part) { part.ProcessInventoryBackup(datastore); });
  1351. }
  1352. #endregion
  1353. #region Client Updating
  1354. public void SendFullUpdateToClient(IClientAPI remoteClient, uint clientFlags)
  1355. {
  1356. lock (m_parts)
  1357. {
  1358. foreach (SceneObjectPart part in m_parts.Values)
  1359. {
  1360. SendPartFullUpdate(remoteClient, part, clientFlags);
  1361. }
  1362. }
  1363. }
  1364. /// <summary>
  1365. ///
  1366. /// </summary>
  1367. /// <param name="remoteClient"></param>
  1368. /// <param name="part"></param>
  1369. internal void SendPartFullUpdate(IClientAPI remoteClient, SceneObjectPart part, uint clientFlags)
  1370. {
  1371. if (m_rootPart.UUID == part.UUID)
  1372. {
  1373. part.SendFullUpdateToClient(remoteClient, AbsolutePosition, clientFlags);
  1374. }
  1375. else
  1376. {
  1377. part.SendFullUpdateToClient(remoteClient, clientFlags);
  1378. }
  1379. }
  1380. /// <summary>
  1381. ///
  1382. /// </summary>
  1383. /// <param name="remoteClient"></param>
  1384. /// <param name="part"></param>
  1385. internal void SendPartTerseUpdate(IClientAPI remoteClient, SceneObjectPart part)
  1386. {
  1387. if (m_rootPart.UUID == part.UUID)
  1388. {
  1389. part.SendTerseUpdateToClient(remoteClient, AbsolutePosition);
  1390. }
  1391. else
  1392. {
  1393. part.SendTerseUpdateToClient(remoteClient);
  1394. }
  1395. }
  1396. #endregion
  1397. public override void UpdateMovement()
  1398. {
  1399. foreach (SceneObjectPart part in m_parts.Values)
  1400. {
  1401. part.UpdateMovement();
  1402. }
  1403. }
  1404. public float GetTimeDilation()
  1405. {
  1406. return m_scene.TimeDilation;
  1407. }
  1408. /// <summary>
  1409. /// Added as a way for the storage provider to reset the scene,
  1410. /// most likely a better way to do this sort of thing but for now...
  1411. /// </summary>
  1412. /// <param name="scene"></param>
  1413. public void SetScene(Scene scene)
  1414. {
  1415. m_scene = scene;
  1416. AttachToBackup();
  1417. }
  1418. /// <summary>
  1419. ///
  1420. /// </summary>
  1421. /// <param name="part"></param>
  1422. public void AddPart(SceneObjectPart part)
  1423. {
  1424. part.SetParent(this);
  1425. part.LinkNum = m_parts.Count;
  1426. m_parts.Add(part.UUID, part);
  1427. }
  1428. /// <summary>
  1429. ///
  1430. /// </summary>
  1431. public void UpdateParentIDs()
  1432. {
  1433. foreach (SceneObjectPart part in m_parts.Values)
  1434. {
  1435. if (part.UUID != m_rootPart.UUID)
  1436. {
  1437. part.ParentID = m_rootPart.LocalID;
  1438. }
  1439. }
  1440. }
  1441. public void RegenerateFullIDs()
  1442. {
  1443. foreach (SceneObjectPart part in m_parts.Values)
  1444. {
  1445. part.UUID = LLUUID.Random();
  1446. }
  1447. }
  1448. public void ResetChildPrimPhysicsPositions()
  1449. {
  1450. AbsolutePosition = AbsolutePosition;
  1451. HasGroupChanged = false;
  1452. }
  1453. public LLUUID GetPartsFullID(uint localID)
  1454. {
  1455. SceneObjectPart part = GetChildPart(localID);
  1456. if (part != null)
  1457. {
  1458. return part.UUID;
  1459. }
  1460. return null;
  1461. }
  1462. public void UpdateText(string text)
  1463. {
  1464. m_rootPart.Text = text;
  1465. m_rootPart.ScheduleTerseUpdate();
  1466. }
  1467. public void ObjectGrabHandler(uint localId, LLVector3 offsetPos, IClientAPI remoteClient)
  1468. {
  1469. if (m_rootPart.LocalID == localId)
  1470. {
  1471. OnGrabGroup(offsetPos, remoteClient);
  1472. }
  1473. else
  1474. {
  1475. SceneObjectPart part = GetChildPart(localId);
  1476. OnGrabPart(part, offsetPos, remoteClient);
  1477. }
  1478. }
  1479. public virtual void OnGrabPart(SceneObjectPart part, LLVector3 offsetPos, IClientAPI remoteClient)
  1480. {
  1481. part.OnGrab(offsetPos, remoteClient);
  1482. }
  1483. public virtual void OnGrabGroup(LLVector3 offsetPos, IClientAPI remoteClient)
  1484. {
  1485. m_scene.EventManager.TriggerGroupGrab(UUID, offsetPos, remoteClient.AgentId);
  1486. }
  1487. public void DeleteGroup()
  1488. {
  1489. DetachFromBackup(this);
  1490. foreach (SceneObjectPart part in m_parts.Values)
  1491. {
  1492. List<ScenePresence> avatars = GetScenePresences();
  1493. for (int i = 0; i < avatars.Count; i++)
  1494. {
  1495. if (avatars[i].ParentID == LocalId)
  1496. {
  1497. avatars[i].StandUp();
  1498. }
  1499. avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalID);
  1500. }
  1501. }
  1502. }
  1503. public void DeleteParts()
  1504. {
  1505. m_rootPart = null;
  1506. m_parts.Clear();
  1507. }
  1508. public void AddScriptLPS(int count)
  1509. {
  1510. InnerScene d = m_scene.m_innerScene;
  1511. d.AddToScriptLPS(count);
  1512. }
  1513. public void AddActiveScriptCount(int count)
  1514. {
  1515. InnerScene d = m_scene.m_innerScene;
  1516. d.AddActiveScripts(count);
  1517. }
  1518. public override void SetText(string text, Vector3 color, double alpha)
  1519. {
  1520. Color = Color.FromArgb(0xff - (int) (alpha*0xff),
  1521. (int) (color.x*0xff),
  1522. (int) (color.y*0xff),
  1523. (int) (color.z*0xff));
  1524. Text = text;
  1525. }
  1526. public void ApplyPhysics(bool m_physicalPrim)
  1527. {
  1528. if (m_parts.Count > 1)
  1529. {
  1530. lock (m_parts)
  1531. {
  1532. foreach (SceneObjectPart part in m_parts.Values)
  1533. {
  1534. part.ApplyPhysics(m_rootPart.ObjectFlags, m_physicalPrim);
  1535. // Hack to get the physics scene geometries in the right spot
  1536. ResetChildPrimPhysicsPositions();
  1537. }
  1538. }
  1539. }
  1540. else
  1541. {
  1542. m_rootPart.ApplyPhysics(m_rootPart.ObjectFlags, m_physicalPrim);
  1543. }
  1544. }
  1545. public void SetOwnerId(LLUUID userId)
  1546. {
  1547. ForEachPart(delegate(SceneObjectPart part)
  1548. { part.OwnerID = userId; });
  1549. }
  1550. public void ForEachPart(Action<SceneObjectPart> whatToDo)
  1551. {
  1552. lock (m_parts)
  1553. {
  1554. foreach (SceneObjectPart part in m_parts.Values)
  1555. {
  1556. whatToDo(part);
  1557. }
  1558. }
  1559. }
  1560. }
  1561. }