PageRenderTime 72ms CodeModel.GetById 9ms RepoModel.GetById 0ms 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
  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. // hack distance to box: inside == 0
  1406. if (vtmp.X > 0)
  1407. {
  1408. vtmp.X -= box.X;
  1409. if (vtmp.X < 0.0)
  1410. vtmp.X = 0.0f;
  1411. }
  1412. else
  1413. {
  1414. vtmp.X += box.X;
  1415. if (vtmp.X > 0.0)
  1416. vtmp.X = 0.0f;
  1417. }
  1418. if (vtmp.Y > 0)
  1419. {
  1420. vtmp.Y -= box.Y;
  1421. if (vtmp.Y < 0.0)
  1422. vtmp.Y = 0.0f;
  1423. }
  1424. else
  1425. {
  1426. vtmp.Y += box.Y;
  1427. if (vtmp.Y > 0.0)
  1428. vtmp.Y = 0.0f;
  1429. }
  1430. if (vtmp.Z > 0)
  1431. {
  1432. vtmp.Z -= box.Z;
  1433. if (vtmp.Z < 0.0)
  1434. vtmp.Z = 0.0f;
  1435. }
  1436. else
  1437. {
  1438. vtmp.Z += box.Z;
  1439. if (vtmp.Z > 0.0)
  1440. vtmp.Z = 0.0f;
  1441. }
  1442. float distSQ = vtmp.LengthSquared();
  1443. if (ParentID != 0 && distSQ < grpdSQ)
  1444. return grpdSQ;
  1445. else
  1446. return distSQ;
  1447. }
  1448. private uint ApplyMask(uint val, bool set, uint mask)
  1449. {
  1450. if (set)
  1451. {
  1452. return val |= mask;
  1453. }
  1454. else
  1455. {
  1456. return val &= ~mask;
  1457. }
  1458. }
  1459. private void SendObjectPropertiesToClient(UUID AgentID)
  1460. {
  1461. IScenePresence SP = ParentGroup.Scene.GetScenePresence(AgentID);
  1462. if (SP != null)
  1463. m_parentGroup.GetProperties(SP.ControllingClient);
  1464. }
  1465. #endregion Private Methods
  1466. #region Public Methods
  1467. internal bool m_hasSubscribedToCollisionEvent;
  1468. public void FixOffsetPosition(Vector3 value, bool single)
  1469. {
  1470. bool triggerMoving_End = false;
  1471. if (m_offsetPosition != value)
  1472. {
  1473. triggerMoving_End = true;
  1474. TriggerScriptMovingStartEvent();
  1475. }
  1476. StoreUndoState();
  1477. m_offsetPosition = value;
  1478. if (ParentEntity != null)
  1479. ParentEntity.ScheduleGroupTerseUpdate();
  1480. ValidpartOOB = false;
  1481. if (ParentGroup != null && !ParentGroup.IsDeleted)
  1482. {
  1483. ParentGroup.HasGroupChanged = true;
  1484. PhysicsObject actor = PhysActor;
  1485. if (_parentID != 0 && actor != null && (single || !actor.IsPhysical))
  1486. {
  1487. actor.Position = GetWorldPosition();
  1488. actor.Orientation = GetWorldRotation();
  1489. }
  1490. }
  1491. if (triggerMoving_End)
  1492. TriggerScriptMovingEndEvent();
  1493. }
  1494. public bool AddFlag(PrimFlags flag)
  1495. {
  1496. // PrimFlags prevflag = Flags;
  1497. if ((Flags & flag) == 0)
  1498. {
  1499. //MainConsole.Instance.Debug("Adding flag: " + ((PrimFlags) flag).ToString());
  1500. Flags |= flag;
  1501. if (flag == PrimFlags.TemporaryOnRez)
  1502. ResetExpire();
  1503. object[] o = new object[2];
  1504. o[0] = this;
  1505. o[1] = flag;
  1506. m_parentGroup.Scene.AuroraEventManager.FireGenericEventHandler("ObjectAddedFlag", o);
  1507. return true;
  1508. }
  1509. return false;
  1510. // MainConsole.Instance.Debug("Aprev: " + prevflag.ToString() + " curr: " + Flags.ToString());
  1511. }
  1512. public void AddNewParticleSystem(Primitive.ParticleSystem pSystem)
  1513. {
  1514. ParticleSystem = pSystem.GetBytes();
  1515. }
  1516. public void RemoveParticleSystem()
  1517. {
  1518. ParticleSystem = Utils.EmptyBytes;
  1519. }
  1520. public void AddTextureAnimation(Primitive.TextureAnimation pTexAnim)
  1521. {
  1522. byte[] data = new byte[16];
  1523. int pos = 0;
  1524. // The flags don't like conversion from uint to byte, so we have to do
  1525. // it the crappy way. See the above function :(
  1526. data[pos] = ConvertScriptUintToByte((uint) pTexAnim.Flags);
  1527. pos++;
  1528. data[pos] = (byte) pTexAnim.Face;
  1529. pos++;
  1530. data[pos] = (byte) pTexAnim.SizeX;
  1531. pos++;
  1532. data[pos] = (byte) pTexAnim.SizeY;
  1533. pos++;
  1534. Utils.FloatToBytes(pTexAnim.Start).CopyTo(data, pos);
  1535. Utils.FloatToBytes(pTexAnim.Length).CopyTo(data, pos + 4);
  1536. Utils.FloatToBytes(pTexAnim.Rate).CopyTo(data, pos + 8);
  1537. TextureAnimation = data;
  1538. }
  1539. public void AdjustSoundGain(double volume)
  1540. {
  1541. if (volume > 1)
  1542. volume = 1;
  1543. if (volume < 0)
  1544. volume = 0;
  1545. m_parentGroup.Scene.ForEachScenePresence(delegate(IScenePresence sp)
  1546. {
  1547. if (!sp.IsChildAgent)
  1548. sp.ControllingClient.SendAttachedSoundGainChange(UUID,
  1549. (float
  1550. )
  1551. volume);
  1552. });
  1553. }
  1554. /// <summary>
  1555. /// hook to the physics scene to apply impulse
  1556. /// This is sent up to the group, which then finds the root prim
  1557. /// and applies the force on the root prim of the group
  1558. /// </summary>
  1559. /// <param name="impulsei">Vector force</param>
  1560. /// <param name="localGlobalTF">true for the local frame, false for the global frame</param>
  1561. public void ApplyImpulse(Vector3 impulsei, bool localGlobalTF)
  1562. {
  1563. Vector3 impulse = impulsei;
  1564. if (localGlobalTF)
  1565. {
  1566. Quaternion grot = GetWorldRotation();
  1567. Quaternion AXgrot = grot;
  1568. Vector3 AXimpulsei = impulsei;
  1569. Vector3 newimpulse = AXimpulsei*AXgrot;
  1570. impulse = newimpulse;
  1571. }
  1572. if (m_parentGroup != null)
  1573. {
  1574. m_parentGroup.applyImpulse(impulse);
  1575. }
  1576. }
  1577. /// <summary>
  1578. /// hook to the physics scene to apply angular impulse
  1579. /// This is sent up to the group, which then finds the root prim
  1580. /// and applies the force on the root prim of the group
  1581. /// </summary>
  1582. /// <param name="impulsei">Vector force</param>
  1583. /// <param name="localGlobalTF">true for the local frame, false for the global frame</param>
  1584. public void ApplyAngularImpulse(Vector3 impulsei, bool localGlobalTF)
  1585. {
  1586. Vector3 impulse = impulsei;
  1587. if (localGlobalTF)
  1588. {
  1589. Quaternion grot = GetWorldRotation();
  1590. Quaternion AXgrot = grot;
  1591. Vector3 AXimpulsei = impulsei;
  1592. Vector3 newimpulse = AXimpulsei*AXgrot;
  1593. impulse = newimpulse;
  1594. }
  1595. if (m_parentGroup != null)
  1596. {
  1597. m_parentGroup.applyAngularImpulse(impulse);
  1598. }
  1599. }
  1600. /// <summary>
  1601. /// hook to the physics scene to apply angular impulse
  1602. /// This is sent up to the group, which then finds the root prim
  1603. /// and applies the force on the root prim of the group
  1604. /// </summary>
  1605. /// <param name="impulsei">Vector force</param>
  1606. /// <param name="localGlobalTF">true for the local frame, false for the global frame</param>
  1607. public void SetAngularImpulse(Vector3 impulsei, bool localGlobalTF)
  1608. {
  1609. Vector3 impulse = impulsei;
  1610. if (localGlobalTF)
  1611. {
  1612. Quaternion grot = GetWorldRotation();
  1613. Quaternion AXgrot = grot;
  1614. Vector3 AXimpulsei = impulsei;
  1615. Vector3 newimpulse = AXimpulsei*AXgrot;
  1616. impulse = newimpulse;
  1617. }
  1618. if (m_parentGroup != null)
  1619. {
  1620. m_parentGroup.setAngularImpulse(impulse);
  1621. }
  1622. }
  1623. public bool GetDieAtEdge()
  1624. {
  1625. if (m_parentGroup == null)
  1626. return false;
  1627. if (m_parentGroup.IsDeleted)
  1628. return false;
  1629. return m_parentGroup.RootPart.DIE_AT_EDGE;
  1630. }
  1631. public bool GetReturnAtEdge()
  1632. {
  1633. if (m_parentGroup == null)
  1634. return false;
  1635. if (m_parentGroup.IsDeleted)
  1636. return false;
  1637. return m_parentGroup.RootPart.RETURN_AT_EDGE;
  1638. }
  1639. public void SetReturnAtEdge(bool p)
  1640. {
  1641. if (m_parentGroup == null)
  1642. return;
  1643. if (m_parentGroup.IsDeleted)
  1644. return;
  1645. m_parentGroup.RootPart.RETURN_AT_EDGE = p;
  1646. }
  1647. public bool GetBlockGrab(bool wholeObjectBlock)
  1648. {
  1649. if (m_parentGroup == null)
  1650. return false;
  1651. if (m_parentGroup.IsDeleted)
  1652. return false;
  1653. if (wholeObjectBlock)
  1654. return m_parentGroup.RootPart.BlockGrabObject;
  1655. else
  1656. return m_parentGroup.RootPart.BlockGrab;
  1657. }
  1658. public void SetBlockGrab(bool block, bool wholeObjectBlock)
  1659. {
  1660. if (m_parentGroup == null)
  1661. return;
  1662. if (m_parentGroup.IsDeleted)
  1663. return;
  1664. if (wholeObjectBlock)
  1665. m_parentGroup.RootPart.BlockGrabObject = block;
  1666. else
  1667. m_parentGroup.RootPart.BlockGrab = block;
  1668. }
  1669. public void SetStatusSandbox(bool p)
  1670. {
  1671. if (m_parentGroup == null)
  1672. return;
  1673. if (m_parentGroup.IsDeleted)
  1674. return;
  1675. StatusSandboxPos = m_parentGroup.RootPart.AbsolutePosition;
  1676. m_parentGroup.RootPart.StatusSandbox = p;
  1677. }
  1678. public bool GetStatusSandbox()
  1679. {
  1680. if (m_parentGroup == null)
  1681. return false;
  1682. if (m_parentGroup.IsDeleted)
  1683. return false;
  1684. return m_parentGroup.RootPart.StatusSandbox;
  1685. }
  1686. public int GetAxisRotation(int axis)
  1687. {
  1688. //Cannot use ScriptBaseClass constants as no referance to it currently.
  1689. if (axis == 2) //STATUS_ROTATE_X
  1690. return STATUS_ROTATE_X;
  1691. if (axis == 4) //STATUS_ROTATE_Y
  1692. return STATUS_ROTATE_Y;
  1693. if (axis == 8) //STATUS_ROTATE_Z
  1694. return STATUS_ROTATE_Z;
  1695. return 0;
  1696. }
  1697. public uint GetEffectiveObjectFlags()
  1698. {
  1699. // Commenting this section of code out since it doesn't actually do anything, as enums are handled by
  1700. // value rather than reference
  1701. // PrimFlags f = _flags;
  1702. // if (m_parentGroup == null || m_parentGroup.RootPart == this)
  1703. // f &= ~(PrimFlags.Touch | PrimFlags.Money);
  1704. return (uint) Flags | (uint) LocalFlags;
  1705. }
  1706. public Vector3 GetGeometricCenter()
  1707. {
  1708. if (PhysActor != null)
  1709. {
  1710. return new Vector3(PhysActor.CenterOfMass.X, PhysActor.CenterOfMass.Y, PhysActor.CenterOfMass.Z);
  1711. }
  1712. else
  1713. {
  1714. return new Vector3(0, 0, 0);
  1715. }
  1716. }
  1717. public float GetMass()
  1718. {
  1719. if (ParentGroup.RootPart.UUID == UUID)
  1720. {
  1721. if (PhysActor != null)
  1722. {
  1723. return PhysActor.Mass;
  1724. }
  1725. else
  1726. {
  1727. return 0;
  1728. }
  1729. }
  1730. else
  1731. {
  1732. return ParentGroup.RootPart.GetMass();
  1733. }
  1734. }
  1735. public Vector3 GetForce()
  1736. {
  1737. if (PhysActor != null)
  1738. return PhysActor.Force;
  1739. else
  1740. return Vector3.Zero;
  1741. }
  1742. public void GetProperties(IClientAPI client)
  1743. {
  1744. IScenePresence sp;
  1745. if (ParentGroup != null && ParentGroup.Scene != null &&
  1746. (sp = ParentGroup.Scene.GetScenePresence(client.AgentId)) != null)
  1747. sp.SceneViewer.QueuePartsForPropertiesUpdate(new ISceneChildEntity[1] {this});
  1748. }
  1749. /// <summary>
  1750. /// Method for a prim to get it's world position from the group.
  1751. /// Remember, the Group Position simply gives the position of the group itself
  1752. /// </summary>
  1753. /// <returns>A Linked Child Prim objects position in world</returns>
  1754. public Vector3 GetWorldPosition()
  1755. {
  1756. return IsRoot ? GroupPosition : GroupPosition + OffsetPosition*ParentGroup.RootPart.GetRotationOffset();
  1757. }
  1758. /// <summary>
  1759. /// Gets the rotation of this prim offset by the group rotation
  1760. /// </summary>
  1761. /// <returns></returns>
  1762. public Quaternion GetWorldRotation()
  1763. {
  1764. Quaternion newRot = GetRotationOffset();
  1765. if (_parentID != 0)
  1766. {
  1767. Quaternion parentRot = ParentGroup.RootPart.GetRotationOffset();
  1768. newRot = parentRot*newRot;
  1769. }
  1770. return newRot;
  1771. }
  1772. public void MoveToTarget(Vector3 target, float tau)
  1773. {
  1774. if (tau > 0)
  1775. {
  1776. m_parentGroup.moveToTarget(target, tau);
  1777. }
  1778. else
  1779. {
  1780. StopMoveToTarget();
  1781. }
  1782. }
  1783. /// <summary>
  1784. /// Uses a PID to attempt to clamp the object on the Z axis at the given height over tau seconds.
  1785. /// </summary>
  1786. /// <param name="height">Height to hover. Height of zero disables hover.</param>
  1787. /// <param name="hoverType">Determines what the height is relative to </param>
  1788. /// <param name="tau">Number of seconds over which to reach target</param>
  1789. public void SetHoverHeight(float height, PIDHoverType hoverType, float tau)
  1790. {
  1791. m_parentGroup.SetHoverHeight(height, hoverType, tau);
  1792. }
  1793. public void PreloadSound(string sound)
  1794. {
  1795. // UUID ownerID = OwnerID;
  1796. UUID objectID = ParentGroup.RootPart.UUID;
  1797. UUID soundID = UUID.Zero;
  1798. if (!UUID.TryParse(sound, out soundID))
  1799. {
  1800. //Trys to fetch sound id from prim's inventory.
  1801. //Prim's inventory doesn't support non script items yet
  1802. lock (TaskInventory)
  1803. {
  1804. foreach (
  1805. KeyValuePair<UUID, TaskInventoryItem> item in
  1806. TaskInventory.Where(item => item.Value.Name == sound))
  1807. {
  1808. soundID = item.Value.ItemID;
  1809. break;
  1810. }
  1811. }
  1812. }
  1813. m_parentGroup.Scene.ForEachScenePresence(delegate(IScenePresence sp)
  1814. {
  1815. if (sp.IsChildAgent)
  1816. return;
  1817. if (
  1818. !(Util.GetDistanceTo(sp.AbsolutePosition,
  1819. AbsolutePosition) >= 100))
  1820. sp.ControllingClient.SendPreLoadSound(objectID,
  1821. objectID, soundID);
  1822. });
  1823. }
  1824. public bool RemFlag(PrimFlags flag)
  1825. {
  1826. // PrimFlags prevflag = Flags;
  1827. if ((Flags & flag) != 0)
  1828. {
  1829. //MainConsole.Instance.Debug("Removing flag: " + ((PrimFlags)flag).ToString());
  1830. Flags &= ~flag;
  1831. object[] o = new object[2];
  1832. o[0] = this;
  1833. o[1] = flag;
  1834. m_parentGroup.Scene.AuroraEventManager.FireGenericEventHandler("ObjectRemovedFlag", o);
  1835. return true;
  1836. }
  1837. return false;
  1838. //MainConsole.Instance.Debug("prev: " + prevflag.ToString() + " curr: " + Flags.ToString());
  1839. //ScheduleFullUpdate();
  1840. }
  1841. public void ResetEntityIDs()
  1842. {
  1843. UUID = UUID.Random();
  1844. //LinkNum = linkNum;
  1845. Inventory.ResetInventoryIDs(false);
  1846. LocalId = ParentGroup.Scene.SceneGraph.AllocateLocalId();
  1847. //Fix the localID now for the physics engine
  1848. if (m_physActor != null)
  1849. {
  1850. m_physActor.LocalID = LocalId;
  1851. PhysActor.UUID = UUID;
  1852. }
  1853. //Fix the rezzed attribute
  1854. Rezzed = DateTime.UtcNow;
  1855. }
  1856. public void RotLookAt(Quaternion target, float strength, float damping)
  1857. {
  1858. if (IsAttachment)
  1859. {
  1860. /*
  1861. ScenePresence avatar = m_scene.GetScenePresence(rootpart.AttachedAvatar);
  1862. if (avatar != null)
  1863. {
  1864. Rotate the Av?
  1865. } */
  1866. }
  1867. else
  1868. {
  1869. APIDEnabled = true;
  1870. APIDDamp = damping;
  1871. APIDStrength = strength;
  1872. APIDTarget = target;
  1873. }
  1874. }
  1875. public void startLookAt(Quaternion rot, float damp, float strength)
  1876. {
  1877. APIDEnabled = true;
  1878. APIDDamp = damp;
  1879. APIDStrength = strength;
  1880. APIDTarget = rot;
  1881. APIDIterations = 1 + (int) (Math.PI*APIDStrength);
  1882. }
  1883. /// <summary>
  1884. /// Schedule a terse update for this prim. Terse updates only send position,
  1885. /// rotation, velocity, and rotational velocity information.
  1886. /// </summary>
  1887. public void ScheduleTerseUpdate()
  1888. {
  1889. ScheduleUpdate(PrimUpdateFlags.TerseUpdate);
  1890. }
  1891. /// <summary>
  1892. /// Tell all avatars in the Scene about the new update
  1893. /// </summary>
  1894. /// <param name="UpdateFlags"></param>
  1895. public void ScheduleUpdate(PrimUpdateFlags UpdateFlags)
  1896. {
  1897. if (m_parentGroup != null && m_parentGroup.Scene != null)
  1898. m_parentGroup.Scene.ForEachScenePresence(avatar => avatar.AddUpdateToAvatar(this, UpdateFlags));
  1899. }
  1900. public void ScriptSetPhantomStatus(bool Phantom)
  1901. {
  1902. if (m_parentGroup != null)
  1903. {
  1904. m_parentGroup.ScriptSetPhantomStatus(Phantom);
  1905. }
  1906. }
  1907. public void ScriptSetTemporaryStatus(bool Temporary)
  1908. {
  1909. if (m_parentGroup != null)
  1910. {
  1911. m_parentGroup.ScriptSetTemporaryStatus(Temporary);
  1912. }
  1913. }
  1914. public void ScriptSetVolumeDetect(bool SetVD)
  1915. {
  1916. if (m_parentGroup != null)
  1917. {
  1918. m_parentGroup.ScriptSetVolumeDetect(SetVD);
  1919. }
  1920. }
  1921. /// <summary>
  1922. /// Trigger or play an attached sound in this part's inventory.
  1923. /// </summary>
  1924. /// <param name="sound"></param>
  1925. /// <param name="volume"></param>
  1926. /// <param name="triggered"></param>
  1927. /// <param name="flags"></param>
  1928. /// <param name="radius"></param>
  1929. /// <param name="useMaster"></param>
  1930. /// <param name="isMaster"></param>
  1931. public void SendSound(string sound, double volume, bool triggered, byte flags, float radius, bool useMaster,
  1932. bool isMaster)
  1933. {
  1934. if (volume > 1)
  1935. volume = 1;
  1936. if (volume < 0)
  1937. volume = 0;
  1938. UUID ownerID = _ownerID;
  1939. UUID objectID = ParentGroup.RootPart.UUID;
  1940. UUID parentID = GetRootPartUUID();
  1941. UUID soundID = UUID.Zero;
  1942. Vector3 position = AbsolutePosition; // region local
  1943. ulong regionHandle = m_parentGroup.Scene.RegionInfo.RegionHandle;
  1944. if (!UUID.TryParse(sound, out soundID))
  1945. {
  1946. // search sound file from inventory
  1947. lock (TaskInventory)
  1948. {
  1949. foreach (
  1950. KeyValuePair<UUID, TaskInventoryItem> item in
  1951. TaskInventory.Where(
  1952. item => item.Value.Name == sound && item.Value.Type == (int) AssetType.Sound))
  1953. {
  1954. soundID = item.Value.ItemID;
  1955. break;
  1956. }
  1957. }
  1958. }
  1959. if (soundID == UUID.Zero)
  1960. return;
  1961. ISoundModule soundModule = m_parentGroup.Scene.RequestModuleInterface<ISoundModule>();
  1962. if (soundModule != null)
  1963. {
  1964. if (useMaster)
  1965. {
  1966. if (isMaster)
  1967. {
  1968. if (triggered)
  1969. soundModule.TriggerSound(soundID, ownerID, objectID, parentID, volume, position,
  1970. regionHandle, radius);
  1971. else
  1972. soundModule.PlayAttachedSound(soundID, ownerID, objectID, volume, position, flags, radius);
  1973. ParentGroup.PlaySoundMasterPrim = this;
  1974. ownerID = _ownerID;
  1975. objectID = ParentGroup.RootPart.UUID;
  1976. parentID = GetRootPartUUID();
  1977. position = AbsolutePosition; // region local
  1978. regionHandle = ParentGroup.Scene.RegionInfo.RegionHandle;
  1979. if (triggered)
  1980. soundModule.TriggerSound(soundID, ownerID, objectID, parentID, volume, position,
  1981. regionHandle, radius);
  1982. else
  1983. soundModule.PlayAttachedSound(soundID, ownerID, objectID, volume, position, flags, radius);
  1984. foreach (SceneObjectPart prim in ParentGroup.PlaySoundSlavePrims)
  1985. {
  1986. ownerID = prim._ownerID;
  1987. objectID = prim.ParentGroup.RootPart.UUID;
  1988. parentID = prim.GetRootPartUUID();
  1989. position = prim.AbsolutePosition; // region local
  1990. regionHandle = prim.ParentGroup.Scene.RegionInfo.RegionHandle;
  1991. if (triggered)
  1992. soundModule.TriggerSound(soundID, ownerID, objectID, parentID, volume, position,
  1993. regionHandle, radius);
  1994. else
  1995. soundModule.PlayAttachedSound(soundID, ownerID, objectID, volume, position, flags,
  1996. radius);
  1997. }
  1998. ParentGroup.PlaySoundSlavePrims.Clear();
  1999. ParentGroup.PlaySoundMasterPrim = null;
  2000. }
  2001. else
  2002. {
  2003. ParentGroup.PlaySoundSlavePrims.Add(this);
  2004. }
  2005. }
  2006. else
  2007. {
  2008. if (triggered)
  2009. soundModule.TriggerSound(soundID, ownerID, objectID, parentID, volume, position, regionHandle,
  2010. radius);
  2011. else
  2012. soundModule.PlayAttachedSound(soundID, ownerID, objectID, volume, position, flags, radius);
  2013. }
  2014. }
  2015. }
  2016. public void SetAvatarOnSitTarget(UUID avatarID)
  2017. {
  2018. lock (SitTargetAvatar)
  2019. {
  2020. if (!SitTargetAvatar.Contains(avatarID))
  2021. SitTargetAvatar.Add(avatarID);
  2022. }
  2023. TriggerScriptChangedEvent(Changed.LINK);
  2024. }
  2025. public void RemoveAvatarOnSitTarget(UUID avatarID)
  2026. {
  2027. lock (SitTargetAvatar)
  2028. {
  2029. if (SitTargetAvatar.Contains(avatarID))
  2030. SitTargetAvatar.Remove(avatarID);
  2031. }
  2032. TriggerScriptChangedEvent(Changed.LINK);
  2033. }
  2034. public void SetAxisRotation(int axis, int rotate)
  2035. {
  2036. if (m_parentGroup != null)
  2037. {
  2038. m_parentGroup.SetAxisRotation(axis, rotate);
  2039. }
  2040. //Cannot use ScriptBaseClass constants as no referance to it currently.
  2041. if ((axis & 2) == 2) //STATUS_ROTATE_X
  2042. STATUS_ROTATE_X = rotate;
  2043. if ((axis & 4) == 4) //STATUS_ROTATE_Y
  2044. STATUS_ROTATE_Y = rotate;
  2045. if ((axis & 8) == 8) //STATUS_ROTATE_Z
  2046. STATUS_ROTATE_Z = rotate;
  2047. }
  2048. public void SetBuoyancy(float fvalue)
  2049. {
  2050. if (PhysActor != null)
  2051. {
  2052. PhysActor.Buoyancy = fvalue;
  2053. }
  2054. }
  2055. public void SetDieAtEdge(bool p)
  2056. {
  2057. if (m_parentGroup == null)
  2058. return;
  2059. if (m_parentGroup.IsDeleted)
  2060. return;
  2061. m_parentGroup.RootPart.DIE_AT_EDGE = p;
  2062. }
  2063. public void SetFloatOnWater(int floatYN)
  2064. {
  2065. if (PhysActor != null)
  2066. {
  2067. PhysActor.FloatOnWater = floatYN == 1;
  2068. }
  2069. }
  2070. public void SetForce(Vector3 force)
  2071. {
  2072. if (PhysActor != null)
  2073. {
  2074. PhysActor.Force = force;
  2075. }
  2076. }
  2077. public void SetVehicleFlags(int param, bool remove)
  2078. {
  2079. if (remove)
  2080. VehicleFlags.Remove(param);
  2081. else
  2082. VehicleFlags.Add(param);
  2083. if (PhysActor != null)
  2084. PhysActor.VehicleFlags(param, remove);
  2085. }
  2086. public void SetVehicleType(int type)
  2087. {
  2088. VehicleType = type;
  2089. if (PhysActor != null)
  2090. PhysActor.VehicleType = type;
  2091. }
  2092. public void SetVehicleFloatParam(int param, float value)
  2093. {
  2094. VehicleParameters[param.ToString()] = value;
  2095. if (PhysActor != null)
  2096. PhysActor.VehicleFloatParam(param, value);
  2097. }
  2098. public void SetVehicleVectorParam(int param, Vector3 value)
  2099. {
  2100. VehicleParameters[param.ToString()] = value;
  2101. if (PhysActor != null)
  2102. PhysActor.VehicleVectorParam(param, value);
  2103. }
  2104. public void SetVehicleRotationParam(int param, Quaternion value)
  2105. {
  2106. VehicleParameters[param.ToString()] = value;
  2107. if (PhysActor != null)
  2108. PhysActor.VehicleRotationParam(param, value);
  2109. }
  2110. /// <summary>
  2111. /// Set the color of prim faces
  2112. /// </summary>
  2113. /// <param name="color"></param>
  2114. /// <param name="face"></param>
  2115. public void SetFaceColor(Vector3 color, int face)
  2116. {
  2117. Primitive.TextureEntry tex = Shape.Textures;
  2118. Color4 texcolor;
  2119. if (face >= 0 && face < GetNumberOfSides())
  2120. {
  2121. texcolor = tex.CreateFace((uint) face).RGBA;
  2122. texcolor.R = Util.Clip(color.X, 0.0f, 1.0f);
  2123. texcolor.G = Util.Clip(color.Y, 0.0f, 1.0f);
  2124. texcolor.B = Util.Clip(color.Z, 0.0f, 1.0f);
  2125. if (!(tex.FaceTextures[face].RGBA.R == texcolor.R &&
  2126. tex.FaceTextures[face].RGBA.G == texcolor.G &&
  2127. tex.FaceTextures[face].RGBA.B == texcolor.B))
  2128. {
  2129. tex.FaceTextures[face].RGBA = texcolor;
  2130. UpdateTexture(tex, true);
  2131. }
  2132. }
  2133. else if (face == ALL_SIDES)
  2134. {
  2135. bool changed = false;
  2136. for (uint i = 0; i < GetNumberOfSides(); i++)
  2137. {
  2138. if (tex.FaceTextures[i] != null)
  2139. {
  2140. texcolor = tex.FaceTextures[i].RGBA;
  2141. texcolor.R = Util.Clip(color.X, 0.0f, 1.0f);
  2142. texcolor.G = Util.Clip(color.Y, 0.0f, 1.0f);
  2143. texcolor.B = Util.Clip(color.Z, 0.0f, 1.0f);
  2144. if (!(tex.FaceTextures[i].RGBA.R == texcolor.R &&
  2145. tex.FaceTextures[i].RGBA.G == texcolor.G &&
  2146. tex.FaceTextures[i].RGBA.B == texcolor.B))
  2147. changed = true;
  2148. tex.FaceTextures[i].RGBA = texcolor;
  2149. }
  2150. texcolor = tex.DefaultTexture.RGBA;
  2151. texcolor.R = Util.Clip(color.X, 0.0f, 1.0f);
  2152. texcolor.G = Util.Clip(color.Y, 0.0f, 1.0f);
  2153. texcolor.B = Util.Clip(color.Z, 0.0f, 1.0f);
  2154. if (!(tex.DefaultTexture.RGBA.R == texcolor.R &&
  2155. tex.DefaultTexture.RGBA.G == texcolor.G &&
  2156. tex.DefaultTexture.RGBA.B == texcolor.B))
  2157. changed = true;
  2158. tex.DefaultTexture.RGBA = texcolor;
  2159. }
  2160. if (changed)
  2161. UpdateTexture(tex, true);
  2162. }
  2163. }
  2164. /// <summary>
  2165. /// Get the number of sides that this part has.
  2166. /// </summary>
  2167. /// <returns></returns>
  2168. public int GetNumberOfSides()
  2169. {
  2170. int ret = 0;
  2171. bool hasCut;
  2172. bool hasHollow;
  2173. bool hasDimple;
  2174. bool hasProfileCut;
  2175. PrimType primType = GetPrimType();
  2176. HasCutHollowDimpleProfileCut(primType, Shape, out hasCut, out hasHollow, out hasDimple, out hasProfileCut);
  2177. switch (primType)
  2178. {
  2179. case PrimType.BOX:
  2180. ret = 6;
  2181. if (hasCut) ret += 2;
  2182. if (hasHollow) ret += 1;
  2183. break;
  2184. case PrimType.CYLINDER:
  2185. ret = 3;
  2186. if (hasCut) ret += 2;
  2187. if (hasHollow) ret += 1;
  2188. break;
  2189. case PrimType.PRISM:
  2190. ret = 5;
  2191. if (hasCut) ret += 2;
  2192. if (hasHollow) ret += 1;
  2193. break;
  2194. case PrimType.SPHERE:
  2195. ret = 1;
  2196. if (hasCut) ret += 2;
  2197. if (hasDimple) ret += 2;
  2198. if (hasHollow) ret += 1;
  2199. break;
  2200. case PrimType.TORUS:
  2201. ret = 1;
  2202. if (hasCut) ret += 2;
  2203. if (hasProfileCut) ret += 2;
  2204. if (hasHollow) ret += 1;
  2205. break;
  2206. case PrimType.TUBE:
  2207. ret = 4;
  2208. if (hasCut) ret += 2;
  2209. if (hasProfileCut) ret += 2;
  2210. if (hasHollow) ret += 1;
  2211. break;
  2212. case PrimType.RING:
  2213. ret = 3;
  2214. if (hasCut) ret += 2;
  2215. if (hasProfileCut) ret += 2;
  2216. if (hasHollow) ret += 1;
  2217. break;
  2218. case PrimType.SCULPT:
  2219. // Special mesh handling
  2220. if (this.Shape.SculptType == 5)
  2221. {
  2222. ret = 8; // its a mesh then max 8 faces
  2223. }
  2224. else
  2225. {
  2226. ret = 1; // its a sculpt then max 1 faces
  2227. }
  2228. break;
  2229. }
  2230. return ret;
  2231. }
  2232. /// <summary>
  2233. /// Tell us what type this prim is
  2234. /// </summary>
  2235. /// <returns></returns>
  2236. public PrimType GetPrimType()
  2237. {
  2238. if (Shape.SculptEntry)
  2239. return PrimType.SCULPT;
  2240. if ((Shape.ProfileCurve & 0x07) == (byte) ProfileShape.Square)
  2241. {
  2242. if (Shape.PathCurve == (byte) Extrusion.Straight)
  2243. return PrimType.BOX;
  2244. else if (Shape.PathCurve == (byte) Extrusion.Curve1)
  2245. return PrimType.TUBE;
  2246. }
  2247. else if ((Shape.ProfileCurve & 0x07) == (byte) ProfileShape.Circle)
  2248. {
  2249. if (Shape.PathCurve == (byte) Extrusion.Straight)
  2250. return PrimType.CYLINDER;
  2251. // ProfileCurve seems to combine hole shape and profile curve so we need to only compare against the lower 3 bits
  2252. else if (Shape.PathCurve == (byte) Extrusion.Curve1)
  2253. return PrimType.TORUS;
  2254. }
  2255. else if ((Shape.ProfileCurve & 0x07) == (byte) ProfileShape.HalfCircle)
  2256. {
  2257. if (Shape.PathCurve == (byte) Extrusion.Curve1 || Shape.PathCurve == (byte) Extrusion.Curve2)
  2258. return PrimType.SPHERE;
  2259. }
  2260. else if ((Shape.ProfileCurve & 0x07) == (byte) ProfileShape.EquilateralTriangle)
  2261. {
  2262. if (Shape.PathCurve == (byte) Extrusion.Straight)
  2263. return PrimType.PRISM;
  2264. else if (Shape.PathCurve == (byte) Extrusion.Curve1)
  2265. return PrimType.RING;
  2266. }
  2267. return PrimType.BOX;
  2268. }
  2269. /// <summary>
  2270. /// </summary>
  2271. public void SetParent(ISceneEntity parent)
  2272. {
  2273. m_parentGroup = (SceneObjectGroup) parent;
  2274. }
  2275. // Use this for attachments! LocalID should be avatar's localid
  2276. public void SetParentLocalId(uint localID)
  2277. {
  2278. _parentID = localID;
  2279. }
  2280. /// <summary>
  2281. /// Set the events that this part will pass on to listeners.
  2282. /// </summary>
  2283. /// <param name="scriptid"></param>
  2284. /// <param name="events"></param>
  2285. public void SetScriptEvents(UUID scriptid, long events)
  2286. {
  2287. // scriptEvents oldparts;
  2288. lock (m_scriptEvents)
  2289. {
  2290. if (m_scriptEvents.ContainsKey(scriptid))
  2291. {
  2292. // oldparts = m_scriptEvents[scriptid];
  2293. // remove values from aggregated script events
  2294. //if (m_scriptEvents[scriptid] == (scriptEvents) events)
  2295. // return;
  2296. m_scriptEvents[scriptid] = (scriptEvents) events;
  2297. }
  2298. else
  2299. {
  2300. m_scriptEvents.Add(scriptid, (scriptEvents) events);
  2301. }
  2302. }
  2303. aggregateScriptEvents();
  2304. }
  2305. public void StopLookAt()
  2306. {
  2307. m_parentGroup.RootPart.stopLookAt();
  2308. m_parentGroup.ScheduleGroupTerseUpdate();
  2309. }
  2310. /// <summary>
  2311. /// Set the text displayed for this part.
  2312. /// </summary>
  2313. /// <param name="text"></param>
  2314. /// <param name="color"></param>
  2315. /// <param name="alpha"></param>
  2316. public void SetText(string text, Vector3 color, double alpha)
  2317. {
  2318. //No triggering Changed_Color, so not using Color
  2319. //Color = ...
  2320. UpdateColor(Color.FromArgb((int) (alpha*0xff),
  2321. (int) (color.X*0xff),
  2322. (int) (color.Y*0xff),
  2323. (int) (color.Z*0xff)), false);
  2324. Text = text;
  2325. ScheduleUpdate(PrimUpdateFlags.Text);
  2326. }
  2327. public void StopMoveToTarget()
  2328. {
  2329. m_parentGroup.stopMoveToTarget();
  2330. m_parentGroup.ScheduleGroupTerseUpdate();
  2331. //m_parentGroup.ScheduleGroupForFullUpdate();
  2332. }
  2333. public void StoreUndoState()
  2334. {
  2335. if (!Undoing)
  2336. {
  2337. if (!IgnoreUndoUpdate)
  2338. {
  2339. IBackupModule backup = null;
  2340. if (ParentGroup != null &&
  2341. ParentGroup.Scene != null)
  2342. backup = ParentGroup.Scene.RequestModuleInterface<IBackupModule>();
  2343. if (m_parentGroup != null &&
  2344. ParentGroup.Scene != null &&
  2345. (backup == null || (backup != null && !backup.LoadingPrims)))
  2346. {
  2347. lock (m_undo)
  2348. {
  2349. if (m_undo.Count > 0)
  2350. {
  2351. UndoState last = m_undo.Peek();
  2352. if (last != null)
  2353. {
  2354. if (last.Compare(this))
  2355. return;
  2356. }
  2357. }
  2358. UndoState nUndo = new UndoState(this);
  2359. m_undo.Push(nUndo);
  2360. }
  2361. }
  2362. }
  2363. }
  2364. }
  2365. public EntityIntersection TestIntersectionOBB(Ray iray, Quaternion parentrot, bool frontFacesOnly,
  2366. bool faceCenters)
  2367. {
  2368. // In this case we're using a rectangular prism, which has 6 faces and therefore 6 planes
  2369. // This breaks down into the ray---> plane equation.
  2370. // TODO: Change to take shape into account
  2371. Vector3[] vertexes = new Vector3[8];
  2372. // float[] distance = new float[6];
  2373. Vector3[] FaceA = new Vector3[6]; // vertex A for Facei
  2374. Vector3[] FaceB = new Vector3[6]; // vertex B for Facei
  2375. Vector3[] FaceC = new Vector3[6]; // vertex C for Facei
  2376. Vector3[] FaceD = new Vector3[6]; // vertex D for Facei
  2377. Vector3[] normals = new Vector3[6]; // Normal for Facei
  2378. Vector3[] AAfacenormals = new Vector3[6]; // Axis Aligned face normals
  2379. AAfacenormals[0] = new Vector3(1, 0, 0);
  2380. AAfacenormals[1] = new Vector3(0, 1, 0);
  2381. AAfacenormals[2] = new Vector3(-1, 0, 0);
  2382. AAfacenormals[3] = new Vector3(0, -1, 0);
  2383. AAfacenormals[4] = new Vector3(0, 0, 1);
  2384. AAfacenormals[5] = new Vector3(0, 0, -1);
  2385. Vector3 AmBa = new Vector3(0, 0, 0); // Vertex A - Vertex B
  2386. Vector3 AmBb = new Vector3(0, 0, 0); // Vertex B - Vertex C
  2387. Vector3 cross = new Vector3();
  2388. Vector3 pos = GetWorldPosition();
  2389. Quaternion rot = GetWorldRotation();
  2390. // Variables prefixed with AX are Axiom.Math copies of the LL variety.
  2391. Quaternion AXrot = rot;
  2392. AXrot.Normalize();
  2393. Vector3 AXpos = pos;
  2394. // tScale is the offset to derive the vertex based on the scale.
  2395. // it's different for each vertex because we've got to rotate it
  2396. // to get the world position of the vertex to produce the Oriented Bounding Box
  2397. Vector3 tScale = Vector3.Zero;
  2398. Vector3 AXscale = new Vector3(m_shape.Scale.X*0.5f, m_shape.Scale.Y*0.5f, m_shape.Scale.Z*0.5f);
  2399. //Vector3 pScale = (AXscale) - (AXrot.Inverse() * (AXscale));
  2400. //Vector3 nScale = (AXscale * -1) - (AXrot.Inverse() * (AXscale * -1));
  2401. // rScale is the rotated offset to find a vertex based on the scale and the world rotation.
  2402. Vector3 rScale = new Vector3();
  2403. // Get Vertexes for Faces Stick them into ABCD for each Face
  2404. // Form: Face<vertex>[face] that corresponds to the below diagram
  2405. #region ABCD Face Vertex Map Comment Diagram
  2406. // A _________ B
  2407. // | |
  2408. // | 4 top |
  2409. // |_________|
  2410. // C D
  2411. // A _________ B
  2412. // | Back |
  2413. // | 3 |
  2414. // |_________|
  2415. // C D
  2416. // A _________ B B _________ A
  2417. // | Left | | Right |
  2418. // | 0 | | 2 |
  2419. // |_________| |_________|
  2420. // C D D C
  2421. // A _________ B
  2422. // | Front |
  2423. // | 1 |
  2424. // |_________|
  2425. // C D
  2426. // C _________ D
  2427. // | |
  2428. // | 5 bot |
  2429. // |_________|
  2430. // A B
  2431. #endregion
  2432. #region Plane Decomposition of Oriented Bounding Box
  2433. tScale = new Vector3(AXscale.X, -AXscale.Y, AXscale.Z);
  2434. rScale = tScale*AXrot;
  2435. vertexes[0] = (new Vector3((pos.X + rScale.X), (pos.Y + rScale.Y), (pos.Z + rScale.Z)));
  2436. // vertexes[0].X = pos.X + vertexes[0].X;
  2437. //vertexes[0].Y = pos.Y + vertexes[0].Y;
  2438. //vertexes[0].Z = pos.Z + vertexes[0].Z;
  2439. FaceA[0] = vertexes[0];
  2440. FaceB[3] = vertexes[0];
  2441. FaceA[4] = vertexes[0];
  2442. tScale = AXscale;
  2443. rScale = tScale*AXrot;
  2444. vertexes[1] = (new Vector3((pos.X + rScale.X), (pos.Y + rScale.Y), (pos.Z + rScale.Z)));
  2445. // vertexes[1].X = pos.X + vertexes[1].X;
  2446. // vertexes[1].Y = pos.Y + vertexes[1].Y;
  2447. //vertexes[1].Z = pos.Z + vertexes[1].Z;
  2448. FaceB[0] = vertexes[1];
  2449. FaceA[1] = vertexes[1];
  2450. FaceC[4] = vertexes[1];
  2451. tScale = new Vector3(AXscale.X, -AXscale.Y, -AXscale.Z);
  2452. rScale = tScale*AXrot;
  2453. vertexes[2] = (new Vector3((pos.X + rScale.X), (pos.Y + rScale.Y), (pos.Z + rScale.Z)));
  2454. //vertexes[2].X = pos.X + vertexes[2].X;
  2455. //vertexes[2].Y = pos.Y + vertexes[2].Y;
  2456. //vertexes[2].Z = pos.Z + vertexes[2].Z;
  2457. FaceC[0] = vertexes[2];
  2458. FaceD[3] = vertexes[2];
  2459. FaceC[5] = vertexes[2];
  2460. tScale = new Vector3(AXscale.X, AXscale.Y, -AXscale.Z);
  2461. rScale = tScale*AXrot;
  2462. vertexes[3] = (new Vector3((pos.X + rScale.X), (pos.Y + rScale.Y), (pos.Z + rScale.Z)));
  2463. //vertexes[3].X = pos.X + vertexes[3].X;
  2464. // vertexes[3].Y = pos.Y + vertexes[3].Y;
  2465. // vertexes[3].Z = pos.Z + vertexes[3].Z;
  2466. FaceD[0] = vertexes[3];
  2467. FaceC[1] = vertexes[3];
  2468. FaceA[5] = vertexes[3];
  2469. tScale = new Vector3(-AXscale.X, AXscale.Y, AXscale.Z);
  2470. rScale = tScale*AXrot;
  2471. vertexes[4] = (new Vector3((pos.X + rScale.X), (pos.Y + rScale.Y), (pos.Z + rScale.Z)));
  2472. // vertexes[4].X = pos.X + vertexes[4].X;
  2473. // vertexes[4].Y = pos.Y + vertexes[4].Y;
  2474. // vertexes[4].Z = pos.Z + vertexes[4].Z;
  2475. FaceB[1] = vertexes[4];
  2476. FaceA[2] = vertexes[4];
  2477. FaceD[4] = vertexes[4];
  2478. tScale = new Vector3(-AXscale.X, AXscale.Y, -AXscale.Z);
  2479. rScale = tScale*AXrot;
  2480. vertexes[5] = (new Vector3((pos.X + rScale.X), (pos.Y + rScale.Y), (pos.Z + rScale.Z)));
  2481. // vertexes[5].X = pos.X + vertexes[5].X;
  2482. // vertexes[5].Y = pos.Y + vertexes[5].Y;
  2483. // vertexes[5].Z = pos.Z + vertexes[5].Z;
  2484. FaceD[1] = vertexes[5];
  2485. FaceC[2] = vertexes[5];
  2486. FaceB[5] = vertexes[5];
  2487. tScale = new Vector3(-AXscale.X, -AXscale.Y, AXscale.Z);
  2488. rScale = tScale*AXrot;
  2489. vertexes[6] = (new Vector3((pos.X + rScale.X), (pos.Y + rScale.Y), (pos.Z + rScale.Z)));
  2490. // vertexes[6].X = pos.X + vertexes[6].X;
  2491. // vertexes[6].Y = pos.Y + vertexes[6].Y;
  2492. // vertexes[6].Z = pos.Z + vertexes[6].Z;
  2493. FaceB[2] = vertexes[6];
  2494. FaceA[3] = vertexes[6];
  2495. FaceB[4] = vertexes[6];
  2496. tScale = new Vector3(-AXscale.X, -AXscale.Y, -AXscale.Z);
  2497. rScale = tScale*AXrot;
  2498. vertexes[7] = (new Vector3((pos.X + rScale.X), (pos.Y + rScale.Y), (pos.Z + rScale.Z)));
  2499. // vertexes[7].X = pos.X + vertexes[7].X;
  2500. // vertexes[7].Y = pos.Y + vertexes[7].Y;
  2501. // vertexes[7].Z = pos.Z + vertexes[7].Z;
  2502. FaceD[2] = vertexes[7];
  2503. FaceC[3] = vertexes[7];
  2504. FaceD[5] = vertexes[7];
  2505. #endregion
  2506. // Get our plane normals
  2507. for (int i = 0; i < 6; i++)
  2508. {
  2509. //MainConsole.Instance.Info("[FACECALCULATION]: FaceA[" + i + "]=" + FaceA[i] + " FaceB[" + i + "]=" + FaceB[i] + " FaceC[" + i + "]=" + FaceC[i] + " FaceD[" + i + "]=" + FaceD[i]);
  2510. // Our Plane direction
  2511. AmBa = FaceA[i] - FaceB[i];
  2512. AmBb = FaceB[i] - FaceC[i];
  2513. cross = Vector3.Cross(AmBb, AmBa);
  2514. // normalize the cross product to get the normal.
  2515. normals[i] = cross/cross.Length();
  2516. //MainConsole.Instance.Info("[NORMALS]: normals[ " + i + "]" + normals[i].ToString());
  2517. //distance[i] = (normals[i].X * AmBa.X + normals[i].Y * AmBa.Y + normals[i].Z * AmBa.Z) * -1;
  2518. }
  2519. EntityIntersection result = new EntityIntersection {distance = 1024};
  2520. float c = 0;
  2521. float a = 0;
  2522. float d = 0;
  2523. Vector3 q = new Vector3();
  2524. #region OBB Version 2 Experiment
  2525. //float fmin = 999999;
  2526. //float fmax = -999999;
  2527. //float s = 0;
  2528. //for (int i=0;i<6;i++)
  2529. //{
  2530. //s = iray.Direction.Dot(normals[i]);
  2531. //d = normals[i].Dot(FaceB[i]);
  2532. //if (s == 0)
  2533. //{
  2534. //if (iray.Origin.Dot(normals[i]) > d)
  2535. //{
  2536. //return result;
  2537. //}
  2538. // else
  2539. //{
  2540. //continue;
  2541. //}
  2542. //}
  2543. //a = (d - iray.Origin.Dot(normals[i])) / s;
  2544. //if (iray.Direction.Dot(normals[i]) < 0)
  2545. //{
  2546. //if (a > fmax)
  2547. //{
  2548. //if (a > fmin)
  2549. //{
  2550. //return result;
  2551. //}
  2552. //fmax = a;
  2553. //}
  2554. //}
  2555. //else
  2556. //{
  2557. //if (a < fmin)
  2558. //{
  2559. //if (a < 0 || a < fmax)
  2560. //{
  2561. //return result;
  2562. //}
  2563. //fmin = a;
  2564. //}
  2565. //}
  2566. //}
  2567. //if (fmax > 0)
  2568. // a= fmax;
  2569. //else
  2570. // a=fmin;
  2571. //q = iray.Origin + a * iray.Direction;
  2572. #endregion
  2573. // Loop over faces (6 of them)
  2574. for (int i = 0; i < 6; i++)
  2575. {
  2576. AmBa = FaceA[i] - FaceB[i];
  2577. AmBb = FaceB[i] - FaceC[i];
  2578. d = Vector3.Dot(normals[i], FaceB[i]);
  2579. //if (faceCenters)
  2580. //{
  2581. // c = normals[i].Dot(normals[i]);
  2582. //}
  2583. //else
  2584. //{
  2585. c = Vector3.Dot(iray.Direction, normals[i]);
  2586. //}
  2587. if (c == 0)
  2588. continue;
  2589. a = (d - Vector3.Dot(iray.Origin, normals[i]))/c;
  2590. if (a < 0)
  2591. continue;
  2592. // If the normal is pointing outside the object
  2593. if (Vector3.Dot(iray.Direction, normals[i]) < 0 || !frontFacesOnly)
  2594. {
  2595. //if (faceCenters)
  2596. //{ //(FaceA[i] + FaceB[i] + FaceC[1] + FaceD[i]) / 4f;
  2597. // q = iray.Origin + a * normals[i];
  2598. //}
  2599. //else
  2600. //{
  2601. q = iray.Origin + iray.Direction*a;
  2602. //}
  2603. float distance2 = (float) GetDistanceTo(q, AXpos);
  2604. // Is this the closest hit to the object's origin?
  2605. //if (faceCenters)
  2606. //{
  2607. // distance2 = (float)GetDistanceTo(q, iray.Origin);
  2608. //}
  2609. if (distance2 < result.distance)
  2610. {
  2611. result.distance = distance2;
  2612. result.HitTF = true;
  2613. result.ipoint = q;
  2614. //MainConsole.Instance.Info("[FACE]:" + i.ToString());
  2615. //MainConsole.Instance.Info("[POINT]: " + q.ToString());
  2616. //MainConsole.Instance.Info("[DIST]: " + distance2.ToString());
  2617. if (faceCenters)
  2618. {
  2619. result.normal = AAfacenormals[i]*AXrot;
  2620. Vector3 scaleComponent = AAfacenormals[i];
  2621. float ScaleOffset = 0.5f;
  2622. if (scaleComponent.X != 0) ScaleOffset = AXscale.X;
  2623. if (scaleComponent.Y != 0) ScaleOffset = AXscale.Y;
  2624. if (scaleComponent.Z != 0) ScaleOffset = AXscale.Z;
  2625. ScaleOffset = Math.Abs(ScaleOffset);
  2626. Vector3 offset = result.normal*ScaleOffset;
  2627. result.ipoint = AXpos + offset;
  2628. //pos = (intersectionpoint + offset);
  2629. }
  2630. else
  2631. {
  2632. result.normal = normals[i];
  2633. }
  2634. result.AAfaceNormal = AAfacenormals[i];
  2635. }
  2636. }
  2637. }
  2638. return result;
  2639. }
  2640. public void TriggerScriptChangedEvent(Changed val)
  2641. {
  2642. if (m_parentGroup != null && m_parentGroup.Scene != null)
  2643. m_parentGroup.Scene.EventManager.TriggerOnScriptChangedEvent(this, (uint) val);
  2644. }
  2645. public void TrimPermissions()
  2646. {
  2647. _baseMask &= (uint) PermissionMask.All;
  2648. _ownerMask &= (uint) PermissionMask.All;
  2649. _groupMask &= (uint) PermissionMask.All;
  2650. _everyoneMask &= (uint) PermissionMask.All;
  2651. _nextOwnerMask &= (uint) PermissionMask.All;
  2652. }
  2653. public void Undo()
  2654. {
  2655. lock (m_undo)
  2656. {
  2657. if (m_undo.Count > 0)
  2658. {
  2659. m_redo.Push(new UndoState(this));
  2660. UndoState goback = m_undo.Pop();
  2661. if (goback != null)
  2662. {
  2663. goback.PlaybackState(this);
  2664. }
  2665. }
  2666. }
  2667. }
  2668. public void Redo()
  2669. {
  2670. lock (m_redo)
  2671. {
  2672. if (m_redo.Count > 0)
  2673. {
  2674. UndoState nUndo = new UndoState(this);
  2675. m_undo.Push(nUndo);
  2676. UndoState gofwd = m_redo.Pop();
  2677. if (gofwd != null)
  2678. gofwd.PlayfwdState(this);
  2679. }
  2680. }
  2681. }
  2682. /// <summary>
  2683. /// </summary>
  2684. /// <param name="pos"></param>
  2685. public void UpdateOffSet(Vector3 pos)
  2686. {
  2687. if ((pos.X != OffsetPosition.X) ||
  2688. (pos.Y != OffsetPosition.Y) ||
  2689. (pos.Z != OffsetPosition.Z))
  2690. {
  2691. Vector3 newPos = new Vector3(pos.X, pos.Y, pos.Z);
  2692. if (ParentGroup.RootPart.GetStatusSandbox())
  2693. {
  2694. if (Util.GetDistanceTo(ParentGroup.RootPart.StatusSandboxPos, newPos) > 10)
  2695. {
  2696. ParentGroup.ScriptSetPhysicsStatus(false);
  2697. newPos = OffsetPosition;
  2698. IChatModule chatModule = ParentGroup.Scene.RequestModuleInterface<IChatModule>();
  2699. if (chatModule != null)
  2700. chatModule.SimChat("Hit Sandbox Limit", ChatTypeEnum.DebugChannel, 0x7FFFFFFF,
  2701. ParentGroup.RootPart.AbsolutePosition, Name, UUID, false,
  2702. ParentGroup.Scene);
  2703. }
  2704. }
  2705. ValidpartOOB = false;
  2706. FixOffsetPosition(newPos, true);
  2707. ScheduleTerseUpdate();
  2708. }
  2709. }
  2710. public bool UpdatePrimFlags(bool UsePhysics, bool IsTemporary, bool IsPhantom, bool IsVD,
  2711. ObjectFlagUpdatePacket.ExtraPhysicsBlock[] blocks)
  2712. {
  2713. bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0);
  2714. bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0);
  2715. bool wasPhantom = ((Flags & PrimFlags.Phantom) != 0);
  2716. bool wasVD = VolumeDetectActive;
  2717. bool needsPhysicalRebuild = false;
  2718. if (blocks != null && blocks.Length != 0)
  2719. {
  2720. ObjectFlagUpdatePacket.ExtraPhysicsBlock block = blocks[0];
  2721. //These 2 are static properties, and do require rebuilding the entire physical representation
  2722. if (PhysicsType != block.PhysicsShapeType)
  2723. {
  2724. PhysicsType = block.PhysicsShapeType;
  2725. needsPhysicalRebuild = true; //Gotta rebuild now
  2726. }
  2727. if (Density != block.Density)
  2728. {
  2729. Density = block.Density;
  2730. needsPhysicalRebuild = true; //Gotta rebuild now
  2731. }
  2732. //These 3 are dynamic properties, and don't require rebuilding the physics representation
  2733. if (Friction != block.Friction)
  2734. Friction = block.Friction;
  2735. if (Restitution != block.Restitution)
  2736. Restitution = block.Restitution;
  2737. if (GravityMultiplier != block.GravityMultiplier)
  2738. GravityMultiplier = block.GravityMultiplier;
  2739. }
  2740. if ((UsePhysics == wasUsingPhysics) && (wasTemporary == IsTemporary) && (wasPhantom == IsPhantom) &&
  2741. (IsVD == wasVD))
  2742. return needsPhysicalRebuild;
  2743. // Special cases for VD. VD can only be called from a script
  2744. // and can't be combined with changes to other states. So we can rely
  2745. // that...
  2746. // ... if VD is changed, all others are not.
  2747. // ... if one of the others is changed, VD is not.
  2748. if (IsVD) // VD is active, special logic applies
  2749. {
  2750. // State machine logic for VolumeDetect
  2751. // More logic below
  2752. bool phanReset = (IsPhantom != wasPhantom) && !IsPhantom;
  2753. if (phanReset) // Phantom changes from on to off switch VD off too
  2754. {
  2755. IsVD = false; // Switch it of for the course of this routine
  2756. VolumeDetectActive = false; // and also permanently
  2757. if (PhysActor != null)
  2758. PhysActor.VolumeDetect = false; // Let physics know about it too
  2759. }
  2760. else
  2761. {
  2762. IsPhantom = false;
  2763. // If volumedetect is active we don't want phantom to be applied.
  2764. // If this is a new call to VD out of the state "phantom"
  2765. // this will also cause the prim to be visible to physics
  2766. }
  2767. }
  2768. if (UsePhysics)
  2769. AddFlag(PrimFlags.Physics);
  2770. else
  2771. RemFlag(PrimFlags.Physics);
  2772. if (PhysActor != null)
  2773. {
  2774. PhysActor.IsPhysical = UsePhysics;
  2775. if (!UsePhysics)
  2776. {
  2777. //Clear out old data
  2778. Velocity = Vector3.Zero;
  2779. Acceleration = Vector3.Zero;
  2780. AngularVelocity = Vector3.Zero;
  2781. PhysActor.RotationalVelocity = Vector3.Zero;
  2782. PhysActor.ClearVelocity();
  2783. GenerateRotationalVelocityFromOmega();
  2784. if (wasUsingPhysics)
  2785. ScheduleTerseUpdate(); //Force it out of the client too
  2786. }
  2787. }
  2788. if (IsPhantom || IsAttachment || (Shape.PathCurve == (byte) Extrusion.Flexible))
  2789. // note: this may have been changed above in the case of joints
  2790. {
  2791. AddFlag(PrimFlags.Phantom);
  2792. needsPhysicalRebuild = true; //Gotta rebuild now
  2793. }
  2794. else // Not phantom
  2795. {
  2796. if (wasPhantom)
  2797. {
  2798. RemFlag(PrimFlags.Phantom);
  2799. needsPhysicalRebuild = true; //Gotta rebuild now
  2800. }
  2801. }
  2802. if (IsVD && IsVD != VolumeDetectActive)
  2803. {
  2804. // If the above logic worked (this is urgent candidate to unit tests!)
  2805. // we now have a physicsactor.
  2806. // Defensive programming calls for a check here.
  2807. // Better would be throwing an exception that could be catched by a unit test as the internal
  2808. // logic should make sure, this Physactor is always here.
  2809. //FALSE, you can go from a phantom prim > VD -7/26
  2810. if (PhysActor != null)
  2811. PhysActor.VolumeDetect = true;
  2812. AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active
  2813. VolumeDetectActive = true;
  2814. }
  2815. else
  2816. {
  2817. if (!IsVD)
  2818. {
  2819. // Remove VolumeDetect in any case. Note, it's safe to call SetVolumeDetect as often as you like
  2820. // (mumbles, well, at least if you have infinte CPU powers :-))
  2821. PhysicsObject pa = this.PhysActor;
  2822. if (pa != null)
  2823. PhysActor.VolumeDetect = false;
  2824. VolumeDetectActive = false;
  2825. }
  2826. }
  2827. if (IsTemporary)
  2828. AddFlag(PrimFlags.TemporaryOnRez);
  2829. else
  2830. RemFlag(PrimFlags.TemporaryOnRez);
  2831. if (UsePhysics != wasUsingPhysics) //Fire the event
  2832. ParentGroup.Scene.AuroraEventManager.FireGenericEventHandler("ObjectChangedPhysicalStatus", ParentGroup);
  2833. ParentGroup.HasGroupChanged = true;
  2834. ScheduleUpdate(PrimUpdateFlags.PrimFlags);
  2835. return needsPhysicalRebuild;
  2836. }
  2837. public void UpdateRotation(Quaternion rot)
  2838. {
  2839. if ((rot.X != GetRotationOffset().X) ||
  2840. (rot.Y != GetRotationOffset().Y) ||
  2841. (rot.Z != GetRotationOffset().Z) ||
  2842. (rot.W != GetRotationOffset().W))
  2843. {
  2844. SetRotationOffset(true, rot, true);
  2845. ValidpartOOB = false;
  2846. ScheduleTerseUpdate();
  2847. }
  2848. }
  2849. /// <summary>
  2850. /// Update the shape of this part.
  2851. /// </summary>
  2852. /// <param name="shapeBlock"></param>
  2853. public void UpdateShape(ObjectShapePacket.ObjectDataBlock shapeBlock)
  2854. {
  2855. UpdateShape(shapeBlock, true);
  2856. }
  2857. /// <summary>
  2858. /// Having this function because I found when scripts updated the shape.. over and over, it would fill up the memory
  2859. /// Having the extra paramater updatePhysics can prevent physics updates on the changes
  2860. /// The onlyplace this effects is if a script changes the shape
  2861. /// If the LocklessQueue gets updated this can be removed
  2862. /// </summary>
  2863. /// <param name="shapeBlock"></param>
  2864. /// <param name="UpdatePhysics"></param>
  2865. public void UpdateShape(ObjectShapePacket.ObjectDataBlock shapeBlock, bool UpdatePhysics)
  2866. {
  2867. IOpenRegionSettingsModule module = ParentGroup.Scene.RequestModuleInterface<IOpenRegionSettingsModule>();
  2868. if (module != null)
  2869. {
  2870. if (shapeBlock.ProfileHollow > (module.MaximumHollowSize*500) &&
  2871. module.MaximumHollowSize != -1)
  2872. //This is so that it works correctly, since the packet sends (N * 500)
  2873. {
  2874. shapeBlock.ProfileHollow = (ushort) (module.MaximumHollowSize*500);
  2875. }
  2876. if (shapeBlock.PathScaleY > (200 - (module.MinimumHoleSize*100)) &&
  2877. module.MinimumHoleSize != -1 && shapeBlock.PathCurve == 32)
  2878. //This is how the packet is set up... so this is how we check for it...
  2879. {
  2880. shapeBlock.PathScaleY = Convert.ToByte((200 - (module.MinimumHoleSize*100)));
  2881. }
  2882. }
  2883. m_shape.PathBegin = shapeBlock.PathBegin;
  2884. m_shape.PathEnd = shapeBlock.PathEnd;
  2885. m_shape.PathScaleX = shapeBlock.PathScaleX;
  2886. m_shape.PathScaleY = shapeBlock.PathScaleY;
  2887. m_shape.PathShearX = shapeBlock.PathShearX;
  2888. m_shape.PathShearY = shapeBlock.PathShearY;
  2889. m_shape.PathSkew = shapeBlock.PathSkew;
  2890. m_shape.ProfileBegin = shapeBlock.ProfileBegin;
  2891. m_shape.ProfileEnd = shapeBlock.ProfileEnd;
  2892. m_shape.PathCurve = shapeBlock.PathCurve;
  2893. m_shape.ProfileCurve = shapeBlock.ProfileCurve;
  2894. m_shape.ProfileHollow = shapeBlock.ProfileHollow;
  2895. m_shape.PathRadiusOffset = shapeBlock.PathRadiusOffset;
  2896. m_shape.PathRevolutions = shapeBlock.PathRevolutions;
  2897. m_shape.PathTaperX = shapeBlock.PathTaperX;
  2898. m_shape.PathTaperY = shapeBlock.PathTaperY;
  2899. m_shape.PathTwist = shapeBlock.PathTwist;
  2900. m_shape.PathTwistBegin = shapeBlock.PathTwistBegin;
  2901. if (m_shape.SculptEntry && UpdatePhysics)
  2902. m_parentGroup.Scene.AssetService.Get(m_shape.SculptTexture.ToString(), true, AssetReceived);
  2903. else
  2904. {
  2905. Shape = m_shape;
  2906. if ((UpdatePhysics) && (PhysActor != null))
  2907. PhysActor.Shape = m_shape;
  2908. }
  2909. // This is what makes vehicle trailers work
  2910. // A script in a child prim re-issues
  2911. // llSetPrimitiveParams(PRIM_TYPE) every few seconds. That
  2912. // prevents autoreturn. This also works in SL.
  2913. if (ParentGroup.RootPart != this)
  2914. ParentGroup.RootPart.Rezzed = DateTime.UtcNow;
  2915. ValidpartOOB = false;
  2916. ParentGroup.HasGroupChanged = true;
  2917. ScheduleUpdate(PrimUpdateFlags.FullUpdate);
  2918. }
  2919. /// <summary>
  2920. /// Update the textures on the part.
  2921. /// </summary>
  2922. /// Added to handle bug in libsecondlife's TextureEntry.ToBytes()
  2923. /// not handling RGBA properly. Cycles through, and "fixes" the color
  2924. /// info
  2925. /// <param name="tex"></param>
  2926. /// <param name="sendChangedEvent"></param>
  2927. public void UpdateTexture(Primitive.TextureEntry tex, bool sendChangedEvent)
  2928. {
  2929. //Color4 tmpcolor;
  2930. //for (uint i = 0; i < 32; i++)
  2931. //{
  2932. // if (tex.FaceTextures[i] != null)
  2933. // {
  2934. // tmpcolor = tex.GetFace((uint) i).RGBA;
  2935. // tmpcolor.A = tmpcolor.A*255;
  2936. // tmpcolor.R = tmpcolor.R*255;
  2937. // tmpcolor.G = tmpcolor.G*255;
  2938. // tmpcolor.B = tmpcolor.B*255;
  2939. // tex.FaceTextures[i].RGBA = tmpcolor;
  2940. // }
  2941. //}
  2942. //tmpcolor = tex.DefaultTexture.RGBA;
  2943. //tmpcolor.A = tmpcolor.A*255;
  2944. //tmpcolor.R = tmpcolor.R*255;
  2945. //tmpcolor.G = tmpcolor.G*255;
  2946. //tmpcolor.B = tmpcolor.B*255;
  2947. //tex.DefaultTexture.RGBA = tmpcolor;
  2948. UpdateTextureEntry(tex.GetBytes(), sendChangedEvent);
  2949. }
  2950. public void aggregateScriptEvents()
  2951. {
  2952. AggregateScriptEvents = 0;
  2953. // Aggregate script events
  2954. lock (m_scriptEvents)
  2955. {
  2956. foreach (scriptEvents s in m_scriptEvents.Values)
  2957. {
  2958. AggregateScriptEvents |= s;
  2959. }
  2960. }
  2961. uint objectflagupdate = 0;
  2962. if (
  2963. ((AggregateScriptEvents & scriptEvents.touch) != 0) ||
  2964. ((AggregateScriptEvents & scriptEvents.touch_end) != 0) ||
  2965. ((AggregateScriptEvents & scriptEvents.touch_start) != 0)
  2966. )
  2967. {
  2968. objectflagupdate |= (uint) PrimFlags.Touch;
  2969. }
  2970. if ((AggregateScriptEvents & scriptEvents.money) != 0)
  2971. {
  2972. objectflagupdate |= (uint) PrimFlags.Money;
  2973. }
  2974. if (AllowedDrop)
  2975. {
  2976. objectflagupdate |= (uint) PrimFlags.AllowInventoryDrop;
  2977. }
  2978. // subscribe to physics updates.
  2979. //We subscribe by default now... so 'shouldn't' need this
  2980. if ((((AggregateScriptEvents & scriptEvents.collision) != 0) ||
  2981. ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
  2982. ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
  2983. ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
  2984. ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
  2985. ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0)
  2986. ) && PhysActor != null)
  2987. {
  2988. if (!m_hasSubscribedToCollisionEvent)
  2989. {
  2990. m_hasSubscribedToCollisionEvent = true;
  2991. PhysActor.OnCollisionUpdate += PhysicsCollision;
  2992. PhysActor.SubscribeEvents(1000);
  2993. }
  2994. }
  2995. else if (PhysActor != null)
  2996. {
  2997. if (m_hasSubscribedToCollisionEvent)
  2998. {
  2999. m_hasSubscribedToCollisionEvent = false;
  3000. PhysActor.OnCollisionUpdate -= PhysicsCollision;
  3001. }
  3002. }
  3003. LocalFlags = (PrimFlags) objectflagupdate;
  3004. if (m_parentGroup != null && m_parentGroup.RootPart == this)
  3005. {
  3006. m_parentGroup.aggregateScriptEvents();
  3007. }
  3008. else
  3009. {
  3010. // MainConsole.Instance.DebugFormat(
  3011. // "[SCENE OBJECT PART]: Scheduling part {0} {1} for full update in aggregateScriptEvents()", Name, LocalId);
  3012. ScheduleUpdate(PrimUpdateFlags.PrimFlags);
  3013. }
  3014. }
  3015. public int registerTargetWaypoint(Vector3 target, float tolerance)
  3016. {
  3017. if (m_parentGroup != null)
  3018. {
  3019. return m_parentGroup.registerTargetWaypoint(target, tolerance);
  3020. }
  3021. return 0;
  3022. }
  3023. public void unregisterTargetWaypoint(int handle)
  3024. {
  3025. if (m_parentGroup != null)
  3026. {
  3027. m_parentGroup.unregisterTargetWaypoint(handle);
  3028. }
  3029. }
  3030. public int registerRotTargetWaypoint(Quaternion target, float tolerance)
  3031. {
  3032. if (m_parentGroup != null)
  3033. {
  3034. return m_parentGroup.registerRotTargetWaypoint(target, tolerance);
  3035. }
  3036. return 0;
  3037. }
  3038. public void unregisterRotTargetWaypoint(int handle)
  3039. {
  3040. if (m_parentGroup != null)
  3041. {
  3042. m_parentGroup.unregisterRotTargetWaypoint(handle);
  3043. }
  3044. }
  3045. #region Vehicle Params
  3046. private OSDArray m_VehicleFlags;
  3047. private OSDMap m_VehicleParams;
  3048. public int VehicleType { get; set; }
  3049. public OSDArray VehicleFlags
  3050. {
  3051. get
  3052. {
  3053. if (m_VehicleFlags == null)
  3054. m_VehicleFlags = new OSDArray();
  3055. return m_VehicleFlags;
  3056. }
  3057. set { m_VehicleFlags = value; }
  3058. }
  3059. public OSDMap VehicleParameters
  3060. {
  3061. get
  3062. {
  3063. if (m_VehicleParams == null)
  3064. m_VehicleParams = new OSDMap();
  3065. return m_VehicleParams;
  3066. }
  3067. set { m_VehicleParams = value; }
  3068. }
  3069. #endregion
  3070. public void SetRotationOffset(bool UpdatePrimActor, Quaternion value, bool single)
  3071. {
  3072. if (ParentGroup != null)
  3073. ParentGroup.HasGroupChanged = true;
  3074. ValidpartOOB = false;
  3075. RotationOffset = value;
  3076. PhysicsObject actor = PhysActor;
  3077. if (actor != null)
  3078. {
  3079. if (value.W == 0) //We have an issue here... try to normalize it
  3080. value.Normalize();
  3081. if (actor.PhysicsActorType != (int) ActorTypes.Prim) // for now let other times get updates
  3082. {
  3083. UpdatePrimActor = true;
  3084. single = false;
  3085. }
  3086. if (UpdatePrimActor)
  3087. {
  3088. try
  3089. {
  3090. // Root prim gets value directly
  3091. if (_parentID == 0)
  3092. {
  3093. actor.Orientation = value;
  3094. //MainConsole.Instance.Info("[PART]: RO1:" + actor.Orientation.ToString());
  3095. }
  3096. else if (single || !actor.IsPhysical)
  3097. {
  3098. // Child prim we have to calculate it's world rotationwel
  3099. Quaternion resultingrotation = GetWorldRotation();
  3100. actor.Orientation = resultingrotation;
  3101. //MainConsole.Instance.Info("[PART]: RO2:" + actor.Orientation.ToString());
  3102. }
  3103. }
  3104. catch (Exception ex)
  3105. {
  3106. MainConsole.Instance.Error("[SCENEOBJECTPART]: ROTATIONOFFSET" + ex.Message);
  3107. }
  3108. }
  3109. }
  3110. }
  3111. public void SetOffsetPosition(Vector3 value)
  3112. {
  3113. m_offsetPosition = value;
  3114. ValidpartOOB = false;
  3115. }
  3116. public void SetGroupPosition(Vector3 value)
  3117. {
  3118. m_groupPosition = new Vector3(value.X, value.Y, value.Z);
  3119. }
  3120. public void FixGroupPosition(Vector3 value, bool single)
  3121. {
  3122. FixGroupPositionComum(true, value, single);
  3123. }
  3124. public void FixGroupPositionComum(bool UpdatePrimActor, Vector3 value, bool single)
  3125. {
  3126. bool TriggerMoving_End = false;
  3127. if (m_groupPosition != value)
  3128. {
  3129. if (ParentGroup != null)
  3130. ParentGroup.HasGroupChanged = true;
  3131. TriggerMoving_End = true;
  3132. TriggerScriptMovingStartEvent();
  3133. }
  3134. m_groupPosition = value;
  3135. PhysicsObject actor = PhysActor;
  3136. if (actor != null)
  3137. {
  3138. if (actor.PhysicsActorType != (int) ActorTypes.Prim) // for now let other times get updates
  3139. {
  3140. UpdatePrimActor = true;
  3141. single = false;
  3142. }
  3143. if (UpdatePrimActor)
  3144. {
  3145. try
  3146. {
  3147. // Root prim actually goes at Position
  3148. if (_parentID == 0)
  3149. {
  3150. actor.Position = value;
  3151. }
  3152. else if (single || !actor.IsPhysical)
  3153. {
  3154. // To move the child prim in respect to the group position and rotation we have to calculate
  3155. actor.Position = GetWorldPosition();
  3156. actor.Orientation = GetWorldRotation();
  3157. }
  3158. // Tell the physics engines that this prim changed.
  3159. }
  3160. catch (Exception e)
  3161. {
  3162. MainConsole.Instance.Error("[SCENEOBJECTPART]: GROUP POSITION. " + e.Message);
  3163. }
  3164. }
  3165. }
  3166. lock (SitTargetAvatar)
  3167. {
  3168. if (SitTargetAvatar.Count != 0)
  3169. {
  3170. foreach (UUID avID in SitTargetAvatar.Where(avID => m_parentGroup != null))
  3171. {
  3172. IScenePresence avatar;
  3173. if (m_parentGroup.Scene.TryGetScenePresence(avID, out avatar))
  3174. {
  3175. avatar.ParentPosition = GetWorldPosition();
  3176. }
  3177. }
  3178. }
  3179. }
  3180. if (TriggerMoving_End)
  3181. TriggerScriptMovingEndEvent();
  3182. }
  3183. public void ResetExpire()
  3184. {
  3185. Expires = DateTime.Now + new TimeSpan(TimeSpan.TicksPerMinute);
  3186. }
  3187. public event AddPhysics OnAddPhysics;
  3188. public event RemovePhysics OnRemovePhysics;
  3189. public void FireOnAddedPhysics()
  3190. {
  3191. if (OnAddPhysics != null)
  3192. OnAddPhysics();
  3193. }
  3194. public void FireOnRemovedPhysics()
  3195. {
  3196. if (OnRemovePhysics != null)
  3197. OnRemovePhysics();
  3198. }
  3199. public void ClearUndoState()
  3200. {
  3201. lock (m_undo)
  3202. {
  3203. m_undo = new UndoStack<UndoState>(5);
  3204. }
  3205. lock (m_redo)
  3206. {
  3207. m_redo = new UndoStack<UndoState>(5);
  3208. }
  3209. StoreUndoState();
  3210. }
  3211. public byte ConvertScriptUintToByte(uint indata)
  3212. {
  3213. byte outdata = (byte) TextureAnimFlags.NONE;
  3214. if ((indata & 1) != 0) outdata |= (byte) TextureAnimFlags.ANIM_ON;
  3215. if ((indata & 2) != 0) outdata |= (byte) TextureAnimFlags.LOOP;
  3216. if ((indata & 4) != 0) outdata |= (byte) TextureAnimFlags.REVERSE;
  3217. if ((indata & 8) != 0) outdata |= (byte) TextureAnimFlags.PING_PONG;
  3218. if ((indata & 16) != 0) outdata |= (byte) TextureAnimFlags.SMOOTH;
  3219. if ((indata & 32) != 0) outdata |= (byte) TextureAnimFlags.ROTATE;
  3220. if ((indata & 64) != 0) outdata |= (byte) TextureAnimFlags.SCALE;
  3221. return outdata;
  3222. }
  3223. /// <summary>
  3224. /// Duplicates this part.
  3225. /// </summary>
  3226. /// <param name="parent"></param>
  3227. /// <param name="clonePhys"></param>
  3228. /// <returns></returns>
  3229. public SceneObjectPart Copy(SceneObjectGroup parent, bool clonePhys)
  3230. {
  3231. SceneObjectPart dupe = (SceneObjectPart) MemberwiseClone();
  3232. dupe.m_parentGroup = parent;
  3233. dupe.m_shape = m_shape.Copy();
  3234. dupe.m_partOOBsize = m_partOOBsize;
  3235. dupe.m_partOOBoffset = m_partOOBoffset;
  3236. dupe.m_partBSphereRadiusSQ = m_partBSphereRadiusSQ;
  3237. dupe.m_regionHandle = m_regionHandle;
  3238. //memberwiseclone means it also clones the physics actor reference
  3239. // This will make physical prim 'bounce' if not set to null.
  3240. if (!clonePhys)
  3241. dupe.PhysActor = null;
  3242. dupe._groupID = GroupID;
  3243. dupe.m_groupPosition = m_groupPosition;
  3244. dupe.m_offsetPosition = m_offsetPosition;
  3245. dupe.RotationOffset = RotationOffset;
  3246. dupe.Velocity = new Vector3(0, 0, 0);
  3247. dupe.Acceleration = new Vector3(0, 0, 0);
  3248. dupe.AngularVelocity = new Vector3(0, 0, 0);
  3249. dupe.Flags = Flags;
  3250. dupe.LinkNum = LinkNum;
  3251. dupe.SitTargetAvatar = new List<UUID>();
  3252. dupe.m_LoopSoundSlavePrims = new List<SceneObjectPart>();
  3253. dupe.m_PlaySoundSlavePrims = new List<SceneObjectPart>();
  3254. dupe.m_ValidpartOOB = false;
  3255. dupe._ownershipCost = _ownershipCost;
  3256. dupe._objectSaleType = _objectSaleType;
  3257. dupe._salePrice = _salePrice;
  3258. dupe._category = _category;
  3259. dupe.Rezzed = Rezzed;
  3260. dupe.m_inventory = new SceneObjectPartInventory(dupe)
  3261. {
  3262. Items = (TaskInventoryDictionary) m_inventory.Items.Clone(),
  3263. HasInventoryChanged = m_inventory.HasInventoryChanged
  3264. };
  3265. byte[] extraP = new byte[Shape.ExtraParams.Length];
  3266. Array.Copy(Shape.ExtraParams, extraP, extraP.Length);
  3267. dupe.Shape.ExtraParams = extraP;
  3268. dupe.m_scriptEvents = new Dictionary<UUID, scriptEvents>();
  3269. dupe.Shape.SculptData = this.Shape.SculptData;
  3270. dupe.GenerateRotationalVelocityFromOmega();
  3271. return dupe;
  3272. }
  3273. public void AssetReceived(string id, Object sender, AssetBase asset)
  3274. {
  3275. if (asset != null)
  3276. {
  3277. this.Shape.SculptEntry = true;
  3278. this.Shape.SculptData = asset.Data; //Set the asset data
  3279. }
  3280. bool isMesh = asset == null ? false : (asset.Type == (int) AssetType.Mesh);
  3281. if (isMesh)
  3282. this.Shape.SculptType = (byte) SculptType.Mesh;
  3283. PrimitiveBaseShape shape = Shape.Copy();
  3284. if ((bool) sender && this.PhysActor != null &&
  3285. (asset != null || (this.Shape.SculptData != null && this.Shape.SculptData.Length != 0)))
  3286. //Update physics
  3287. {
  3288. //Get physics to update in a hackish way
  3289. this.PhysActor.Shape = shape;
  3290. }
  3291. this.Shape = shape;
  3292. }
  3293. public double GetDistanceTo(Vector3 a, Vector3 b)
  3294. {
  3295. float dx = a.X - b.X;
  3296. float dy = a.Y - b.Y;
  3297. float dz = a.Z - b.Z;
  3298. return Math.Sqrt(dx*dx + dy*dy + dz*dz);
  3299. }
  3300. public UUID GetRootPartUUID()
  3301. {
  3302. if (m_parentGroup != null)
  3303. {
  3304. return m_parentGroup.UUID;
  3305. }
  3306. return UUID.Zero;
  3307. }
  3308. public void SetMoveToTarget(bool Enabled, Vector3 target, float tau)
  3309. {
  3310. if (Enabled)
  3311. {
  3312. m_initialPIDLocation = AbsolutePosition;
  3313. PIDTarget = target;
  3314. PIDTau = tau;
  3315. PIDActive = true;
  3316. }
  3317. else
  3318. {
  3319. PIDActive = false;
  3320. m_initialPIDLocation = Vector3.Zero;
  3321. }
  3322. }
  3323. public void StopHover()
  3324. {
  3325. m_parentGroup.SetHoverHeight(0f, PIDHoverType.Ground, 0f);
  3326. }
  3327. public virtual void OnGrab(Vector3 offsetPos, IClientAPI remoteClient)
  3328. {
  3329. }
  3330. public void PhysicsCollision(EventArgs e)
  3331. {
  3332. // single threaded here
  3333. if (e == null)
  3334. return;
  3335. CollisionEventUpdate a = (CollisionEventUpdate) e;
  3336. Dictionary<uint, ContactPoint> collissionswith = a.GetCollisionEvents();
  3337. List<uint> thisHitColliders = new List<uint>();
  3338. List<uint> startedColliders = new List<uint>();
  3339. ContactPoint startedCollider = new ContactPoint();
  3340. // calculate things that started colliding this time
  3341. // and build up list of colliders this time
  3342. foreach (uint localID in collissionswith.Keys)
  3343. {
  3344. thisHitColliders.Add(localID);
  3345. if (!m_lastColliders.Contains(localID))
  3346. {
  3347. startedCollider = collissionswith[localID];
  3348. startedColliders.Add(localID);
  3349. }
  3350. //MainConsole.Instance.Debug("[OBJECT]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString());
  3351. }
  3352. // calculate things that ended colliding
  3353. List<uint> endedColliders = m_lastColliders.Where(localID => !thisHitColliders.Contains(localID)).ToList();
  3354. //add the items that started colliding this time to the last colliders list.
  3355. m_lastColliders.AddRange(startedColliders);
  3356. // remove things that ended colliding from the last colliders list
  3357. foreach (uint localID in endedColliders)
  3358. m_lastColliders.Remove(localID);
  3359. if (m_parentGroup == null)
  3360. return;
  3361. if (m_parentGroup.IsDeleted)
  3362. return;
  3363. const string SoundGlassCollision = "6a45ba0b-5775-4ea8-8513-26008a17f873";
  3364. const string SoundMetalCollision = "9e5c1297-6eed-40c0-825a-d9bcd86e3193";
  3365. const string SoundStoneCollision = "9538f37c-456e-4047-81be-6435045608d4";
  3366. const string SoundFleshCollision = "dce5fdd4-afe4-4ea1-822f-dd52cac46b08";
  3367. const string SoundPlasticCollision = "0e24a717-b97e-4b77-9c94-b59a5a88b2da";
  3368. const string SoundRubberCollision = "153c8bf7-fb89-4d89-b263-47e58b1b4774";
  3369. const string SoundWoodCollision = "063c97d3-033a-4e9b-98d8-05c8074922cb";
  3370. // play the sound.
  3371. if (startedColliders.Count > 0 && CollisionSound != UUID.Zero && CollisionSoundVolume > 0.0f)
  3372. {
  3373. SendSound(CollisionSound.ToString(), CollisionSoundVolume, true, 0, 0, false, false);
  3374. }
  3375. else if (startedColliders.Count > 0)
  3376. {
  3377. switch (startedCollider.Type)
  3378. {
  3379. case ActorTypes.Agent:
  3380. break; // Agents will play the sound so we don't
  3381. case ActorTypes.Ground:
  3382. SendSound(SoundWoodCollision, 1, true, 0, 0, false, false);
  3383. break; //Always play the click or thump sound when hitting ground
  3384. case ActorTypes.Prim:
  3385. switch (Material)
  3386. {
  3387. case (int) OpenMetaverse.Material.Flesh:
  3388. SendSound(SoundFleshCollision, 1, true, 0, 0, false, false);
  3389. break;
  3390. case (int) OpenMetaverse.Material.Glass:
  3391. SendSound(SoundGlassCollision, 1, true, 0, 0, false, false);
  3392. break;
  3393. case (int) OpenMetaverse.Material.Metal:
  3394. SendSound(SoundMetalCollision, 1, true, 0, 0, false, false);
  3395. break;
  3396. case (int) OpenMetaverse.Material.Plastic:
  3397. SendSound(SoundPlasticCollision, 1, true, 0, 0, false, false);
  3398. break;
  3399. case (int) OpenMetaverse.Material.Rubber:
  3400. SendSound(SoundRubberCollision, 1, true, 0, 0, false, false);
  3401. break;
  3402. case (int) OpenMetaverse.Material.Stone:
  3403. SendSound(SoundStoneCollision, 1, true, 0, 0, false, false);
  3404. break;
  3405. case (int) OpenMetaverse.Material.Wood:
  3406. SendSound(SoundWoodCollision, 1, true, 0, 0, false, false);
  3407. break;
  3408. }
  3409. break; //Play based on material type in prim2prim collisions
  3410. default:
  3411. break; //Unclear of what this object is, no sounds
  3412. }
  3413. }
  3414. if (CollisionSprite != UUID.Zero && CollisionSoundVolume > 0.0f)
  3415. // The collision volume isn't a mistake, its an SL feature/bug
  3416. {
  3417. // TODO: make a sprite!
  3418. }
  3419. if (((AggregateScriptEvents & scriptEvents.collision) != 0) ||
  3420. ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
  3421. ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
  3422. ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
  3423. ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
  3424. ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
  3425. (CollisionSound != UUID.Zero) ||
  3426. PassCollisions != 2)
  3427. {
  3428. if ((m_parentGroup.RootPart.ScriptEvents & scriptEvents.collision_start) != 0 ||
  3429. (m_parentGroup.RootPart.ScriptEvents & scriptEvents.collision) != 0)
  3430. {
  3431. // do event notification
  3432. if (startedColliders.Count > 0)
  3433. {
  3434. ColliderArgs StartCollidingMessage = new ColliderArgs();
  3435. List<DetectedObject> colliding = new List<DetectedObject>();
  3436. foreach (uint localId in startedColliders)
  3437. {
  3438. if (localId != 0)
  3439. {
  3440. // always running this check because if the user deletes the object it would return a null reference.
  3441. if (m_parentGroup == null)
  3442. return;
  3443. if (m_parentGroup.Scene == null)
  3444. return;
  3445. ISceneChildEntity obj = m_parentGroup.Scene.GetSceneObjectPart(localId);
  3446. string data = "";
  3447. if (obj != null)
  3448. {
  3449. if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString()) ||
  3450. m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name))
  3451. {
  3452. bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
  3453. //If it is 1, it is to accept ONLY collisions from this object
  3454. if (found)
  3455. {
  3456. DetectedObject detobj = new DetectedObject
  3457. {
  3458. keyUUID = obj.UUID,
  3459. nameStr = obj.Name,
  3460. ownerUUID = obj.OwnerID,
  3461. posVector = obj.AbsolutePosition,
  3462. rotQuat = obj.GetWorldRotation(),
  3463. velVector = obj.Velocity,
  3464. colliderType = 0,
  3465. groupUUID = obj.GroupID
  3466. };
  3467. colliding.Add(detobj);
  3468. }
  3469. //If it is 0, it is to not accept collisions from this object
  3470. else
  3471. {
  3472. }
  3473. }
  3474. else
  3475. {
  3476. bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
  3477. //If it is 1, it is to accept ONLY collisions from this object, so this other object will not work
  3478. if (!found)
  3479. {
  3480. DetectedObject detobj = new DetectedObject
  3481. {
  3482. keyUUID = obj.UUID,
  3483. nameStr = obj.Name,
  3484. ownerUUID = obj.OwnerID,
  3485. posVector = obj.AbsolutePosition,
  3486. rotQuat = obj.GetWorldRotation(),
  3487. velVector = obj.Velocity,
  3488. colliderType = 0,
  3489. groupUUID = obj.GroupID
  3490. };
  3491. colliding.Add(detobj);
  3492. }
  3493. }
  3494. }
  3495. else
  3496. {
  3497. IScenePresence av = ParentGroup.Scene.GetScenePresence(localId);
  3498. if (av != null)
  3499. {
  3500. if (av.LocalId == localId)
  3501. {
  3502. if (
  3503. m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString()) ||
  3504. m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.Name))
  3505. {
  3506. bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1,
  3507. out data);
  3508. //If it is 1, it is to accept ONLY collisions from this avatar
  3509. if (found)
  3510. {
  3511. DetectedObject detobj = new DetectedObject
  3512. {
  3513. keyUUID = av.UUID,
  3514. nameStr = av.ControllingClient.Name,
  3515. ownerUUID = av.UUID,
  3516. posVector = av.AbsolutePosition,
  3517. rotQuat = av.Rotation,
  3518. velVector = av.Velocity,
  3519. colliderType = 0,
  3520. groupUUID =
  3521. av.ControllingClient
  3522. .ActiveGroupId
  3523. };
  3524. colliding.Add(detobj);
  3525. }
  3526. //If it is 0, it is to not accept collisions from this avatar
  3527. else
  3528. {
  3529. }
  3530. }
  3531. else
  3532. {
  3533. bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1,
  3534. out data);
  3535. //If it is 1, it is to accept ONLY collisions from this avatar, so this other avatar will not work
  3536. if (!found)
  3537. {
  3538. DetectedObject detobj = new DetectedObject
  3539. {
  3540. keyUUID = av.UUID,
  3541. nameStr = av.ControllingClient.Name,
  3542. ownerUUID = av.UUID,
  3543. posVector = av.AbsolutePosition,
  3544. rotQuat = av.Rotation,
  3545. velVector = av.Velocity,
  3546. colliderType = 0,
  3547. groupUUID =
  3548. av.ControllingClient
  3549. .ActiveGroupId
  3550. };
  3551. colliding.Add(detobj);
  3552. }
  3553. }
  3554. }
  3555. }
  3556. }
  3557. }
  3558. }
  3559. if (colliding.Count > 0)
  3560. {
  3561. StartCollidingMessage.Colliders = colliding;
  3562. // always running this check because if the user deletes the object it would return a null reference.
  3563. if (m_parentGroup == null)
  3564. return;
  3565. if (m_parentGroup.Scene == null)
  3566. return;
  3567. //Always send to the prim it is occuring to
  3568. m_parentGroup.Scene.EventManager.TriggerScriptCollidingStart(this, StartCollidingMessage);
  3569. if ((this.UUID != this.ParentGroup.RootPart.UUID))
  3570. {
  3571. const int PASS_IF_NOT_HANDLED = 0;
  3572. const int PASS_ALWAYS = 1;
  3573. const int PASS_NEVER = 2;
  3574. if (this.PassCollisions == PASS_NEVER)
  3575. {
  3576. }
  3577. if (this.PassCollisions == PASS_ALWAYS)
  3578. {
  3579. m_parentGroup.Scene.EventManager.TriggerScriptCollidingStart(
  3580. this.ParentGroup.RootPart, StartCollidingMessage);
  3581. }
  3582. else if (((this.ScriptEvents & scriptEvents.collision_start) == 0) &&
  3583. this.PassCollisions == PASS_IF_NOT_HANDLED)
  3584. //If no event in this prim, pass to parent
  3585. {
  3586. m_parentGroup.Scene.EventManager.TriggerScriptCollidingStart(
  3587. this.ParentGroup.RootPart, StartCollidingMessage);
  3588. }
  3589. }
  3590. }
  3591. }
  3592. }
  3593. if ((m_parentGroup.RootPart.ScriptEvents & scriptEvents.collision) != 0)
  3594. {
  3595. if (m_lastColliders.Count > 0)
  3596. {
  3597. ColliderArgs CollidingMessage = new ColliderArgs();
  3598. List<DetectedObject> colliding = new List<DetectedObject>();
  3599. foreach (uint localId in m_lastColliders)
  3600. {
  3601. if (localId != 0)
  3602. {
  3603. if (m_parentGroup == null)
  3604. return;
  3605. if (m_parentGroup.Scene == null)
  3606. return;
  3607. ISceneChildEntity obj = m_parentGroup.Scene.GetSceneObjectPart(localId);
  3608. string data = "";
  3609. if (obj != null)
  3610. {
  3611. if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString()) ||
  3612. m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name))
  3613. {
  3614. bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
  3615. //If it is 1, it is to accept ONLY collisions from this object
  3616. if (found)
  3617. {
  3618. DetectedObject detobj = new DetectedObject
  3619. {
  3620. keyUUID = obj.UUID,
  3621. nameStr = obj.Name,
  3622. ownerUUID = obj.OwnerID,
  3623. posVector = obj.AbsolutePosition,
  3624. rotQuat = obj.GetWorldRotation(),
  3625. velVector = obj.Velocity,
  3626. colliderType = 0,
  3627. groupUUID = obj.GroupID
  3628. };
  3629. colliding.Add(detobj);
  3630. }
  3631. //If it is 0, it is to not accept collisions from this object
  3632. else
  3633. {
  3634. }
  3635. }
  3636. else
  3637. {
  3638. bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
  3639. //If it is 1, it is to accept ONLY collisions from this object, so this other object will not work
  3640. if (!found)
  3641. {
  3642. DetectedObject detobj = new DetectedObject
  3643. {
  3644. keyUUID = obj.UUID,
  3645. nameStr = obj.Name,
  3646. ownerUUID = obj.OwnerID,
  3647. posVector = obj.AbsolutePosition,
  3648. rotQuat = obj.GetWorldRotation(),
  3649. velVector = obj.Velocity,
  3650. colliderType = 0,
  3651. groupUUID = obj.GroupID
  3652. };
  3653. colliding.Add(detobj);
  3654. }
  3655. }
  3656. }
  3657. else
  3658. {
  3659. IScenePresence av = ParentGroup.Scene.GetScenePresence(localId);
  3660. if (av != null)
  3661. {
  3662. if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString()) ||
  3663. m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.Name))
  3664. {
  3665. bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
  3666. //If it is 1, it is to accept ONLY collisions from this avatar
  3667. if (found)
  3668. {
  3669. DetectedObject detobj = new DetectedObject
  3670. {
  3671. keyUUID = av.UUID,
  3672. nameStr = av.ControllingClient.Name,
  3673. ownerUUID = av.UUID,
  3674. posVector = av.AbsolutePosition,
  3675. rotQuat = av.Rotation,
  3676. velVector = av.Velocity,
  3677. colliderType = 0,
  3678. groupUUID =
  3679. av.ControllingClient.ActiveGroupId
  3680. };
  3681. colliding.Add(detobj);
  3682. }
  3683. //If it is 0, it is to not accept collisions from this avatar
  3684. else
  3685. {
  3686. }
  3687. }
  3688. else
  3689. {
  3690. bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
  3691. //If it is 1, it is to accept ONLY collisions from this avatar, so this other avatar will not work
  3692. if (!found)
  3693. {
  3694. DetectedObject detobj = new DetectedObject
  3695. {
  3696. keyUUID = av.UUID,
  3697. nameStr = av.ControllingClient.Name,
  3698. ownerUUID = av.UUID,
  3699. posVector = av.AbsolutePosition,
  3700. rotQuat = av.Rotation,
  3701. velVector = av.Velocity,
  3702. colliderType = 0,
  3703. groupUUID =
  3704. av.ControllingClient.ActiveGroupId
  3705. };
  3706. colliding.Add(detobj);
  3707. }
  3708. }
  3709. }
  3710. }
  3711. }
  3712. }
  3713. if (colliding.Count > 0)
  3714. {
  3715. CollidingMessage.Colliders = colliding;
  3716. // always running this check because if the user deletes the object it would return a null reference.
  3717. if (m_parentGroup == null)
  3718. return;
  3719. if (m_parentGroup.Scene == null)
  3720. return;
  3721. m_parentGroup.Scene.EventManager.TriggerScriptColliding(this, CollidingMessage);
  3722. if ((this.UUID != this.ParentGroup.RootPart.UUID))
  3723. {
  3724. const int PASS_IF_NOT_HANDLED = 0;
  3725. const int PASS_ALWAYS = 1;
  3726. const int PASS_NEVER = 2;
  3727. if (this.PassCollisions == PASS_NEVER)
  3728. {
  3729. }
  3730. if (this.PassCollisions == PASS_ALWAYS)
  3731. {
  3732. m_parentGroup.Scene.EventManager.TriggerScriptColliding(this.ParentGroup.RootPart,
  3733. CollidingMessage);
  3734. }
  3735. else if (((this.ScriptEvents & scriptEvents.collision) == 0) &&
  3736. this.PassCollisions == PASS_IF_NOT_HANDLED)
  3737. //If no event in this prim, pass to parent
  3738. {
  3739. m_parentGroup.Scene.EventManager.TriggerScriptColliding(
  3740. this.ParentGroup.RootPart, CollidingMessage);
  3741. }
  3742. }
  3743. }
  3744. }
  3745. }
  3746. if ((m_parentGroup.RootPart.ScriptEvents & scriptEvents.collision_end) != 0)
  3747. {
  3748. if (endedColliders.Count > 0)
  3749. {
  3750. ColliderArgs EndCollidingMessage = new ColliderArgs();
  3751. List<DetectedObject> colliding = new List<DetectedObject>();
  3752. foreach (uint localId in endedColliders)
  3753. {
  3754. if (localId != 0)
  3755. {
  3756. // always running this check because if the user deletes the object it would return a null reference.
  3757. if (m_parentGroup == null)
  3758. return;
  3759. if (m_parentGroup.Scene == null)
  3760. return;
  3761. ISceneChildEntity obj = m_parentGroup.Scene.GetSceneObjectPart(localId);
  3762. string data = "";
  3763. if (obj != null)
  3764. {
  3765. if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString()) ||
  3766. m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name))
  3767. {
  3768. bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
  3769. //If it is 1, it is to accept ONLY collisions from this object
  3770. if (found)
  3771. {
  3772. DetectedObject detobj = new DetectedObject
  3773. {
  3774. keyUUID = obj.UUID,
  3775. nameStr = obj.Name,
  3776. ownerUUID = obj.OwnerID,
  3777. posVector = obj.AbsolutePosition,
  3778. rotQuat = obj.GetWorldRotation(),
  3779. velVector = obj.Velocity,
  3780. colliderType = 0,
  3781. groupUUID = obj.GroupID
  3782. };
  3783. colliding.Add(detobj);
  3784. }
  3785. //If it is 0, it is to not accept collisions from this object
  3786. else
  3787. {
  3788. }
  3789. }
  3790. else
  3791. {
  3792. bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
  3793. //If it is 1, it is to accept ONLY collisions from this object, so this other object will not work
  3794. if (!found)
  3795. {
  3796. DetectedObject detobj = new DetectedObject
  3797. {
  3798. keyUUID = obj.UUID,
  3799. nameStr = obj.Name,
  3800. ownerUUID = obj.OwnerID,
  3801. posVector = obj.AbsolutePosition,
  3802. rotQuat = obj.GetWorldRotation(),
  3803. velVector = obj.Velocity,
  3804. colliderType = 0,
  3805. groupUUID = obj.GroupID
  3806. };
  3807. colliding.Add(detobj);
  3808. }
  3809. }
  3810. }
  3811. else
  3812. {
  3813. IScenePresence av = ParentGroup.Scene.GetScenePresence(localId);
  3814. if (av != null)
  3815. {
  3816. if (av.LocalId == localId)
  3817. {
  3818. if (
  3819. m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString()) ||
  3820. m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.Name))
  3821. {
  3822. bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1,
  3823. out data);
  3824. //If it is 1, it is to accept ONLY collisions from this avatar
  3825. if (found)
  3826. {
  3827. DetectedObject detobj = new DetectedObject
  3828. {
  3829. keyUUID = av.UUID,
  3830. nameStr = av.ControllingClient.Name,
  3831. ownerUUID = av.UUID,
  3832. posVector = av.AbsolutePosition,
  3833. rotQuat = av.Rotation,
  3834. velVector = av.Velocity,
  3835. colliderType = 0,
  3836. groupUUID =
  3837. av.ControllingClient
  3838. .ActiveGroupId
  3839. };
  3840. colliding.Add(detobj);
  3841. }
  3842. //If it is 0, it is to not accept collisions from this avatar
  3843. else
  3844. {
  3845. }
  3846. }
  3847. else
  3848. {
  3849. bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1,
  3850. out data);
  3851. //If it is 1, it is to accept ONLY collisions from this avatar, so this other avatar will not work
  3852. if (!found)
  3853. {
  3854. DetectedObject detobj = new DetectedObject
  3855. {
  3856. keyUUID = av.UUID,
  3857. nameStr = av.ControllingClient.Name,
  3858. ownerUUID = av.UUID,
  3859. posVector = av.AbsolutePosition,
  3860. rotQuat = av.Rotation,
  3861. velVector = av.Velocity,
  3862. colliderType = 0,
  3863. groupUUID =
  3864. av.ControllingClient
  3865. .ActiveGroupId
  3866. };
  3867. colliding.Add(detobj);
  3868. }
  3869. }
  3870. }
  3871. }
  3872. }
  3873. }
  3874. }
  3875. if (colliding.Count > 0)
  3876. {
  3877. EndCollidingMessage.Colliders = colliding;
  3878. // always running this check because if the user deletes the object it would return a null reference.
  3879. if (m_parentGroup == null)
  3880. return;
  3881. if (m_parentGroup.Scene == null)
  3882. return;
  3883. m_parentGroup.Scene.EventManager.TriggerScriptCollidingEnd(this, EndCollidingMessage);
  3884. if ((this.UUID != this.ParentGroup.RootPart.UUID))
  3885. {
  3886. const int PASS_IF_NOT_HANDLED = 0;
  3887. const int PASS_ALWAYS = 1;
  3888. const int PASS_NEVER = 2;
  3889. if (this.PassCollisions == PASS_NEVER)
  3890. {
  3891. }
  3892. if (this.PassCollisions == PASS_ALWAYS)
  3893. {
  3894. m_parentGroup.Scene.EventManager.TriggerScriptCollidingEnd(
  3895. this.ParentGroup.RootPart, EndCollidingMessage);
  3896. }
  3897. else if (((this.ScriptEvents & scriptEvents.collision_end) == 0) &&
  3898. this.PassCollisions == PASS_IF_NOT_HANDLED)
  3899. //If no event in this prim, pass to parent
  3900. {
  3901. m_parentGroup.Scene.EventManager.TriggerScriptCollidingEnd(
  3902. this.ParentGroup.RootPart, EndCollidingMessage);
  3903. }
  3904. }
  3905. }
  3906. }
  3907. }
  3908. if ((m_parentGroup.RootPart.ScriptEvents & scriptEvents.land_collision_start) != 0 ||
  3909. (m_parentGroup.RootPart.ScriptEvents & scriptEvents.land_collision) != 0)
  3910. {
  3911. if (startedColliders.Count > 0)
  3912. {
  3913. ColliderArgs LandStartCollidingMessage = new ColliderArgs();
  3914. List<DetectedObject> colliding = (from localId in startedColliders
  3915. where localId == 0
  3916. select new DetectedObject
  3917. {
  3918. keyUUID = UUID.Zero,
  3919. nameStr = "",
  3920. ownerUUID = UUID.Zero,
  3921. posVector =
  3922. m_parentGroup.RootPart.AbsolutePosition,
  3923. rotQuat = Quaternion.Identity,
  3924. velVector = Vector3.Zero,
  3925. colliderType = 0,
  3926. groupUUID = UUID.Zero
  3927. }).ToList();
  3928. if (colliding.Count > 0)
  3929. {
  3930. LandStartCollidingMessage.Colliders = colliding;
  3931. // always running this check because if the user deletes the object it would return a null reference.
  3932. if (m_parentGroup == null)
  3933. return;
  3934. if (m_parentGroup.Scene == null)
  3935. return;
  3936. m_parentGroup.Scene.EventManager.TriggerScriptLandCollidingStart(this,
  3937. LandStartCollidingMessage);
  3938. if ((this.UUID != this.ParentGroup.RootPart.UUID))
  3939. {
  3940. const int PASS_IF_NOT_HANDLED = 0;
  3941. const int PASS_ALWAYS = 1;
  3942. const int PASS_NEVER = 2;
  3943. if (this.PassCollisions == PASS_NEVER)
  3944. {
  3945. }
  3946. if (this.PassCollisions == PASS_ALWAYS)
  3947. {
  3948. m_parentGroup.Scene.EventManager.TriggerScriptLandCollidingStart(
  3949. this.ParentGroup.RootPart, LandStartCollidingMessage);
  3950. }
  3951. else if (((this.ScriptEvents & scriptEvents.land_collision_start) == 0) &&
  3952. this.PassCollisions == PASS_IF_NOT_HANDLED)
  3953. //If no event in this prim, pass to parent
  3954. {
  3955. m_parentGroup.Scene.EventManager.TriggerScriptLandCollidingStart(
  3956. this.ParentGroup.RootPart, LandStartCollidingMessage);
  3957. }
  3958. }
  3959. }
  3960. }
  3961. }
  3962. if ((m_parentGroup.RootPart.ScriptEvents & scriptEvents.land_collision) != 0)
  3963. {
  3964. if (m_lastColliders.Count > 0)
  3965. {
  3966. ColliderArgs LandCollidingMessage = new ColliderArgs();
  3967. List<DetectedObject> colliding = new List<DetectedObject>();
  3968. foreach (uint localId in m_lastColliders)
  3969. {
  3970. if (localId == 0)
  3971. {
  3972. //Hope that all is left is ground!
  3973. DetectedObject detobj = new DetectedObject
  3974. {
  3975. keyUUID = UUID.Zero,
  3976. nameStr = "",
  3977. ownerUUID = UUID.Zero,
  3978. posVector = m_parentGroup.RootPart.AbsolutePosition,
  3979. rotQuat = Quaternion.Identity,
  3980. velVector = Vector3.Zero,
  3981. colliderType = 0,
  3982. groupUUID = UUID.Zero
  3983. };
  3984. colliding.Add(detobj);
  3985. }
  3986. }
  3987. if (colliding.Count > 0)
  3988. {
  3989. LandCollidingMessage.Colliders = colliding;
  3990. // always running this check because if the user deletes the object it would return a null reference.
  3991. if (m_parentGroup == null)
  3992. return;
  3993. if (m_parentGroup.Scene == null)
  3994. return;
  3995. m_parentGroup.Scene.EventManager.TriggerScriptLandColliding(this, LandCollidingMessage);
  3996. if ((this.UUID != this.ParentGroup.RootPart.UUID))
  3997. {
  3998. const int PASS_IF_NOT_HANDLED = 0;
  3999. const int PASS_ALWAYS = 1;
  4000. const int PASS_NEVER = 2;
  4001. if (this.PassCollisions == PASS_NEVER)
  4002. {
  4003. }
  4004. if (this.PassCollisions == PASS_ALWAYS)
  4005. {
  4006. m_parentGroup.Scene.EventManager.TriggerScriptLandColliding(
  4007. this.ParentGroup.RootPart,
  4008. LandCollidingMessage);
  4009. }
  4010. else if (((this.ScriptEvents & scriptEvents.land_collision) == 0) &&
  4011. this.PassCollisions == PASS_IF_NOT_HANDLED)
  4012. //If no event in this prim, pass to parent
  4013. {
  4014. m_parentGroup.Scene.EventManager.TriggerScriptLandColliding(
  4015. this.ParentGroup.RootPart, LandCollidingMessage);
  4016. }
  4017. }
  4018. }
  4019. }
  4020. }
  4021. if ((m_parentGroup.RootPart.ScriptEvents & scriptEvents.land_collision_end) != 0)
  4022. {
  4023. if (endedColliders.Count > 0)
  4024. {
  4025. ColliderArgs LandEndCollidingMessage = new ColliderArgs();
  4026. List<DetectedObject> colliding = (from localId in startedColliders
  4027. where localId == 0
  4028. select new DetectedObject
  4029. {
  4030. keyUUID = UUID.Zero,
  4031. nameStr = "",
  4032. ownerUUID = UUID.Zero,
  4033. posVector =
  4034. m_parentGroup.RootPart.AbsolutePosition,
  4035. rotQuat = Quaternion.Identity,
  4036. velVector = Vector3.Zero,
  4037. colliderType = 0,
  4038. groupUUID = UUID.Zero
  4039. }).ToList();
  4040. if (colliding.Count > 0)
  4041. {
  4042. LandEndCollidingMessage.Colliders = colliding;
  4043. // always running this check because if the user deletes the object it would return a null reference.
  4044. if (m_parentGroup == null)
  4045. return;
  4046. if (m_parentGroup.Scene == null)
  4047. return;
  4048. m_parentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd(this, LandEndCollidingMessage);
  4049. if ((this.UUID != this.ParentGroup.RootPart.UUID))
  4050. {
  4051. const int PASS_IF_NOT_HANDLED = 0;
  4052. const int PASS_ALWAYS = 1;
  4053. const int PASS_NEVER = 2;
  4054. if (this.PassCollisions == PASS_NEVER)
  4055. {
  4056. }
  4057. if (this.PassCollisions == PASS_ALWAYS)
  4058. {
  4059. m_parentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd(
  4060. this.ParentGroup.RootPart, LandEndCollidingMessage);
  4061. }
  4062. else if (((this.ScriptEvents & scriptEvents.land_collision_end) == 0) &&
  4063. this.PassCollisions == PASS_IF_NOT_HANDLED)
  4064. //If no event in this prim, pass to parent
  4065. {
  4066. m_parentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd(
  4067. this.ParentGroup.RootPart, LandEndCollidingMessage);
  4068. }
  4069. }
  4070. }
  4071. }
  4072. }
  4073. }
  4074. }
  4075. public void PhysicsOutOfBounds(Vector3 pos)
  4076. {
  4077. MainConsole.Instance.Error("[Physics]: Physical object " + Name + ", localID " + LocalId +
  4078. " went out of bounds at " + pos + ". Stopping at " + AbsolutePosition +
  4079. " and making non-physical.");
  4080. lock (ParentGroup.Scene.PhysicsReturns)
  4081. {
  4082. if (!ParentGroup.Scene.PhysicsReturns.Contains(ParentGroup))
  4083. ParentGroup.Scene.PhysicsReturns.Add(ParentGroup);
  4084. }
  4085. }
  4086. public virtual void PhysicsRequestingTerseUpdate()
  4087. {
  4088. if (PhysActor != null)
  4089. {
  4090. // Vector3 newpos = new Vector3(PhysActor.Position.GetBytes(), 0);
  4091. m_parentGroup.SetAbsolutePosition(false, PhysActor.Position);
  4092. //m_parentGroup.RootPart.m_groupPosition = newpos;
  4093. }
  4094. ScheduleUpdate(PrimUpdateFlags.TerseUpdate);
  4095. }
  4096. public void RemoveScriptEvents(UUID scriptid)
  4097. {
  4098. lock (m_scriptEvents)
  4099. {
  4100. if (m_scriptEvents.ContainsKey(scriptid))
  4101. {
  4102. scriptEvents oldparts = scriptEvents.None;
  4103. oldparts = m_scriptEvents[scriptid];
  4104. // remove values from aggregated script events
  4105. AggregateScriptEvents &= ~oldparts;
  4106. m_scriptEvents.Remove(scriptid);
  4107. aggregateScriptEvents();
  4108. }
  4109. }
  4110. }
  4111. /// <summary>
  4112. /// Resize this part.
  4113. /// </summary>
  4114. /// <param name="scale"></param>
  4115. public void Resize(Vector3 scale)
  4116. {
  4117. Scale = scale;
  4118. ParentGroup.HasGroupChanged = true;
  4119. ScheduleUpdate(PrimUpdateFlags.Shape);
  4120. }
  4121. public void stopLookAt()
  4122. {
  4123. APIDEnabled = false;
  4124. }
  4125. /// <summary>
  4126. /// Check to see whether the given flags make it a terse update
  4127. /// </summary>
  4128. /// <param name="flags"></param>
  4129. /// <returns></returns>
  4130. private bool IsTerse(PrimUpdateFlags flags)
  4131. {
  4132. return flags.HasFlag((PrimUpdateFlags.TerseUpdate))
  4133. && !flags.HasFlag((PrimUpdateFlags.AttachmentPoint | PrimUpdateFlags.ClickAction |
  4134. PrimUpdateFlags.CollisionPlane | PrimUpdateFlags.ExtraData |
  4135. PrimUpdateFlags.FindBest | PrimUpdateFlags.FullUpdate |
  4136. PrimUpdateFlags.Joint | PrimUpdateFlags.Material | PrimUpdateFlags.MediaURL |
  4137. PrimUpdateFlags.NameValue |
  4138. PrimUpdateFlags.ParentID | PrimUpdateFlags.Particles | PrimUpdateFlags.PrimData |
  4139. PrimUpdateFlags.PrimFlags |
  4140. PrimUpdateFlags.ScratchPad | PrimUpdateFlags.Shape | PrimUpdateFlags.Sound |
  4141. PrimUpdateFlags.Text |
  4142. PrimUpdateFlags.TextureAnim | PrimUpdateFlags.Textures)) &&
  4143. !flags.HasFlag(PrimUpdateFlags.ForcedFullUpdate);
  4144. }
  4145. public void SetAttachmentPoint(int AttachmentPoint)
  4146. {
  4147. //Update the saved if needed
  4148. if (AttachmentPoint == 0 && this.AttachmentPoint != 0)
  4149. {
  4150. this.SavedAttachedPos = this.AttachedPos;
  4151. this.SavedAttachmentPoint = this.AttachmentPoint;
  4152. }
  4153. this.AttachmentPoint = AttachmentPoint;
  4154. IsAttachment = AttachmentPoint != 0;
  4155. // save the attachment point.
  4156. //if (AttachmentPoint != 0)
  4157. //{
  4158. m_shape.State = (byte) AttachmentPoint;
  4159. //}
  4160. }
  4161. public void SetPhysActorCameraPos(Quaternion CameraRotation)
  4162. {
  4163. if (PhysActor != null)
  4164. {
  4165. PhysActor.SetCameraPos(CameraRotation);
  4166. }
  4167. }
  4168. /// <summary>
  4169. /// Tell us if this object has cut, hollow, dimple, and other factors affecting the number of faces
  4170. /// </summary>
  4171. /// <param name="primType"></param>
  4172. /// <param name="shape"></param>
  4173. /// <param name="hasCut"></param>
  4174. /// <param name="hasHollow"></param>
  4175. /// <param name="hasDimple"></param>
  4176. /// <param name="hasProfileCut"></param>
  4177. protected static void HasCutHollowDimpleProfileCut(PrimType primType, PrimitiveBaseShape shape, out bool hasCut,
  4178. out bool hasHollow,
  4179. out bool hasDimple, out bool hasProfileCut)
  4180. {
  4181. if (primType == PrimType.BOX
  4182. ||
  4183. primType == PrimType.CYLINDER
  4184. ||
  4185. primType == PrimType.PRISM)
  4186. hasCut = (shape.ProfileBegin > 0) || (shape.ProfileEnd > 0);
  4187. else
  4188. hasCut = (shape.PathBegin > 0) || (shape.PathEnd > 0);
  4189. hasHollow = shape.ProfileHollow > 0;
  4190. hasDimple = (shape.ProfileBegin > 0) || (shape.ProfileEnd > 0); // taken from llSetPrimitiveParms
  4191. hasProfileCut = hasDimple; // is it the same thing?
  4192. }
  4193. public void SetGroup(UUID groupID)
  4194. {
  4195. _groupID = groupID;
  4196. }
  4197. public void SetPhysicsAxisRotation()
  4198. {
  4199. if (PhysActor != null)
  4200. PhysActor.LockAngularMotion(RotationAxis);
  4201. }
  4202. /// <summary>
  4203. /// Serialize this part to xml.
  4204. /// </summary>
  4205. /// <param name="xmlWriter"></param>
  4206. public void ToXml(XmlTextWriter xmlWriter)
  4207. {
  4208. SceneEntitySerializer.SceneObjectSerializer.ToXmlFormat(this, xmlWriter);
  4209. }
  4210. public void UpdateExtraParam(ushort type, bool inUse, byte[] data)
  4211. {
  4212. m_shape.ReadInUpdateExtraParam(type, inUse, data);
  4213. if (type == 0x30)
  4214. {
  4215. if (m_shape.SculptEntry && m_shape.SculptTexture != UUID.Zero)
  4216. m_parentGroup.Scene.AssetService.Get(m_shape.SculptTexture.ToString(), true, AssetReceived);
  4217. }
  4218. ValidpartOOB = false;
  4219. ParentGroup.HasGroupChanged = true;
  4220. ScheduleUpdate(PrimUpdateFlags.Shape);
  4221. }
  4222. public void UpdateGroupPosition(Vector3 pos)
  4223. {
  4224. if ((pos.X != GroupPosition.X) ||
  4225. (pos.Y != GroupPosition.Y) ||
  4226. (pos.Z != GroupPosition.Z))
  4227. {
  4228. // Vector3 newPos = new Vector3(pos.X, pos.Y, pos.Z);
  4229. FixGroupPosition(pos, false);
  4230. ScheduleTerseUpdate();
  4231. }
  4232. }
  4233. public void UpdatePermissions(UUID AgentID, byte field, uint localID, uint mask, byte addRemTF)
  4234. {
  4235. bool set = addRemTF == 1;
  4236. bool god = m_parentGroup.Scene.Permissions.IsGod(AgentID);
  4237. uint baseMask = _baseMask;
  4238. if (god)
  4239. baseMask = 0x7ffffff0;
  4240. // Are we the owner?
  4241. if (m_parentGroup.Scene.Permissions.CanEditObject(this.UUID, AgentID))
  4242. {
  4243. uint exportPermission = (1 << 30);
  4244. if ((mask & exportPermission) == exportPermission)
  4245. {
  4246. //Only the creator can set export permissions
  4247. if (CreatorID != AgentID)
  4248. mask &= exportPermission;
  4249. }
  4250. switch (field)
  4251. {
  4252. case 1:
  4253. if (god)
  4254. {
  4255. _baseMask = ApplyMask(_baseMask, set, mask);
  4256. Inventory.ApplyGodPermissions(_baseMask);
  4257. }
  4258. break;
  4259. case 2:
  4260. _ownerMask = ApplyMask(_ownerMask, set, mask) &
  4261. baseMask;
  4262. break;
  4263. case 4:
  4264. _groupMask = ApplyMask(_groupMask, set, mask) &
  4265. baseMask;
  4266. break;
  4267. case 8:
  4268. _everyoneMask = ApplyMask(_everyoneMask, set, mask) &
  4269. baseMask;
  4270. break;
  4271. case 16:
  4272. _nextOwnerMask = ApplyMask(_nextOwnerMask, set, mask) &
  4273. baseMask;
  4274. // Prevent the client from creating no mod, no copy
  4275. // objects
  4276. if ((_nextOwnerMask & (uint) PermissionMask.Copy) == 0)
  4277. _nextOwnerMask |= (uint) PermissionMask.Transfer;
  4278. _nextOwnerMask |= (uint) PermissionMask.Move;
  4279. break;
  4280. }
  4281. ParentGroup.ScheduleGroupUpdate(PrimUpdateFlags.PrimFlags);
  4282. SendObjectPropertiesToClient(AgentID);
  4283. }
  4284. }
  4285. /// <summary>
  4286. /// Update the texture entry for this part.
  4287. /// </summary>
  4288. /// <param name="textureEntry"></param>
  4289. /// <param name="sendChangedEvent"></param>
  4290. public void UpdateTextureEntry(byte[] textureEntry, bool sendChangedEvent)
  4291. {
  4292. bool same = true;
  4293. byte[] old = m_shape.TextureEntry;
  4294. if (old.Length == textureEntry.Length)
  4295. {
  4296. if (textureEntry.Where((t, i) => old[i] != t).Any())
  4297. {
  4298. same = false;
  4299. }
  4300. }
  4301. else
  4302. same = false;
  4303. if (same)
  4304. return;
  4305. Primitive.TextureEntry oldEntry = m_shape.Textures;
  4306. m_shape.TextureEntry = textureEntry;
  4307. bool textureChanged = false;
  4308. bool colorChanged = false;
  4309. if (m_shape.Textures.DefaultTexture.RGBA.A != oldEntry.DefaultTexture.RGBA.A ||
  4310. m_shape.Textures.DefaultTexture.RGBA.R != oldEntry.DefaultTexture.RGBA.R ||
  4311. m_shape.Textures.DefaultTexture.RGBA.G != oldEntry.DefaultTexture.RGBA.G ||
  4312. m_shape.Textures.DefaultTexture.RGBA.B != oldEntry.DefaultTexture.RGBA.B)
  4313. {
  4314. colorChanged = true;
  4315. }
  4316. if (m_shape.Textures.DefaultTexture.TextureID != oldEntry.DefaultTexture.TextureID)
  4317. {
  4318. textureChanged = true;
  4319. }
  4320. if (!(colorChanged && textureChanged)) // if both already changed so don't bother checking further
  4321. {
  4322. for (int i = 0; i < GetNumberOfSides(); i++)
  4323. {
  4324. if (m_shape.Textures.FaceTextures[i] != null &&
  4325. oldEntry.FaceTextures[i] != null)
  4326. {
  4327. if (m_shape.Textures.FaceTextures[i].RGBA.A != oldEntry.FaceTextures[i].RGBA.A ||
  4328. m_shape.Textures.FaceTextures[i].RGBA.R != oldEntry.FaceTextures[i].RGBA.R ||
  4329. m_shape.Textures.FaceTextures[i].RGBA.G != oldEntry.FaceTextures[i].RGBA.G ||
  4330. m_shape.Textures.FaceTextures[i].RGBA.B != oldEntry.FaceTextures[i].RGBA.B)
  4331. {
  4332. colorChanged = true;
  4333. }
  4334. if (m_shape.Textures.FaceTextures[i].TextureID != oldEntry.FaceTextures[i].TextureID)
  4335. {
  4336. textureChanged = true;
  4337. }
  4338. }
  4339. }
  4340. }
  4341. if (colorChanged && sendChangedEvent) TriggerScriptChangedEvent(Changed.COLOR);
  4342. if (textureChanged && sendChangedEvent) TriggerScriptChangedEvent(Changed.TEXTURE);
  4343. ParentGroup.HasGroupChanged = true;
  4344. ScheduleUpdate(PrimUpdateFlags.FullUpdate);
  4345. }
  4346. public override string ToString()
  4347. {
  4348. return String.Format("{0} {1} linkNum {3} (parent {2}))", Name, UUID, ParentGroup, LinkNum);
  4349. }
  4350. #endregion Public Methods
  4351. public void ApplyPermissions(uint permissions)
  4352. {
  4353. _ownerMask = permissions;
  4354. }
  4355. private void UpdateLookAt()
  4356. {
  4357. try
  4358. {
  4359. //PID movement
  4360. // Has to be physical (works with phantom too)
  4361. if (PIDActive && ((Flags & PrimFlags.Physics) != 0))
  4362. {
  4363. Vector3 _target_velocity =
  4364. new Vector3(
  4365. (PIDTarget.X - m_initialPIDLocation.X)*(PIDTau),
  4366. (PIDTarget.Y - m_initialPIDLocation.Y)*(PIDTau),
  4367. (PIDTarget.Z - m_initialPIDLocation.Z)*(PIDTau)
  4368. );
  4369. if (PIDTarget.ApproxEquals(AbsolutePosition, 0.1f))
  4370. {
  4371. ParentGroup.Velocity = Vector3.Zero;
  4372. ParentGroup.SetAbsolutePosition(true, PIDTarget);
  4373. this.ScheduleTerseUpdate();
  4374. //End the movement
  4375. //SetMoveToTarget(false, Vector3.Zero, 0);
  4376. }
  4377. else
  4378. {
  4379. //ParentGroup.SetAbsolutePosition(true, ParentGroup.AbsolutePosition + _target_velocity);
  4380. Velocity = _target_velocity;
  4381. this.ScheduleTerseUpdate();
  4382. }
  4383. }
  4384. else if (PIDHoverActive)
  4385. {
  4386. Vector3 _target_velocity;
  4387. ITerrainChannel terrain = ParentGroup.Scene.RequestModuleInterface<ITerrainChannel>();
  4388. if (terrain == null)
  4389. return;
  4390. float groundHeight =
  4391. terrain[(int) ParentGroup.AbsolutePosition.X, (int) ParentGroup.AbsolutePosition.Y];
  4392. switch (PIDHoverType)
  4393. {
  4394. case PIDHoverType.Ground:
  4395. _target_velocity =
  4396. new Vector3(
  4397. 0, 0, ((groundHeight + PIDHoverHeight) - m_initialPIDLocation.Z)*(PIDTau)
  4398. );
  4399. break;
  4400. case PIDHoverType.GroundAndWater:
  4401. if (ParentGroup.Scene.RegionInfo.RegionSettings.WaterHeight < groundHeight)
  4402. groundHeight = (float) ParentGroup.Scene.RegionInfo.RegionSettings.WaterHeight;
  4403. _target_velocity =
  4404. new Vector3(
  4405. 0, 0, ((groundHeight + PIDHoverHeight) - m_initialPIDLocation.Z)*(PIDTau)
  4406. );
  4407. break;
  4408. default:
  4409. return;
  4410. }
  4411. Velocity = _target_velocity;
  4412. this.ScheduleTerseUpdate();
  4413. }
  4414. if (APIDEnabled)
  4415. {
  4416. if (APIDIterations <= 1)
  4417. {
  4418. UpdateRotation(APIDTarget);
  4419. APIDTarget = Quaternion.Identity;
  4420. return;
  4421. }
  4422. Quaternion rot = Quaternion.Slerp(GetRotationOffset(), APIDTarget, 1.0f/(float) APIDIterations);
  4423. UpdateRotation(rot);
  4424. APIDIterations--;
  4425. // This ensures that we'll check this object on the next iteration
  4426. ParentGroup.ScheduleGroupTerseUpdate();
  4427. }
  4428. }
  4429. catch (Exception ex)
  4430. {
  4431. MainConsole.Instance.Error("[Physics] " + ex);
  4432. }
  4433. }
  4434. internal void TriggerScriptMovingStartEvent()
  4435. {
  4436. if ((AggregateScriptEvents & scriptEvents.moving_start) == 0)
  4437. return;
  4438. if (m_parentGroup != null && m_parentGroup.Scene != null && m_parentGroup.Scene.EventManager != null)
  4439. m_parentGroup.Scene.EventManager.TriggerOnScriptMovingStartEvent(this);
  4440. }
  4441. internal void TriggerScriptMovingEndEvent()
  4442. {
  4443. if ((AggregateScriptEvents & scriptEvents.moving_end) == 0)
  4444. return;
  4445. if (m_parentGroup != null && m_parentGroup.Scene != null && m_parentGroup.Scene.EventManager != null)
  4446. m_parentGroup.Scene.EventManager.TriggerOnScriptMovingEndEvent(this);
  4447. }
  4448. }
  4449. }