PageRenderTime 72ms CodeModel.GetById 30ms RepoModel.GetById 1ms app.codeStats 1ms

/Aurora/Region/SceneObjectPart.cs

https://bitbucket.org/VirtualReality/async-sim-testing
C# | 5027 lines | 3865 code | 578 blank | 584 comment | 942 complexity | fdcecf184a40ea269bf0a51eedb27a9b MD5 | raw file

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

  1. /*
  2. * Copyright (c) Contributors, http://aurora-sim.org/, 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 Aurora-Sim 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 Aurora.Framework;
  28. using Aurora.Framework.ClientInterfaces;
  29. using Aurora.Framework.ConsoleFramework;
  30. using Aurora.Framework.Modules;
  31. using Aurora.Framework.Physics;
  32. using Aurora.Framework.PresenceInfo;
  33. using Aurora.Framework.SceneInfo;
  34. using Aurora.Framework.SceneInfo.Entities;
  35. using Aurora.Framework.Serialization;
  36. using Aurora.Framework.Services.ClassHelpers.Assets;
  37. using Aurora.Framework.Utilities;
  38. using OpenMetaverse;
  39. using OpenMetaverse.Packets;
  40. using OpenMetaverse.StructuredData;
  41. using ProtoBuf;
  42. using System;
  43. using System.Collections.Generic;
  44. using System.Drawing;
  45. using System.Linq;
  46. using System.Xml;
  47. using System.Xml.Serialization;
  48. using PrimType = Aurora.Framework.SceneInfo.PrimType;
  49. namespace Aurora.Region
  50. {
  51. [Serializable, ProtoContract()]
  52. public class SceneObjectPart : ISceneChildEntity
  53. {
  54. /// <value>
  55. /// Denote all sides of the prim
  56. /// </value>
  57. public const int ALL_SIDES = -1;
  58. public virtual Quaternion GroupRotation
  59. {
  60. get { return ParentGroup.GroupRotation; }
  61. }
  62. #region ISceneChildEntity Members
  63. /// <value>
  64. /// Is this sop a root part?
  65. /// </value>
  66. [XmlIgnore]
  67. public bool IsRoot
  68. {
  69. get { return ParentGroup.RootPart == this; }
  70. }
  71. public virtual Quaternion Rotation
  72. {
  73. get { return ParentGroup.GroupRotation; }
  74. set { }
  75. }
  76. //---------------
  77. public void ApplyNextOwnerPermissions()
  78. {
  79. _baseMask &= _nextOwnerMask;
  80. _ownerMask &= _nextOwnerMask;
  81. _everyoneMask &= _nextOwnerMask;
  82. Inventory.ApplyNextOwnerPermissions();
  83. }
  84. public Color4 GetTextColor()
  85. {
  86. Color color = Color;
  87. return new Color4(color.R, color.G, color.B, (byte) (0xFF - color.A));
  88. }
  89. public void SetSoundQueueing(int queue)
  90. {
  91. UseSoundQueue = queue;
  92. }
  93. public void SetConeOfSilence(double radius)
  94. {
  95. ISoundModule module = m_parentGroup.Scene.RequestModuleInterface<ISoundModule>();
  96. //TODO: Save SetConeOfSilence
  97. if (module != null)
  98. {
  99. if (radius != 0)
  100. module.AddConeOfSilence(UUID, AbsolutePosition, radius);
  101. else
  102. module.RemoveConeOfSilence(UUID);
  103. }
  104. }
  105. #endregion
  106. #region Fields
  107. private readonly List<uint> m_lastColliders = new List<uint>();
  108. [XmlIgnore] public scriptEvents AggregateScriptEvents;
  109. [XmlIgnore] public bool IgnoreUndoUpdate;
  110. [XmlIgnore] public bool IsWaitingForFirstSpinUpdatePacket;
  111. [XmlIgnore] private PrimFlags LocalFlags;
  112. [XmlIgnore] public Vector3 RotationAxis = Vector3.One;
  113. [XmlIgnore] public Quaternion SpinOldOrientation = Quaternion.Identity;
  114. [XmlIgnore] public uint TimeStampLastActivity; // Will be used for AutoReturn
  115. [XmlIgnore]
  116. public bool Undoing { get; set; }
  117. private UUID _creatorID;
  118. [XmlIgnore] private UUID m_AttachedAvatar;
  119. [XmlIgnore] private Dictionary<int, string> m_CollisionFilter = new Dictionary<int, string>();
  120. [XmlIgnore] private bool m_IsAttachment;
  121. [XmlIgnore] private bool m_IsSelected;
  122. [XmlIgnore] private int[] m_PayPrice = {-2, -2, -2, -2, -2};
  123. [XmlIgnore] private bool m_ValidpartOOB; // control recalcutation
  124. protected Vector3 m_acceleration;
  125. protected Vector3 m_angularVelocity;
  126. private byte m_clickAction;
  127. private UUID m_collisionSound;
  128. private float m_collisionSoundVolume;
  129. private UUID m_collisionSprite;
  130. protected uint m_crc;
  131. private string m_creatorData = string.Empty;
  132. private string m_description = String.Empty;
  133. protected Vector3 m_groupPosition;
  134. private Vector3 m_initialPIDLocation = Vector3.Zero;
  135. protected SceneObjectPartInventory m_inventory;
  136. protected Vector3 m_lastAcceleration;
  137. protected Vector3 m_lastAngularVelocity;
  138. protected Vector3 m_lastGroupPosition;
  139. protected Vector3 m_lastPosition;
  140. protected Quaternion m_lastRotation;
  141. protected Vector3 m_lastVelocity;
  142. private int m_linkNum;
  143. protected uint m_localId;
  144. /// <summary>
  145. /// Stores media texture data
  146. /// </summary>
  147. protected string m_mediaUrl;
  148. protected string m_name;
  149. protected Vector3 m_offsetPosition;
  150. protected SceneObjectGroup m_parentGroup;
  151. [XmlIgnore] private float m_partBSphereRadiusSQ; // the square of the radius of a sphere containing the oob
  152. [XmlIgnore] private Vector3 m_partOOBoffset;
  153. // the position center of the bounding box relative to it's Position
  154. [XmlIgnore] private Vector3 m_partOOBsize;
  155. // the size of a bounding box oriented as prim, is future will consider cutted prims, meshs etc
  156. protected byte[] m_particleSystem = Utils.EmptyBytes;
  157. private int m_passTouches;
  158. private PhysicsObject m_physActor;
  159. private bool m_pidActive;
  160. private bool m_pidhoverActive;
  161. private UndoStack<UndoState> m_redo = new UndoStack<UndoState>(5);
  162. protected ulong m_regionHandle;
  163. [XmlIgnore] private int m_scriptAccessPin;
  164. [XmlIgnore] private Dictionary<UUID, scriptEvents> m_scriptEvents = new Dictionary<UUID, scriptEvents>();
  165. protected PrimitiveBaseShape m_shape;
  166. private string m_sitAnimation = "SIT";
  167. private string m_sitName = String.Empty;
  168. private UUID m_sound;
  169. private string m_text = String.Empty;
  170. private string m_touchName = String.Empty;
  171. private UndoStack<UndoState> m_undo = new UndoStack<UndoState>(5);
  172. protected UUID m_uuid;
  173. private bool m_volumeDetectActive;
  174. [XmlIgnore]
  175. [ProtoMember(92)]
  176. public bool RETURN_AT_EDGE { get; set; }
  177. [XmlIgnore]
  178. [ProtoMember(93)]
  179. public bool BlockGrab { get; set; }
  180. [XmlIgnore]
  181. [ProtoMember(94)]
  182. public bool BlockGrabObject { get; set; }
  183. [XmlIgnore]
  184. public bool IsLoading { get; set; }
  185. [XmlIgnore]
  186. [ProtoMember(96)]
  187. public bool StatusSandbox { get; set; }
  188. [XmlIgnore]
  189. [ProtoMember(97)]
  190. public Vector3 StatusSandboxPos { get; set; }
  191. [XmlIgnore]
  192. [ProtoMember(98)]
  193. public int STATUS_ROTATE_X { get; set; }
  194. [XmlIgnore]
  195. [ProtoMember(99)]
  196. public int STATUS_ROTATE_Y { get; set; }
  197. [XmlIgnore]
  198. [ProtoMember(100)]
  199. public int STATUS_ROTATE_Z { get; set; }
  200. [XmlIgnore]
  201. public bool ValidpartOOB
  202. {
  203. set { m_ValidpartOOB = value; }
  204. }
  205. // the size of a bounding box oriented as the prim, is future will consider cutted prims, meshs etc
  206. [XmlIgnore]
  207. public Vector3 OOBsize
  208. {
  209. get
  210. {
  211. if (!m_ValidpartOOB)
  212. UpdateOOBfromOOBs();
  213. return m_partOOBsize;
  214. }
  215. }
  216. // the position center of the bounding box relative to it's Position
  217. // on complex forms this will not be zero
  218. [XmlIgnore]
  219. public Vector3 OOBoffset
  220. {
  221. get
  222. {
  223. if (!m_ValidpartOOB)
  224. UpdateOOBfromOOBs();
  225. return m_partOOBoffset;
  226. }
  227. }
  228. // the square of the radius of a sphere containing the oobb
  229. [XmlIgnore]
  230. public float BSphereRadiusSQ
  231. {
  232. get
  233. {
  234. if (!m_ValidpartOOB)
  235. UpdateOOBfromOOBs();
  236. return m_partBSphereRadiusSQ;
  237. }
  238. }
  239. [ProtoMember(1)]
  240. public bool AllowedDrop { get; set; }
  241. [XmlIgnore]
  242. [ProtoMember(91)]
  243. public bool DIE_AT_EDGE { get; set; }
  244. [XmlIgnore]
  245. [ProtoMember(90)]
  246. public int UseSoundQueue { get; set; }
  247. [ProtoMember(70, OverwriteList = true)]
  248. public int[] PayPrice
  249. {
  250. get { return m_PayPrice; }
  251. set { m_PayPrice = value; }
  252. }
  253. [XmlIgnore]
  254. public PhysicsObject PhysActor
  255. {
  256. get { return m_physActor; }
  257. set
  258. {
  259. // MainConsole.Instance.DebugFormat("[SOP]: PhysActor set to {0} for {1} {2}", value, Name, UUID);
  260. m_physActor = value;
  261. }
  262. }
  263. [XmlIgnore]
  264. [ProtoMember(71)]
  265. public UUID Sound
  266. {
  267. get { return m_sound; }
  268. set { m_sound = value; }
  269. }
  270. [XmlIgnore]
  271. [ProtoMember(72)]
  272. public byte SoundFlags { get; set; }
  273. [XmlIgnore]
  274. [ProtoMember(73)]
  275. public double SoundGain { get; set; }
  276. [XmlIgnore]
  277. [ProtoMember(74)]
  278. public double SoundRadius { get; set; }
  279. [XmlIgnore]
  280. [ProtoMember(75)]
  281. public Vector3 PIDTarget { get; set; }
  282. [XmlIgnore]
  283. [ProtoMember(76)]
  284. public bool PIDActive
  285. {
  286. get { return m_pidActive; }
  287. set
  288. {
  289. IScene s = ParentGroup == null ? null : ParentGroup.Scene ?? null;
  290. if (s != null)
  291. {
  292. if (value)
  293. s.EventManager.OnFrame += UpdateLookAt;
  294. else
  295. s.EventManager.OnFrame -= UpdateLookAt;
  296. }
  297. m_pidActive = value;
  298. }
  299. }
  300. [XmlIgnore]
  301. [ProtoMember(77)]
  302. public float PIDTau { get; set; }
  303. [ProtoMember(78)]
  304. public float PIDHoverHeight { get; set; }
  305. [ProtoMember(79)]
  306. public float PIDHoverTau { get; set; }
  307. [ProtoMember(80)]
  308. public bool PIDHoverActive
  309. {
  310. get { return m_pidhoverActive; }
  311. set { m_pidhoverActive = value; }
  312. }
  313. [ProtoMember(81)]
  314. public PIDHoverType PIDHoverType { get; set; }
  315. [XmlIgnore]
  316. [ProtoMember(82)]
  317. public UUID FromUserInventoryItemID { get; set; }
  318. [XmlIgnore]
  319. [ProtoMember(83)]
  320. public UUID FromUserInventoryAssetID { get; set; }
  321. [XmlIgnore]
  322. public bool IsAttachment
  323. {
  324. get { return m_IsAttachment; }
  325. set { m_IsAttachment = value; }
  326. }
  327. [XmlIgnore]
  328. public UUID AttachedAvatar
  329. {
  330. get { return m_AttachedAvatar; }
  331. set { m_AttachedAvatar = value; }
  332. }
  333. [XmlIgnore]
  334. public Vector3 AttachedPos { get; set; }
  335. /// <summary>
  336. /// NOTE: THIS WILL NOT BE UP TO DATE AS THEY WILL BE ONE REV BEHIND
  337. /// Used to save attachment pos and point over rezzing/taking
  338. /// </summary>
  339. [XmlIgnore]
  340. public int AttachmentPoint { get; set; }
  341. /// <summary>
  342. /// NOTE: THIS WILL NOT BE UP TO DATE AS THEY WILL BE ONE REV BEHIND
  343. /// Used to save attachment pos and point over rezzing/taking
  344. /// </summary>
  345. [ProtoMember(84)]
  346. public Vector3 SavedAttachedPos { get; set; }
  347. [ProtoMember(85)]
  348. public int SavedAttachmentPoint { get; set; }
  349. [XmlIgnore]
  350. [ProtoMember(86)]
  351. public bool VolumeDetectActive
  352. {
  353. get { return m_volumeDetectActive; }
  354. set { m_volumeDetectActive = value; }
  355. }
  356. /// <summary>
  357. /// This part's inventory
  358. /// </summary>
  359. [XmlIgnore]
  360. public IEntityInventory Inventory
  361. {
  362. get { return m_inventory; }
  363. }
  364. [ProtoMember(87)]
  365. public Vector3 CameraEyeOffset { get; set; }
  366. [ProtoMember(88)]
  367. public Vector3 CameraAtOffset { get; set; }
  368. [ProtoMember(89)]
  369. public bool ForceMouselook { get; set; }
  370. [ProtoMember(102)]
  371. public KeyframeAnimation KeyframeAnimation { get; set; }
  372. [ProtoMember(103)]
  373. public Dictionary<UUID, StateSave> StateSaves { get; set; }
  374. public Vector3 GroupScale()
  375. {
  376. return m_parentGroup.GroupScale();
  377. }
  378. #endregion Fields
  379. #region Constructors
  380. /// <summary>
  381. /// No arg constructor called by region restore db code
  382. /// </summary>
  383. public SceneObjectPart()
  384. {
  385. SitTargetAvatar = new List<UUID>();
  386. StateSaves = new Dictionary<UUID, StateSave>();
  387. m_inventory = new SceneObjectPartInventory(this);
  388. m_shape = new PrimitiveBaseShape();
  389. Material = (int) OpenMetaverse.Material.Wood;
  390. }
  391. /// <summary>
  392. /// Create a completely new SceneObjectPart (prim). This will need to be added separately to a SceneObjectGroup
  393. /// </summary>
  394. /// <param name="ownerID"></param>
  395. /// <param name="shape"></param>
  396. /// <param name="groupPosition"></param>
  397. /// <param name="rotationOffset"></param>
  398. /// <param name="offsetPosition"></param>
  399. /// <param name="name"></param>
  400. public SceneObjectPart(
  401. UUID ownerID, PrimitiveBaseShape shape, Vector3 groupPosition,
  402. Quaternion rotationOffset, Vector3 offsetPosition, string name)
  403. {
  404. m_name = name;
  405. CreationDate = (int) Utils.DateTimeToUnixTime(DateTime.Now);
  406. _ownerID = ownerID;
  407. _creatorID = _ownerID;
  408. LastOwnerID = UUID.Zero;
  409. UUID = UUID.Random();
  410. Shape = shape;
  411. CRC = 1;
  412. _ownershipCost = 0;
  413. _flags = 0;
  414. _groupID = UUID.Zero;
  415. _objectSaleType = 0;
  416. _salePrice = 0;
  417. _category = 0;
  418. LastOwnerID = _creatorID;
  419. m_groupPosition = groupPosition;
  420. m_offsetPosition = offsetPosition;
  421. RotationOffset = rotationOffset;
  422. Velocity = Vector3.Zero;
  423. AngularVelocity = Vector3.Zero;
  424. Acceleration = Vector3.Zero;
  425. SitTargetAvatar = new List<UUID>();
  426. StateSaves = new Dictionary<UUID, StateSave>();
  427. ValidpartOOB = false;
  428. // Prims currently only contain a single folder (Contents). From looking at the Second Life protocol,
  429. // this appears to have the same UUID (!) as the prim. If this isn't the case, one can't drag items from
  430. // the prim into an agent inventory (Linden client reports that the "Object not found for drop" in its log
  431. Flags = 0;
  432. CreateSelected = true;
  433. TrimPermissions();
  434. //m_undo = new UndoStack<UndoState>(ParentGroup.GetSceneMaxUndo());
  435. m_inventory = new SceneObjectPartInventory(this);
  436. Material = (int) OpenMetaverse.Material.Wood;
  437. }
  438. public override int GetHashCode()
  439. {
  440. return UUID.GetHashCode();
  441. }
  442. #endregion Constructors
  443. #region XML Schema
  444. private uint _baseMask = (uint) PermissionMask.All;
  445. private uint _category;
  446. private uint _everyoneMask = (uint) PermissionMask.None;
  447. private PrimFlags _flags = PrimFlags.None;
  448. private UUID _groupID;
  449. private uint _groupMask = (uint) PermissionMask.None;
  450. private uint _nextOwnerMask = (uint) PermissionMask.All;
  451. private byte _objectSaleType;
  452. private UUID _ownerID;
  453. private uint _ownerMask = (uint) PermissionMask.All;
  454. private int _ownershipCost;
  455. private uint _parentID;
  456. private int _salePrice;
  457. private List<SceneObjectPart> m_LoopSoundSlavePrims = new List<SceneObjectPart>();
  458. private byte[] m_ParticleSystem;
  459. private List<SceneObjectPart> m_PlaySoundSlavePrims = new List<SceneObjectPart>();
  460. private string m_currentMediaVersion = "x-mv:0000000001/00000000-0000-0000-0000-000000000000";
  461. private int m_passCollision;
  462. private byte[] m_textureAnimation;
  463. [XmlIgnore]
  464. public string CurrentMediaVersion
  465. {
  466. get { return m_currentMediaVersion; }
  467. set { m_currentMediaVersion = value; }
  468. }
  469. /// <summary>
  470. /// Used by the DB layer to retrieve / store the entire user identification.
  471. /// The identification can either be a simple UUID or a string of the form
  472. /// uuid[;profile_url[;name]]
  473. /// </summary>
  474. public string CreatorIdentification
  475. {
  476. get
  477. {
  478. if (!string.IsNullOrEmpty(m_creatorData))
  479. return _creatorID.ToString() + ';' + m_creatorData;
  480. else
  481. return _creatorID.ToString();
  482. }
  483. set
  484. {
  485. if ((value == null) || (value != null && value == string.Empty))
  486. {
  487. m_creatorData = string.Empty;
  488. return;
  489. }
  490. if (!value.Contains(";")) // plain UUID
  491. {
  492. UUID uuid = UUID.Zero;
  493. UUID.TryParse(value, out uuid);
  494. _creatorID = uuid;
  495. }
  496. else // <uuid>[;<endpoint>[;name]]
  497. {
  498. string name = "Unknown User";
  499. string[] parts = value.Split(';');
  500. if (parts.Length >= 1)
  501. {
  502. UUID uuid = UUID.Zero;
  503. UUID.TryParse(parts[0], out uuid);
  504. _creatorID = uuid;
  505. }
  506. if (parts.Length >= 2)
  507. m_creatorData = parts[1];
  508. if (parts.Length >= 3)
  509. name = parts[2];
  510. m_creatorData += ';' + name;
  511. }
  512. }
  513. }
  514. /// <summary>
  515. /// This is idential to the Flags property, except that the returned value is uint rather than PrimFlags
  516. /// </summary>
  517. [Obsolete("Use Flags property instead")]
  518. public uint ObjectFlags
  519. {
  520. get { return (uint) Flags; }
  521. set
  522. {
  523. if (ParentGroup != null)
  524. ParentGroup.HasGroupChanged = true;
  525. Flags = (PrimFlags) value;
  526. }
  527. }
  528. private Quaternion m_APIDTarget;
  529. [XmlIgnore, ProtoMember(65)]
  530. public Quaternion APIDTarget
  531. {
  532. get { return m_APIDTarget; }
  533. set
  534. {
  535. IScene s = ParentGroup == null ? null : ParentGroup.Scene ?? null;
  536. if (s != null)
  537. {
  538. if (value != Quaternion.Identity)
  539. s.EventManager.OnFrame += UpdateLookAt;
  540. else
  541. s.EventManager.OnFrame -= UpdateLookAt;
  542. }
  543. m_APIDTarget = value;
  544. }
  545. }
  546. [XmlIgnore, ProtoMember(66)]
  547. public float APIDDamp { get; set; }
  548. [XmlIgnore, ProtoMember(67)]
  549. public float APIDStrength { get; set; }
  550. [ProtoMember(68)]
  551. public int APIDIterations { get; set; }
  552. [ProtoMember(69)]
  553. public bool APIDEnabled { get; set; }
  554. [XmlIgnore]
  555. public SceneObjectPart PlaySoundMasterPrim { get; set; }
  556. [XmlIgnore]
  557. public List<SceneObjectPart> PlaySoundSlavePrims
  558. {
  559. get { return m_PlaySoundSlavePrims; }
  560. set { m_PlaySoundSlavePrims = value; }
  561. }
  562. [XmlIgnore]
  563. public SceneObjectPart LoopSoundMasterPrim { get; set; }
  564. [XmlIgnore]
  565. public List<SceneObjectPart> LoopSoundSlavePrims
  566. {
  567. get { return m_LoopSoundSlavePrims; }
  568. set { m_LoopSoundSlavePrims = value; }
  569. }
  570. [XmlIgnore, ProtoMember(64)]
  571. public float Damage { get; set; }
  572. public Vector3 RelativePosition
  573. {
  574. get
  575. {
  576. if (IsRoot)
  577. {
  578. if (IsAttachment)
  579. return OffsetPosition;
  580. else
  581. return AbsolutePosition;
  582. }
  583. else
  584. {
  585. return OffsetPosition;
  586. }
  587. }
  588. }
  589. [ProtoMember(2)]
  590. public UUID CreatorID
  591. {
  592. get { return _creatorID; }
  593. set { _creatorID = value; }
  594. }
  595. /// <summary>
  596. /// Data about the creator in the form profile_url;name
  597. /// </summary>
  598. [ProtoMember(3)]
  599. public string CreatorData
  600. {
  601. get { return m_creatorData; }
  602. set { m_creatorData = value; }
  603. }
  604. /// <value>
  605. /// Access should be via Inventory directly - this property temporarily remains for xml serialization purposes
  606. /// </value>
  607. [ProtoMember(4)]
  608. public uint InventorySerial
  609. {
  610. get { return m_inventory.Serial; }
  611. set { m_inventory.Serial = value; }
  612. }
  613. /// <value>
  614. /// Access should be via Inventory directly - this property temporarily remains for xml serialization purposes
  615. /// </value>
  616. [ProtoMember(5)]
  617. public TaskInventoryDictionary TaskInventory
  618. {
  619. get { return m_inventory.Items; }
  620. set { m_inventory.Items = value; }
  621. }
  622. [ProtoMember(6)]
  623. public UUID UUID
  624. {
  625. get { return m_uuid; }
  626. set
  627. {
  628. UUID oldID = m_uuid;
  629. if (ParentGroup != null)
  630. ParentGroup.HasGroupChanged = true;
  631. m_uuid = value;
  632. // This is necessary so that TaskInventoryItem parent ids correctly reference the new uuid of this part
  633. if (Inventory != null)
  634. Inventory.ResetObjectID();
  635. }
  636. }
  637. [ProtoMember(7)]
  638. public uint LocalId
  639. {
  640. get { return m_localId; }
  641. set { m_localId = value; }
  642. }
  643. [XmlIgnore]
  644. public uint CRC { get; set; }
  645. [ProtoMember(8)]
  646. public virtual string Name
  647. {
  648. get { return m_name; }
  649. set
  650. {
  651. if (m_name != value)
  652. {
  653. if (ParentGroup != null)
  654. ParentGroup.HasGroupChanged = true;
  655. m_name = value;
  656. }
  657. }
  658. }
  659. [ProtoMember(9)]
  660. public int Material { get; set; }
  661. public void UpdateMaterial(int val)
  662. {
  663. if (Material == val)
  664. return;
  665. if (ParentGroup != null)
  666. ParentGroup.HasGroupChanged = true;
  667. Material = val;
  668. if (PhysActor != null)
  669. PhysActor.SetMaterial(val, true);
  670. }
  671. [ProtoMember(10)]
  672. public int PassTouch
  673. {
  674. get { return m_passTouches; }
  675. set
  676. {
  677. m_passTouches = value;
  678. if (ParentGroup != null)
  679. ParentGroup.HasGroupChanged = true;
  680. }
  681. }
  682. [ProtoMember(11)]
  683. public int PassCollisions
  684. {
  685. get { return m_passCollision; }
  686. set
  687. {
  688. if (ParentGroup != null)
  689. ParentGroup.HasGroupChanged = true;
  690. m_passCollision = value;
  691. }
  692. }
  693. [XmlIgnore, ProtoMember(12)]
  694. public Dictionary<int, string> CollisionFilter
  695. {
  696. get { return m_CollisionFilter; }
  697. set
  698. {
  699. if (ParentGroup != null)
  700. ParentGroup.HasGroupChanged = true;
  701. m_CollisionFilter = value;
  702. }
  703. }
  704. [ProtoMember(13)]
  705. public int ScriptAccessPin
  706. {
  707. get { return m_scriptAccessPin; }
  708. set { m_scriptAccessPin = value; }
  709. }
  710. [ProtoMember(60, OverwriteList = true)]
  711. public Byte[] TextureAnimation
  712. {
  713. get { return m_textureAnimation; }
  714. set { m_textureAnimation = value; }
  715. }
  716. [XmlIgnore]
  717. [ProtoMember(61, OverwriteList = true)]
  718. public Byte[] ParticleSystem
  719. {
  720. get { return m_ParticleSystem; }
  721. set { m_ParticleSystem = value; }
  722. }
  723. [XmlIgnore, ProtoMember(62)]
  724. public DateTime Expires { get; set; }
  725. [XmlIgnore, ProtoMember(63)]
  726. public DateTime Rezzed { get; set; }
  727. /// <summary>
  728. /// The position of the entire group that this prim belongs to.
  729. /// </summary>
  730. [ProtoMember(14)]
  731. public Vector3 GroupPosition
  732. {
  733. get { return GetGroupPosition(); }
  734. set { FixGroupPosition(value, false); }
  735. }
  736. public Vector3 GetGroupPosition()
  737. {
  738. // If this is a linkset, we don't want the physics engine mucking up our group position here.
  739. PhysicsObject actor = PhysActor;
  740. if (actor != null && _parentID == 0)
  741. {
  742. m_groupPosition = actor.Position;
  743. }
  744. if (IsAttachment)
  745. {
  746. IScenePresence sp = m_parentGroup.Scene.GetScenePresence(AttachedAvatar);
  747. if (sp != null)
  748. return sp.AbsolutePosition;
  749. }
  750. return m_groupPosition;
  751. }
  752. [ProtoMember(15)]
  753. public Vector3 OffsetPosition
  754. {
  755. get { return m_offsetPosition; }
  756. set
  757. {
  758. m_offsetPosition = value;
  759. ValidpartOOB = false;
  760. }
  761. }
  762. [ProtoMember(16)]
  763. public Quaternion RotationOffset { get; set; }
  764. public Quaternion GetRotationOffset()
  765. {
  766. PhysicsObject actor = m_physActor;
  767. if (_parentID == 0 && (m_shape.PCode != 9 || m_shape.State == 0) && actor != null)
  768. {
  769. if (actor.Orientation.X != 0f || actor.Orientation.Y != 0f
  770. || actor.Orientation.Z != 0f || actor.Orientation.W != 0f)
  771. {
  772. RotationOffset = actor.Orientation;
  773. }
  774. }
  775. return RotationOffset;
  776. }
  777. private Vector3 m_tempVelocity = Vector3.Zero;
  778. /// <summary>
  779. /// </summary>
  780. [ProtoMember(17)]
  781. public Vector3 Velocity
  782. {
  783. get
  784. {
  785. PhysicsObject actor = PhysActor;
  786. if (actor != null)
  787. {
  788. if (actor.IsPhysical)
  789. {
  790. return actor.Velocity;
  791. }
  792. }
  793. return m_tempVelocity;
  794. }
  795. set
  796. {
  797. PhysicsObject actor = PhysActor;
  798. if (actor != null)
  799. {
  800. if (actor.IsPhysical)
  801. {
  802. actor.Velocity = value;
  803. m_tempVelocity = Vector3.Zero;
  804. }
  805. else
  806. m_tempVelocity = value;
  807. }
  808. else
  809. m_tempVelocity = value;
  810. }
  811. }
  812. /// <summary>
  813. /// </summary>
  814. [ProtoMember(18)]
  815. public Vector3 AngularVelocity
  816. {
  817. get
  818. {
  819. PhysicsObject actor = PhysActor;
  820. if ((actor != null) && actor.IsPhysical)
  821. {
  822. m_angularVelocity = actor.RotationalVelocity;
  823. }
  824. return m_angularVelocity;
  825. }
  826. set { m_angularVelocity = value; }
  827. }
  828. public void GenerateRotationalVelocityFromOmega()
  829. {
  830. if (OmegaGain == 0.0f) //Disable spin
  831. AngularVelocity = Vector3.Zero;
  832. else
  833. AngularVelocity = new Vector3((float) (OmegaAxis.X*OmegaSpinRate),
  834. (float) (OmegaAxis.Y*OmegaSpinRate),
  835. (float) (OmegaAxis.Z*OmegaSpinRate));
  836. }
  837. /// <summary>
  838. /// </summary>
  839. [ProtoMember(19)]
  840. public Vector3 Acceleration
  841. {
  842. get { return m_acceleration; }
  843. set { m_acceleration = value; }
  844. }
  845. [ProtoMember(20)]
  846. public string Description
  847. {
  848. get { return m_description; }
  849. set
  850. {
  851. if (m_description == value)
  852. return;
  853. if (ParentGroup != null)
  854. ParentGroup.HasGroupChanged = true;
  855. m_description = value;
  856. }
  857. }
  858. /// <value>
  859. /// Text color.
  860. /// </value>
  861. [XmlIgnore]
  862. [ProtoMember(21)]
  863. public Color Color { get; set; }
  864. public void UpdateColor(Color c, bool triggerChangedColor)
  865. {
  866. if (c.A != Color.A ||
  867. c.B != Color.B ||
  868. c.G != Color.G ||
  869. c.R != Color.R)
  870. {
  871. if (ParentGroup != null)
  872. ParentGroup.HasGroupChanged = true;
  873. Color = c;
  874. if (triggerChangedColor)
  875. TriggerScriptChangedEvent(Changed.COLOR);
  876. /* ScheduleFullUpdate() need not be called b/c after
  877. * setting the color, the text will be set, so then
  878. * ScheduleFullUpdate() will be called. */
  879. //ScheduleFullUpdate();
  880. }
  881. }
  882. [ProtoMember(22)]
  883. public string Text
  884. {
  885. get
  886. {
  887. string returnstr = m_text;
  888. if (returnstr.Length > 255)
  889. {
  890. returnstr = returnstr.Substring(0, 254);
  891. }
  892. return returnstr;
  893. }
  894. set
  895. {
  896. if (m_text == value)
  897. return;
  898. if (ParentGroup != null)
  899. ParentGroup.HasGroupChanged = true;
  900. m_text = value;
  901. }
  902. }
  903. [ProtoMember(23)]
  904. public string SitName
  905. {
  906. get { return m_sitName; }
  907. set
  908. {
  909. if (m_sitName == value)
  910. return;
  911. if (ParentGroup != null)
  912. ParentGroup.HasGroupChanged = true;
  913. m_sitName = value;
  914. }
  915. }
  916. [ProtoMember(24)]
  917. public string TouchName
  918. {
  919. get { return m_touchName; }
  920. set
  921. {
  922. if (m_touchName == value)
  923. return;
  924. if (ParentGroup != null)
  925. ParentGroup.HasGroupChanged = true;
  926. m_touchName = value;
  927. }
  928. }
  929. [ProtoMember(25)]
  930. public int LinkNum
  931. {
  932. get { return m_linkNum; }
  933. set
  934. {
  935. if (m_linkNum == value)
  936. return;
  937. if (ParentGroup != null)
  938. ParentGroup.HasGroupChanged = true;
  939. m_linkNum = value;
  940. }
  941. }
  942. [ProtoMember(26)]
  943. public byte ClickAction
  944. {
  945. get { return m_clickAction; }
  946. set
  947. {
  948. if (m_clickAction == value)
  949. return;
  950. if (ParentGroup != null)
  951. ParentGroup.HasGroupChanged = true;
  952. m_clickAction = value;
  953. }
  954. }
  955. [ProtoMember(27)]
  956. public PrimitiveBaseShape Shape
  957. {
  958. get { return m_shape; }
  959. set
  960. {
  961. ValidpartOOB = false;
  962. if (ParentGroup != null)
  963. ParentGroup.HasGroupChanged = true;
  964. bool shape_changed = false;
  965. // TODO: this should really be restricted to the right
  966. // set of attributes on shape change. For instance,
  967. // changing the lighting on a shape shouldn't cause
  968. // this.
  969. if (m_shape != null)
  970. shape_changed = true;
  971. m_shape = value;
  972. if (shape_changed)
  973. TriggerScriptChangedEvent(Changed.SHAPE);
  974. }
  975. }
  976. public Vector3 Scale
  977. {
  978. get { return m_shape.Scale; }
  979. set
  980. {
  981. ValidpartOOB = false;
  982. if (m_shape != null)
  983. {
  984. if (m_shape.Scale != value)
  985. {
  986. StoreUndoState();
  987. if (ParentGroup != null)
  988. ParentGroup.HasGroupChanged = true;
  989. m_shape.Scale = value;
  990. PhysicsActor actor = PhysActor;
  991. if (actor != null && m_parentGroup != null &&
  992. m_parentGroup.Scene != null &&
  993. m_parentGroup.Scene.PhysicsScene != null)
  994. actor.Size = m_shape.Scale;
  995. TriggerScriptChangedEvent(Changed.SCALE);
  996. }
  997. }
  998. }
  999. }
  1000. /// <summary>
  1001. /// Used for media on a prim.
  1002. /// </summary>
  1003. /// Do not change this value directly - always do it through an IMoapModule.
  1004. [ProtoMember(29)]
  1005. public string MediaUrl
  1006. {
  1007. get { return m_mediaUrl; }
  1008. set
  1009. {
  1010. if (m_mediaUrl == value)
  1011. return;
  1012. m_mediaUrl = value;
  1013. if (ParentGroup != null)
  1014. ParentGroup.HasGroupChanged = true;
  1015. }
  1016. }
  1017. [XmlIgnore]
  1018. public bool CreateSelected { get; set; }
  1019. [XmlIgnore]
  1020. public bool IsSelected
  1021. {
  1022. get { return m_IsSelected; }
  1023. set
  1024. {
  1025. if (m_IsSelected != value)
  1026. {
  1027. if (PhysActor != null)
  1028. {
  1029. PhysActor.Selected = value;
  1030. }
  1031. if (ParentID != 0 && ParentGroup != null &&
  1032. ParentGroup.RootPart != null && ParentGroup.RootPart != this &&
  1033. ParentGroup.RootPart.IsSelected != value)
  1034. ParentGroup.RootPart.IsSelected = value;
  1035. m_IsSelected = value;
  1036. }
  1037. }
  1038. }
  1039. #endregion
  1040. #region Public Properties with only Get
  1041. private UUID _parentUUID = UUID.Zero;
  1042. private float m_friction;
  1043. private float m_density;
  1044. private float m_gravityMultiplier;
  1045. private float m_restitution;
  1046. public SceneObjectGroup ParentGroup
  1047. {
  1048. get { return m_parentGroup; }
  1049. }
  1050. public scriptEvents ScriptEvents
  1051. {
  1052. get { return AggregateScriptEvents; }
  1053. }
  1054. public bool Stopped
  1055. {
  1056. get
  1057. {
  1058. double threshold = 0.02;
  1059. return (Math.Abs(Velocity.X) < threshold &&
  1060. Math.Abs(Velocity.Y) < threshold &&
  1061. Math.Abs(Velocity.Z) < threshold &&
  1062. Math.Abs(AngularVelocity.X) < threshold &&
  1063. Math.Abs(AngularVelocity.Y) < threshold &&
  1064. Math.Abs(AngularVelocity.Z) < threshold);
  1065. }
  1066. }
  1067. [ProtoMember(39)]
  1068. public uint Category
  1069. {
  1070. get { return _category; }
  1071. set { _category = value; }
  1072. }
  1073. [ProtoMember(40)]
  1074. public int OwnershipCost
  1075. {
  1076. get { return _ownershipCost; }
  1077. set { _ownershipCost = value; }
  1078. }
  1079. [XmlIgnore]
  1080. public virtual UUID RegionID
  1081. {
  1082. get
  1083. {
  1084. if (ParentGroup != null && ParentGroup.Scene != null)
  1085. return ParentGroup.Scene.RegionInfo.RegionID;
  1086. else
  1087. return UUID.Zero;
  1088. }
  1089. set { } // read only
  1090. }
  1091. public Vector3 AbsolutePosition
  1092. {
  1093. get
  1094. {
  1095. if (IsAttachment)
  1096. return GroupPosition;
  1097. return GetWorldPosition();
  1098. }
  1099. set { }
  1100. }
  1101. public ISceneEntity ParentEntity
  1102. {
  1103. get { return m_parentGroup; }
  1104. }
  1105. [ProtoMember(30)]
  1106. public Quaternion SitTargetOrientation { get; set; }
  1107. [ProtoMember(31)]
  1108. public Vector3 SitTargetPosition { get; set; }
  1109. [ProtoMember(32)]
  1110. public Vector3 OmegaAxis { get; set; }
  1111. [ProtoMember(33)]
  1112. public double OmegaSpinRate { get; set; }
  1113. [ProtoMember(34)]
  1114. public double OmegaGain { get; set; }
  1115. [ProtoMember(35)]
  1116. public uint ParentID
  1117. {
  1118. get { return _parentID; }
  1119. set { _parentID = value; }
  1120. }
  1121. [ProtoMember(36)]
  1122. public int CreationDate { get; set; }
  1123. [ProtoMember(37)]
  1124. public int SalePrice
  1125. {
  1126. get { return _salePrice; }
  1127. set { _salePrice = value; }
  1128. }
  1129. [ProtoMember(38)]
  1130. public byte ObjectSaleType
  1131. {
  1132. get { return _objectSaleType; }
  1133. set { _objectSaleType = value; }
  1134. }
  1135. [ProtoMember(43)]
  1136. public UUID GroupID
  1137. {
  1138. get { return _groupID; }
  1139. set { _groupID = value; }
  1140. }
  1141. [ProtoMember(44)]
  1142. public UUID OwnerID
  1143. {
  1144. get { return _ownerID; }
  1145. set { _ownerID = value; }
  1146. }
  1147. [ProtoMember(45)]
  1148. public UUID LastOwnerID { get; set; }
  1149. [ProtoMember(46)]
  1150. public uint BaseMask
  1151. {
  1152. get { return _baseMask; }
  1153. set { _baseMask = value; }
  1154. }
  1155. [ProtoMember(101)]
  1156. public uint OwnerMask
  1157. {
  1158. get { return _ownerMask; }
  1159. set { _ownerMask = value; }
  1160. }
  1161. [ProtoMember(47)]
  1162. public uint GroupMask
  1163. {
  1164. get { return _groupMask; }
  1165. set { _groupMask = value; }
  1166. }
  1167. [ProtoMember(48)]
  1168. public uint EveryoneMask
  1169. {
  1170. get { return _everyoneMask; }
  1171. set { _everyoneMask = value; }
  1172. }
  1173. [ProtoMember(49)]
  1174. public uint NextOwnerMask
  1175. {
  1176. get { return _nextOwnerMask; }
  1177. set { _nextOwnerMask = value; }
  1178. }
  1179. [ProtoMember(50)]
  1180. public byte PhysicsType { get; set; }
  1181. [ProtoMember(51)]
  1182. public float Density
  1183. {
  1184. get
  1185. {
  1186. if (m_density != 0)
  1187. return m_density;
  1188. return (m_density = 1000f);
  1189. }
  1190. set { m_density = value; }
  1191. }
  1192. [ProtoMember(52)]
  1193. public float Friction
  1194. {
  1195. get
  1196. {
  1197. if (m_friction != 0)
  1198. return m_friction;
  1199. return (m_friction = 0.6f);
  1200. }
  1201. set { m_friction = value; }
  1202. }
  1203. [ProtoMember(53)]
  1204. public float Restitution
  1205. {
  1206. get
  1207. {
  1208. if (m_restitution != 0)
  1209. return m_restitution;
  1210. return (m_restitution = 0.5f);
  1211. }
  1212. set { m_restitution = value; }
  1213. }
  1214. [ProtoMember(54)]
  1215. public float GravityMultiplier
  1216. {
  1217. get
  1218. {
  1219. if (m_gravityMultiplier != 0)
  1220. return m_gravityMultiplier;
  1221. return (m_gravityMultiplier = 1);
  1222. }
  1223. set { m_gravityMultiplier = value; }
  1224. }
  1225. /// <summary>
  1226. /// Property flags. See OpenMetaverse.PrimFlags
  1227. /// </summary>
  1228. /// Example properties are PrimFlags.Phantom and PrimFlags.DieAtEdge
  1229. [ProtoMember(55)]
  1230. public PrimFlags Flags
  1231. {
  1232. get { return _flags; }
  1233. set
  1234. {
  1235. // MainConsole.Instance.DebugFormat("[SOP]: Setting flags for {0} {1} to {2}", UUID, Name, value);
  1236. //if (ParentGroup != null && _flags != value)
  1237. // ParentGroup.HasGroupChanged = true;
  1238. _flags = value;
  1239. }
  1240. }
  1241. [XmlIgnore]
  1242. public List<UUID> SitTargetAvatar { get; set; }
  1243. [XmlIgnore]
  1244. public UUID ParentUUID
  1245. {
  1246. get
  1247. {
  1248. if (ParentGroup != null)
  1249. _parentUUID = ParentGroup.UUID;
  1250. return _parentUUID;
  1251. }
  1252. set
  1253. {
  1254. if (ParentGroup != null)
  1255. ParentGroup.HasGroupChanged = true;
  1256. _parentUUID = value;
  1257. }
  1258. }
  1259. [XmlIgnore]
  1260. [ProtoMember(56)]
  1261. public string SitAnimation
  1262. {
  1263. get { return m_sitAnimation; }
  1264. set
  1265. {
  1266. if (ParentGroup != null)
  1267. ParentGroup.HasGroupChanged = true;
  1268. m_sitAnimation = value;
  1269. }
  1270. }
  1271. [ProtoMember(57)]
  1272. public UUID CollisionSound
  1273. {
  1274. get { return m_collisionSound; }
  1275. set
  1276. {
  1277. if (ParentGroup != null)
  1278. ParentGroup.HasGroupChanged = true;
  1279. m_collisionSound = value;
  1280. //Why?
  1281. //aggregateScriptEvents();
  1282. }
  1283. }
  1284. [ProtoMember(58)]
  1285. public UUID CollisionSprite
  1286. {
  1287. get { return m_collisionSprite; }
  1288. set
  1289. {
  1290. if (ParentGroup != null)
  1291. ParentGroup.HasGroupChanged = true;
  1292. m_collisionSprite = value;
  1293. }
  1294. }
  1295. [ProtoMember(59)]
  1296. public float CollisionSoundVolume
  1297. {
  1298. get { return m_collisionSoundVolume; }
  1299. set
  1300. {
  1301. if (ParentGroup != null)
  1302. ParentGroup.HasGroupChanged = true;
  1303. m_collisionSoundVolume = value;
  1304. }
  1305. }
  1306. #endregion Public Properties with only Get
  1307. #region Private Methods
  1308. public void FinishedSerializingGenericProperties()
  1309. {
  1310. if ((APIDEnabled || PIDActive) && this.ParentEntity != null) //Make sure to activate it
  1311. this.ParentEntity.Scene.EventManager.OnFrame += UpdateLookAt;
  1312. }
  1313. private void UpdateOOBfromOOBs()
  1314. {
  1315. m_partOOBoffset = Vector3.Zero;
  1316. Vector3 ts = Scale;
  1317. m_partOOBsize.X = ts.X*0.5f;
  1318. m_partOOBsize.Y = ts.Y*0.5f;
  1319. m_partOOBsize.Z = ts.Z*0.5f;
  1320. m_partBSphereRadiusSQ = m_partOOBsize.LengthSquared();
  1321. ValidpartOOB = true;
  1322. }
  1323. // distance from aabb to point ( untested)
  1324. public float AABdistanceToSQ(Vector3 target)
  1325. {
  1326. // distance to group in world
  1327. Vector3 vtmp = target - m_groupPosition; // assume this updated
  1328. if (ParentID != 0)
  1329. {
  1330. // rotate into group reference
  1331. vtmp *= Quaternion.Inverse(ParentGroup.GroupRotation);
  1332. // move into offseted local ref
  1333. vtmp -= m_offsetPosition;
  1334. }
  1335. // rotate into local reference ( part or grp )
  1336. vtmp *= Quaternion.Inverse(GetRotationOffset());
  1337. // now oob pos
  1338. vtmp -= OOBoffset; // force update
  1339. Vector3 box = OOBsize;
  1340. // hack distance to box: inside == 0
  1341. if (vtmp.X > 0)
  1342. {
  1343. vtmp.X -= box.X;
  1344. if (vtmp.X < 0.0)
  1345. vtmp.X = 0.0f;
  1346. }
  1347. else
  1348. {
  1349. vtmp.X += box.X;
  1350. if (vtmp.X > 0.0)
  1351. vtmp.X = 0.0f;
  1352. }
  1353. if (vtmp.Y > 0)
  1354. {
  1355. vtmp.Y -= box.Y;
  1356. if (vtmp.Y < 0.0)
  1357. vtmp.Y = 0.0f;
  1358. }
  1359. else
  1360. {
  1361. vtmp.Y += box.Y;
  1362. if (vtmp.Y > 0.0)
  1363. vtmp.Y = 0.0f;
  1364. }
  1365. if (vtmp.Z > 0)
  1366. {
  1367. vtmp.Z -= box.Z;
  1368. if (vtmp.Z < 0.0)
  1369. vtmp.Z = 0.0f;
  1370. }
  1371. else
  1372. {
  1373. vtmp.Z += box.Z;
  1374. if (vtmp.Z > 0.0)
  1375. vtmp.Z = 0.0f;
  1376. }
  1377. return vtmp.LengthSquared();
  1378. }
  1379. // distance from aabb to point ( untested)
  1380. // if smaller than simplied distance to group returns that one
  1381. // hack to send root prims first
  1382. public float clampedAABdistanceToSQ(Vector3 target)
  1383. {
  1384. float grpdSQ = 0;
  1385. // distance to group in world
  1386. Vector3 vtmp = target - m_groupPosition; // assume this updated
  1387. if (ParentID != 0)
  1388. {
  1389. // rotate into group reference
  1390. vtmp *= Quaternion.Inverse(ParentGroup.GroupRotation);
  1391. // compute distance to grp oob
  1392. Vector3 grpv = vtmp - ParentGroup.OOBoffset;
  1393. grpdSQ = grpv.LengthSquared() - ParentGroup.BSphereRadiusSQ;
  1394. if (grpdSQ < 0)
  1395. grpdSQ = 0;
  1396. // back
  1397. // move into offseted local ref
  1398. vtmp -= m_offsetPosition;
  1399. }
  1400. // rotate into local reference
  1401. vtmp *= Quaternion.Inverse(GetRotationOffset());
  1402. // now oob pos
  1403. vtmp -= OOBoffset; // force update
  1404. Vector3 box = OOBsize;
  1405. // ha…

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