SceneObjectGroup.cs 131 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584
  1. /*
  2. * Copyright (c) Contributors, http://opensimulator.org/
  3. * See CONTRIBUTORS.TXT for a full list of copyright holders.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. * * Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * * Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * * Neither the name of the OpenSimulator Project nor the
  13. * names of its contributors may be used to endorse or promote products
  14. * derived from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
  17. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19. * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
  20. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  21. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  22. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  23. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  25. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. using System;
  28. using System.Collections.Generic;
  29. using System.Drawing;
  30. using System.IO;
  31. using System.Threading;
  32. using System.Xml;
  33. using System.Xml.Serialization;
  34. using OpenMetaverse;
  35. using OpenMetaverse.Packets;
  36. using OpenSim.Framework;
  37. using OpenSim.Region.Framework.Interfaces;
  38. using OpenSim.Region.Physics.Manager;
  39. using OpenSim.Region.Framework.Scenes.Serialization;
  40. namespace OpenSim.Region.Framework.Scenes
  41. {
  42. [Flags]
  43. public enum scriptEvents
  44. {
  45. None = 0,
  46. attach = 1,
  47. collision = 16,
  48. collision_end = 32,
  49. collision_start = 64,
  50. control = 128,
  51. dataserver = 256,
  52. email = 512,
  53. http_response = 1024,
  54. land_collision = 2048,
  55. land_collision_end = 4096,
  56. land_collision_start = 8192,
  57. at_target = 16384,
  58. at_rot_target = 16777216,
  59. listen = 32768,
  60. money = 65536,
  61. moving_end = 131072,
  62. moving_start = 262144,
  63. not_at_rot_target = 524288,
  64. not_at_target = 1048576,
  65. remote_data = 8388608,
  66. run_time_permissions = 268435456,
  67. state_entry = 1073741824,
  68. state_exit = 2,
  69. timer = 4,
  70. touch = 8,
  71. touch_end = 536870912,
  72. touch_start = 2097152,
  73. object_rez = 4194304
  74. }
  75. struct scriptPosTarget
  76. {
  77. public Vector3 targetPos;
  78. public float tolerance;
  79. public uint handle;
  80. }
  81. struct scriptRotTarget
  82. {
  83. public Quaternion targetRot;
  84. public float tolerance;
  85. public uint handle;
  86. }
  87. public delegate void PrimCountTaintedDelegate();
  88. /// <summary>
  89. /// A scene object group is conceptually an object in the scene. The object is constituted of SceneObjectParts
  90. /// (often known as prims), one of which is considered the root part.
  91. /// </summary>
  92. public partial class SceneObjectGroup : EntityBase, ISceneObject
  93. {
  94. // private PrimCountTaintedDelegate handlerPrimCountTainted = null;
  95. /// <summary>
  96. /// Signal whether the non-inventory attributes of any prims in the group have changed
  97. /// since the group's last persistent backup
  98. /// </summary>
  99. private bool m_hasGroupChanged = false;
  100. private long timeFirstChanged;
  101. private long timeLastChanged;
  102. public bool HasGroupChanged
  103. {
  104. set
  105. {
  106. if (value)
  107. {
  108. timeLastChanged = DateTime.Now.Ticks;
  109. if (!m_hasGroupChanged)
  110. timeFirstChanged = DateTime.Now.Ticks;
  111. }
  112. m_hasGroupChanged = value;
  113. }
  114. get { return m_hasGroupChanged; }
  115. }
  116. private bool isTimeToPersist()
  117. {
  118. if (IsSelected || IsDeleted || IsAttachment)
  119. return false;
  120. if (!m_hasGroupChanged)
  121. return false;
  122. if (m_scene.ShuttingDown)
  123. return true;
  124. long currentTime = DateTime.Now.Ticks;
  125. if (currentTime - timeLastChanged > m_scene.m_dontPersistBefore || currentTime - timeFirstChanged > m_scene.m_persistAfter)
  126. return true;
  127. return false;
  128. }
  129. /// <value>
  130. /// Is this scene object acting as an attachment?
  131. ///
  132. /// We return false if the group has already been deleted.
  133. ///
  134. /// TODO: At the moment set must be done on the part itself. There may be a case for doing it here since I
  135. /// presume either all or no parts in a linkset can be part of an attachment (in which
  136. /// case the value would get proprogated down into all the descendent parts).
  137. /// </value>
  138. public bool IsAttachment
  139. {
  140. get
  141. {
  142. if (!IsDeleted)
  143. return m_rootPart.IsAttachment;
  144. return false;
  145. }
  146. }
  147. public float scriptScore = 0f;
  148. private Vector3 lastPhysGroupPos;
  149. private Quaternion lastPhysGroupRot;
  150. private bool m_isBackedUp = false;
  151. /// <summary>
  152. /// The constituent parts of this group
  153. /// </summary>
  154. protected Dictionary<UUID, SceneObjectPart> m_parts = new Dictionary<UUID, SceneObjectPart>();
  155. protected ulong m_regionHandle;
  156. protected SceneObjectPart m_rootPart;
  157. // private Dictionary<UUID, scriptEvents> m_scriptEvents = new Dictionary<UUID, scriptEvents>();
  158. private Dictionary<uint, scriptPosTarget> m_targets = new Dictionary<uint, scriptPosTarget>();
  159. private Dictionary<uint, scriptRotTarget> m_rotTargets = new Dictionary<uint, scriptRotTarget>();
  160. private bool m_scriptListens_atTarget = false;
  161. private bool m_scriptListens_notAtTarget = false;
  162. private bool m_scriptListens_atRotTarget = false;
  163. private bool m_scriptListens_notAtRotTarget = false;
  164. internal Dictionary<UUID, string> m_savedScriptState = null;
  165. #region Properties
  166. /// <summary>
  167. /// The name of an object grouping is always the same as its root part
  168. /// </summary>
  169. public override string Name
  170. {
  171. get {
  172. if (RootPart == null)
  173. return "";
  174. return RootPart.Name;
  175. }
  176. set { RootPart.Name = value; }
  177. }
  178. /// <summary>
  179. /// Added because the Parcel code seems to use it
  180. /// but not sure a object should have this
  181. /// as what does it tell us? that some avatar has selected it (but not what Avatar/user)
  182. /// think really there should be a list (or whatever) in each scenepresence
  183. /// saying what prim(s) that user has selected.
  184. /// </summary>
  185. protected bool m_isSelected = false;
  186. /// <summary>
  187. /// Number of prims in this group
  188. /// </summary>
  189. public int PrimCount
  190. {
  191. get { lock (m_parts) { return m_parts.Count; } }
  192. }
  193. protected Quaternion m_rotation = Quaternion.Identity;
  194. public virtual Quaternion Rotation
  195. {
  196. get { return m_rotation; }
  197. set { m_rotation = value; }
  198. }
  199. public Quaternion GroupRotation
  200. {
  201. get { return m_rootPart.RotationOffset; }
  202. }
  203. public UUID GroupID
  204. {
  205. get { return m_rootPart.GroupID; }
  206. set { m_rootPart.GroupID = value; }
  207. }
  208. /// <value>
  209. /// The parts of this scene object group. You must lock this property before using it.
  210. /// If you're doing anything other than reading values, please take a copy of the values rather than locking
  211. /// the dictionary for the entirety of the operation. This increases liveness and reduces the danger of deadlock
  212. /// If you want to know the number of children, consider using the PrimCount property instead
  213. /// </value>
  214. public Dictionary<UUID, SceneObjectPart> Children
  215. {
  216. get { return m_parts; }
  217. set { m_parts = value; }
  218. }
  219. /// <value>
  220. /// The root part of this scene object
  221. /// </value>
  222. public SceneObjectPart RootPart
  223. {
  224. get { return m_rootPart; }
  225. }
  226. public ulong RegionHandle
  227. {
  228. get { return m_regionHandle; }
  229. set
  230. {
  231. m_regionHandle = value;
  232. lock (m_parts)
  233. {
  234. foreach (SceneObjectPart part in m_parts.Values)
  235. {
  236. part.RegionHandle = m_regionHandle;
  237. }
  238. }
  239. }
  240. }
  241. /// <summary>
  242. /// Check both the attachment property and the relevant properties of the underlying root part.
  243. /// </summary>
  244. /// This is necessary in some cases, particularly when a scene object has just crossed into a region and doesn't
  245. /// have the IsAttachment property yet checked.
  246. ///
  247. /// FIXME: However, this should be fixed so that this property
  248. /// propertly reflects the underlying status.
  249. /// <returns></returns>
  250. public bool IsAttachmentCheckFull()
  251. {
  252. return (IsAttachment || (m_rootPart.Shape.PCode == 9 && m_rootPart.Shape.State != 0));
  253. }
  254. /// <summary>
  255. /// The absolute position of this scene object in the scene
  256. /// </summary>
  257. public override Vector3 AbsolutePosition
  258. {
  259. get { return m_rootPart.GroupPosition; }
  260. set
  261. {
  262. Vector3 val = value;
  263. if ((m_scene.TestBorderCross(val - Vector3.UnitX, Cardinals.E) || m_scene.TestBorderCross(val + Vector3.UnitX, Cardinals.W)
  264. || m_scene.TestBorderCross(val - Vector3.UnitY, Cardinals.N) || m_scene.TestBorderCross(val + Vector3.UnitY, Cardinals.S))
  265. && !IsAttachmentCheckFull() && (!m_scene.LoadingPrims))
  266. {
  267. m_scene.CrossPrimGroupIntoNewRegion(val, this, true);
  268. }
  269. if (RootPart.GetStatusSandbox())
  270. {
  271. if (Util.GetDistanceTo(RootPart.StatusSandboxPos, value) > 10)
  272. {
  273. RootPart.ScriptSetPhysicsStatus(false);
  274. Scene.SimChat(Utils.StringToBytes("Hit Sandbox Limit"),
  275. ChatTypeEnum.DebugChannel, 0x7FFFFFFF, RootPart.AbsolutePosition, Name, UUID, false);
  276. return;
  277. }
  278. }
  279. lock (m_parts)
  280. {
  281. foreach (SceneObjectPart part in m_parts.Values)
  282. {
  283. part.GroupPosition = val;
  284. }
  285. }
  286. //if (m_rootPart.PhysActor != null)
  287. //{
  288. //m_rootPart.PhysActor.Position =
  289. //new PhysicsVector(m_rootPart.GroupPosition.X, m_rootPart.GroupPosition.Y,
  290. //m_rootPart.GroupPosition.Z);
  291. //m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor);
  292. //}
  293. }
  294. }
  295. public override uint LocalId
  296. {
  297. get { return m_rootPart.LocalId; }
  298. set { m_rootPart.LocalId = value; }
  299. }
  300. public override UUID UUID
  301. {
  302. get { return m_rootPart.UUID; }
  303. set
  304. {
  305. m_rootPart.UUID = value;
  306. lock (m_parts)
  307. {
  308. m_parts.Remove(m_rootPart.UUID);
  309. m_parts.Add(m_rootPart.UUID, m_rootPart);
  310. }
  311. }
  312. }
  313. public UUID OwnerID
  314. {
  315. get { return m_rootPart.OwnerID; }
  316. set { m_rootPart.OwnerID = value; }
  317. }
  318. public float Damage
  319. {
  320. get { return m_rootPart.Damage; }
  321. set { m_rootPart.Damage = value; }
  322. }
  323. public Color Color
  324. {
  325. get { return m_rootPart.Color; }
  326. set { m_rootPart.Color = value; }
  327. }
  328. public string Text
  329. {
  330. get {
  331. string returnstr = m_rootPart.Text;
  332. if (returnstr.Length > 255)
  333. {
  334. returnstr = returnstr.Substring(0, 255);
  335. }
  336. return returnstr;
  337. }
  338. set { m_rootPart.Text = value; }
  339. }
  340. protected virtual bool InSceneBackup
  341. {
  342. get { return true; }
  343. }
  344. private bool m_passCollision;
  345. public bool PassCollision
  346. {
  347. get { return m_passCollision; }
  348. set
  349. {
  350. m_passCollision = value;
  351. HasGroupChanged = true;
  352. }
  353. }
  354. public bool IsSelected
  355. {
  356. get { return m_isSelected; }
  357. set
  358. {
  359. m_isSelected = value;
  360. // Tell physics engine that group is selected
  361. if (m_rootPart.PhysActor != null)
  362. {
  363. m_rootPart.PhysActor.Selected = value;
  364. // Pass it on to the children.
  365. foreach (SceneObjectPart child in Children.Values)
  366. {
  367. if (child.PhysActor != null)
  368. {
  369. child.PhysActor.Selected = value;
  370. }
  371. }
  372. }
  373. }
  374. }
  375. private SceneObjectPart m_PlaySoundMasterPrim = null;
  376. public SceneObjectPart PlaySoundMasterPrim
  377. {
  378. get { return m_PlaySoundMasterPrim; }
  379. set { m_PlaySoundMasterPrim = value; }
  380. }
  381. private List<SceneObjectPart> m_PlaySoundSlavePrims = new List<SceneObjectPart>();
  382. public List<SceneObjectPart> PlaySoundSlavePrims
  383. {
  384. get { return m_PlaySoundSlavePrims; }
  385. set { m_PlaySoundSlavePrims = value; }
  386. }
  387. private SceneObjectPart m_LoopSoundMasterPrim = null;
  388. public SceneObjectPart LoopSoundMasterPrim
  389. {
  390. get { return m_LoopSoundMasterPrim; }
  391. set { m_LoopSoundMasterPrim = value; }
  392. }
  393. private List<SceneObjectPart> m_LoopSoundSlavePrims = new List<SceneObjectPart>();
  394. public List<SceneObjectPart> LoopSoundSlavePrims
  395. {
  396. get { return m_LoopSoundSlavePrims; }
  397. set { m_LoopSoundSlavePrims = value; }
  398. }
  399. // The UUID for the Region this Object is in.
  400. public UUID RegionUUID
  401. {
  402. get
  403. {
  404. if (m_scene != null)
  405. {
  406. return m_scene.RegionInfo.RegionID;
  407. }
  408. return UUID.Zero;
  409. }
  410. }
  411. #endregion
  412. #region Constructors
  413. /// <summary>
  414. /// Constructor
  415. /// </summary>
  416. public SceneObjectGroup()
  417. {
  418. }
  419. /// <summary>
  420. /// This constructor creates a SceneObjectGroup using a pre-existing SceneObjectPart.
  421. /// The original SceneObjectPart will be used rather than a copy, preserving
  422. /// its existing localID and UUID.
  423. /// </summary>
  424. public SceneObjectGroup(SceneObjectPart part)
  425. {
  426. SetRootPart(part);
  427. }
  428. /// <summary>
  429. /// Constructor. This object is added to the scene later via AttachToScene()
  430. /// </summary>
  431. public SceneObjectGroup(UUID ownerID, Vector3 pos, Quaternion rot, PrimitiveBaseShape shape)
  432. {
  433. SetRootPart(new SceneObjectPart(ownerID, shape, pos, rot, Vector3.Zero));
  434. }
  435. /// <summary>
  436. /// Constructor.
  437. /// </summary>
  438. public SceneObjectGroup(UUID ownerID, Vector3 pos, PrimitiveBaseShape shape)
  439. : this(ownerID, pos, Quaternion.Identity, shape)
  440. {
  441. }
  442. public void LoadScriptState(XmlDocument doc)
  443. {
  444. XmlNodeList nodes = doc.GetElementsByTagName("SavedScriptState");
  445. if (nodes.Count > 0)
  446. {
  447. m_savedScriptState = new Dictionary<UUID, string>();
  448. foreach (XmlNode node in nodes)
  449. {
  450. if (node.Attributes["UUID"] != null)
  451. {
  452. UUID itemid = new UUID(node.Attributes["UUID"].Value);
  453. m_savedScriptState.Add(itemid, node.InnerXml);
  454. }
  455. }
  456. }
  457. }
  458. public void SetFromItemID(UUID AssetId)
  459. {
  460. lock (m_parts)
  461. {
  462. foreach (SceneObjectPart part in m_parts.Values)
  463. {
  464. part.FromItemID = AssetId;
  465. }
  466. }
  467. }
  468. public UUID GetFromItemID()
  469. {
  470. return m_rootPart.FromItemID;
  471. }
  472. /// <summary>
  473. /// Hooks this object up to the backup event so that it is persisted to the database when the update thread executes.
  474. /// </summary>
  475. public virtual void AttachToBackup()
  476. {
  477. if (InSceneBackup)
  478. {
  479. //m_log.DebugFormat(
  480. // "[SCENE OBJECT GROUP]: Attaching object {0} {1} to scene presistence sweep", Name, UUID);
  481. if (!m_isBackedUp)
  482. m_scene.EventManager.OnBackup += ProcessBackup;
  483. m_isBackedUp = true;
  484. }
  485. }
  486. /// <summary>
  487. /// Attach this object to a scene. It will also now appear to agents.
  488. /// </summary>
  489. /// <param name="scene"></param>
  490. public void AttachToScene(Scene scene)
  491. {
  492. m_scene = scene;
  493. RegionHandle = m_scene.RegionInfo.RegionHandle;
  494. if (m_rootPart.Shape.PCode != 9 || m_rootPart.Shape.State == 0)
  495. m_rootPart.ParentID = 0;
  496. if (m_rootPart.LocalId == 0)
  497. m_rootPart.LocalId = m_scene.AllocateLocalId();
  498. lock (m_parts)
  499. {
  500. foreach (SceneObjectPart part in m_parts.Values)
  501. {
  502. if (Object.ReferenceEquals(part, m_rootPart))
  503. {
  504. continue;
  505. }
  506. if (part.LocalId == 0)
  507. {
  508. part.LocalId = m_scene.AllocateLocalId();
  509. }
  510. part.ParentID = m_rootPart.LocalId;
  511. //m_log.DebugFormat("[SCENE]: Given local id {0} to part {1}, linknum {2}, parent {3} {4}", part.LocalId, part.UUID, part.LinkNum, part.ParentID, part.ParentUUID);
  512. }
  513. }
  514. ApplyPhysics(m_scene.m_physicalPrim);
  515. // Don't trigger the update here - otherwise some client issues occur when multiple updates are scheduled
  516. // for the same object with very different properties. The caller must schedule the update.
  517. //ScheduleGroupForFullUpdate();
  518. }
  519. public Vector3 GroupScale()
  520. {
  521. Vector3 minScale = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionSize);
  522. Vector3 maxScale = Vector3.Zero;
  523. Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f);
  524. lock (m_parts)
  525. {
  526. foreach (SceneObjectPart part in m_parts.Values)
  527. {
  528. Vector3 partscale = part.Scale;
  529. Vector3 partoffset = part.OffsetPosition;
  530. minScale.X = (partscale.X + partoffset.X < minScale.X) ? partscale.X + partoffset.X : minScale.X;
  531. minScale.Y = (partscale.Y + partoffset.Y < minScale.Y) ? partscale.Y + partoffset.Y : minScale.Y;
  532. minScale.Z = (partscale.Z + partoffset.Z < minScale.Z) ? partscale.Z + partoffset.Z : minScale.Z;
  533. maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X;
  534. maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y;
  535. maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z;
  536. }
  537. }
  538. finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X;
  539. finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y;
  540. finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z;
  541. return finalScale;
  542. }
  543. public EntityIntersection TestIntersection(Ray hRay, bool frontFacesOnly, bool faceCenters)
  544. {
  545. // We got a request from the inner_scene to raytrace along the Ray hRay
  546. // We're going to check all of the prim in this group for intersection with the ray
  547. // If we get a result, we're going to find the closest result to the origin of the ray
  548. // and send back the intersection information back to the innerscene.
  549. EntityIntersection result = new EntityIntersection();
  550. lock (m_parts)
  551. {
  552. foreach (SceneObjectPart part in m_parts.Values)
  553. {
  554. // Temporary commented to stop compiler warning
  555. //Vector3 partPosition =
  556. // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z);
  557. Quaternion parentrotation = GroupRotation;
  558. // Telling the prim to raytrace.
  559. //EntityIntersection inter = part.TestIntersection(hRay, parentrotation);
  560. EntityIntersection inter = part.TestIntersectionOBB(hRay, parentrotation,frontFacesOnly, faceCenters);
  561. // This may need to be updated to the maximum draw distance possible..
  562. // We might (and probably will) be checking for prim creation from other sims
  563. // when the camera crosses the border.
  564. float idist = Constants.RegionSize;
  565. if (inter.HitTF)
  566. {
  567. // We need to find the closest prim to return to the testcaller along the ray
  568. if (inter.distance < idist)
  569. {
  570. result.HitTF = true;
  571. result.ipoint = inter.ipoint;
  572. result.obj = part;
  573. result.normal = inter.normal;
  574. result.distance = inter.distance;
  575. }
  576. }
  577. }
  578. }
  579. return result;
  580. }
  581. /// <summary>
  582. /// Gets a vector representing the size of the bounding box containing all the prims in the group
  583. /// Treats all prims as rectangular, so no shape (cut etc) is taken into account
  584. /// offsetHeight is the offset in the Z axis from the centre of the bounding box to the centre of the root prim
  585. /// </summary>
  586. /// <returns></returns>
  587. public void GetAxisAlignedBoundingBoxRaw(out float minX, out float maxX, out float minY, out float maxY, out float minZ, out float maxZ)
  588. {
  589. maxX = -256f;
  590. maxY = -256f;
  591. maxZ = -256f;
  592. minX = 256f;
  593. minY = 256f;
  594. minZ = 8192f;
  595. lock(m_parts)
  596. {
  597. foreach (SceneObjectPart part in m_parts.Values)
  598. {
  599. Vector3 worldPos = part.GetWorldPosition();
  600. Vector3 offset = worldPos - AbsolutePosition;
  601. Quaternion worldRot;
  602. if (part.ParentID == 0)
  603. {
  604. worldRot = part.RotationOffset;
  605. }
  606. else
  607. {
  608. worldRot = part.GetWorldRotation();
  609. }
  610. Vector3 frontTopLeft;
  611. Vector3 frontTopRight;
  612. Vector3 frontBottomLeft;
  613. Vector3 frontBottomRight;
  614. Vector3 backTopLeft;
  615. Vector3 backTopRight;
  616. Vector3 backBottomLeft;
  617. Vector3 backBottomRight;
  618. // Vector3[] corners = new Vector3[8];
  619. Vector3 orig = Vector3.Zero;
  620. frontTopLeft.X = orig.X - (part.Scale.X / 2);
  621. frontTopLeft.Y = orig.Y - (part.Scale.Y / 2);
  622. frontTopLeft.Z = orig.Z + (part.Scale.Z / 2);
  623. frontTopRight.X = orig.X - (part.Scale.X / 2);
  624. frontTopRight.Y = orig.Y + (part.Scale.Y / 2);
  625. frontTopRight.Z = orig.Z + (part.Scale.Z / 2);
  626. frontBottomLeft.X = orig.X - (part.Scale.X / 2);
  627. frontBottomLeft.Y = orig.Y - (part.Scale.Y / 2);
  628. frontBottomLeft.Z = orig.Z - (part.Scale.Z / 2);
  629. frontBottomRight.X = orig.X - (part.Scale.X / 2);
  630. frontBottomRight.Y = orig.Y + (part.Scale.Y / 2);
  631. frontBottomRight.Z = orig.Z - (part.Scale.Z / 2);
  632. backTopLeft.X = orig.X + (part.Scale.X / 2);
  633. backTopLeft.Y = orig.Y - (part.Scale.Y / 2);
  634. backTopLeft.Z = orig.Z + (part.Scale.Z / 2);
  635. backTopRight.X = orig.X + (part.Scale.X / 2);
  636. backTopRight.Y = orig.Y + (part.Scale.Y / 2);
  637. backTopRight.Z = orig.Z + (part.Scale.Z / 2);
  638. backBottomLeft.X = orig.X + (part.Scale.X / 2);
  639. backBottomLeft.Y = orig.Y - (part.Scale.Y / 2);
  640. backBottomLeft.Z = orig.Z - (part.Scale.Z / 2);
  641. backBottomRight.X = orig.X + (part.Scale.X / 2);
  642. backBottomRight.Y = orig.Y + (part.Scale.Y / 2);
  643. backBottomRight.Z = orig.Z - (part.Scale.Z / 2);
  644. //m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z);
  645. //m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z);
  646. //m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z);
  647. //m_log.InfoFormat("pre corner 4 is {0} {1} {2}", frontBottomLeft.X, frontBottomLeft.Y, frontBottomLeft.Z);
  648. //m_log.InfoFormat("pre corner 5 is {0} {1} {2}", backTopLeft.X, backTopLeft.Y, backTopLeft.Z);
  649. //m_log.InfoFormat("pre corner 6 is {0} {1} {2}", backTopRight.X, backTopRight.Y, backTopRight.Z);
  650. //m_log.InfoFormat("pre corner 7 is {0} {1} {2}", backBottomRight.X, backBottomRight.Y, backBottomRight.Z);
  651. //m_log.InfoFormat("pre corner 8 is {0} {1} {2}", backBottomLeft.X, backBottomLeft.Y, backBottomLeft.Z);
  652. //for (int i = 0; i < 8; i++)
  653. //{
  654. // corners[i] = corners[i] * worldRot;
  655. // corners[i] += offset;
  656. // if (corners[i].X > maxX)
  657. // maxX = corners[i].X;
  658. // if (corners[i].X < minX)
  659. // minX = corners[i].X;
  660. // if (corners[i].Y > maxY)
  661. // maxY = corners[i].Y;
  662. // if (corners[i].Y < minY)
  663. // minY = corners[i].Y;
  664. // if (corners[i].Z > maxZ)
  665. // maxZ = corners[i].Y;
  666. // if (corners[i].Z < minZ)
  667. // minZ = corners[i].Z;
  668. //}
  669. frontTopLeft = frontTopLeft * worldRot;
  670. frontTopRight = frontTopRight * worldRot;
  671. frontBottomLeft = frontBottomLeft * worldRot;
  672. frontBottomRight = frontBottomRight * worldRot;
  673. backBottomLeft = backBottomLeft * worldRot;
  674. backBottomRight = backBottomRight * worldRot;
  675. backTopLeft = backTopLeft * worldRot;
  676. backTopRight = backTopRight * worldRot;
  677. frontTopLeft += offset;
  678. frontTopRight += offset;
  679. frontBottomLeft += offset;
  680. frontBottomRight += offset;
  681. backBottomLeft += offset;
  682. backBottomRight += offset;
  683. backTopLeft += offset;
  684. backTopRight += offset;
  685. //m_log.InfoFormat("corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z);
  686. //m_log.InfoFormat("corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z);
  687. //m_log.InfoFormat("corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z);
  688. //m_log.InfoFormat("corner 4 is {0} {1} {2}", frontBottomLeft.X, frontBottomLeft.Y, frontBottomLeft.Z);
  689. //m_log.InfoFormat("corner 5 is {0} {1} {2}", backTopLeft.X, backTopLeft.Y, backTopLeft.Z);
  690. //m_log.InfoFormat("corner 6 is {0} {1} {2}", backTopRight.X, backTopRight.Y, backTopRight.Z);
  691. //m_log.InfoFormat("corner 7 is {0} {1} {2}", backBottomRight.X, backBottomRight.Y, backBottomRight.Z);
  692. //m_log.InfoFormat("corner 8 is {0} {1} {2}", backBottomLeft.X, backBottomLeft.Y, backBottomLeft.Z);
  693. if (frontTopRight.X > maxX)
  694. maxX = frontTopRight.X;
  695. if (frontTopLeft.X > maxX)
  696. maxX = frontTopLeft.X;
  697. if (frontBottomRight.X > maxX)
  698. maxX = frontBottomRight.X;
  699. if (frontBottomLeft.X > maxX)
  700. maxX = frontBottomLeft.X;
  701. if (backTopRight.X > maxX)
  702. maxX = backTopRight.X;
  703. if (backTopLeft.X > maxX)
  704. maxX = backTopLeft.X;
  705. if (backBottomRight.X > maxX)
  706. maxX = backBottomRight.X;
  707. if (backBottomLeft.X > maxX)
  708. maxX = backBottomLeft.X;
  709. if (frontTopRight.X < minX)
  710. minX = frontTopRight.X;
  711. if (frontTopLeft.X < minX)
  712. minX = frontTopLeft.X;
  713. if (frontBottomRight.X < minX)
  714. minX = frontBottomRight.X;
  715. if (frontBottomLeft.X < minX)
  716. minX = frontBottomLeft.X;
  717. if (backTopRight.X < minX)
  718. minX = backTopRight.X;
  719. if (backTopLeft.X < minX)
  720. minX = backTopLeft.X;
  721. if (backBottomRight.X < minX)
  722. minX = backBottomRight.X;
  723. if (backBottomLeft.X < minX)
  724. minX = backBottomLeft.X;
  725. //
  726. if (frontTopRight.Y > maxY)
  727. maxY = frontTopRight.Y;
  728. if (frontTopLeft.Y > maxY)
  729. maxY = frontTopLeft.Y;
  730. if (frontBottomRight.Y > maxY)
  731. maxY = frontBottomRight.Y;
  732. if (frontBottomLeft.Y > maxY)
  733. maxY = frontBottomLeft.Y;
  734. if (backTopRight.Y > maxY)
  735. maxY = backTopRight.Y;
  736. if (backTopLeft.Y > maxY)
  737. maxY = backTopLeft.Y;
  738. if (backBottomRight.Y > maxY)
  739. maxY = backBottomRight.Y;
  740. if (backBottomLeft.Y > maxY)
  741. maxY = backBottomLeft.Y;
  742. if (frontTopRight.Y < minY)
  743. minY = frontTopRight.Y;
  744. if (frontTopLeft.Y < minY)
  745. minY = frontTopLeft.Y;
  746. if (frontBottomRight.Y < minY)
  747. minY = frontBottomRight.Y;
  748. if (frontBottomLeft.Y < minY)
  749. minY = frontBottomLeft.Y;
  750. if (backTopRight.Y < minY)
  751. minY = backTopRight.Y;
  752. if (backTopLeft.Y < minY)
  753. minY = backTopLeft.Y;
  754. if (backBottomRight.Y < minY)
  755. minY = backBottomRight.Y;
  756. if (backBottomLeft.Y < minY)
  757. minY = backBottomLeft.Y;
  758. //
  759. if (frontTopRight.Z > maxZ)
  760. maxZ = frontTopRight.Z;
  761. if (frontTopLeft.Z > maxZ)
  762. maxZ = frontTopLeft.Z;
  763. if (frontBottomRight.Z > maxZ)
  764. maxZ = frontBottomRight.Z;
  765. if (frontBottomLeft.Z > maxZ)
  766. maxZ = frontBottomLeft.Z;
  767. if (backTopRight.Z > maxZ)
  768. maxZ = backTopRight.Z;
  769. if (backTopLeft.Z > maxZ)
  770. maxZ = backTopLeft.Z;
  771. if (backBottomRight.Z > maxZ)
  772. maxZ = backBottomRight.Z;
  773. if (backBottomLeft.Z > maxZ)
  774. maxZ = backBottomLeft.Z;
  775. if (frontTopRight.Z < minZ)
  776. minZ = frontTopRight.Z;
  777. if (frontTopLeft.Z < minZ)
  778. minZ = frontTopLeft.Z;
  779. if (frontBottomRight.Z < minZ)
  780. minZ = frontBottomRight.Z;
  781. if (frontBottomLeft.Z < minZ)
  782. minZ = frontBottomLeft.Z;
  783. if (backTopRight.Z < minZ)
  784. minZ = backTopRight.Z;
  785. if (backTopLeft.Z < minZ)
  786. minZ = backTopLeft.Z;
  787. if (backBottomRight.Z < minZ)
  788. minZ = backBottomRight.Z;
  789. if (backBottomLeft.Z < minZ)
  790. minZ = backBottomLeft.Z;
  791. }
  792. }
  793. }
  794. public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight)
  795. {
  796. float minX;
  797. float maxX;
  798. float minY;
  799. float maxY;
  800. float minZ;
  801. float maxZ;
  802. GetAxisAlignedBoundingBoxRaw(out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
  803. Vector3 boundingBox = new Vector3(maxX - minX, maxY - minY, maxZ - minZ);
  804. offsetHeight = 0;
  805. float lower = (minZ * -1);
  806. if (lower > maxZ)
  807. {
  808. offsetHeight = lower - (boundingBox.Z / 2);
  809. }
  810. else if (maxZ > lower)
  811. {
  812. offsetHeight = maxZ - (boundingBox.Z / 2);
  813. offsetHeight *= -1;
  814. }
  815. // m_log.InfoFormat("BoundingBox is {0} , {1} , {2} ", boundingBox.X, boundingBox.Y, boundingBox.Z);
  816. return boundingBox;
  817. }
  818. #endregion
  819. public void SaveScriptedState(XmlTextWriter writer)
  820. {
  821. XmlDocument doc = new XmlDocument();
  822. Dictionary<UUID,string> states = new Dictionary<UUID,string>();
  823. // Capture script state while holding the lock
  824. lock (m_parts)
  825. {
  826. foreach (SceneObjectPart part in m_parts.Values)
  827. {
  828. Dictionary<UUID,string> pstates = part.Inventory.GetScriptStates();
  829. foreach (UUID itemid in pstates.Keys)
  830. {
  831. states.Add(itemid, pstates[itemid]);
  832. }
  833. }
  834. }
  835. if (states.Count > 0)
  836. {
  837. // Now generate the necessary XML wrappings
  838. writer.WriteStartElement(String.Empty, "GroupScriptStates", String.Empty);
  839. foreach (UUID itemid in states.Keys)
  840. {
  841. doc.LoadXml(states[itemid]);
  842. writer.WriteStartElement(String.Empty, "SavedScriptState", String.Empty);
  843. writer.WriteAttributeString(String.Empty, "UUID", String.Empty, itemid.ToString());
  844. writer.WriteRaw(doc.DocumentElement.OuterXml); // Writes ScriptState element
  845. writer.WriteEndElement(); // End of SavedScriptState
  846. }
  847. writer.WriteEndElement(); // End of GroupScriptStates
  848. }
  849. }
  850. public byte GetAttachmentPoint()
  851. {
  852. return m_rootPart.Shape.State;
  853. }
  854. public void ClearPartAttachmentData()
  855. {
  856. SetAttachmentPoint((Byte)0);
  857. }
  858. public void DetachToGround()
  859. {
  860. ScenePresence avatar = m_scene.GetScenePresence(m_rootPart.AttachedAvatar);
  861. if (avatar == null)
  862. return;
  863. avatar.RemoveAttachment(this);
  864. Vector3 detachedpos = new Vector3(127f,127f,127f);
  865. if (avatar == null)
  866. return;
  867. detachedpos = avatar.AbsolutePosition;
  868. RootPart.FromItemID = UUID.Zero;
  869. AbsolutePosition = detachedpos;
  870. m_rootPart.AttachedAvatar = UUID.Zero;
  871. //Anakin Lohner bug #3839
  872. lock (m_parts)
  873. {
  874. foreach (SceneObjectPart p in m_parts.Values)
  875. {
  876. p.AttachedAvatar = UUID.Zero;
  877. }
  878. }
  879. m_rootPart.SetParentLocalId(0);
  880. SetAttachmentPoint((byte)0);
  881. m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_scene.m_physicalPrim);
  882. HasGroupChanged = true;
  883. RootPart.Rezzed = DateTime.Now;
  884. RootPart.RemFlag(PrimFlags.TemporaryOnRez);
  885. AttachToBackup();
  886. m_scene.EventManager.TriggerParcelPrimCountTainted();
  887. m_rootPart.ScheduleFullUpdate();
  888. m_rootPart.ClearUndoState();
  889. }
  890. public void DetachToInventoryPrep()
  891. {
  892. ScenePresence avatar = m_scene.GetScenePresence(m_rootPart.AttachedAvatar);
  893. //Vector3 detachedpos = new Vector3(127f, 127f, 127f);
  894. if (avatar != null)
  895. {
  896. //detachedpos = avatar.AbsolutePosition;
  897. avatar.RemoveAttachment(this);
  898. }
  899. m_rootPart.AttachedAvatar = UUID.Zero;
  900. //Anakin Lohner bug #3839
  901. lock (m_parts)
  902. {
  903. foreach (SceneObjectPart p in m_parts.Values)
  904. {
  905. p.AttachedAvatar = UUID.Zero;
  906. }
  907. }
  908. m_rootPart.SetParentLocalId(0);
  909. //m_rootPart.SetAttachmentPoint((byte)0);
  910. m_rootPart.IsAttachment = false;
  911. AbsolutePosition = m_rootPart.AttachedPos;
  912. //m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_scene.m_physicalPrim);
  913. //AttachToBackup();
  914. //m_rootPart.ScheduleFullUpdate();
  915. }
  916. /// <summary>
  917. ///
  918. /// </summary>
  919. /// <param name="part"></param>
  920. private void SetPartAsNonRoot(SceneObjectPart part)
  921. {
  922. part.ParentID = m_rootPart.LocalId;
  923. part.ClearUndoState();
  924. }
  925. public override void UpdateMovement()
  926. {
  927. lock (m_parts)
  928. {
  929. foreach (SceneObjectPart part in m_parts.Values)
  930. {
  931. part.UpdateMovement();
  932. }
  933. }
  934. }
  935. public ushort GetTimeDilation()
  936. {
  937. return Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f);
  938. }
  939. /// <summary>
  940. /// Added as a way for the storage provider to reset the scene,
  941. /// most likely a better way to do this sort of thing but for now...
  942. /// </summary>
  943. /// <param name="scene"></param>
  944. public void SetScene(Scene scene)
  945. {
  946. m_scene = scene;
  947. }
  948. /// <summary>
  949. /// Set a part to act as the root part for this scene object
  950. /// </summary>
  951. /// <param name="part"></param>
  952. public void SetRootPart(SceneObjectPart part)
  953. {
  954. if (part == null)
  955. throw new ArgumentNullException("Cannot give SceneObjectGroup a null root SceneObjectPart");
  956. part.SetParent(this);
  957. m_rootPart = part;
  958. if (!IsAttachment)
  959. part.ParentID = 0;
  960. part.LinkNum = 0;
  961. lock (m_parts)
  962. m_parts.Add(m_rootPart.UUID, m_rootPart);
  963. }
  964. /// <summary>
  965. /// Add a new part to this scene object. The part must already be correctly configured.
  966. /// </summary>
  967. /// <param name="part"></param>
  968. public void AddPart(SceneObjectPart part)
  969. {
  970. lock (m_parts)
  971. {
  972. part.SetParent(this);
  973. m_parts.Add(part.UUID, part);
  974. part.LinkNum = m_parts.Count;
  975. if (part.LinkNum == 2 && RootPart != null)
  976. RootPart.LinkNum = 1;
  977. }
  978. }
  979. /// <summary>
  980. /// Make sure that every non root part has the proper parent root part local id
  981. /// </summary>
  982. private void UpdateParentIDs()
  983. {
  984. lock (m_parts)
  985. {
  986. foreach (SceneObjectPart part in m_parts.Values)
  987. {
  988. if (part.UUID != m_rootPart.UUID)
  989. {
  990. part.ParentID = m_rootPart.LocalId;
  991. }
  992. }
  993. }
  994. }
  995. public void RegenerateFullIDs()
  996. {
  997. lock (m_parts)
  998. {
  999. foreach (SceneObjectPart part in m_parts.Values)
  1000. {
  1001. part.UUID = UUID.Random();
  1002. }
  1003. }
  1004. }
  1005. // helper provided for parts.
  1006. public int GetSceneMaxUndo()
  1007. {
  1008. if (m_scene != null)
  1009. return m_scene.MaxUndoCount;
  1010. return 5;
  1011. }
  1012. // justincc: I don't believe this hack is needed any longer, especially since the physics
  1013. // parts of set AbsolutePosition were already commented out. By changing HasGroupChanged to false
  1014. // this method was preventing proper reload of scene objects.
  1015. // dahlia: I had to uncomment it, without it meshing was failing on some prims and objects
  1016. // at region startup
  1017. // teravus: After this was removed from the linking algorithm, Linked prims no longer collided
  1018. // properly when non-physical if they havn't been moved. This breaks ALL builds.
  1019. // see: http://opensimulator.org/mantis/view.php?id=3108
  1020. // Here's the deal, this is ABSOLUTELY CRITICAL so the physics scene gets the update about the
  1021. // position of linkset prims. IF YOU CHANGE THIS, YOU MUST TEST colliding with just linked and
  1022. // unmoved prims! As soon as you move a Prim/group, it will collide properly because Absolute
  1023. // Position has been set!
  1024. public void ResetChildPrimPhysicsPositions()
  1025. {
  1026. AbsolutePosition = AbsolutePosition; // could someone in the know please explain how this works?
  1027. // teravus: AbsolutePosition is NOT a normal property!
  1028. // the code in the getter of AbsolutePosition is significantly different then the code in the setter!
  1029. }
  1030. public UUID GetPartsFullID(uint localID)
  1031. {
  1032. SceneObjectPart part = GetChildPart(localID);
  1033. if (part != null)
  1034. {
  1035. return part.UUID;
  1036. }
  1037. return UUID.Zero;
  1038. }
  1039. public void ObjectGrabHandler(uint localId, Vector3 offsetPos, IClientAPI remoteClient)
  1040. {
  1041. if (m_rootPart.LocalId == localId)
  1042. {
  1043. OnGrabGroup(offsetPos, remoteClient);
  1044. }
  1045. else
  1046. {
  1047. SceneObjectPart part = GetChildPart(localId);
  1048. OnGrabPart(part, offsetPos, remoteClient);
  1049. }
  1050. }
  1051. public virtual void OnGrabPart(SceneObjectPart part, Vector3 offsetPos, IClientAPI remoteClient)
  1052. {
  1053. part.StoreUndoState();
  1054. part.OnGrab(offsetPos, remoteClient);
  1055. }
  1056. public virtual void OnGrabGroup(Vector3 offsetPos, IClientAPI remoteClient)
  1057. {
  1058. m_scene.EventManager.TriggerGroupGrab(UUID, offsetPos, remoteClient.AgentId);
  1059. }
  1060. /// <summary>
  1061. /// Delete this group from its scene.
  1062. /// </summary>
  1063. ///
  1064. /// This only handles the in-world consequences of deletion (e.g. any avatars sitting on it are forcibly stood
  1065. /// up and all avatars receive notification of its removal. Removal of the scene object from database backup
  1066. /// must be handled by the caller.
  1067. ///
  1068. /// <param name="silent">If true then deletion is not broadcast to clients</param>
  1069. public void DeleteGroup(bool silent)
  1070. {
  1071. lock (m_parts)
  1072. {
  1073. foreach (SceneObjectPart part in m_parts.Values)
  1074. {
  1075. // part.Inventory.RemoveScriptInstances();
  1076. Scene.ForEachScenePresence(delegate(ScenePresence avatar)
  1077. {
  1078. if (avatar.ParentID == LocalId)
  1079. {
  1080. avatar.StandUp();
  1081. }
  1082. if (!silent)
  1083. {
  1084. part.UpdateFlag = 0;
  1085. if (part == m_rootPart)
  1086. avatar.ControllingClient.SendKillObject(m_regionHandle, part.LocalId);
  1087. }
  1088. });
  1089. }
  1090. }
  1091. }
  1092. public void AddScriptLPS(int count)
  1093. {
  1094. if (scriptScore + count >= float.MaxValue - count)
  1095. scriptScore = 0;
  1096. scriptScore += (float)count;
  1097. SceneGraph d = m_scene.SceneGraph;
  1098. d.AddToScriptLPS(count);
  1099. }
  1100. public void AddActiveScriptCount(int count)
  1101. {
  1102. SceneGraph d = m_scene.SceneGraph;
  1103. d.AddActiveScripts(count);
  1104. }
  1105. public void aggregateScriptEvents()
  1106. {
  1107. PrimFlags objectflagupdate = (PrimFlags)RootPart.GetEffectiveObjectFlags();
  1108. scriptEvents aggregateScriptEvents = 0;
  1109. lock (m_parts)
  1110. {
  1111. foreach (SceneObjectPart part in m_parts.Values)
  1112. {
  1113. if (part == null)
  1114. continue;
  1115. if (part != RootPart)
  1116. part.Flags = objectflagupdate;
  1117. aggregateScriptEvents |= part.AggregateScriptEvents;
  1118. }
  1119. }
  1120. m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0);
  1121. m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0);
  1122. if (!m_scriptListens_atTarget && !m_scriptListens_notAtTarget)
  1123. {
  1124. lock (m_targets)
  1125. m_targets.Clear();
  1126. m_scene.RemoveGroupTarget(this);
  1127. }
  1128. m_scriptListens_atRotTarget = ((aggregateScriptEvents & scriptEvents.at_rot_target) != 0);
  1129. m_scriptListens_notAtRotTarget = ((aggregateScriptEvents & scriptEvents.not_at_rot_target) != 0);
  1130. if (!m_scriptListens_atRotTarget && !m_scriptListens_notAtRotTarget)
  1131. {
  1132. lock (m_rotTargets)
  1133. m_rotTargets.Clear();
  1134. m_scene.RemoveGroupTarget(this);
  1135. }
  1136. ScheduleGroupForFullUpdate();
  1137. }
  1138. public void SetText(string text, Vector3 color, double alpha)
  1139. {
  1140. Color = Color.FromArgb(0xff - (int) (alpha * 0xff),
  1141. (int) (color.X * 0xff),
  1142. (int) (color.Y * 0xff),
  1143. (int) (color.Z * 0xff));
  1144. Text = text;
  1145. HasGroupChanged = true;
  1146. m_rootPart.ScheduleFullUpdate();
  1147. }
  1148. /// <summary>
  1149. /// Apply physics to this group
  1150. /// </summary>
  1151. /// <param name="m_physicalPrim"></param>
  1152. public void ApplyPhysics(bool m_physicalPrim)
  1153. {
  1154. lock (m_parts)
  1155. {
  1156. if (m_parts.Count > 1)
  1157. {
  1158. m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
  1159. foreach (SceneObjectPart part in m_parts.Values)
  1160. {
  1161. if (part.LocalId != m_rootPart.LocalId)
  1162. {
  1163. part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim);
  1164. }
  1165. }
  1166. // Hack to get the physics scene geometries in the right spot
  1167. ResetChildPrimPhysicsPositions();
  1168. }
  1169. else
  1170. {
  1171. m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
  1172. }
  1173. }
  1174. }
  1175. public void SetOwnerId(UUID userId)
  1176. {
  1177. ForEachPart(delegate(SceneObjectPart part) { part.OwnerID = userId; });
  1178. }
  1179. public void ForEachPart(Action<SceneObjectPart> whatToDo)
  1180. {
  1181. lock (m_parts)
  1182. {
  1183. foreach (SceneObjectPart part in m_parts.Values)
  1184. {
  1185. whatToDo(part);
  1186. }
  1187. }
  1188. }
  1189. #region Events
  1190. /// <summary>
  1191. /// Processes backup.
  1192. /// </summary>
  1193. /// <param name="datastore"></param>
  1194. public virtual void ProcessBackup(IRegionDataStore datastore, bool forcedBackup)
  1195. {
  1196. if (!m_isBackedUp)
  1197. {
  1198. // m_log.DebugFormat(
  1199. // "[WATER WARS]: Ignoring backup of {0} {1} since object is not marked to be backed up", Name, UUID);
  1200. return;
  1201. }
  1202. if (IsDeleted || UUID == UUID.Zero)
  1203. {
  1204. // m_log.DebugFormat(
  1205. // "[WATER WARS]: Ignoring backup of {0} {1} since object is marked as already deleted", Name, UUID);
  1206. return;
  1207. }
  1208. // Since this is the top of the section of call stack for backing up a particular scene object, don't let
  1209. // any exception propogate upwards.
  1210. try
  1211. {
  1212. if (!m_scene.ShuttingDown) // if shutting down then there will be nothing to handle the return so leave till next restart
  1213. {
  1214. ILandObject parcel = m_scene.LandChannel.GetLandObject(
  1215. m_rootPart.GroupPosition.X, m_rootPart.GroupPosition.Y);
  1216. if (parcel != null && parcel.LandData != null &&
  1217. parcel.LandData.OtherCleanTime != 0)
  1218. {
  1219. if (parcel.LandData.OwnerID != OwnerID &&
  1220. (parcel.LandData.GroupID != GroupID ||
  1221. parcel.LandData.GroupID == UUID.Zero))
  1222. {
  1223. if ((DateTime.UtcNow - RootPart.Rezzed).TotalMinutes >
  1224. parcel.LandData.OtherCleanTime)
  1225. {
  1226. DetachFromBackup();
  1227. m_log.InfoFormat("[SCENE]: Returning object {0} due to parcel auto return", RootPart.UUID.ToString());
  1228. m_scene.AddReturn(OwnerID, Name, AbsolutePosition, "parcel auto return");
  1229. m_scene.DeRezObject(null, RootPart.LocalId,
  1230. RootPart.GroupID, DeRezAction.Return, UUID.Zero);
  1231. return;
  1232. }
  1233. }
  1234. }
  1235. }
  1236. if (HasGroupChanged)
  1237. {
  1238. // don't backup while it's selected or you're asking for changes mid stream.
  1239. if (isTimeToPersist() || forcedBackup)
  1240. {
  1241. m_log.DebugFormat(
  1242. "[SCENE]: Storing {0}, {1} in {2}",
  1243. Name, UUID, m_scene.RegionInfo.RegionName);
  1244. SceneObjectGroup backup_group = Copy(false);
  1245. backup_group.RootPart.Velocity = RootPart.Velocity;
  1246. backup_group.RootPart.Acceleration = RootPart.Acceleration;
  1247. backup_group.RootPart.AngularVelocity = RootPart.AngularVelocity;
  1248. backup_group.RootPart.ParticleSystem = RootPart.ParticleSystem;
  1249. HasGroupChanged = false;
  1250. m_scene.EventManager.TriggerOnSceneObjectPreSave(backup_group, this);
  1251. datastore.StoreObject(backup_group, m_scene.RegionInfo.RegionID);
  1252. backup_group.ForEachPart(delegate(SceneObjectPart part)
  1253. {
  1254. part.Inventory.ProcessInventoryBackup(datastore);
  1255. });
  1256. backup_group = null;
  1257. }
  1258. // else
  1259. // {
  1260. // m_log.DebugFormat(
  1261. // "[SCENE]: Did not update persistence of object {0} {1}, selected = {2}",
  1262. // Name, UUID, IsSelected);
  1263. // }
  1264. }
  1265. }
  1266. catch (Exception e)
  1267. {
  1268. m_log.ErrorFormat(
  1269. "[SCENE]: Storing of {0}, {1} in {2} failed with exception {3}{4}",
  1270. Name, UUID, m_scene.RegionInfo.RegionName, e.Message, e.StackTrace);
  1271. }
  1272. }
  1273. #endregion
  1274. public void SendFullUpdateToClient(IClientAPI remoteClient)
  1275. {
  1276. RootPart.SendFullUpdate(
  1277. remoteClient, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID));
  1278. lock (m_parts)
  1279. {
  1280. foreach (SceneObjectPart part in m_parts.Values)
  1281. {
  1282. if (part != RootPart)
  1283. part.SendFullUpdate(
  1284. remoteClient, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID));
  1285. }
  1286. }
  1287. }
  1288. #region Copying
  1289. /// <summary>
  1290. /// Duplicates this object, including operations such as physics set up and attaching to the backup event.
  1291. /// </summary>
  1292. /// <param name="userExposed">True if the duplicate will immediately be in the scene, false otherwise</param>
  1293. /// <returns></returns>
  1294. public SceneObjectGroup Copy(bool userExposed)
  1295. {
  1296. SceneObjectGroup dupe = (SceneObjectGroup)MemberwiseClone();
  1297. dupe.m_isBackedUp = false;
  1298. dupe.m_parts = new Dictionary<UUID, SceneObjectPart>();
  1299. // Warning, The following code related to previousAttachmentStatus is needed so that clones of
  1300. // attachments do not bordercross while they're being duplicated. This is hacktastic!
  1301. // Normally, setting AbsolutePosition will bordercross a prim if it's outside the region!
  1302. // unless IsAttachment is true!, so to prevent border crossing, we save it's attachment state
  1303. // (which should be false anyway) set it as an Attachment and then set it's Absolute Position,
  1304. // then restore it's attachment state
  1305. // This is only necessary when userExposed is false!
  1306. bool previousAttachmentStatus = dupe.RootPart.IsAttachment;
  1307. if (!userExposed)
  1308. dupe.RootPart.IsAttachment = true;
  1309. dupe.AbsolutePosition = new Vector3(AbsolutePosition.X, AbsolutePosition.Y, AbsolutePosition.Z);
  1310. if (!userExposed)
  1311. {
  1312. dupe.RootPart.IsAttachment = previousAttachmentStatus;
  1313. }
  1314. dupe.CopyRootPart(m_rootPart, OwnerID, GroupID, userExposed);
  1315. dupe.m_rootPart.LinkNum = m_rootPart.LinkNum;
  1316. if (userExposed)
  1317. dupe.m_rootPart.TrimPermissions();
  1318. List<SceneObjectPart> partList;
  1319. lock (m_parts)
  1320. {
  1321. partList = new List<SceneObjectPart>(m_parts.Values);
  1322. }
  1323. partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2)
  1324. {
  1325. return p1.LinkNum.CompareTo(p2.LinkNum);
  1326. }
  1327. );
  1328. foreach (SceneObjectPart part in partList)
  1329. {
  1330. if (part.UUID != m_rootPart.UUID)
  1331. {
  1332. SceneObjectPart newPart = dupe.CopyPart(part, OwnerID, GroupID, userExposed);
  1333. newPart.LinkNum = part.LinkNum;
  1334. }
  1335. // Need to duplicate the physics actor as well
  1336. if (part.PhysActor != null && userExposed)
  1337. {
  1338. PrimitiveBaseShape pbs = part.Shape;
  1339. part.PhysActor
  1340. = m_scene.PhysicsScene.AddPrimShape(
  1341. part.Name,
  1342. pbs,
  1343. part.AbsolutePosition,
  1344. part.Scale,
  1345. part.RotationOffset,
  1346. part.PhysActor.IsPhysical);
  1347. part.PhysActor.LocalID = part.LocalId;
  1348. part.DoPhysicsPropertyUpdate(part.PhysActor.IsPhysical, true);
  1349. }
  1350. }
  1351. if (userExposed)
  1352. {
  1353. dupe.UpdateParentIDs();
  1354. dupe.HasGroupChanged = true;
  1355. dupe.AttachToBackup();
  1356. ScheduleGroupForFullUpdate();
  1357. }
  1358. return dupe;
  1359. }
  1360. /// <summary>
  1361. /// Copy the given part as the root part of this scene object.
  1362. /// </summary>
  1363. /// <param name="part"></param>
  1364. /// <param name="cAgentID"></param>
  1365. /// <param name="cGroupID"></param>
  1366. public void CopyRootPart(SceneObjectPart part, UUID cAgentID, UUID cGroupID, bool userExposed)
  1367. {
  1368. SetRootPart(part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, 0, userExposed));
  1369. }
  1370. public void ScriptSetPhysicsStatus(bool UsePhysics)
  1371. {
  1372. bool IsTemporary = ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0);
  1373. bool IsPhantom = ((RootPart.Flags & PrimFlags.Phantom) != 0);
  1374. bool IsVolumeDetect = RootPart.VolumeDetectActive;
  1375. UpdatePrimFlags(RootPart.LocalId, UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect);
  1376. }
  1377. public void ScriptSetTemporaryStatus(bool TemporaryStatus)
  1378. {
  1379. bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0);
  1380. bool IsPhantom = ((RootPart.Flags & PrimFlags.Phantom) != 0);
  1381. bool IsVolumeDetect = RootPart.VolumeDetectActive;
  1382. UpdatePrimFlags(RootPart.LocalId, UsePhysics, TemporaryStatus, IsPhantom, IsVolumeDetect);
  1383. }
  1384. public void ScriptSetPhantomStatus(bool PhantomStatus)
  1385. {
  1386. bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0);
  1387. bool IsTemporary = ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0);
  1388. bool IsVolumeDetect = RootPart.VolumeDetectActive;
  1389. UpdatePrimFlags(RootPart.LocalId, UsePhysics, IsTemporary, PhantomStatus, IsVolumeDetect);
  1390. }
  1391. public void ScriptSetVolumeDetect(bool VDStatus)
  1392. {
  1393. bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0);
  1394. bool IsTemporary = ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0);
  1395. bool IsPhantom = ((RootPart.Flags & PrimFlags.Phantom) != 0);
  1396. UpdatePrimFlags(RootPart.LocalId, UsePhysics, IsTemporary, IsPhantom, VDStatus);
  1397. /*
  1398. ScriptSetPhantomStatus(false); // What ever it was before, now it's not phantom anymore
  1399. if (PhysActor != null) // Should always be the case now
  1400. {
  1401. PhysActor.SetVolumeDetect(param);
  1402. }
  1403. if (param != 0)
  1404. AddFlag(PrimFlags.Phantom);
  1405. ScheduleFullUpdate();
  1406. */
  1407. }
  1408. public void applyImpulse(Vector3 impulse)
  1409. {
  1410. // We check if rootpart is null here because scripts don't delete if you delete the host.
  1411. // This means that unfortunately, we can pass a null physics actor to Simulate!
  1412. // Make sure we don't do that!
  1413. SceneObjectPart rootpart = m_rootPart;
  1414. if (rootpart != null)
  1415. {
  1416. if (IsAttachment)
  1417. {
  1418. ScenePresence avatar = m_scene.GetScenePresence(rootpart.AttachedAvatar);
  1419. if (avatar != null)
  1420. {
  1421. avatar.PushForce(impulse);
  1422. }
  1423. }
  1424. else
  1425. {
  1426. if (rootpart.PhysActor != null)
  1427. {
  1428. rootpart.PhysActor.AddForce(impulse, true);
  1429. m_scene.PhysicsScene.AddPhysicsActorTaint(rootpart.PhysActor);
  1430. }
  1431. }
  1432. }
  1433. }
  1434. public void applyAngularImpulse(Vector3 impulse)
  1435. {
  1436. // We check if rootpart is null here because scripts don't delete if you delete the host.
  1437. // This means that unfortunately, we can pass a null physics actor to Simulate!
  1438. // Make sure we don't do that!
  1439. SceneObjectPart rootpart = m_rootPart;
  1440. if (rootpart != null)
  1441. {
  1442. if (rootpart.PhysActor != null)
  1443. {
  1444. if (!IsAttachment)
  1445. {
  1446. rootpart.PhysActor.AddAngularForce(impulse, true);
  1447. m_scene.PhysicsScene.AddPhysicsActorTaint(rootpart.PhysActor);
  1448. }
  1449. }
  1450. }
  1451. }
  1452. public void setAngularImpulse(Vector3 impulse)
  1453. {
  1454. // We check if rootpart is null here because scripts don't delete if you delete the host.
  1455. // This means that unfortunately, we can pass a null physics actor to Simulate!
  1456. // Make sure we don't do that!
  1457. SceneObjectPart rootpart = m_rootPart;
  1458. if (rootpart != null)
  1459. {
  1460. if (rootpart.PhysActor != null)
  1461. {
  1462. if (!IsAttachment)
  1463. {
  1464. rootpart.PhysActor.Torque = impulse;
  1465. m_scene.PhysicsScene.AddPhysicsActorTaint(rootpart.PhysActor);
  1466. }
  1467. }
  1468. }
  1469. }
  1470. public Vector3 GetTorque()
  1471. {
  1472. // We check if rootpart is null here because scripts don't delete if you delete the host.
  1473. // This means that unfortunately, we can pass a null physics actor to Simulate!
  1474. // Make sure we don't do that!
  1475. SceneObjectPart rootpart = m_rootPart;
  1476. if (rootpart != null)
  1477. {
  1478. if (rootpart.PhysActor != null)
  1479. {
  1480. if (!IsAttachment)
  1481. {
  1482. Vector3 torque = rootpart.PhysActor.Torque;
  1483. return torque;
  1484. }
  1485. }
  1486. }
  1487. return Vector3.Zero;
  1488. }
  1489. public void moveToTarget(Vector3 target, float tau)
  1490. {
  1491. SceneObjectPart rootpart = m_rootPart;
  1492. if (rootpart != null)
  1493. {
  1494. if (IsAttachment)
  1495. {
  1496. ScenePresence avatar = m_scene.GetScenePresence(rootpart.AttachedAvatar);
  1497. if (avatar != null)
  1498. {
  1499. List<string> coords = new List<string>();
  1500. uint regionX = 0;
  1501. uint regionY = 0;
  1502. Utils.LongToUInts(Scene.RegionInfo.RegionHandle, out regionX, out regionY);
  1503. target.X += regionX;
  1504. target.Y += regionY;
  1505. coords.Add(target.X.ToString());
  1506. coords.Add(target.Y.ToString());
  1507. coords.Add(target.Z.ToString());
  1508. avatar.DoMoveToPosition(avatar, "", coords);
  1509. }
  1510. }
  1511. else
  1512. {
  1513. if (rootpart.PhysActor != null)
  1514. {
  1515. rootpart.PhysActor.PIDTarget = target;
  1516. rootpart.PhysActor.PIDTau = tau;
  1517. rootpart.PhysActor.PIDActive = true;
  1518. }
  1519. }
  1520. }
  1521. }
  1522. public void stopMoveToTarget()
  1523. {
  1524. SceneObjectPart rootpart = m_rootPart;
  1525. if (rootpart != null)
  1526. {
  1527. if (rootpart.PhysActor != null)
  1528. {
  1529. rootpart.PhysActor.PIDActive = false;
  1530. }
  1531. }
  1532. }
  1533. public void stopLookAt()
  1534. {
  1535. SceneObjectPart rootpart = m_rootPart;
  1536. if (rootpart != null)
  1537. {
  1538. if (rootpart.PhysActor != null)
  1539. {
  1540. rootpart.PhysActor.APIDActive = false;
  1541. }
  1542. }
  1543. }
  1544. /// <summary>
  1545. /// Uses a PID to attempt to clamp the object on the Z axis at the given height over tau seconds.
  1546. /// </summary>
  1547. /// <param name="height">Height to hover. Height of zero disables hover.</param>
  1548. /// <param name="hoverType">Determines what the height is relative to </param>
  1549. /// <param name="tau">Number of seconds over which to reach target</param>
  1550. public void SetHoverHeight(float height, PIDHoverType hoverType, float tau)
  1551. {
  1552. SceneObjectPart rootpart = m_rootPart;
  1553. if (rootpart != null)
  1554. {
  1555. if (rootpart.PhysActor != null)
  1556. {
  1557. if (height != 0f)
  1558. {
  1559. rootpart.PhysActor.PIDHoverHeight = height;
  1560. rootpart.PhysActor.PIDHoverType = hoverType;
  1561. rootpart.PhysActor.PIDTau = tau;
  1562. rootpart.PhysActor.PIDHoverActive = true;
  1563. }
  1564. else
  1565. {
  1566. rootpart.PhysActor.PIDHoverActive = false;
  1567. }
  1568. }
  1569. }
  1570. }
  1571. /// <summary>
  1572. /// Set the owner of the root part.
  1573. /// </summary>
  1574. /// <param name="part"></param>
  1575. /// <param name="cAgentID"></param>
  1576. /// <param name="cGroupID"></param>
  1577. public void SetRootPartOwner(SceneObjectPart part, UUID cAgentID, UUID cGroupID)
  1578. {
  1579. part.LastOwnerID = part.OwnerID;
  1580. part.OwnerID = cAgentID;
  1581. part.GroupID = cGroupID;
  1582. if (part.OwnerID != cAgentID)
  1583. {
  1584. // Apply Next Owner Permissions if we're not bypassing permissions
  1585. if (!m_scene.Permissions.BypassPermissions())
  1586. ApplyNextOwnerPermissions();
  1587. }
  1588. part.ScheduleFullUpdate();
  1589. }
  1590. /// <summary>
  1591. /// Make a copy of the given part.
  1592. /// </summary>
  1593. /// <param name="part"></param>
  1594. /// <param name="cAgentID"></param>
  1595. /// <param name="cGroupID"></param>
  1596. public SceneObjectPart CopyPart(SceneObjectPart part, UUID cAgentID, UUID cGroupID, bool userExposed)
  1597. {
  1598. SceneObjectPart newPart = null;
  1599. lock (m_parts)
  1600. {
  1601. newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed);
  1602. newPart.SetParent(this);
  1603. m_parts.Add(newPart.UUID, newPart);
  1604. }
  1605. SetPartAsNonRoot(newPart);
  1606. return newPart;
  1607. }
  1608. /// <summary>
  1609. /// Reset the UUIDs for all the prims that make up this group.
  1610. ///
  1611. /// This is called by methods which want to add a new group to an existing scene, in order
  1612. /// to ensure that there are no clashes with groups already present.
  1613. /// </summary>
  1614. public void ResetIDs()
  1615. {
  1616. lock (m_parts)
  1617. {
  1618. List<SceneObjectPart> partsList = new List<SceneObjectPart>(m_parts.Values);
  1619. m_parts.Clear();
  1620. foreach (SceneObjectPart part in partsList)
  1621. {
  1622. part.ResetIDs(part.LinkNum); // Don't change link nums
  1623. m_parts.Add(part.UUID, part);
  1624. }
  1625. }
  1626. }
  1627. /// <summary>
  1628. ///
  1629. /// </summary>
  1630. /// <param name="part"></param>
  1631. public void ServiceObjectPropertiesFamilyRequest(IClientAPI remoteClient, UUID AgentID, uint RequestFlags)
  1632. {
  1633. remoteClient.SendObjectPropertiesFamilyData(RequestFlags, RootPart.UUID, RootPart.OwnerID, RootPart.GroupID, RootPart.BaseMask,
  1634. RootPart.OwnerMask, RootPart.GroupMask, RootPart.EveryoneMask, RootPart.NextOwnerMask,
  1635. RootPart.OwnershipCost, RootPart.ObjectSaleType, RootPart.SalePrice, RootPart.Category,
  1636. RootPart.CreatorID, RootPart.Name, RootPart.Description);
  1637. }
  1638. public void SetPartOwner(SceneObjectPart part, UUID cAgentID, UUID cGroupID)
  1639. {
  1640. part.OwnerID = cAgentID;
  1641. part.GroupID = cGroupID;
  1642. }
  1643. #endregion
  1644. #region Scheduling
  1645. public override void Update()
  1646. {
  1647. // Check that the group was not deleted before the scheduled update
  1648. // FIXME: This is merely a temporary measure to reduce the incidence of failure when
  1649. // an object has been deleted from a scene before update was processed.
  1650. // A more fundamental overhaul of the update mechanism is required to eliminate all
  1651. // the race conditions.
  1652. if (m_isDeleted)
  1653. return;
  1654. // Even temporary objects take part in physics (e.g. temp-on-rez bullets)
  1655. //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0)
  1656. // return;
  1657. bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0);
  1658. if (UsePhysics && !AbsolutePosition.ApproxEquals(lastPhysGroupPos, 0.02f))
  1659. {
  1660. m_rootPart.UpdateFlag = 1;
  1661. lastPhysGroupPos = AbsolutePosition;
  1662. }
  1663. if (UsePhysics && !GroupRotation.ApproxEquals(lastPhysGroupRot, 0.1f))
  1664. {
  1665. m_rootPart.UpdateFlag = 1;
  1666. lastPhysGroupRot = GroupRotation;
  1667. }
  1668. List<SceneObjectPart> partList = null;
  1669. lock (m_parts)
  1670. partList = new List<SceneObjectPart>(m_parts.Values);
  1671. foreach (SceneObjectPart part in partList)
  1672. {
  1673. if (!IsSelected)
  1674. part.UpdateLookAt();
  1675. part.SendScheduledUpdates();
  1676. }
  1677. }
  1678. public void ScheduleFullUpdateToAvatar(ScenePresence presence)
  1679. {
  1680. // m_log.DebugFormat("[SOG]: Scheduling full update for {0} {1} just to avatar {2}", Name, UUID, presence.Name);
  1681. RootPart.AddFullUpdateToAvatar(presence);
  1682. lock (m_parts)
  1683. {
  1684. foreach (SceneObjectPart part in m_parts.Values)
  1685. {
  1686. if (part != RootPart)
  1687. part.AddFullUpdateToAvatar(presence);
  1688. }
  1689. }
  1690. }
  1691. public void ScheduleTerseUpdateToAvatar(ScenePresence presence)
  1692. {
  1693. // m_log.DebugFormat("[SOG]: Scheduling terse update for {0} {1} just to avatar {2}", Name, UUID, presence.Name);
  1694. lock (m_parts)
  1695. {
  1696. foreach (SceneObjectPart part in m_parts.Values)
  1697. {
  1698. part.AddTerseUpdateToAvatar(presence);
  1699. }
  1700. }
  1701. }
  1702. /// <summary>
  1703. /// Schedule a full update for this scene object
  1704. /// </summary>
  1705. public void ScheduleGroupForFullUpdate()
  1706. {
  1707. // if (IsAttachment)
  1708. // m_log.DebugFormat("[SOG]: Scheduling full update for {0} {1}", Name, LocalId);
  1709. checkAtTargets();
  1710. RootPart.ScheduleFullUpdate();
  1711. lock (m_parts)
  1712. {
  1713. foreach (SceneObjectPart part in m_parts.Values)
  1714. {
  1715. if (part != RootPart)
  1716. part.ScheduleFullUpdate();
  1717. }
  1718. }
  1719. }
  1720. /// <summary>
  1721. /// Schedule a terse update for this scene object
  1722. /// </summary>
  1723. public void ScheduleGroupForTerseUpdate()
  1724. {
  1725. // m_log.DebugFormat("[SOG]: Scheduling terse update for {0} {1}", Name, UUID);
  1726. lock (m_parts)
  1727. {
  1728. foreach (SceneObjectPart part in m_parts.Values)
  1729. {
  1730. part.ScheduleTerseUpdate();
  1731. }
  1732. }
  1733. }
  1734. /// <summary>
  1735. /// Immediately send a full update for this scene object.
  1736. /// </summary>
  1737. public void SendGroupFullUpdate()
  1738. {
  1739. if (IsDeleted)
  1740. return;
  1741. // m_log.DebugFormat("[SOG]: Sending immediate full group update for {0} {1}", Name, UUID);
  1742. RootPart.SendFullUpdateToAllClients();
  1743. lock (m_parts)
  1744. {
  1745. foreach (SceneObjectPart part in m_parts.Values)
  1746. {
  1747. if (part != RootPart)
  1748. part.SendFullUpdateToAllClients();
  1749. }
  1750. }
  1751. }
  1752. /// <summary>
  1753. /// Immediately send an update for this scene object's root prim only.
  1754. /// This is for updates regarding the object as a whole, and none of its parts in particular.
  1755. /// Note: this may not be used by opensim (it probably should) but it's used by
  1756. /// external modules.
  1757. /// </summary>
  1758. public void SendGroupRootTerseUpdate()
  1759. {
  1760. if (IsDeleted)
  1761. return;
  1762. RootPart.SendTerseUpdateToAllClients();
  1763. }
  1764. public void QueueForUpdateCheck()
  1765. {
  1766. if (m_scene == null) // Need to check here as it's null during object creation
  1767. return;
  1768. m_scene.SceneGraph.AddToUpdateList(this);
  1769. }
  1770. /// <summary>
  1771. /// Immediately send a terse update for this scene object.
  1772. /// </summary>
  1773. public void SendGroupTerseUpdate()
  1774. {
  1775. if (IsDeleted)
  1776. return;
  1777. lock (m_parts)
  1778. {
  1779. foreach (SceneObjectPart part in m_parts.Values)
  1780. {
  1781. part.SendTerseUpdateToAllClients();
  1782. }
  1783. }
  1784. }
  1785. #endregion
  1786. #region SceneGroupPart Methods
  1787. /// <summary>
  1788. /// Get the child part by LinkNum
  1789. /// </summary>
  1790. /// <param name="linknum"></param>
  1791. /// <returns>null if no child part with that linknum or child part</returns>
  1792. public SceneObjectPart GetLinkNumPart(int linknum)
  1793. {
  1794. lock (m_parts)
  1795. {
  1796. foreach (SceneObjectPart part in m_parts.Values)
  1797. {
  1798. if (part.LinkNum == linknum)
  1799. {
  1800. return part;
  1801. }
  1802. }
  1803. }
  1804. return null;
  1805. }
  1806. /// <summary>
  1807. /// Get a part with a given UUID
  1808. /// </summary>
  1809. /// <param name="primID"></param>
  1810. /// <returns>null if a child part with the primID was not found</returns>
  1811. public SceneObjectPart GetChildPart(UUID primID)
  1812. {
  1813. SceneObjectPart childPart;
  1814. lock (m_parts)
  1815. m_parts.TryGetValue(primID, out childPart);
  1816. return childPart;
  1817. }
  1818. /// <summary>
  1819. /// Get a part with a given local ID
  1820. /// </summary>
  1821. /// <param name="localID"></param>
  1822. /// <returns>null if a child part with the local ID was not found</returns>
  1823. public SceneObjectPart GetChildPart(uint localID)
  1824. {
  1825. //m_log.DebugFormat("Entered looking for {0}", localID);
  1826. lock (m_parts)
  1827. {
  1828. foreach (SceneObjectPart part in m_parts.Values)
  1829. {
  1830. //m_log.DebugFormat("Found {0}", part.LocalId);
  1831. if (part.LocalId == localID)
  1832. {
  1833. return part;
  1834. }
  1835. }
  1836. }
  1837. return null;
  1838. }
  1839. /// <summary>
  1840. /// Does this group contain the child prim
  1841. /// should be able to remove these methods once we have a entity index in scene
  1842. /// </summary>
  1843. /// <param name="primID"></param>
  1844. /// <returns></returns>
  1845. public bool HasChildPrim(UUID primID)
  1846. {
  1847. lock (m_parts)
  1848. {
  1849. if (m_parts.ContainsKey(primID))
  1850. return true;
  1851. }
  1852. return false;
  1853. }
  1854. /// <summary>
  1855. /// Does this group contain the child prim
  1856. /// should be able to remove these methods once we have a entity index in scene
  1857. /// </summary>
  1858. /// <param name="localID"></param>
  1859. /// <returns></returns>
  1860. public bool HasChildPrim(uint localID)
  1861. {
  1862. //m_log.DebugFormat("Entered HasChildPrim looking for {0}", localID);
  1863. lock (m_parts)
  1864. {
  1865. foreach (SceneObjectPart part in m_parts.Values)
  1866. {
  1867. //m_log.DebugFormat("Found {0}", part.LocalId);
  1868. if (part.LocalId == localID)
  1869. {
  1870. return true;
  1871. }
  1872. }
  1873. }
  1874. return false;
  1875. }
  1876. #endregion
  1877. #region Packet Handlers
  1878. /// <summary>
  1879. /// Link the prims in a given group to this group
  1880. /// </summary>
  1881. /// <param name="objectGroup">The group of prims which should be linked to this group</param>
  1882. public void LinkToGroup(SceneObjectGroup objectGroup)
  1883. {
  1884. // Make sure we have sent any pending unlinks or stuff.
  1885. //if (objectGroup.RootPart.UpdateFlag > 0)
  1886. //{
  1887. // m_log.WarnFormat(
  1888. // "[SCENE OBJECT GROUP]: Forcing send of linkset {0}, {1} to {2}, {3} as its still waiting.",
  1889. // objectGroup.RootPart.Name, objectGroup.RootPart.UUID, RootPart.Name, RootPart.UUID);
  1890. // objectGroup.RootPart.SendScheduledUpdates();
  1891. //}
  1892. // m_log.DebugFormat(
  1893. // "[SCENE OBJECT GROUP]: Linking group with root part {0}, {1} to group with root part {2}, {3}",
  1894. // objectGroup.RootPart.Name, objectGroup.RootPart.UUID, RootPart.Name, RootPart.UUID);
  1895. SceneObjectPart linkPart = objectGroup.m_rootPart;
  1896. Vector3 oldGroupPosition = linkPart.GroupPosition;
  1897. Quaternion oldRootRotation = linkPart.RotationOffset;
  1898. linkPart.OffsetPosition = linkPart.GroupPosition - AbsolutePosition;
  1899. linkPart.GroupPosition = AbsolutePosition;
  1900. Vector3 axPos = linkPart.OffsetPosition;
  1901. Quaternion parentRot = m_rootPart.RotationOffset;
  1902. axPos *= Quaternion.Inverse(parentRot);
  1903. linkPart.OffsetPosition = axPos;
  1904. Quaternion oldRot = linkPart.RotationOffset;
  1905. Quaternion newRot = Quaternion.Inverse(parentRot) * oldRot;
  1906. linkPart.RotationOffset = newRot;
  1907. linkPart.ParentID = m_rootPart.LocalId;
  1908. if (m_rootPart.LinkNum == 0)
  1909. m_rootPart.LinkNum = 1;
  1910. lock (m_parts)
  1911. {
  1912. m_parts.Add(linkPart.UUID, linkPart);
  1913. // Insert in terms of link numbers, the new links
  1914. // before the current ones (with the exception of
  1915. // the root prim. Shuffle the old ones up
  1916. foreach (KeyValuePair<UUID, SceneObjectPart> kvp in m_parts)
  1917. {
  1918. if (kvp.Value.LinkNum != 1)
  1919. {
  1920. // Don't update root prim link number
  1921. kvp.Value.LinkNum += objectGroup.PrimCount;
  1922. }
  1923. }
  1924. linkPart.LinkNum = 2;
  1925. linkPart.SetParent(this);
  1926. linkPart.CreateSelected = true;
  1927. //if (linkPart.PhysActor != null)
  1928. //{
  1929. // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor);
  1930. //linkPart.PhysActor = null;
  1931. //}
  1932. //TODO: rest of parts
  1933. int linkNum = 3;
  1934. foreach (SceneObjectPart part in objectGroup.Children.Values)
  1935. {
  1936. if (part.UUID != objectGroup.m_rootPart.UUID)
  1937. {
  1938. LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++);
  1939. }
  1940. part.ClearUndoState();
  1941. }
  1942. }
  1943. m_scene.UnlinkSceneObject(objectGroup, true);
  1944. objectGroup.m_isDeleted = true;
  1945. lock (objectGroup.m_parts)
  1946. {
  1947. objectGroup.m_parts.Clear();
  1948. }
  1949. // Can't do this yet since backup still makes use of the root part without any synchronization
  1950. // objectGroup.m_rootPart = null;
  1951. AttachToBackup();
  1952. // Here's the deal, this is ABSOLUTELY CRITICAL so the physics scene gets the update about the
  1953. // position of linkset prims. IF YOU CHANGE THIS, YOU MUST TEST colliding with just linked and
  1954. // unmoved prims!
  1955. ResetChildPrimPhysicsPositions();
  1956. //HasGroupChanged = true;
  1957. //ScheduleGroupForFullUpdate();
  1958. }
  1959. /// <summary>
  1960. /// Delink the given prim from this group. The delinked prim is established as
  1961. /// an independent SceneObjectGroup.
  1962. /// </summary>
  1963. /// <param name="partID"></param>
  1964. /// <returns>The object group of the newly delinked prim. Null if part could not be found</returns>
  1965. public SceneObjectGroup DelinkFromGroup(uint partID)
  1966. {
  1967. return DelinkFromGroup(partID, true);
  1968. }
  1969. /// <summary>
  1970. /// Delink the given prim from this group. The delinked prim is established as
  1971. /// an independent SceneObjectGroup.
  1972. /// </summary>
  1973. /// <param name="partID"></param>
  1974. /// <param name="sendEvents"></param>
  1975. /// <returns>The object group of the newly delinked prim. Null if part could not be found</returns>
  1976. public SceneObjectGroup DelinkFromGroup(uint partID, bool sendEvents)
  1977. {
  1978. SceneObjectPart linkPart = GetChildPart(partID);
  1979. if (linkPart != null)
  1980. {
  1981. return DelinkFromGroup(linkPart, sendEvents);
  1982. }
  1983. else
  1984. {
  1985. m_log.WarnFormat("[SCENE OBJECT GROUP]: " +
  1986. "DelinkFromGroup(): Child prim {0} not found in object {1}, {2}",
  1987. partID, LocalId, UUID);
  1988. return null;
  1989. }
  1990. }
  1991. /// <summary>
  1992. /// Delink the given prim from this group. The delinked prim is established as
  1993. /// an independent SceneObjectGroup.
  1994. /// </summary>
  1995. /// <param name="partID"></param>
  1996. /// <param name="sendEvents"></param>
  1997. /// <returns>The object group of the newly delinked prim.</returns>
  1998. public SceneObjectGroup DelinkFromGroup(SceneObjectPart linkPart, bool sendEvents)
  1999. {
  2000. // m_log.DebugFormat(
  2001. // "[SCENE OBJECT GROUP]: Delinking part {0}, {1} from group with root part {2}, {3}",
  2002. // linkPart.Name, linkPart.UUID, RootPart.Name, RootPart.UUID);
  2003. linkPart.ClearUndoState();
  2004. Quaternion worldRot = linkPart.GetWorldRotation();
  2005. // Remove the part from this object
  2006. lock (m_parts)
  2007. {
  2008. m_parts.Remove(linkPart.UUID);
  2009. if (m_parts.Count == 1 && RootPart != null) //Single prim is left
  2010. {
  2011. RootPart.LinkNum = 0;
  2012. }
  2013. else
  2014. {
  2015. foreach (SceneObjectPart p in m_parts.Values)
  2016. {
  2017. if (p.LinkNum > linkPart.LinkNum)
  2018. p.LinkNum--;
  2019. }
  2020. }
  2021. }
  2022. linkPart.ParentID = 0;
  2023. linkPart.LinkNum = 0;
  2024. if (linkPart.PhysActor != null)
  2025. {
  2026. m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor);
  2027. }
  2028. // We need to reset the child part's position
  2029. // ready for life as a separate object after being a part of another object
  2030. Quaternion parentRot = m_rootPart.RotationOffset;
  2031. Vector3 axPos = linkPart.OffsetPosition;
  2032. axPos *= parentRot;
  2033. linkPart.OffsetPosition = new Vector3(axPos.X, axPos.Y, axPos.Z);
  2034. linkPart.GroupPosition = AbsolutePosition + linkPart.OffsetPosition;
  2035. linkPart.OffsetPosition = new Vector3(0, 0, 0);
  2036. linkPart.RotationOffset = worldRot;
  2037. SceneObjectGroup objectGroup = new SceneObjectGroup(linkPart);
  2038. m_scene.AddNewSceneObject(objectGroup, true);
  2039. if (sendEvents)
  2040. linkPart.TriggerScriptChangedEvent(Changed.LINK);
  2041. linkPart.Rezzed = RootPart.Rezzed;
  2042. //HasGroupChanged = true;
  2043. //ScheduleGroupForFullUpdate();
  2044. return objectGroup;
  2045. }
  2046. /// <summary>
  2047. /// Stop this object from being persisted over server restarts.
  2048. /// </summary>
  2049. /// <param name="objectGroup"></param>
  2050. public virtual void DetachFromBackup()
  2051. {
  2052. if (m_isBackedUp)
  2053. m_scene.EventManager.OnBackup -= ProcessBackup;
  2054. m_isBackedUp = false;
  2055. }
  2056. private void LinkNonRootPart(SceneObjectPart part, Vector3 oldGroupPosition, Quaternion oldGroupRotation, int linkNum)
  2057. {
  2058. Quaternion parentRot = oldGroupRotation;
  2059. Quaternion oldRot = part.RotationOffset;
  2060. Quaternion worldRot = parentRot * oldRot;
  2061. parentRot = oldGroupRotation;
  2062. Vector3 axPos = part.OffsetPosition;
  2063. axPos *= parentRot;
  2064. part.OffsetPosition = axPos;
  2065. part.GroupPosition = oldGroupPosition + part.OffsetPosition;
  2066. part.OffsetPosition = Vector3.Zero;
  2067. part.RotationOffset = worldRot;
  2068. part.SetParent(this);
  2069. part.ParentID = m_rootPart.LocalId;
  2070. // Caller locks m_parts for us
  2071. m_parts.Add(part.UUID, part);
  2072. part.LinkNum = linkNum;
  2073. part.OffsetPosition = part.GroupPosition - AbsolutePosition;
  2074. Quaternion rootRotation = m_rootPart.RotationOffset;
  2075. Vector3 pos = part.OffsetPosition;
  2076. pos *= Quaternion.Inverse(rootRotation);
  2077. part.OffsetPosition = pos;
  2078. parentRot = m_rootPart.RotationOffset;
  2079. oldRot = part.RotationOffset;
  2080. Quaternion newRot = Quaternion.Inverse(parentRot) * oldRot;
  2081. part.RotationOffset = newRot;
  2082. }
  2083. /// <summary>
  2084. /// If object is physical, apply force to move it around
  2085. /// If object is not physical, just put it at the resulting location
  2086. /// </summary>
  2087. /// <param name="offset">Always seems to be 0,0,0, so ignoring</param>
  2088. /// <param name="pos">New position. We do the math here to turn it into a force</param>
  2089. /// <param name="remoteClient"></param>
  2090. public void GrabMovement(Vector3 offset, Vector3 pos, IClientAPI remoteClient)
  2091. {
  2092. if (m_scene.EventManager.TriggerGroupMove(UUID, pos))
  2093. {
  2094. if (m_rootPart.PhysActor != null)
  2095. {
  2096. if (m_rootPart.PhysActor.IsPhysical)
  2097. {
  2098. if (!m_rootPart.BlockGrab)
  2099. {
  2100. Vector3 llmoveforce = pos - AbsolutePosition;
  2101. Vector3 grabforce = llmoveforce;
  2102. grabforce = (grabforce / 10) * m_rootPart.PhysActor.Mass;
  2103. m_rootPart.PhysActor.AddForce(grabforce, true);
  2104. m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor);
  2105. }
  2106. }
  2107. else
  2108. {
  2109. //NonPhysicalGrabMovement(pos);
  2110. }
  2111. }
  2112. else
  2113. {
  2114. //NonPhysicalGrabMovement(pos);
  2115. }
  2116. }
  2117. }
  2118. public void NonPhysicalGrabMovement(Vector3 pos)
  2119. {
  2120. AbsolutePosition = pos;
  2121. m_rootPart.SendTerseUpdateToAllClients();
  2122. }
  2123. /// <summary>
  2124. /// If object is physical, prepare for spinning torques (set flag to save old orientation)
  2125. /// </summary>
  2126. /// <param name="rotation">Rotation. We do the math here to turn it into a torque</param>
  2127. /// <param name="remoteClient"></param>
  2128. public void SpinStart(IClientAPI remoteClient)
  2129. {
  2130. if (m_scene.EventManager.TriggerGroupSpinStart(UUID))
  2131. {
  2132. if (m_rootPart.PhysActor != null)
  2133. {
  2134. if (m_rootPart.PhysActor.IsPhysical)
  2135. {
  2136. m_rootPart.IsWaitingForFirstSpinUpdatePacket = true;
  2137. }
  2138. }
  2139. }
  2140. }
  2141. /// <summary>
  2142. /// If object is physical, apply torque to spin it around
  2143. /// </summary>
  2144. /// <param name="rotation">Rotation. We do the math here to turn it into a torque</param>
  2145. /// <param name="remoteClient"></param>
  2146. public void SpinMovement(Quaternion newOrientation, IClientAPI remoteClient)
  2147. {
  2148. // The incoming newOrientation, sent by the client, "seems" to be the
  2149. // desired target orientation. This needs further verification; in particular,
  2150. // one would expect that the initial incoming newOrientation should be
  2151. // fairly close to the original prim's physical orientation,
  2152. // m_rootPart.PhysActor.Orientation. This however does not seem to be the
  2153. // case (might just be an issue with different quaternions representing the
  2154. // same rotation, or it might be a coordinate system issue).
  2155. //
  2156. // Since it's not clear what the relationship is between the PhysActor.Orientation
  2157. // and the incoming orientations sent by the client, we take an alternative approach
  2158. // of calculating the delta rotation between the orientations being sent by the
  2159. // client. (Since a spin is invoked by ctrl+shift+drag in the client, we expect
  2160. // a steady stream of several new orientations coming in from the client.)
  2161. // This ensures that the delta rotations are being calculated from self-consistent
  2162. // pairs of old/new rotations. Given the delta rotation, we apply a torque around
  2163. // the delta rotation axis, scaled by the object mass times an arbitrary scaling
  2164. // factor (to ensure the resulting torque is not "too strong" or "too weak").
  2165. //
  2166. // Ideally we need to calculate (probably iteratively) the exact torque or series
  2167. // of torques needed to arrive exactly at the destination orientation. However, since
  2168. // it is not yet clear how to map the destination orientation (provided by the viewer)
  2169. // into PhysActor orientations (needed by the physics engine), we omit this step.
  2170. // This means that the resulting torque will at least be in the correct direction,
  2171. // but it will result in over-shoot or under-shoot of the target orientation.
  2172. // For the end user, this means that ctrl+shift+drag can be used for relative,
  2173. // but not absolute, adjustments of orientation for physical prims.
  2174. if (m_scene.EventManager.TriggerGroupSpin(UUID, newOrientation))
  2175. {
  2176. if (m_rootPart.PhysActor != null)
  2177. {
  2178. if (m_rootPart.PhysActor.IsPhysical)
  2179. {
  2180. if (m_rootPart.IsWaitingForFirstSpinUpdatePacket)
  2181. {
  2182. // first time initialization of "old" orientation for calculation of delta rotations
  2183. m_rootPart.SpinOldOrientation = newOrientation;
  2184. m_rootPart.IsWaitingForFirstSpinUpdatePacket = false;
  2185. }
  2186. else
  2187. {
  2188. // save and update old orientation
  2189. Quaternion old = m_rootPart.SpinOldOrientation;
  2190. m_rootPart.SpinOldOrientation = newOrientation;
  2191. //m_log.Error("[SCENE OBJECT GROUP]: Old orientation is " + old);
  2192. //m_log.Error("[SCENE OBJECT GROUP]: Incoming new orientation is " + newOrientation);
  2193. // compute difference between previous old rotation and new incoming rotation
  2194. Quaternion minimalRotationFromQ1ToQ2 = Quaternion.Inverse(old) * newOrientation;
  2195. float rotationAngle;
  2196. Vector3 rotationAxis;
  2197. minimalRotationFromQ1ToQ2.GetAxisAngle(out rotationAxis, out rotationAngle);
  2198. rotationAxis.Normalize();
  2199. //m_log.Error("SCENE OBJECT GROUP]: rotation axis is " + rotationAxis);
  2200. Vector3 spinforce = new Vector3(rotationAxis.X, rotationAxis.Y, rotationAxis.Z);
  2201. spinforce = (spinforce/8) * m_rootPart.PhysActor.Mass; // 8 is an arbitrary torque scaling factor
  2202. m_rootPart.PhysActor.AddAngularForce(spinforce,true);
  2203. m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor);
  2204. }
  2205. }
  2206. else
  2207. {
  2208. //NonPhysicalSpinMovement(pos);
  2209. }
  2210. }
  2211. else
  2212. {
  2213. //NonPhysicalSpinMovement(pos);
  2214. }
  2215. }
  2216. }
  2217. /// <summary>
  2218. /// Return metadata about a prim (name, description, sale price, etc.)
  2219. /// </summary>
  2220. /// <param name="client"></param>
  2221. public void GetProperties(IClientAPI client)
  2222. {
  2223. m_rootPart.GetProperties(client);
  2224. }
  2225. /// <summary>
  2226. /// Set the name of a prim
  2227. /// </summary>
  2228. /// <param name="name"></param>
  2229. /// <param name="localID"></param>
  2230. public void SetPartName(string name, uint localID)
  2231. {
  2232. SceneObjectPart part = GetChildPart(localID);
  2233. if (part != null)
  2234. {
  2235. part.Name = name;
  2236. }
  2237. }
  2238. public void SetPartDescription(string des, uint localID)
  2239. {
  2240. SceneObjectPart part = GetChildPart(localID);
  2241. if (part != null)
  2242. {
  2243. part.Description = des;
  2244. }
  2245. }
  2246. public void SetPartText(string text, uint localID)
  2247. {
  2248. SceneObjectPart part = GetChildPart(localID);
  2249. if (part != null)
  2250. {
  2251. part.SetText(text);
  2252. }
  2253. }
  2254. public void SetPartText(string text, UUID partID)
  2255. {
  2256. SceneObjectPart part = GetChildPart(partID);
  2257. if (part != null)
  2258. {
  2259. part.SetText(text);
  2260. }
  2261. }
  2262. public string GetPartName(uint localID)
  2263. {
  2264. SceneObjectPart part = GetChildPart(localID);
  2265. if (part != null)
  2266. {
  2267. return part.Name;
  2268. }
  2269. return String.Empty;
  2270. }
  2271. public string GetPartDescription(uint localID)
  2272. {
  2273. SceneObjectPart part = GetChildPart(localID);
  2274. if (part != null)
  2275. {
  2276. return part.Description;
  2277. }
  2278. return String.Empty;
  2279. }
  2280. /// <summary>
  2281. /// Update prim flags for this group.
  2282. /// </summary>
  2283. /// <param name="localID"></param>
  2284. /// <param name="type"></param>
  2285. /// <param name="inUse"></param>
  2286. /// <param name="data"></param>
  2287. public void UpdatePrimFlags(uint localID, bool UsePhysics, bool IsTemporary, bool IsPhantom, bool IsVolumeDetect)
  2288. {
  2289. SceneObjectPart selectionPart = GetChildPart(localID);
  2290. if (IsTemporary)
  2291. {
  2292. DetachFromBackup();
  2293. // Remove from database and parcel prim count
  2294. //
  2295. m_scene.DeleteFromStorage(UUID);
  2296. m_scene.EventManager.TriggerParcelPrimCountTainted();
  2297. }
  2298. if (selectionPart != null)
  2299. {
  2300. lock (m_parts)
  2301. {
  2302. foreach (SceneObjectPart part in m_parts.Values)
  2303. {
  2304. if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax ||
  2305. part.Scale.Y > m_scene.RegionInfo.PhysPrimMax ||
  2306. part.Scale.Z > m_scene.RegionInfo.PhysPrimMax)
  2307. {
  2308. UsePhysics = false; // Reset physics
  2309. break;
  2310. }
  2311. }
  2312. foreach (SceneObjectPart part in m_parts.Values)
  2313. {
  2314. part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect);
  2315. }
  2316. }
  2317. }
  2318. }
  2319. public void UpdateExtraParam(uint localID, ushort type, bool inUse, byte[] data)
  2320. {
  2321. SceneObjectPart part = GetChildPart(localID);
  2322. if (part != null)
  2323. {
  2324. part.UpdateExtraParam(type, inUse, data);
  2325. }
  2326. }
  2327. /// <summary>
  2328. /// Get the parts of this scene object
  2329. /// </summary>
  2330. /// <returns></returns>
  2331. public SceneObjectPart[] GetParts()
  2332. {
  2333. int numParts = Children.Count;
  2334. SceneObjectPart[] partArray = new SceneObjectPart[numParts];
  2335. Children.Values.CopyTo(partArray, 0);
  2336. return partArray;
  2337. }
  2338. /// <summary>
  2339. /// Update the texture entry for this part
  2340. /// </summary>
  2341. /// <param name="localID"></param>
  2342. /// <param name="textureEntry"></param>
  2343. public void UpdateTextureEntry(uint localID, byte[] textureEntry)
  2344. {
  2345. SceneObjectPart part = GetChildPart(localID);
  2346. if (part != null)
  2347. {
  2348. part.UpdateTextureEntry(textureEntry);
  2349. }
  2350. }
  2351. public void UpdatePermissions(UUID AgentID, byte field, uint localID,
  2352. uint mask, byte addRemTF)
  2353. {
  2354. List<SceneObjectPart> partList = null;
  2355. lock (m_parts)
  2356. partList = new List<SceneObjectPart>(m_parts.Values);
  2357. foreach (SceneObjectPart part in partList)
  2358. part.UpdatePermissions(AgentID, field, localID, mask, addRemTF);
  2359. HasGroupChanged = true;
  2360. }
  2361. #endregion
  2362. #region Shape
  2363. /// <summary>
  2364. ///
  2365. /// </summary>
  2366. /// <param name="shapeBlock"></param>
  2367. public void UpdateShape(ObjectShapePacket.ObjectDataBlock shapeBlock, uint localID)
  2368. {
  2369. SceneObjectPart part = GetChildPart(localID);
  2370. if (part != null)
  2371. {
  2372. part.UpdateShape(shapeBlock);
  2373. if (part.PhysActor != null)
  2374. m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor);
  2375. }
  2376. }
  2377. #endregion
  2378. #region Resize
  2379. /// <summary>
  2380. /// Resize the given part
  2381. /// </summary>
  2382. /// <param name="scale"></param>
  2383. /// <param name="localID"></param>
  2384. public void Resize(Vector3 scale, uint localID)
  2385. {
  2386. if (scale.X > m_scene.m_maxNonphys)
  2387. scale.X = m_scene.m_maxNonphys;
  2388. if (scale.Y > m_scene.m_maxNonphys)
  2389. scale.Y = m_scene.m_maxNonphys;
  2390. if (scale.Z > m_scene.m_maxNonphys)
  2391. scale.Z = m_scene.m_maxNonphys;
  2392. SceneObjectPart part = GetChildPart(localID);
  2393. if (part != null)
  2394. {
  2395. part.Resize(scale);
  2396. if (part.PhysActor != null)
  2397. {
  2398. if (part.PhysActor.IsPhysical)
  2399. {
  2400. if (scale.X > m_scene.m_maxPhys)
  2401. scale.X = m_scene.m_maxPhys;
  2402. if (scale.Y > m_scene.m_maxPhys)
  2403. scale.Y = m_scene.m_maxPhys;
  2404. if (scale.Z > m_scene.m_maxPhys)
  2405. scale.Z = m_scene.m_maxPhys;
  2406. }
  2407. part.PhysActor.Size = scale;
  2408. m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor);
  2409. }
  2410. //if (part.UUID != m_rootPart.UUID)
  2411. HasGroupChanged = true;
  2412. ScheduleGroupForFullUpdate();
  2413. //if (part.UUID == m_rootPart.UUID)
  2414. //{
  2415. //if (m_rootPart.PhysActor != null)
  2416. //{
  2417. //m_rootPart.PhysActor.Size =
  2418. //new PhysicsVector(m_rootPart.Scale.X, m_rootPart.Scale.Y, m_rootPart.Scale.Z);
  2419. //m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor);
  2420. //}
  2421. //}
  2422. }
  2423. }
  2424. public void GroupResize(Vector3 scale, uint localID)
  2425. {
  2426. SceneObjectPart part = GetChildPart(localID);
  2427. if (part != null)
  2428. {
  2429. part.IgnoreUndoUpdate = true;
  2430. if (scale.X > m_scene.m_maxNonphys)
  2431. scale.X = m_scene.m_maxNonphys;
  2432. if (scale.Y > m_scene.m_maxNonphys)
  2433. scale.Y = m_scene.m_maxNonphys;
  2434. if (scale.Z > m_scene.m_maxNonphys)
  2435. scale.Z = m_scene.m_maxNonphys;
  2436. if (part.PhysActor != null && part.PhysActor.IsPhysical)
  2437. {
  2438. if (scale.X > m_scene.m_maxPhys)
  2439. scale.X = m_scene.m_maxPhys;
  2440. if (scale.Y > m_scene.m_maxPhys)
  2441. scale.Y = m_scene.m_maxPhys;
  2442. if (scale.Z > m_scene.m_maxPhys)
  2443. scale.Z = m_scene.m_maxPhys;
  2444. }
  2445. float x = (scale.X / part.Scale.X);
  2446. float y = (scale.Y / part.Scale.Y);
  2447. float z = (scale.Z / part.Scale.Z);
  2448. lock (m_parts)
  2449. {
  2450. if (x > 1.0f || y > 1.0f || z > 1.0f)
  2451. {
  2452. foreach (SceneObjectPart obPart in m_parts.Values)
  2453. {
  2454. if (obPart.UUID != m_rootPart.UUID)
  2455. {
  2456. obPart.IgnoreUndoUpdate = true;
  2457. Vector3 oldSize = new Vector3(obPart.Scale);
  2458. float f = 1.0f;
  2459. float a = 1.0f;
  2460. if (part.PhysActor != null && part.PhysActor.IsPhysical)
  2461. {
  2462. if (oldSize.X*x > m_scene.m_maxPhys)
  2463. {
  2464. f = m_scene.m_maxPhys / oldSize.X;
  2465. a = f / x;
  2466. x *= a;
  2467. y *= a;
  2468. z *= a;
  2469. }
  2470. if (oldSize.Y*y > m_scene.m_maxPhys)
  2471. {
  2472. f = m_scene.m_maxPhys / oldSize.Y;
  2473. a = f / y;
  2474. x *= a;
  2475. y *= a;
  2476. z *= a;
  2477. }
  2478. if (oldSize.Z*z > m_scene.m_maxPhys)
  2479. {
  2480. f = m_scene.m_maxPhys / oldSize.Z;
  2481. a = f / z;
  2482. x *= a;
  2483. y *= a;
  2484. z *= a;
  2485. }
  2486. }
  2487. else
  2488. {
  2489. if (oldSize.X*x > m_scene.m_maxNonphys)
  2490. {
  2491. f = m_scene.m_maxNonphys / oldSize.X;
  2492. a = f / x;
  2493. x *= a;
  2494. y *= a;
  2495. z *= a;
  2496. }
  2497. if (oldSize.Y*y > m_scene.m_maxNonphys)
  2498. {
  2499. f = m_scene.m_maxNonphys / oldSize.Y;
  2500. a = f / y;
  2501. x *= a;
  2502. y *= a;
  2503. z *= a;
  2504. }
  2505. if (oldSize.Z*z > m_scene.m_maxNonphys)
  2506. {
  2507. f = m_scene.m_maxNonphys / oldSize.Z;
  2508. a = f / z;
  2509. x *= a;
  2510. y *= a;
  2511. z *= a;
  2512. }
  2513. }
  2514. obPart.IgnoreUndoUpdate = false;
  2515. obPart.StoreUndoState();
  2516. }
  2517. }
  2518. }
  2519. }
  2520. Vector3 prevScale = part.Scale;
  2521. prevScale.X *= x;
  2522. prevScale.Y *= y;
  2523. prevScale.Z *= z;
  2524. part.Resize(prevScale);
  2525. lock (m_parts)
  2526. {
  2527. foreach (SceneObjectPart obPart in m_parts.Values)
  2528. {
  2529. obPart.IgnoreUndoUpdate = true;
  2530. if (obPart.UUID != m_rootPart.UUID)
  2531. {
  2532. Vector3 currentpos = new Vector3(obPart.OffsetPosition);
  2533. currentpos.X *= x;
  2534. currentpos.Y *= y;
  2535. currentpos.Z *= z;
  2536. Vector3 newSize = new Vector3(obPart.Scale);
  2537. newSize.X *= x;
  2538. newSize.Y *= y;
  2539. newSize.Z *= z;
  2540. obPart.Resize(newSize);
  2541. obPart.UpdateOffSet(currentpos);
  2542. }
  2543. obPart.IgnoreUndoUpdate = false;
  2544. obPart.StoreUndoState();
  2545. }
  2546. }
  2547. if (part.PhysActor != null)
  2548. {
  2549. part.PhysActor.Size = prevScale;
  2550. m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor);
  2551. }
  2552. part.IgnoreUndoUpdate = false;
  2553. part.StoreUndoState();
  2554. HasGroupChanged = true;
  2555. ScheduleGroupForTerseUpdate();
  2556. }
  2557. }
  2558. #endregion
  2559. #region Position
  2560. /// <summary>
  2561. /// Move this scene object
  2562. /// </summary>
  2563. /// <param name="pos"></param>
  2564. public void UpdateGroupPosition(Vector3 pos)
  2565. {
  2566. foreach (SceneObjectPart part in Children.Values)
  2567. {
  2568. part.StoreUndoState();
  2569. }
  2570. if (m_scene.EventManager.TriggerGroupMove(UUID, pos))
  2571. {
  2572. if (IsAttachment)
  2573. {
  2574. m_rootPart.AttachedPos = pos;
  2575. }
  2576. if (RootPart.GetStatusSandbox())
  2577. {
  2578. if (Util.GetDistanceTo(RootPart.StatusSandboxPos, pos) > 10)
  2579. {
  2580. RootPart.ScriptSetPhysicsStatus(false);
  2581. pos = AbsolutePosition;
  2582. Scene.SimChat(Utils.StringToBytes("Hit Sandbox Limit"),
  2583. ChatTypeEnum.DebugChannel, 0x7FFFFFFF, RootPart.AbsolutePosition, Name, UUID, false);
  2584. }
  2585. }
  2586. AbsolutePosition = pos;
  2587. HasGroupChanged = true;
  2588. }
  2589. //we need to do a terse update even if the move wasn't allowed
  2590. // so that the position is reset in the client (the object snaps back)
  2591. ScheduleGroupForTerseUpdate();
  2592. }
  2593. /// <summary>
  2594. /// Update the position of a single part of this scene object
  2595. /// </summary>
  2596. /// <param name="pos"></param>
  2597. /// <param name="localID"></param>
  2598. public void UpdateSinglePosition(Vector3 pos, uint localID)
  2599. {
  2600. SceneObjectPart part = GetChildPart(localID);
  2601. foreach (SceneObjectPart parts in Children.Values)
  2602. {
  2603. parts.StoreUndoState();
  2604. }
  2605. if (part != null)
  2606. {
  2607. if (part.UUID == m_rootPart.UUID)
  2608. {
  2609. UpdateRootPosition(pos);
  2610. }
  2611. else
  2612. {
  2613. part.UpdateOffSet(pos);
  2614. }
  2615. HasGroupChanged = true;
  2616. }
  2617. }
  2618. /// <summary>
  2619. ///
  2620. /// </summary>
  2621. /// <param name="pos"></param>
  2622. private void UpdateRootPosition(Vector3 pos)
  2623. {
  2624. foreach (SceneObjectPart part in Children.Values)
  2625. {
  2626. part.StoreUndoState();
  2627. }
  2628. Vector3 newPos = new Vector3(pos.X, pos.Y, pos.Z);
  2629. Vector3 oldPos =
  2630. new Vector3(AbsolutePosition.X + m_rootPart.OffsetPosition.X,
  2631. AbsolutePosition.Y + m_rootPart.OffsetPosition.Y,
  2632. AbsolutePosition.Z + m_rootPart.OffsetPosition.Z);
  2633. Vector3 diff = oldPos - newPos;
  2634. Vector3 axDiff = new Vector3(diff.X, diff.Y, diff.Z);
  2635. Quaternion partRotation = m_rootPart.RotationOffset;
  2636. axDiff *= Quaternion.Inverse(partRotation);
  2637. diff = axDiff;
  2638. lock (m_parts)
  2639. {
  2640. foreach (SceneObjectPart obPart in m_parts.Values)
  2641. {
  2642. if (obPart.UUID != m_rootPart.UUID)
  2643. {
  2644. obPart.OffsetPosition = obPart.OffsetPosition + diff;
  2645. }
  2646. }
  2647. }
  2648. AbsolutePosition = newPos;
  2649. HasGroupChanged = true;
  2650. ScheduleGroupForTerseUpdate();
  2651. }
  2652. public void OffsetForNewRegion(Vector3 offset)
  2653. {
  2654. m_rootPart.GroupPosition = offset;
  2655. }
  2656. #endregion
  2657. #region Rotation
  2658. /// <summary>
  2659. ///
  2660. /// </summary>
  2661. /// <param name="rot"></param>
  2662. public void UpdateGroupRotationR(Quaternion rot)
  2663. {
  2664. foreach (SceneObjectPart parts in Children.Values)
  2665. {
  2666. parts.StoreUndoState();
  2667. }
  2668. m_rootPart.UpdateRotation(rot);
  2669. PhysicsActor actor = m_rootPart.PhysActor;
  2670. if (actor != null)
  2671. {
  2672. actor.Orientation = m_rootPart.RotationOffset;
  2673. m_scene.PhysicsScene.AddPhysicsActorTaint(actor);
  2674. }
  2675. HasGroupChanged = true;
  2676. ScheduleGroupForTerseUpdate();
  2677. }
  2678. /// <summary>
  2679. ///
  2680. /// </summary>
  2681. /// <param name="pos"></param>
  2682. /// <param name="rot"></param>
  2683. public void UpdateGroupRotationPR(Vector3 pos, Quaternion rot)
  2684. {
  2685. foreach (SceneObjectPart parts in Children.Values)
  2686. {
  2687. parts.StoreUndoState();
  2688. }
  2689. m_rootPart.UpdateRotation(rot);
  2690. PhysicsActor actor = m_rootPart.PhysActor;
  2691. if (actor != null)
  2692. {
  2693. actor.Orientation = m_rootPart.RotationOffset;
  2694. m_scene.PhysicsScene.AddPhysicsActorTaint(actor);
  2695. }
  2696. AbsolutePosition = pos;
  2697. HasGroupChanged = true;
  2698. ScheduleGroupForTerseUpdate();
  2699. }
  2700. /// <summary>
  2701. ///
  2702. /// </summary>
  2703. /// <param name="rot"></param>
  2704. /// <param name="localID"></param>
  2705. public void UpdateSingleRotation(Quaternion rot, uint localID)
  2706. {
  2707. SceneObjectPart part = GetChildPart(localID);
  2708. foreach (SceneObjectPart parts in Children.Values)
  2709. {
  2710. parts.StoreUndoState();
  2711. }
  2712. if (part != null)
  2713. {
  2714. if (part.UUID == m_rootPart.UUID)
  2715. {
  2716. UpdateRootRotation(rot);
  2717. }
  2718. else
  2719. {
  2720. part.UpdateRotation(rot);
  2721. }
  2722. }
  2723. }
  2724. /// <summary>
  2725. ///
  2726. /// </summary>
  2727. /// <param name="rot"></param>
  2728. /// <param name="localID"></param>
  2729. public void UpdateSingleRotation(Quaternion rot, Vector3 pos, uint localID)
  2730. {
  2731. SceneObjectPart part = GetChildPart(localID);
  2732. if (part != null)
  2733. {
  2734. if (part.UUID == m_rootPart.UUID)
  2735. {
  2736. UpdateRootRotation(rot);
  2737. AbsolutePosition = pos;
  2738. }
  2739. else
  2740. {
  2741. part.IgnoreUndoUpdate = true;
  2742. part.UpdateRotation(rot);
  2743. part.OffsetPosition = pos;
  2744. part.IgnoreUndoUpdate = false;
  2745. part.StoreUndoState();
  2746. }
  2747. }
  2748. }
  2749. /// <summary>
  2750. ///
  2751. /// </summary>
  2752. /// <param name="rot"></param>
  2753. private void UpdateRootRotation(Quaternion rot)
  2754. {
  2755. Quaternion axRot = rot;
  2756. Quaternion oldParentRot = m_rootPart.RotationOffset;
  2757. m_rootPart.StoreUndoState();
  2758. m_rootPart.UpdateRotation(rot);
  2759. if (m_rootPart.PhysActor != null)
  2760. {
  2761. m_rootPart.PhysActor.Orientation = m_rootPart.RotationOffset;
  2762. m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor);
  2763. }
  2764. lock (m_parts)
  2765. {
  2766. foreach (SceneObjectPart prim in m_parts.Values)
  2767. {
  2768. if (prim.UUID != m_rootPart.UUID)
  2769. {
  2770. prim.IgnoreUndoUpdate = true;
  2771. Vector3 axPos = prim.OffsetPosition;
  2772. axPos *= oldParentRot;
  2773. axPos *= Quaternion.Inverse(axRot);
  2774. prim.OffsetPosition = axPos;
  2775. Quaternion primsRot = prim.RotationOffset;
  2776. Quaternion newRot = primsRot * oldParentRot;
  2777. newRot *= Quaternion.Inverse(axRot);
  2778. prim.RotationOffset = newRot;
  2779. prim.ScheduleTerseUpdate();
  2780. }
  2781. }
  2782. }
  2783. foreach (SceneObjectPart childpart in Children.Values)
  2784. {
  2785. if (childpart != m_rootPart)
  2786. {
  2787. childpart.IgnoreUndoUpdate = false;
  2788. childpart.StoreUndoState();
  2789. }
  2790. }
  2791. m_rootPart.ScheduleTerseUpdate();
  2792. }
  2793. #endregion
  2794. internal void SetAxisRotation(int axis, int rotate10)
  2795. {
  2796. bool setX = false;
  2797. bool setY = false;
  2798. bool setZ = false;
  2799. int xaxis = 2;
  2800. int yaxis = 4;
  2801. int zaxis = 8;
  2802. if (m_rootPart != null)
  2803. {
  2804. setX = ((axis & xaxis) != 0) ? true : false;
  2805. setY = ((axis & yaxis) != 0) ? true : false;
  2806. setZ = ((axis & zaxis) != 0) ? true : false;
  2807. float setval = (rotate10 > 0) ? 1f : 0f;
  2808. if (setX)
  2809. m_rootPart.RotationAxis.X = setval;
  2810. if (setY)
  2811. m_rootPart.RotationAxis.Y = setval;
  2812. if (setZ)
  2813. m_rootPart.RotationAxis.Z = setval;
  2814. if (setX || setY || setZ)
  2815. {
  2816. m_rootPart.SetPhysicsAxisRotation();
  2817. }
  2818. }
  2819. }
  2820. public int registerRotTargetWaypoint(Quaternion target, float tolerance)
  2821. {
  2822. scriptRotTarget waypoint = new scriptRotTarget();
  2823. waypoint.targetRot = target;
  2824. waypoint.tolerance = tolerance;
  2825. uint handle = m_scene.AllocateLocalId();
  2826. waypoint.handle = handle;
  2827. lock (m_rotTargets)
  2828. {
  2829. m_rotTargets.Add(handle, waypoint);
  2830. }
  2831. m_scene.AddGroupTarget(this);
  2832. return (int)handle;
  2833. }
  2834. public void unregisterRotTargetWaypoint(int handle)
  2835. {
  2836. lock (m_targets)
  2837. {
  2838. m_rotTargets.Remove((uint)handle);
  2839. if (m_targets.Count == 0)
  2840. m_scene.RemoveGroupTarget(this);
  2841. }
  2842. }
  2843. public int registerTargetWaypoint(Vector3 target, float tolerance)
  2844. {
  2845. scriptPosTarget waypoint = new scriptPosTarget();
  2846. waypoint.targetPos = target;
  2847. waypoint.tolerance = tolerance;
  2848. uint handle = m_scene.AllocateLocalId();
  2849. waypoint.handle = handle;
  2850. lock (m_targets)
  2851. {
  2852. m_targets.Add(handle, waypoint);
  2853. }
  2854. m_scene.AddGroupTarget(this);
  2855. return (int)handle;
  2856. }
  2857. public void unregisterTargetWaypoint(int handle)
  2858. {
  2859. lock (m_targets)
  2860. {
  2861. m_targets.Remove((uint)handle);
  2862. if (m_targets.Count == 0)
  2863. m_scene.RemoveGroupTarget(this);
  2864. }
  2865. }
  2866. public void checkAtTargets()
  2867. {
  2868. if (m_scriptListens_atTarget || m_scriptListens_notAtTarget)
  2869. {
  2870. if (m_targets.Count > 0)
  2871. {
  2872. bool at_target = false;
  2873. //Vector3 targetPos;
  2874. //uint targetHandle;
  2875. Dictionary<uint, scriptPosTarget> atTargets = new Dictionary<uint, scriptPosTarget>();
  2876. lock (m_targets)
  2877. {
  2878. foreach (uint idx in m_targets.Keys)
  2879. {
  2880. scriptPosTarget target = m_targets[idx];
  2881. if (Util.GetDistanceTo(target.targetPos, m_rootPart.GroupPosition) <= target.tolerance)
  2882. {
  2883. // trigger at_target
  2884. if (m_scriptListens_atTarget)
  2885. {
  2886. at_target = true;
  2887. scriptPosTarget att = new scriptPosTarget();
  2888. att.targetPos = target.targetPos;
  2889. att.tolerance = target.tolerance;
  2890. att.handle = target.handle;
  2891. atTargets.Add(idx, att);
  2892. }
  2893. }
  2894. }
  2895. }
  2896. if (atTargets.Count > 0)
  2897. {
  2898. uint[] localids = new uint[0];
  2899. lock (m_parts)
  2900. {
  2901. localids = new uint[m_parts.Count];
  2902. int cntr = 0;
  2903. foreach (SceneObjectPart part in m_parts.Values)
  2904. {
  2905. localids[cntr] = part.LocalId;
  2906. cntr++;
  2907. }
  2908. }
  2909. for (int ctr = 0; ctr < localids.Length; ctr++)
  2910. {
  2911. foreach (uint target in atTargets.Keys)
  2912. {
  2913. scriptPosTarget att = atTargets[target];
  2914. m_scene.EventManager.TriggerAtTargetEvent(
  2915. localids[ctr], att.handle, att.targetPos, m_rootPart.GroupPosition);
  2916. }
  2917. }
  2918. return;
  2919. }
  2920. if (m_scriptListens_notAtTarget && !at_target)
  2921. {
  2922. //trigger not_at_target
  2923. uint[] localids = new uint[0];
  2924. lock (m_parts)
  2925. {
  2926. localids = new uint[m_parts.Count];
  2927. int cntr = 0;
  2928. foreach (SceneObjectPart part in m_parts.Values)
  2929. {
  2930. localids[cntr] = part.LocalId;
  2931. cntr++;
  2932. }
  2933. }
  2934. for (int ctr = 0; ctr < localids.Length; ctr++)
  2935. {
  2936. m_scene.EventManager.TriggerNotAtTargetEvent(localids[ctr]);
  2937. }
  2938. }
  2939. }
  2940. }
  2941. if (m_scriptListens_atRotTarget || m_scriptListens_notAtRotTarget)
  2942. {
  2943. if (m_rotTargets.Count > 0)
  2944. {
  2945. bool at_Rottarget = false;
  2946. Dictionary<uint, scriptRotTarget> atRotTargets = new Dictionary<uint, scriptRotTarget>();
  2947. lock (m_rotTargets)
  2948. {
  2949. foreach (uint idx in m_rotTargets.Keys)
  2950. {
  2951. scriptRotTarget target = m_rotTargets[idx];
  2952. double angle = Math.Acos(target.targetRot.X * m_rootPart.RotationOffset.X + target.targetRot.Y * m_rootPart.RotationOffset.Y + target.targetRot.Z * m_rootPart.RotationOffset.Z + target.targetRot.W * m_rootPart.RotationOffset.W) * 2;
  2953. if (angle < 0) angle = -angle;
  2954. if (angle > Math.PI) angle = (Math.PI * 2 - angle);
  2955. if (angle <= target.tolerance)
  2956. {
  2957. // trigger at_rot_target
  2958. if (m_scriptListens_atRotTarget)
  2959. {
  2960. at_Rottarget = true;
  2961. scriptRotTarget att = new scriptRotTarget();
  2962. att.targetRot = target.targetRot;
  2963. att.tolerance = target.tolerance;
  2964. att.handle = target.handle;
  2965. atRotTargets.Add(idx, att);
  2966. }
  2967. }
  2968. }
  2969. }
  2970. if (atRotTargets.Count > 0)
  2971. {
  2972. uint[] localids = new uint[0];
  2973. lock (m_parts)
  2974. {
  2975. localids = new uint[m_parts.Count];
  2976. int cntr = 0;
  2977. foreach (SceneObjectPart part in m_parts.Values)
  2978. {
  2979. localids[cntr] = part.LocalId;
  2980. cntr++;
  2981. }
  2982. }
  2983. for (int ctr = 0; ctr < localids.Length; ctr++)
  2984. {
  2985. foreach (uint target in atRotTargets.Keys)
  2986. {
  2987. scriptRotTarget att = atRotTargets[target];
  2988. m_scene.EventManager.TriggerAtRotTargetEvent(
  2989. localids[ctr], att.handle, att.targetRot, m_rootPart.RotationOffset);
  2990. }
  2991. }
  2992. return;
  2993. }
  2994. if (m_scriptListens_notAtRotTarget && !at_Rottarget)
  2995. {
  2996. //trigger not_at_target
  2997. uint[] localids = new uint[0];
  2998. lock (m_parts)
  2999. {
  3000. localids = new uint[m_parts.Count];
  3001. int cntr = 0;
  3002. foreach (SceneObjectPart part in m_parts.Values)
  3003. {
  3004. localids[cntr] = part.LocalId;
  3005. cntr++;
  3006. }
  3007. }
  3008. for (int ctr = 0; ctr < localids.Length; ctr++)
  3009. {
  3010. m_scene.EventManager.TriggerNotAtRotTargetEvent(localids[ctr]);
  3011. }
  3012. }
  3013. }
  3014. }
  3015. }
  3016. public float GetMass()
  3017. {
  3018. float retmass = 0f;
  3019. lock (m_parts)
  3020. {
  3021. foreach (SceneObjectPart part in m_parts.Values)
  3022. {
  3023. retmass += part.GetMass();
  3024. }
  3025. }
  3026. return retmass;
  3027. }
  3028. public void CheckSculptAndLoad()
  3029. {
  3030. lock (m_parts)
  3031. {
  3032. if (!IsDeleted)
  3033. {
  3034. if ((RootPart.GetEffectiveObjectFlags() & (uint)PrimFlags.Phantom) == 0)
  3035. {
  3036. foreach (SceneObjectPart part in m_parts.Values)
  3037. {
  3038. if (part.Shape.SculptEntry && part.Shape.SculptTexture != UUID.Zero)
  3039. {
  3040. // check if a previously decoded sculpt map has been cached
  3041. if (File.Exists(System.IO.Path.Combine("j2kDecodeCache", "smap_" + part.Shape.SculptTexture.ToString())))
  3042. {
  3043. part.SculptTextureCallback(part.Shape.SculptTexture, null);
  3044. }
  3045. else
  3046. {
  3047. m_scene.AssetService.Get(
  3048. part.Shape.SculptTexture.ToString(), part, AssetReceived);
  3049. }
  3050. }
  3051. }
  3052. }
  3053. }
  3054. }
  3055. }
  3056. protected void AssetReceived(string id, Object sender, AssetBase asset)
  3057. {
  3058. SceneObjectPart sop = (SceneObjectPart)sender;
  3059. if (sop != null)
  3060. {
  3061. if (asset != null)
  3062. sop.SculptTextureCallback(asset.FullID, asset);
  3063. }
  3064. }
  3065. /// <summary>
  3066. /// Set the user group to which this scene object belongs.
  3067. /// </summary>
  3068. /// <param name="GroupID"></param>
  3069. /// <param name="client"></param>
  3070. public void SetGroup(UUID GroupID, IClientAPI client)
  3071. {
  3072. lock (m_parts)
  3073. {
  3074. foreach (SceneObjectPart part in m_parts.Values)
  3075. {
  3076. part.SetGroup(GroupID, client);
  3077. part.Inventory.ChangeInventoryGroup(GroupID);
  3078. }
  3079. HasGroupChanged = true;
  3080. }
  3081. // Don't trigger the update here - otherwise some client issues occur when multiple updates are scheduled
  3082. // for the same object with very different properties. The caller must schedule the update.
  3083. //ScheduleGroupForFullUpdate();
  3084. }
  3085. public void TriggerScriptChangedEvent(Changed val)
  3086. {
  3087. foreach (SceneObjectPart part in Children.Values)
  3088. {
  3089. part.TriggerScriptChangedEvent(val);
  3090. }
  3091. }
  3092. public override string ToString()
  3093. {
  3094. return String.Format("{0} {1} ({2})", Name, UUID, AbsolutePosition);
  3095. }
  3096. public void SetAttachmentPoint(byte point)
  3097. {
  3098. lock (m_parts)
  3099. {
  3100. foreach (SceneObjectPart part in m_parts.Values)
  3101. part.SetAttachmentPoint(point);
  3102. }
  3103. }
  3104. #region ISceneObject
  3105. public virtual ISceneObject CloneForNewScene()
  3106. {
  3107. SceneObjectGroup sog = Copy(false);
  3108. sog.m_isDeleted = false;
  3109. return sog;
  3110. }
  3111. public virtual string ToXml2()
  3112. {
  3113. return SceneObjectSerializer.ToXml2Format(this);
  3114. }
  3115. public virtual string ExtraToXmlString()
  3116. {
  3117. return "<ExtraFromItemID>" + GetFromItemID().ToString() + "</ExtraFromItemID>";
  3118. }
  3119. public virtual void ExtraFromXmlString(string xmlstr)
  3120. {
  3121. string id = xmlstr.Substring(xmlstr.IndexOf("<ExtraFromItemID>"));
  3122. id = xmlstr.Replace("<ExtraFromItemID>", "");
  3123. id = id.Replace("</ExtraFromItemID>", "");
  3124. UUID uuid = UUID.Zero;
  3125. UUID.TryParse(id, out uuid);
  3126. SetFromItemID(uuid);
  3127. }
  3128. #endregion
  3129. }
  3130. }