aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs1204
1 files changed, 602 insertions, 602 deletions
diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs
index ac35e46..6af7662 100644
--- a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs
@@ -39,9 +39,8 @@ using OpenSim.Region.Physics.Manager;
39 39
40namespace OpenSim.Region.Environment.Scenes 40namespace OpenSim.Region.Environment.Scenes
41{ 41{
42
43 [Flags] 42 [Flags]
44 public enum scriptEvents : int 43 public enum scriptEvents
45 { 44 {
46 None = 0, 45 None = 0,
47 attach = 1, 46 attach = 1,
@@ -77,16 +76,6 @@ namespace OpenSim.Region.Environment.Scenes
77 76
78 public partial class SceneObjectGroup : EntityBase 77 public partial class SceneObjectGroup : EntityBase
79 { 78 {
80 protected SceneObjectPart m_rootPart;
81
82 /// <summary>
83 /// The constituent parts of this group
84 /// </summary>
85 protected Dictionary<LLUUID, SceneObjectPart> m_parts = new Dictionary<LLUUID, SceneObjectPart>();
86
87 protected ulong m_regionHandle;
88
89 public event PrimCountTaintedDelegate OnPrimCountTainted;
90 private PrimCountTaintedDelegate handlerPrimCountTainted = null; 79 private PrimCountTaintedDelegate handlerPrimCountTainted = null;
91 80
92 /// <summary> 81 /// <summary>
@@ -94,17 +83,34 @@ namespace OpenSim.Region.Environment.Scenes
94 /// since the group's last persistent backup 83 /// since the group's last persistent backup
95 /// </summary> 84 /// </summary>
96 public bool HasGroupChanged = false; 85 public bool HasGroupChanged = false;
97 86
98 87
99 private LLVector3 lastPhysGroupPos; 88 private LLVector3 lastPhysGroupPos;
100 private LLQuaternion lastPhysGroupRot; 89 private LLQuaternion lastPhysGroupRot;
101 90
102 private Dictionary<LLUUID, scriptEvents> m_scriptEvents = new Dictionary<LLUUID, scriptEvents>();
103 private scriptEvents m_aggregateScriptEvents = scriptEvents.None; 91 private scriptEvents m_aggregateScriptEvents = scriptEvents.None;
104 92
93 /// <summary>
94 /// The constituent parts of this group
95 /// </summary>
96 protected Dictionary<LLUUID, SceneObjectPart> m_parts = new Dictionary<LLUUID, SceneObjectPart>();
97
98 protected ulong m_regionHandle;
99 protected SceneObjectPart m_rootPart;
100 private Dictionary<LLUUID, scriptEvents> m_scriptEvents = new Dictionary<LLUUID, scriptEvents>();
101
105 #region Properties 102 #region Properties
106 103
107 /// <summary> 104 /// <summary>
105 /// Added because the Parcel code seems to use it
106 /// but not sure a object should have this
107 /// as what does it tell us? that some avatar has selected it (but not what Avatar/user)
108 /// think really there should be a list (or whatever) in each scenepresence
109 /// saying what prim(s) that user has selected.
110 /// </summary>
111 protected bool m_isSelected = false;
112
113 /// <summary>
108 /// 114 ///
109 /// </summary> 115 /// </summary>
110 public int PrimCount 116 public int PrimCount
@@ -116,11 +122,13 @@ namespace OpenSim.Region.Environment.Scenes
116 { 122 {
117 get { return m_rootPart.RotationOffset; } 123 get { return m_rootPart.RotationOffset; }
118 } 124 }
125
119 public LLUUID GroupID 126 public LLUUID GroupID
120 { 127 {
121 get { return m_rootPart.GroupID; } 128 get { return m_rootPart.GroupID; }
122 set { m_rootPart.GroupID = value; } 129 set { m_rootPart.GroupID = value; }
123 } 130 }
131
124 /// <summary> 132 /// <summary>
125 /// 133 ///
126 /// </summary> 134 /// </summary>
@@ -161,7 +169,7 @@ namespace OpenSim.Region.Environment.Scenes
161 { 169 {
162 get 170 get
163 { 171 {
164 if( m_rootPart == null ) 172 if (m_rootPart == null)
165 { 173 {
166 throw new NullReferenceException( 174 throw new NullReferenceException(
167 string.Format("[SCENE OBJECT GROUP]: Object {0} has no root part.", m_uuid)); 175 string.Format("[SCENE OBJECT GROUP]: Object {0} has no root part.", m_uuid));
@@ -176,7 +184,7 @@ namespace OpenSim.Region.Environment.Scenes
176 { 184 {
177 m_scene.CrossPrimGroupIntoNewRegion(val, this); 185 m_scene.CrossPrimGroupIntoNewRegion(val, this);
178 } 186 }
179 187
180 188
181 lock (m_parts) 189 lock (m_parts)
182 { 190 {
@@ -187,24 +195,26 @@ namespace OpenSim.Region.Environment.Scenes
187 } 195 }
188 //if (m_rootPart.PhysActor != null) 196 //if (m_rootPart.PhysActor != null)
189 //{ 197 //{
190 //m_rootPart.PhysActor.Position = 198 //m_rootPart.PhysActor.Position =
191 //new PhysicsVector(m_rootPart.GroupPosition.X, m_rootPart.GroupPosition.Y, 199 //new PhysicsVector(m_rootPart.GroupPosition.X, m_rootPart.GroupPosition.Y,
192 //m_rootPart.GroupPosition.Z); 200 //m_rootPart.GroupPosition.Z);
193 //m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); 201 //m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor);
194 //} 202 //}
195 } 203 }
196 } 204 }
197 205
198 public override uint LocalId 206 public override uint LocalId
199 { 207 {
200 get { 208 get
209 {
201 if (m_rootPart == null) 210 if (m_rootPart == null)
202 { 211 {
203 m_log.Error("[SCENE OBJECT GROUP]: Unable to find the rootpart for a LocalId Request!"); 212 m_log.Error("[SCENE OBJECT GROUP]: Unable to find the rootpart for a LocalId Request!");
204 return 0; 213 return 0;
205 } 214 }
206 215
207 return m_rootPart.LocalId; } 216 return m_rootPart.LocalId;
217 }
208 set { m_rootPart.LocalId = value; } 218 set { m_rootPart.LocalId = value; }
209 } 219 }
210 220
@@ -216,11 +226,12 @@ namespace OpenSim.Region.Environment.Scenes
216 226
217 public LLUUID OwnerID 227 public LLUUID OwnerID
218 { 228 {
219 get { 229 get
230 {
220 if (m_rootPart == null) 231 if (m_rootPart == null)
221 return LLUUID.Zero; 232 return LLUUID.Zero;
222 233
223 return m_rootPart.OwnerID; 234 return m_rootPart.OwnerID;
224 } 235 }
225 set { m_rootPart.OwnerID = value; } 236 set { m_rootPart.OwnerID = value; }
226 } 237 }
@@ -237,15 +248,6 @@ namespace OpenSim.Region.Environment.Scenes
237 set { m_rootPart.Text = value; } 248 set { m_rootPart.Text = value; }
238 } 249 }
239 250
240 /// <summary>
241 /// Added because the Parcel code seems to use it
242 /// but not sure a object should have this
243 /// as what does it tell us? that some avatar has selected it (but not what Avatar/user)
244 /// think really there should be a list (or whatever) in each scenepresence
245 /// saying what prim(s) that user has selected.
246 /// </summary>
247 protected bool m_isSelected = false;
248
249 protected virtual bool InSceneBackup 251 protected virtual bool InSceneBackup
250 { 252 {
251 get { return true; } 253 get { return true; }
@@ -254,7 +256,8 @@ namespace OpenSim.Region.Environment.Scenes
254 public bool IsSelected 256 public bool IsSelected
255 { 257 {
256 get { return m_isSelected; } 258 get { return m_isSelected; }
257 set { 259 set
260 {
258 m_isSelected = value; 261 m_isSelected = value;
259 // Tell physics engine that group is selected 262 // Tell physics engine that group is selected
260 if (m_rootPart.PhysActor != null) 263 if (m_rootPart.PhysActor != null)
@@ -304,11 +307,11 @@ namespace OpenSim.Region.Environment.Scenes
304 public SceneObjectGroup(Scene scene, ulong regionHandle, SceneObjectPart part) 307 public SceneObjectGroup(Scene scene, ulong regionHandle, SceneObjectPart part)
305 { 308 {
306 m_scene = scene; 309 m_scene = scene;
307 310
308 part.SetParent(this); 311 part.SetParent(this);
309 part.ParentID = 0; 312 part.ParentID = 0;
310 part.LinkNum = 0; 313 part.LinkNum = 0;
311 314
312 m_parts.Add(part.UUID, part); 315 m_parts.Add(part.UUID, part);
313 316
314 SetPartAsRoot(part); 317 SetPartAsRoot(part);
@@ -329,7 +332,7 @@ namespace OpenSim.Region.Environment.Scenes
329 { 332 {
330 m_scene = scene; 333 m_scene = scene;
331 m_regionHandle = regionHandle; 334 m_regionHandle = regionHandle;
332 335
333 StringReader sr = new StringReader(xmlData); 336 StringReader sr = new StringReader(xmlData);
334 XmlTextReader reader = new XmlTextReader(sr); 337 XmlTextReader reader = new XmlTextReader(sr);
335 try 338 try
@@ -339,11 +342,11 @@ namespace OpenSim.Region.Environment.Scenes
339 reader.ReadStartElement("RootPart"); 342 reader.ReadStartElement("RootPart");
340 m_rootPart = SceneObjectPart.FromXml(reader); 343 m_rootPart = SceneObjectPart.FromXml(reader);
341 AddPart(m_rootPart); 344 AddPart(m_rootPart);
342 345
343 m_log.DebugFormat("[SCENE OBJECT GROUP]: Current node {0}", reader.Name); 346 m_log.DebugFormat("[SCENE OBJECT GROUP]: Current node {0}", reader.Name);
344 347
345 reader.ReadEndElement(); 348 reader.ReadEndElement();
346 349
347 while (reader.Read()) 350 while (reader.Read())
348 { 351 {
349 switch (reader.NodeType) 352 switch (reader.NodeType)
@@ -356,7 +359,7 @@ namespace OpenSim.Region.Environment.Scenes
356 part.LocalId = m_scene.PrimIDAllocate(); 359 part.LocalId = m_scene.PrimIDAllocate();
357 AddPart(part); 360 AddPart(part);
358 part.RegionHandle = m_regionHandle; 361 part.RegionHandle = m_regionHandle;
359 362
360 part.TrimPermissions(); 363 part.TrimPermissions();
361 } 364 }
362 break; 365 break;
@@ -368,10 +371,10 @@ namespace OpenSim.Region.Environment.Scenes
368 catch (XmlException) 371 catch (XmlException)
369 { 372 {
370 m_log.ErrorFormat("[SCENE OBJECT GROUP]: Deserialization of following xml failed, {0}", xmlData); 373 m_log.ErrorFormat("[SCENE OBJECT GROUP]: Deserialization of following xml failed, {0}", xmlData);
371 374
372 // Let's see if carrying on does anything for us 375 // Let's see if carrying on does anything for us
373 } 376 }
374 377
375 reader.Close(); 378 reader.Close();
376 sr.Close(); 379 sr.Close();
377 380
@@ -436,6 +439,37 @@ namespace OpenSim.Region.Environment.Scenes
436 } 439 }
437 440
438 /// <summary> 441 /// <summary>
442 ///
443 /// </summary>
444 public SceneObjectGroup(Scene scene, ulong regionHandle, LLUUID ownerID, uint localID, LLVector3 pos,
445 LLQuaternion rot, PrimitiveBaseShape shape)
446 {
447 m_regionHandle = regionHandle;
448 m_scene = scene;
449
450 // this.Pos = pos;
451 LLVector3 rootOffset = new LLVector3(0, 0, 0);
452 SceneObjectPart newPart =
453 new SceneObjectPart(m_regionHandle, this, ownerID, localID, shape, pos, rot, rootOffset);
454 newPart.LinkNum = m_parts.Count;
455 m_parts.Add(newPart.UUID, newPart);
456 SetPartAsRoot(newPart);
457
458 AttachToBackup();
459
460 //ApplyPhysics(scene.m_physicalPrim);
461 }
462
463 /// <summary>
464 ///
465 /// </summary>
466 public SceneObjectGroup(Scene scene, ulong regionHandle, LLUUID ownerID, uint localID, LLVector3 pos,
467 PrimitiveBaseShape shape)
468 : this(scene, regionHandle, ownerID, localID, pos, LLQuaternion.Identity, shape)
469 {
470 }
471
472 /// <summary>
439 /// Hooks this object up to the backup event so that it is persisted to the database when the update thread executes. 473 /// Hooks this object up to the backup event so that it is persisted to the database when the update thread executes.
440 /// </summary> 474 /// </summary>
441 private void AttachToBackup() 475 private void AttachToBackup()
@@ -473,7 +507,7 @@ namespace OpenSim.Region.Environment.Scenes
473 // This may need to be updated to the maximum draw distance possible.. 507 // This may need to be updated to the maximum draw distance possible..
474 // We might (and probably will) be checking for prim creation from other sims 508 // We might (and probably will) be checking for prim creation from other sims
475 // when the camera crosses the border. 509 // when the camera crosses the border.
476 float idist = (float)Constants.RegionSize; 510 float idist = Constants.RegionSize;
477 511
478 512
479 if (inter.HitTF) 513 if (inter.HitTF)
@@ -481,7 +515,6 @@ namespace OpenSim.Region.Environment.Scenes
481 // We need to find the closest prim to return to the testcaller along the ray 515 // We need to find the closest prim to return to the testcaller along the ray
482 if (inter.distance < idist) 516 if (inter.distance < idist)
483 { 517 {
484 idist = inter.distance;
485 returnresult.HitTF = true; 518 returnresult.HitTF = true;
486 returnresult.ipoint = inter.ipoint; 519 returnresult.ipoint = inter.ipoint;
487 returnresult.obj = part; 520 returnresult.obj = part;
@@ -494,39 +527,10 @@ namespace OpenSim.Region.Environment.Scenes
494 return returnresult; 527 return returnresult;
495 } 528 }
496 529
497 /// <summary>
498 ///
499 /// </summary>
500 public SceneObjectGroup(Scene scene, ulong regionHandle, LLUUID ownerID, uint localID, LLVector3 pos,
501 LLQuaternion rot, PrimitiveBaseShape shape)
502 {
503 m_regionHandle = regionHandle;
504 m_scene = scene;
505
506 // this.Pos = pos;
507 LLVector3 rootOffset = new LLVector3(0, 0, 0);
508 SceneObjectPart newPart =
509 new SceneObjectPart(m_regionHandle, this, ownerID, localID, shape, pos, rot, rootOffset);
510 newPart.LinkNum = m_parts.Count;
511 m_parts.Add(newPart.UUID, newPart);
512 SetPartAsRoot(newPart);
513
514 AttachToBackup();
515
516 //ApplyPhysics(scene.m_physicalPrim);
517 }
518
519 /// <summary>
520 ///
521 /// </summary>
522 public SceneObjectGroup(Scene scene, ulong regionHandle, LLUUID ownerID, uint localID, LLVector3 pos,
523 PrimitiveBaseShape shape)
524 : this(scene, regionHandle, ownerID, localID, pos, LLQuaternion.Identity, shape)
525 {
526 }
527
528 #endregion 530 #endregion
529 531
532 public event PrimCountTaintedDelegate OnPrimCountTainted;
533
530 public string ToXmlString() 534 public string ToXmlString()
531 { 535 {
532 using (StringWriter sw = new StringWriter()) 536 using (StringWriter sw = new StringWriter())
@@ -547,7 +551,7 @@ namespace OpenSim.Region.Environment.Scenes
547 m_rootPart.ToXml(writer); 551 m_rootPart.ToXml(writer);
548 writer.WriteEndElement(); 552 writer.WriteEndElement();
549 writer.WriteStartElement(String.Empty, "OtherParts", String.Empty); 553 writer.WriteStartElement(String.Empty, "OtherParts", String.Empty);
550 554
551 lock (m_parts) 555 lock (m_parts)
552 { 556 {
553 foreach (SceneObjectPart part in m_parts.Values) 557 foreach (SceneObjectPart part in m_parts.Values)
@@ -560,7 +564,7 @@ namespace OpenSim.Region.Environment.Scenes
560 } 564 }
561 } 565 }
562 } 566 }
563 567
564 writer.WriteEndElement(); 568 writer.WriteEndElement();
565 writer.WriteEndElement(); 569 writer.WriteEndElement();
566 } 570 }
@@ -583,7 +587,7 @@ namespace OpenSim.Region.Environment.Scenes
583 writer.WriteStartElement(String.Empty, "SceneObjectGroup", String.Empty); 587 writer.WriteStartElement(String.Empty, "SceneObjectGroup", String.Empty);
584 m_rootPart.ToXml(writer); 588 m_rootPart.ToXml(writer);
585 writer.WriteStartElement(String.Empty, "OtherParts", String.Empty); 589 writer.WriteStartElement(String.Empty, "OtherParts", String.Empty);
586 590
587 lock (m_parts) 591 lock (m_parts)
588 { 592 {
589 foreach (SceneObjectPart part in m_parts.Values) 593 foreach (SceneObjectPart part in m_parts.Values)
@@ -594,11 +598,434 @@ namespace OpenSim.Region.Environment.Scenes
594 } 598 }
595 } 599 }
596 } 600 }
597 601
598 writer.WriteEndElement(); 602 writer.WriteEndElement();
599 writer.WriteEndElement(); 603 writer.WriteEndElement();
600 } 604 }
601 605
606 /// <summary>
607 ///
608 /// </summary>
609 /// <param name="part"></param>
610 private void SetPartAsRoot(SceneObjectPart part)
611 {
612 m_rootPart = part;
613 }
614
615 /// <summary>
616 ///
617 /// </summary>
618 /// <param name="part"></param>
619 private void SetPartAsNonRoot(SceneObjectPart part)
620 {
621 part.ParentID = m_rootPart.LocalId;
622 }
623
624 /// <summary>
625 ///
626 /// </summary>
627 /// <returns></returns>
628 public List<ScenePresence> GetScenePresences()
629 {
630 return m_scene.GetScenePresences();
631 }
632
633 public override void UpdateMovement()
634 {
635 lock (m_parts)
636 {
637 foreach (SceneObjectPart part in m_parts.Values)
638 {
639 part.UpdateMovement();
640 }
641 }
642 }
643
644 public float GetTimeDilation()
645 {
646 return m_scene.TimeDilation;
647 }
648
649 /// <summary>
650 /// Added as a way for the storage provider to reset the scene,
651 /// most likely a better way to do this sort of thing but for now...
652 /// </summary>
653 /// <param name="scene"></param>
654 public void SetScene(Scene scene)
655 {
656 m_scene = scene;
657 AttachToBackup();
658 }
659
660 /// <summary>
661 ///
662 /// </summary>
663 /// <param name="part"></param>
664 public void AddPart(SceneObjectPart part)
665 {
666 lock (m_parts)
667 {
668 part.SetParent(this);
669 part.LinkNum = m_parts.Count;
670
671 try
672 {
673 m_parts.Add(part.UUID, part);
674 }
675 catch (Exception e)
676 {
677 m_log.Error("Failed to add scened object part", e);
678 }
679 }
680 }
681
682 /// <summary>
683 ///
684 /// </summary>
685 public void UpdateParentIDs()
686 {
687 lock (m_parts)
688 {
689 foreach (SceneObjectPart part in m_parts.Values)
690 {
691 if (part.UUID != m_rootPart.UUID)
692 {
693 part.ParentID = m_rootPart.LocalId;
694 }
695 }
696 }
697 }
698
699 public void RegenerateFullIDs()
700 {
701 lock (m_parts)
702 {
703 foreach (SceneObjectPart part in m_parts.Values)
704 {
705 part.UUID = LLUUID.Random();
706 }
707 }
708 }
709
710 public void ResetChildPrimPhysicsPositions()
711 {
712 AbsolutePosition = AbsolutePosition;
713 HasGroupChanged = false;
714 }
715
716 public LLUUID GetPartsFullID(uint localID)
717 {
718 SceneObjectPart part = GetChildPart(localID);
719 if (part != null)
720 {
721 return part.UUID;
722 }
723 return null;
724 }
725
726 public void ObjectGrabHandler(uint localId, LLVector3 offsetPos, IClientAPI remoteClient)
727 {
728 if (m_rootPart.LocalId == localId)
729 {
730 OnGrabGroup(offsetPos, remoteClient);
731 }
732 else
733 {
734 SceneObjectPart part = GetChildPart(localId);
735 OnGrabPart(part, offsetPos, remoteClient);
736 }
737 }
738
739 public virtual void OnGrabPart(SceneObjectPart part, LLVector3 offsetPos, IClientAPI remoteClient)
740 {
741 part.OnGrab(offsetPos, remoteClient);
742 }
743
744 public virtual void OnGrabGroup(LLVector3 offsetPos, IClientAPI remoteClient)
745 {
746 m_scene.EventManager.TriggerGroupGrab(UUID, offsetPos, remoteClient.AgentId);
747 }
748
749 /// <summary>
750 /// Completely delete this group and tell all the scene presences about that deletion.
751 /// </summary>
752 public void DeleteGroup()
753 {
754 DetachFromBackup(this);
755
756 lock (m_parts)
757 {
758 foreach (SceneObjectPart part in m_parts.Values)
759 {
760 List<ScenePresence> avatars = GetScenePresences();
761 for (int i = 0; i < avatars.Count; i++)
762 {
763 if (avatars[i].ParentID == LocalId)
764 {
765 avatars[i].StandUp();
766 }
767
768 avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId);
769 }
770 }
771 }
772 }
773
774 /// <summary>
775 /// Delete all the parts in this group.
776 /// </summary>
777 public void DeleteParts()
778 {
779 lock (m_parts)
780 {
781 foreach (SceneObjectPart part in m_parts.Values)
782 {
783 part.StopScripts();
784 }
785
786 m_rootPart = null;
787 m_parts.Clear();
788 }
789 }
790
791 public void AddScriptLPS(int count)
792 {
793 InnerScene d = m_scene.m_innerScene;
794 d.AddToScriptLPS(count);
795 }
796
797 public void AddActiveScriptCount(int count)
798 {
799 InnerScene d = m_scene.m_innerScene;
800 d.AddActiveScripts(count);
801 }
802
803 public void RemoveScriptEvents(LLUUID scriptid)
804 {
805 lock (m_scriptEvents)
806 {
807 if (m_scriptEvents.ContainsKey(scriptid))
808 {
809 scriptEvents oldparts = scriptEvents.None;
810 oldparts = (scriptEvents) m_scriptEvents[scriptid];
811
812 // remove values from aggregated script events
813 m_aggregateScriptEvents &= ~oldparts;
814 m_scriptEvents.Remove(scriptid);
815 }
816 }
817 aggregateScriptEvents();
818 }
819
820 public void SetScriptEvents(LLUUID scriptid, int events)
821 {
822 scriptEvents oldparts;
823 lock (m_scriptEvents)
824 {
825 if (m_scriptEvents.ContainsKey(scriptid))
826 {
827 oldparts = m_scriptEvents[scriptid];
828
829 // remove values from aggregated script events
830 m_aggregateScriptEvents &= ~oldparts;
831 m_scriptEvents[scriptid] = (scriptEvents) events;
832 }
833 else
834 {
835 m_scriptEvents.Add(scriptid, (scriptEvents) events);
836 }
837 }
838
839 aggregateScriptEvents();
840 }
841
842 public void aggregateScriptEvents()
843 {
844 // Aggregate script events
845 lock (m_scriptEvents)
846 {
847 foreach (scriptEvents s in m_scriptEvents.Values)
848 {
849 m_aggregateScriptEvents |= s;
850 }
851 }
852 uint objectflagupdate = m_rootPart.ObjectFlags;
853
854 if (
855 ((m_aggregateScriptEvents & scriptEvents.touch) != 0) ||
856 ((m_aggregateScriptEvents & scriptEvents.touch_end) != 0) ||
857 ((m_aggregateScriptEvents & scriptEvents.touch_start) != 0)
858 )
859 {
860 objectflagupdate |= (uint) LLObject.ObjectFlags.Touch;
861 }
862 else
863 {
864 objectflagupdate &= ~(uint) LLObject.ObjectFlags.Touch;
865 }
866
867 if ((m_aggregateScriptEvents & scriptEvents.money) != 0)
868 {
869 objectflagupdate |= (uint) LLObject.ObjectFlags.Money;
870 }
871 else
872 {
873 objectflagupdate &= ~(uint) LLObject.ObjectFlags.Money;
874 }
875
876 if (
877 ((m_aggregateScriptEvents & scriptEvents.collision) != 0) ||
878 ((m_aggregateScriptEvents & scriptEvents.collision_end) != 0) ||
879 ((m_aggregateScriptEvents & scriptEvents.collision_start) != 0)
880 )
881 {
882 // subscribe to physics updates.
883 }
884 else
885 {
886 // unsubscribe to physics updates.
887 }
888 lock (m_parts)
889 {
890 foreach (SceneObjectPart part in m_parts.Values)
891 {
892 part.ObjectFlags = objectflagupdate;
893 }
894 }
895 ScheduleGroupForFullUpdate();
896 }
897
898 public override void SetText(string text, Vector3 color, double alpha)
899 {
900 Color = Color.FromArgb(0xff - (int) (alpha * 0xff),
901 (int) (color.x * 0xff),
902 (int) (color.y * 0xff),
903 (int) (color.z * 0xff));
904 Text = text;
905
906 m_rootPart.ScheduleFullUpdate();
907 }
908
909 public void ApplyPhysics(bool m_physicalPrim)
910 {
911 lock (m_parts)
912 {
913 if (m_parts.Count > 1)
914 {
915 m_rootPart.ApplyPhysics(m_rootPart.ObjectFlags, m_physicalPrim);
916 foreach (SceneObjectPart part in m_parts.Values)
917 {
918 if (part.LocalId != m_rootPart.LocalId)
919 {
920 part.ApplyPhysics(m_rootPart.ObjectFlags, m_physicalPrim);
921 }
922 // Hack to get the physics scene geometries in the right spot
923 ResetChildPrimPhysicsPositions();
924 }
925 }
926 else
927 {
928 m_rootPart.ApplyPhysics(m_rootPart.ObjectFlags, m_physicalPrim);
929 }
930 }
931 }
932
933 public void SetOwnerId(LLUUID userId)
934 {
935 ForEachPart(delegate(SceneObjectPart part) { part.OwnerID = userId; });
936 }
937
938 public void ForEachPart(Action<SceneObjectPart> whatToDo)
939 {
940 lock (m_parts)
941 {
942 foreach (SceneObjectPart part in m_parts.Values)
943 {
944 whatToDo(part);
945 }
946 }
947 }
948
949 #region Events
950
951 /// <summary>
952 ///
953 /// </summary>
954 public void TriggerTainted()
955 {
956 handlerPrimCountTainted = OnPrimCountTainted;
957 if (handlerPrimCountTainted != null)
958 {
959 handlerPrimCountTainted();
960 }
961 }
962
963 /// <summary>
964 /// Processes backup
965 /// </summary>
966 /// <param name="datastore"></param>
967 public void ProcessBackup(IRegionDataStore datastore)
968 {
969 if (HasGroupChanged)
970 {
971 datastore.StoreObject(this, m_scene.RegionInfo.RegionID);
972 HasGroupChanged = false;
973 }
974
975 ForEachPart(delegate(SceneObjectPart part) { part.ProcessInventoryBackup(datastore); });
976 }
977
978 #endregion
979
980 #region Client Updating
981
982 public void SendFullUpdateToClient(IClientAPI remoteClient, uint clientFlags)
983 {
984 lock (m_parts)
985 {
986 foreach (SceneObjectPart part in m_parts.Values)
987 {
988 SendPartFullUpdate(remoteClient, part, clientFlags);
989 }
990 }
991 }
992
993 /// <summary>
994 /// Send a full update to the client for the given part
995 /// </summary>
996 /// <param name="remoteClient"></param>
997 /// <param name="part"></param>
998 internal void SendPartFullUpdate(IClientAPI remoteClient, SceneObjectPart part, uint clientFlags)
999 {
1000 if (m_rootPart.UUID == part.UUID)
1001 {
1002 part.SendFullUpdateToClient(remoteClient, AbsolutePosition, clientFlags);
1003 }
1004 else
1005 {
1006 part.SendFullUpdateToClient(remoteClient, clientFlags);
1007 }
1008 }
1009
1010 /// <summary>
1011 /// Send a terse update to the client for the given part
1012 /// </summary>
1013 /// <param name="remoteClient"></param>
1014 /// <param name="part"></param>
1015 internal void SendPartTerseUpdate(IClientAPI remoteClient, SceneObjectPart part)
1016 {
1017 if (m_rootPart.UUID == part.UUID)
1018 {
1019 part.SendTerseUpdateToClient(remoteClient, AbsolutePosition);
1020 }
1021 else
1022 {
1023 part.SendTerseUpdateToClient(remoteClient);
1024 }
1025 }
1026
1027 #endregion
1028
602 #region Copying 1029 #region Copying
603 1030
604 /// <summary> 1031 /// <summary>
@@ -633,7 +1060,7 @@ namespace OpenSim.Region.Environment.Scenes
633 new Quaternion(dupe.RootPart.RotationOffset.W, dupe.RootPart.RotationOffset.X, 1060 new Quaternion(dupe.RootPart.RotationOffset.W, dupe.RootPart.RotationOffset.X,
634 dupe.RootPart.RotationOffset.Y, dupe.RootPart.RotationOffset.Z), 1061 dupe.RootPart.RotationOffset.Y, dupe.RootPart.RotationOffset.Z),
635 dupe.RootPart.PhysActor.IsPhysical); 1062 dupe.RootPart.PhysActor.IsPhysical);
636 1063
637 dupe.RootPart.PhysActor.LocalID = dupe.RootPart.LocalId; 1064 dupe.RootPart.PhysActor.LocalID = dupe.RootPart.LocalId;
638 1065
639 dupe.RootPart.DoPhysicsPropertyUpdate(dupe.RootPart.PhysActor.IsPhysical, true); 1066 dupe.RootPart.DoPhysicsPropertyUpdate(dupe.RootPart.PhysActor.IsPhysical, true);
@@ -670,21 +1097,23 @@ namespace OpenSim.Region.Environment.Scenes
670 /// 1097 ///
671 /// </summary> 1098 /// </summary>
672 /// <param name="part"></param> 1099 /// <param name="part"></param>
1100 /// <param name="cAgentID"></param>
1101 /// <param name="cGroupID"></param>
673 public void CopyRootPart(SceneObjectPart part, LLUUID cAgentID, LLUUID cGroupID) 1102 public void CopyRootPart(SceneObjectPart part, LLUUID cAgentID, LLUUID cGroupID)
674 { 1103 {
675 SceneObjectPart newPart = part.Copy(m_scene.PrimIDAllocate(), OwnerID, GroupID, m_parts.Count); 1104 SceneObjectPart newPart = part.Copy(m_scene.PrimIDAllocate(), OwnerID, GroupID, m_parts.Count);
676 newPart.SetParent(this); 1105 newPart.SetParent(this);
677 1106
678 lock (m_parts) 1107 lock (m_parts)
679 { 1108 {
680 m_parts.Add(newPart.UUID, newPart); 1109 m_parts.Add(newPart.UUID, newPart);
681 } 1110 }
682 1111
683 SetPartAsRoot(newPart); 1112 SetPartAsRoot(newPart);
684 } 1113 }
685 1114
686 public void ScriptSetPhysicsStatus(bool UsePhysics) 1115 public void ScriptSetPhysicsStatus(bool UsePhysics)
687 { 1116 {
688 if (m_scene.m_physicalPrim) 1117 if (m_scene.m_physicalPrim)
689 { 1118 {
690 lock (m_parts) 1119 lock (m_parts)
@@ -701,7 +1130,6 @@ namespace OpenSim.Region.Environment.Scenes
701 } 1130 }
702 } 1131 }
703 } 1132 }
704
705 } 1133 }
706 1134
707 public void ScriptSetPhantomStatus(bool PhantomStatus) 1135 public void ScriptSetPhantomStatus(bool PhantomStatus)
@@ -721,7 +1149,7 @@ namespace OpenSim.Region.Environment.Scenes
721 else 1149 else
722 { 1150 {
723 part.RemFlag(LLObject.ObjectFlags.Phantom); 1151 part.RemFlag(LLObject.ObjectFlags.Phantom);
724 if ((part.ObjectFlags & (int)LLObject.ObjectFlags.Physics) != 0) 1152 if ((part.ObjectFlags & (int) LLObject.ObjectFlags.Physics) != 0)
725 { 1153 {
726 part.DoPhysicsPropertyUpdate(true, false); 1154 part.DoPhysicsPropertyUpdate(true, false);
727 } 1155 }
@@ -756,6 +1184,7 @@ namespace OpenSim.Region.Environment.Scenes
756 rootpart.PhysActor.PIDActive = true; 1184 rootpart.PhysActor.PIDActive = true;
757 } 1185 }
758 } 1186 }
1187
759 public void stopMoveToTarget() 1188 public void stopMoveToTarget()
760 { 1189 {
761 SceneObjectPart rootpart = m_rootPart; 1190 SceneObjectPart rootpart = m_rootPart;
@@ -786,16 +1215,18 @@ namespace OpenSim.Region.Environment.Scenes
786 /// 1215 ///
787 /// </summary> 1216 /// </summary>
788 /// <param name="part"></param> 1217 /// <param name="part"></param>
1218 /// <param name="cAgentID"></param>
1219 /// <param name="cGroupID"></param>
789 public void CopyPart(SceneObjectPart part, LLUUID cAgentID, LLUUID cGroupID) 1220 public void CopyPart(SceneObjectPart part, LLUUID cAgentID, LLUUID cGroupID)
790 { 1221 {
791 SceneObjectPart newPart = part.Copy(m_scene.PrimIDAllocate(), OwnerID, GroupID, m_parts.Count); 1222 SceneObjectPart newPart = part.Copy(m_scene.PrimIDAllocate(), OwnerID, GroupID, m_parts.Count);
792 newPart.SetParent(this); 1223 newPart.SetParent(this);
793 1224
794 lock (m_parts) 1225 lock (m_parts)
795 { 1226 {
796 m_parts.Add(newPart.UUID, newPart); 1227 m_parts.Add(newPart.UUID, newPart);
797 } 1228 }
798 1229
799 SetPartAsNonRoot(newPart); 1230 SetPartAsNonRoot(newPart);
800 } 1231 }
801 1232
@@ -813,7 +1244,7 @@ namespace OpenSim.Region.Environment.Scenes
813 m_parts.Clear(); 1244 m_parts.Clear();
814 foreach (SceneObjectPart part in partsList) 1245 foreach (SceneObjectPart part in partsList)
815 { 1246 {
816 part.ResetIDs(m_parts.Count); 1247 part.ResetIDs(m_parts.Count);
817 m_parts.Add(part.UUID, part); 1248 m_parts.Add(part.UUID, part);
818 } 1249 }
819 } 1250 }
@@ -869,15 +1300,15 @@ namespace OpenSim.Region.Environment.Scenes
869 lock (m_parts) 1300 lock (m_parts)
870 { 1301 {
871 if (Util.GetDistanceTo(lastPhysGroupPos, AbsolutePosition) > 0.02) 1302 if (Util.GetDistanceTo(lastPhysGroupPos, AbsolutePosition) > 0.02)
872 { 1303 {
873 foreach (SceneObjectPart part in m_parts.Values) 1304 foreach (SceneObjectPart part in m_parts.Values)
874 { 1305 {
875 if (part.UpdateFlag == 0) part.UpdateFlag = 1; 1306 if (part.UpdateFlag == 0) part.UpdateFlag = 1;
876 } 1307 }
877 1308
878 lastPhysGroupPos = AbsolutePosition; 1309 lastPhysGroupPos = AbsolutePosition;
879 } 1310 }
880 1311
881 if ((Math.Abs(lastPhysGroupRot.W - GroupRotation.W) > 0.1) 1312 if ((Math.Abs(lastPhysGroupRot.W - GroupRotation.W) > 0.1)
882 || (Math.Abs(lastPhysGroupRot.X - GroupRotation.X) > 0.1) 1313 || (Math.Abs(lastPhysGroupRot.X - GroupRotation.X) > 0.1)
883 || (Math.Abs(lastPhysGroupRot.Y - GroupRotation.Y) > 0.1) 1314 || (Math.Abs(lastPhysGroupRot.Y - GroupRotation.Y) > 0.1)
@@ -887,10 +1318,10 @@ namespace OpenSim.Region.Environment.Scenes
887 { 1318 {
888 if (part.UpdateFlag == 0) part.UpdateFlag = 1; 1319 if (part.UpdateFlag == 0) part.UpdateFlag = 1;
889 } 1320 }
890 1321
891 lastPhysGroupRot = GroupRotation; 1322 lastPhysGroupRot = GroupRotation;
892 } 1323 }
893 1324
894 foreach (SceneObjectPart part in m_parts.Values) 1325 foreach (SceneObjectPart part in m_parts.Values)
895 { 1326 {
896 part.SendScheduledUpdates(); 1327 part.SendScheduledUpdates();
@@ -926,7 +1357,7 @@ namespace OpenSim.Region.Environment.Scenes
926 public void ScheduleGroupForFullUpdate() 1357 public void ScheduleGroupForFullUpdate()
927 { 1358 {
928 HasGroupChanged = true; 1359 HasGroupChanged = true;
929 1360
930 lock (m_parts) 1361 lock (m_parts)
931 { 1362 {
932 foreach (SceneObjectPart part in m_parts.Values) 1363 foreach (SceneObjectPart part in m_parts.Values)
@@ -942,7 +1373,7 @@ namespace OpenSim.Region.Environment.Scenes
942 public void ScheduleGroupForTerseUpdate() 1373 public void ScheduleGroupForTerseUpdate()
943 { 1374 {
944 HasGroupChanged = true; 1375 HasGroupChanged = true;
945 1376
946 lock (m_parts) 1377 lock (m_parts)
947 { 1378 {
948 foreach (SceneObjectPart part in m_parts.Values) 1379 foreach (SceneObjectPart part in m_parts.Values)
@@ -958,7 +1389,7 @@ namespace OpenSim.Region.Environment.Scenes
958 public void SendGroupFullUpdate() 1389 public void SendGroupFullUpdate()
959 { 1390 {
960 HasGroupChanged = true; 1391 HasGroupChanged = true;
961 1392
962 lock (m_parts) 1393 lock (m_parts)
963 { 1394 {
964 foreach (SceneObjectPart part in m_parts.Values) 1395 foreach (SceneObjectPart part in m_parts.Values)
@@ -979,7 +1410,7 @@ namespace OpenSim.Region.Environment.Scenes
979 public void SendGroupTerseUpdate() 1410 public void SendGroupTerseUpdate()
980 { 1411 {
981 HasGroupChanged = true; 1412 HasGroupChanged = true;
982 1413
983 lock (m_parts) 1414 lock (m_parts)
984 { 1415 {
985 foreach (SceneObjectPart part in m_parts.Values) 1416 foreach (SceneObjectPart part in m_parts.Values)
@@ -1010,7 +1441,7 @@ namespace OpenSim.Region.Environment.Scenes
1010 } 1441 }
1011 } 1442 }
1012 } 1443 }
1013 1444
1014 return null; 1445 return null;
1015 } 1446 }
1016 1447
@@ -1046,7 +1477,7 @@ namespace OpenSim.Region.Environment.Scenes
1046 } 1477 }
1047 } 1478 }
1048 } 1479 }
1049 1480
1050 return null; 1481 return null;
1051 } 1482 }
1052 1483
@@ -1085,7 +1516,7 @@ namespace OpenSim.Region.Environment.Scenes
1085 } 1516 }
1086 return false; 1517 return false;
1087 } 1518 }
1088 1519
1089 #endregion 1520 #endregion
1090 1521
1091 #region Packet Handlers 1522 #region Packet Handlers
@@ -1100,18 +1531,18 @@ namespace OpenSim.Region.Environment.Scenes
1100 { 1531 {
1101 // I've never actually seen this happen, though I think it's theoretically possible 1532 // I've never actually seen this happen, though I think it's theoretically possible
1102 m_log.WarnFormat( 1533 m_log.WarnFormat(
1103 "[SCENE OBJECT GROUP]: Aborted linking {0}, {1} to {2}, {3} as it has yet to finish delinking", 1534 "[SCENE OBJECT GROUP]: Aborted linking {0}, {1} to {2}, {3} as it has yet to finish delinking",
1104 objectGroup.RootPart.Name, objectGroup.RootPart.UUID, RootPart.Name, RootPart.UUID); 1535 objectGroup.RootPart.Name, objectGroup.RootPart.UUID, RootPart.Name, RootPart.UUID);
1105 1536
1106 return; 1537 return;
1107 } 1538 }
1108 1539
1109// m_log.DebugFormat( 1540// m_log.DebugFormat(
1110// "[SCENE OBJECT GROUP]: Linking group with root part {0}, {1} to group with root part {2}, {3}", 1541// "[SCENE OBJECT GROUP]: Linking group with root part {0}, {1} to group with root part {2}, {3}",
1111// objectGroup.RootPart.Name, objectGroup.RootPart.UUID, RootPart.Name, RootPart.UUID); 1542// objectGroup.RootPart.Name, objectGroup.RootPart.UUID, RootPart.Name, RootPart.UUID);
1112 1543
1113 SceneObjectPart linkPart = objectGroup.m_rootPart; 1544 SceneObjectPart linkPart = objectGroup.m_rootPart;
1114 1545
1115 Vector3 oldGroupPosition = 1546 Vector3 oldGroupPosition =
1116 new Vector3(linkPart.GroupPosition.X, linkPart.GroupPosition.Y, linkPart.GroupPosition.Z); 1547 new Vector3(linkPart.GroupPosition.X, linkPart.GroupPosition.Y, linkPart.GroupPosition.Z);
1117 Quaternion oldRootRotation = 1548 Quaternion oldRootRotation =
@@ -1121,35 +1552,35 @@ namespace OpenSim.Region.Environment.Scenes
1121 linkPart.OffsetPosition = linkPart.GroupPosition - AbsolutePosition; 1552 linkPart.OffsetPosition = linkPart.GroupPosition - AbsolutePosition;
1122 linkPart.GroupPosition = AbsolutePosition; 1553 linkPart.GroupPosition = AbsolutePosition;
1123 Vector3 axPos = new Vector3(linkPart.OffsetPosition.X, linkPart.OffsetPosition.Y, linkPart.OffsetPosition.Z); 1554 Vector3 axPos = new Vector3(linkPart.OffsetPosition.X, linkPart.OffsetPosition.Y, linkPart.OffsetPosition.Z);
1124 1555
1125 Quaternion parentRot = 1556 Quaternion parentRot =
1126 new Quaternion(m_rootPart.RotationOffset.W, m_rootPart.RotationOffset.X, m_rootPart.RotationOffset.Y, 1557 new Quaternion(m_rootPart.RotationOffset.W, m_rootPart.RotationOffset.X, m_rootPart.RotationOffset.Y,
1127 m_rootPart.RotationOffset.Z); 1558 m_rootPart.RotationOffset.Z);
1128 axPos = parentRot.Inverse()*axPos; 1559 axPos = parentRot.Inverse() * axPos;
1129 1560
1130 linkPart.OffsetPosition = new LLVector3(axPos.x, axPos.y, axPos.z); 1561 linkPart.OffsetPosition = new LLVector3(axPos.x, axPos.y, axPos.z);
1131 Quaternion oldRot = 1562 Quaternion oldRot =
1132 new Quaternion(linkPart.RotationOffset.W, linkPart.RotationOffset.X, linkPart.RotationOffset.Y, 1563 new Quaternion(linkPart.RotationOffset.W, linkPart.RotationOffset.X, linkPart.RotationOffset.Y,
1133 linkPart.RotationOffset.Z); 1564 linkPart.RotationOffset.Z);
1134 Quaternion newRot = parentRot.Inverse()*oldRot; 1565 Quaternion newRot = parentRot.Inverse() * oldRot;
1135 linkPart.RotationOffset = new LLQuaternion(newRot.x, newRot.y, newRot.z, newRot.w); 1566 linkPart.RotationOffset = new LLQuaternion(newRot.x, newRot.y, newRot.z, newRot.w);
1136 1567
1137 linkPart.ParentID = m_rootPart.LocalId; 1568 linkPart.ParentID = m_rootPart.LocalId;
1138 1569
1139 linkPart.LinkNum = m_parts.Count; 1570 linkPart.LinkNum = m_parts.Count;
1140 1571
1141 lock (m_parts) 1572 lock (m_parts)
1142 { 1573 {
1143 m_parts.Add(linkPart.UUID, linkPart); 1574 m_parts.Add(linkPart.UUID, linkPart);
1144 } 1575 }
1145 1576
1146 linkPart.SetParent(this); 1577 linkPart.SetParent(this);
1147 1578
1148 //if (linkPart.PhysActor != null) 1579 //if (linkPart.PhysActor != null)
1149 //{ 1580 //{
1150 // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor); 1581 // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor);
1151 1582
1152 //linkPart.PhysActor = null; 1583 //linkPart.PhysActor = null;
1153 //} 1584 //}
1154 1585
1155 //TODO: rest of parts 1586 //TODO: rest of parts
@@ -1180,30 +1611,30 @@ namespace OpenSim.Region.Environment.Scenes
1180 /// </summary> 1611 /// </summary>
1181 /// <param name="partID"></param> 1612 /// <param name="partID"></param>
1182 public void DelinkFromGroup(uint partID) 1613 public void DelinkFromGroup(uint partID)
1183 { 1614 {
1184 SceneObjectPart linkPart = GetChildPart(partID); 1615 SceneObjectPart linkPart = GetChildPart(partID);
1185 1616
1186 if (null != linkPart) 1617 if (null != linkPart)
1187 { 1618 {
1188// m_log.DebugFormat( 1619// m_log.DebugFormat(
1189// "[SCENE OBJECT GROUP]: Delinking part {0}, {1} from group with root part {2}, {3}", 1620// "[SCENE OBJECT GROUP]: Delinking part {0}, {1} from group with root part {2}, {3}",
1190// linkPart.Name, linkPart.UUID, RootPart.Name, RootPart.UUID); 1621// linkPart.Name, linkPart.UUID, RootPart.Name, RootPart.UUID);
1191 1622
1192 LLQuaternion worldRot = linkPart.GetWorldRotation(); 1623 LLQuaternion worldRot = linkPart.GetWorldRotation();
1193 1624
1194 // Remove the part from this object 1625 // Remove the part from this object
1195 lock (m_parts) 1626 lock (m_parts)
1196 { 1627 {
1197 m_parts.Remove(linkPart.UUID); 1628 m_parts.Remove(linkPart.UUID);
1198 } 1629 }
1199 1630
1200 linkPart.ParentID = 0; 1631 linkPart.ParentID = 0;
1201 1632
1202 if (linkPart.PhysActor != null) 1633 if (linkPart.PhysActor != null)
1203 { 1634 {
1204 m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor); 1635 m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor);
1205 } 1636 }
1206 1637
1207 // We need to reset the child part's position 1638 // We need to reset the child part's position
1208 // ready for life as a separate object after being a part of another object 1639 // ready for life as a separate object after being a part of another object
1209 Quaternion parentRot 1640 Quaternion parentRot
@@ -1219,7 +1650,7 @@ namespace OpenSim.Region.Environment.Scenes
1219 linkPart.OffsetPosition.Y, 1650 linkPart.OffsetPosition.Y,
1220 linkPart.OffsetPosition.Z); 1651 linkPart.OffsetPosition.Z);
1221 1652
1222 axPos = parentRot*axPos; 1653 axPos = parentRot * axPos;
1223 linkPart.OffsetPosition = new LLVector3(axPos.x, axPos.y, axPos.z); 1654 linkPart.OffsetPosition = new LLVector3(axPos.x, axPos.y, axPos.z);
1224 linkPart.GroupPosition = AbsolutePosition + linkPart.OffsetPosition; 1655 linkPart.GroupPosition = AbsolutePosition + linkPart.OffsetPosition;
1225 linkPart.OffsetPosition = new LLVector3(0, 0, 0); 1656 linkPart.OffsetPosition = new LLVector3(0, 0, 0);
@@ -1243,19 +1674,19 @@ namespace OpenSim.Region.Environment.Scenes
1243 // SceneObjectPart.UpdatePrimFlags() 1674 // SceneObjectPart.UpdatePrimFlags()
1244 //if (m_rootPart.PhysActor != null) 1675 //if (m_rootPart.PhysActor != null)
1245 //{ 1676 //{
1246 //linkPart.PhysActor = m_scene.PhysicsScene.AddPrimShape( 1677 //linkPart.PhysActor = m_scene.PhysicsScene.AddPrimShape(
1247 //linkPart.Name, 1678 //linkPart.Name,
1248 //linkPart.Shape, 1679 //linkPart.Shape,
1249 //new PhysicsVector(linkPart.AbsolutePosition.X, linkPart.AbsolutePosition.Y, 1680 //new PhysicsVector(linkPart.AbsolutePosition.X, linkPart.AbsolutePosition.Y,
1250 //linkPart.AbsolutePosition.Z), 1681 //linkPart.AbsolutePosition.Z),
1251 //new PhysicsVector(linkPart.Scale.X, linkPart.Scale.Y, linkPart.Scale.Z), 1682 //new PhysicsVector(linkPart.Scale.X, linkPart.Scale.Y, linkPart.Scale.Z),
1252 //new Quaternion(linkPart.RotationOffset.W, linkPart.RotationOffset.X, 1683 //new Quaternion(linkPart.RotationOffset.W, linkPart.RotationOffset.X,
1253 //linkPart.RotationOffset.Y, linkPart.RotationOffset.Z), 1684 //linkPart.RotationOffset.Y, linkPart.RotationOffset.Z),
1254 //m_rootPart.PhysActor.IsPhysical); 1685 //m_rootPart.PhysActor.IsPhysical);
1255 //m_rootPart.DoPhysicsPropertyUpdate(m_rootPart.PhysActor.IsPhysical, true); 1686 //m_rootPart.DoPhysicsPropertyUpdate(m_rootPart.PhysActor.IsPhysical, true);
1256 //} 1687 //}
1257 1688
1258 SceneObjectGroup objectGroup = new SceneObjectGroup(m_scene, m_regionHandle, linkPart); 1689 SceneObjectGroup objectGroup = new SceneObjectGroup(m_scene, m_regionHandle, linkPart);
1259 1690
1260 m_scene.AddEntity(objectGroup); 1691 m_scene.AddEntity(objectGroup);
1261 1692
@@ -1279,14 +1710,14 @@ namespace OpenSim.Region.Environment.Scenes
1279 part.SetParent(this); 1710 part.SetParent(this);
1280 part.ParentID = m_rootPart.LocalId; 1711 part.ParentID = m_rootPart.LocalId;
1281 part.LinkNum = m_parts.Count; 1712 part.LinkNum = m_parts.Count;
1282 1713
1283 lock (m_parts) 1714 lock (m_parts)
1284 { 1715 {
1285 m_parts.Add(part.UUID, part); 1716 m_parts.Add(part.UUID, part);
1286 } 1717 }
1287 1718
1288 Vector3 axiomOldPos = new Vector3(part.OffsetPosition.X, part.OffsetPosition.Y, part.OffsetPosition.Z); 1719 Vector3 axiomOldPos = new Vector3(part.OffsetPosition.X, part.OffsetPosition.Y, part.OffsetPosition.Z);
1289 axiomOldPos = oldGroupRotation*axiomOldPos; 1720 axiomOldPos = oldGroupRotation * axiomOldPos;
1290 axiomOldPos += oldGroupPosition; 1721 axiomOldPos += oldGroupPosition;
1291 LLVector3 oldAbsolutePosition = new LLVector3(axiomOldPos.x, axiomOldPos.y, axiomOldPos.z); 1722 LLVector3 oldAbsolutePosition = new LLVector3(axiomOldPos.x, axiomOldPos.y, axiomOldPos.z);
1292 part.OffsetPosition = oldAbsolutePosition - AbsolutePosition; 1723 part.OffsetPosition = oldAbsolutePosition - AbsolutePosition;
@@ -1296,15 +1727,15 @@ namespace OpenSim.Region.Environment.Scenes
1296 m_rootPart.RotationOffset.Z); 1727 m_rootPart.RotationOffset.Z);
1297 1728
1298 Vector3 axiomPos = new Vector3(part.OffsetPosition.X, part.OffsetPosition.Y, part.OffsetPosition.Z); 1729 Vector3 axiomPos = new Vector3(part.OffsetPosition.X, part.OffsetPosition.Y, part.OffsetPosition.Z);
1299 axiomPos = axiomRootRotation.Inverse()*axiomPos; 1730 axiomPos = axiomRootRotation.Inverse() * axiomPos;
1300 part.OffsetPosition = new LLVector3(axiomPos.x, axiomPos.y, axiomPos.z); 1731 part.OffsetPosition = new LLVector3(axiomPos.x, axiomPos.y, axiomPos.z);
1301 1732
1302 Quaternion axiomPartRotation = 1733 Quaternion axiomPartRotation =
1303 new Quaternion(part.RotationOffset.W, part.RotationOffset.X, part.RotationOffset.Y, 1734 new Quaternion(part.RotationOffset.W, part.RotationOffset.X, part.RotationOffset.Y,
1304 part.RotationOffset.Z); 1735 part.RotationOffset.Z);
1305 1736
1306 axiomPartRotation = oldGroupRotation*axiomPartRotation; 1737 axiomPartRotation = oldGroupRotation * axiomPartRotation;
1307 axiomPartRotation = axiomRootRotation.Inverse()*axiomPartRotation; 1738 axiomPartRotation = axiomRootRotation.Inverse() * axiomPartRotation;
1308 part.RotationOffset = 1739 part.RotationOffset =
1309 new LLQuaternion(axiomPartRotation.x, axiomPartRotation.y, axiomPartRotation.z, axiomPartRotation.w); 1740 new LLQuaternion(axiomPartRotation.x, axiomPartRotation.y, axiomPartRotation.z, axiomPartRotation.w);
1310 } 1741 }
@@ -1318,10 +1749,8 @@ namespace OpenSim.Region.Environment.Scenes
1318 /// <param name="remoteClient"></param> 1749 /// <param name="remoteClient"></param>
1319 public void GrabMovement(LLVector3 offset, LLVector3 pos, IClientAPI remoteClient) 1750 public void GrabMovement(LLVector3 offset, LLVector3 pos, IClientAPI remoteClient)
1320 { 1751 {
1321
1322 if (m_scene.EventManager.TriggerGroupMove(UUID, pos)) 1752 if (m_scene.EventManager.TriggerGroupMove(UUID, pos))
1323 { 1753 {
1324
1325 if (m_rootPart.PhysActor != null) 1754 if (m_rootPart.PhysActor != null)
1326 { 1755 {
1327 if (m_rootPart.PhysActor.IsPhysical) 1756 if (m_rootPart.PhysActor.IsPhysical)
@@ -1343,12 +1772,13 @@ namespace OpenSim.Region.Environment.Scenes
1343 } 1772 }
1344 } 1773 }
1345 } 1774 }
1775
1346 public void NonPhysicalGrabMovement(LLVector3 pos) 1776 public void NonPhysicalGrabMovement(LLVector3 pos)
1347 { 1777 {
1348 AbsolutePosition = pos; 1778 AbsolutePosition = pos;
1349 m_rootPart.SendTerseUpdateToAllClients(); 1779 m_rootPart.SendTerseUpdateToAllClients();
1350
1351 } 1780 }
1781
1352 /// <summary> 1782 /// <summary>
1353 /// 1783 ///
1354 /// </summary> 1784 /// </summary>
@@ -1412,8 +1842,8 @@ namespace OpenSim.Region.Environment.Scenes
1412 SceneObjectPart part = GetChildPart(localID); 1842 SceneObjectPart part = GetChildPart(localID);
1413 if (part != null) 1843 if (part != null)
1414 { 1844 {
1415 part.SetText( text ); 1845 part.SetText(text);
1416 } 1846 }
1417 } 1847 }
1418 1848
1419 public void SetPartText(string text, LLUUID partID) 1849 public void SetPartText(string text, LLUUID partID)
@@ -1421,7 +1851,7 @@ namespace OpenSim.Region.Environment.Scenes
1421 SceneObjectPart part = GetChildPart(partID); 1851 SceneObjectPart part = GetChildPart(partID);
1422 if (part != null) 1852 if (part != null)
1423 { 1853 {
1424 part.SetText( text ); 1854 part.SetText(text);
1425 } 1855 }
1426 } 1856 }
1427 1857
@@ -1460,7 +1890,7 @@ namespace OpenSim.Region.Environment.Scenes
1460 { 1890 {
1461 // If we have children 1891 // If we have children
1462 lock (m_parts) 1892 lock (m_parts)
1463 { 1893 {
1464 if (m_parts.Count > 1) 1894 if (m_parts.Count > 1)
1465 { 1895 {
1466 foreach (SceneObjectPart parts in m_parts.Values) 1896 foreach (SceneObjectPart parts in m_parts.Values)
@@ -1484,6 +1914,7 @@ namespace OpenSim.Region.Environment.Scenes
1484 part.UpdateExtraParam(type, inUse, data); 1914 part.UpdateExtraParam(type, inUse, data);
1485 } 1915 }
1486 } 1916 }
1917
1487 public SceneObjectPart[] GetParts() 1918 public SceneObjectPart[] GetParts()
1488 { 1919 {
1489 int numParts = Children.Count; 1920 int numParts = Children.Count;
@@ -1491,7 +1922,7 @@ namespace OpenSim.Region.Environment.Scenes
1491 Children.Values.CopyTo(partArray, 0); 1922 Children.Values.CopyTo(partArray, 0);
1492 return partArray; 1923 return partArray;
1493 } 1924 }
1494 1925
1495 /// <summary> 1926 /// <summary>
1496 /// 1927 ///
1497 /// </summary> 1928 /// </summary>
@@ -1531,7 +1962,6 @@ namespace OpenSim.Region.Environment.Scenes
1531 if (part.PhysActor != null) 1962 if (part.PhysActor != null)
1532 m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); 1963 m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor);
1533 } 1964 }
1534
1535 } 1965 }
1536 1966
1537 #endregion 1967 #endregion
@@ -1552,23 +1982,24 @@ namespace OpenSim.Region.Environment.Scenes
1552 if (part.PhysActor != null) 1982 if (part.PhysActor != null)
1553 { 1983 {
1554 part.PhysActor.Size = 1984 part.PhysActor.Size =
1555 new PhysicsVector(scale.X, scale.Y, scale.Z); 1985 new PhysicsVector(scale.X, scale.Y, scale.Z);
1556 m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); 1986 m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor);
1557 } 1987 }
1558 //if (part.UUID != m_rootPart.UUID) 1988 //if (part.UUID != m_rootPart.UUID)
1559 ScheduleGroupForFullUpdate(); 1989 ScheduleGroupForFullUpdate();
1560 1990
1561 //if (part.UUID == m_rootPart.UUID) 1991 //if (part.UUID == m_rootPart.UUID)
1562 //{ 1992 //{
1563 //if (m_rootPart.PhysActor != null) 1993 //if (m_rootPart.PhysActor != null)
1564 //{ 1994 //{
1565 //m_rootPart.PhysActor.Size = 1995 //m_rootPart.PhysActor.Size =
1566 //new PhysicsVector(m_rootPart.Scale.X, m_rootPart.Scale.Y, m_rootPart.Scale.Z); 1996 //new PhysicsVector(m_rootPart.Scale.X, m_rootPart.Scale.Y, m_rootPart.Scale.Z);
1567 //m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); 1997 //m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor);
1568 //} 1998 //}
1569 //} 1999 //}
1570 } 2000 }
1571 } 2001 }
2002
1572 public void GroupResize(LLVector3 scale, uint localID) 2003 public void GroupResize(LLVector3 scale, uint localID)
1573 { 2004 {
1574 SceneObjectPart part = GetChildPart(localID); 2005 SceneObjectPart part = GetChildPart(localID);
@@ -1578,14 +2009,13 @@ namespace OpenSim.Region.Environment.Scenes
1578 float y = (scale.Y / part.Scale.Y); 2009 float y = (scale.Y / part.Scale.Y);
1579 float z = (scale.Z / part.Scale.Z); 2010 float z = (scale.Z / part.Scale.Z);
1580 part.Resize(scale); 2011 part.Resize(scale);
1581 2012
1582 lock (m_parts) 2013 lock (m_parts)
1583 { 2014 {
1584 foreach (SceneObjectPart obPart in m_parts.Values) 2015 foreach (SceneObjectPart obPart in m_parts.Values)
1585 { 2016 {
1586 if (obPart.UUID != m_rootPart.UUID) 2017 if (obPart.UUID != m_rootPart.UUID)
1587 { 2018 {
1588
1589 LLVector3 currentpos = new LLVector3(obPart.OffsetPosition); 2019 LLVector3 currentpos = new LLVector3(obPart.OffsetPosition);
1590 currentpos.X *= x; 2020 currentpos.X *= x;
1591 currentpos.Y *= y; 2021 currentpos.Y *= y;
@@ -1599,16 +2029,16 @@ namespace OpenSim.Region.Environment.Scenes
1599 } 2029 }
1600 } 2030 }
1601 } 2031 }
1602 2032
1603 if (part.PhysActor != null) 2033 if (part.PhysActor != null)
1604 { 2034 {
1605 part.PhysActor.Size = 2035 part.PhysActor.Size =
1606 new PhysicsVector(scale.X, scale.Y, scale.Z); 2036 new PhysicsVector(scale.X, scale.Y, scale.Z);
1607 m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); 2037 m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor);
1608 } 2038 }
1609
1610 2039
1611 ScheduleGroupForTerseUpdate(); 2040
2041 ScheduleGroupForTerseUpdate();
1612 } 2042 }
1613 } 2043 }
1614 2044
@@ -1668,7 +2098,7 @@ namespace OpenSim.Region.Environment.Scenes
1668 Quaternion partRotation = 2098 Quaternion partRotation =
1669 new Quaternion(m_rootPart.RotationOffset.W, m_rootPart.RotationOffset.X, m_rootPart.RotationOffset.Y, 2099 new Quaternion(m_rootPart.RotationOffset.W, m_rootPart.RotationOffset.X, m_rootPart.RotationOffset.Y,
1670 m_rootPart.RotationOffset.Z); 2100 m_rootPart.RotationOffset.Z);
1671 axDiff = partRotation.Inverse()*axDiff; 2101 axDiff = partRotation.Inverse() * axDiff;
1672 diff.X = axDiff.x; 2102 diff.X = axDiff.x;
1673 diff.Y = axDiff.y; 2103 diff.Y = axDiff.y;
1674 diff.Z = axDiff.z; 2104 diff.Z = axDiff.z;
@@ -1683,7 +2113,7 @@ namespace OpenSim.Region.Environment.Scenes
1683 } 2113 }
1684 } 2114 }
1685 } 2115 }
1686 2116
1687 AbsolutePosition = newPos; 2117 AbsolutePosition = newPos;
1688 ScheduleGroupForTerseUpdate(); 2118 ScheduleGroupForTerseUpdate();
1689 } 2119 }
@@ -1781,453 +2211,23 @@ namespace OpenSim.Region.Environment.Scenes
1781 if (prim.UUID != m_rootPart.UUID) 2211 if (prim.UUID != m_rootPart.UUID)
1782 { 2212 {
1783 Vector3 axPos = new Vector3(prim.OffsetPosition.X, prim.OffsetPosition.Y, prim.OffsetPosition.Z); 2213 Vector3 axPos = new Vector3(prim.OffsetPosition.X, prim.OffsetPosition.Y, prim.OffsetPosition.Z);
1784 axPos = oldParentRot*axPos; 2214 axPos = oldParentRot * axPos;
1785 axPos = axRot.Inverse()*axPos; 2215 axPos = axRot.Inverse() * axPos;
1786 prim.OffsetPosition = new LLVector3(axPos.x, axPos.y, axPos.z); 2216 prim.OffsetPosition = new LLVector3(axPos.x, axPos.y, axPos.z);
1787 Quaternion primsRot = 2217 Quaternion primsRot =
1788 new Quaternion(prim.RotationOffset.W, prim.RotationOffset.X, prim.RotationOffset.Y, 2218 new Quaternion(prim.RotationOffset.W, prim.RotationOffset.X, prim.RotationOffset.Y,
1789 prim.RotationOffset.Z); 2219 prim.RotationOffset.Z);
1790 Quaternion newRot = oldParentRot*primsRot; 2220 Quaternion newRot = oldParentRot * primsRot;
1791 newRot = axRot.Inverse()*newRot; 2221 newRot = axRot.Inverse() * newRot;
1792 prim.RotationOffset = new LLQuaternion(newRot.x, newRot.y, newRot.z, newRot.w); 2222 prim.RotationOffset = new LLQuaternion(newRot.x, newRot.y, newRot.z, newRot.w);
1793 prim.ScheduleTerseUpdate(); 2223 prim.ScheduleTerseUpdate();
1794 } 2224 }
1795 } 2225 }
1796 } 2226 }
1797
1798 m_rootPart.ScheduleTerseUpdate();
1799 }
1800
1801 #endregion
1802
1803 /// <summary>
1804 ///
1805 /// </summary>
1806 /// <param name="part"></param>
1807 private void SetPartAsRoot(SceneObjectPart part)
1808 {
1809 m_rootPart = part;
1810 }
1811
1812 /// <summary>
1813 ///
1814 /// </summary>
1815 /// <param name="part"></param>
1816 private void SetPartAsNonRoot(SceneObjectPart part)
1817 {
1818 part.ParentID = m_rootPart.LocalId;
1819 }
1820
1821 /// <summary>
1822 ///
1823 /// </summary>
1824 /// <returns></returns>
1825 public List<ScenePresence> GetScenePresences()
1826 {
1827 return m_scene.GetScenePresences();
1828 }
1829 2227
1830 #region Events 2228 m_rootPart.ScheduleTerseUpdate();
1831
1832 /// <summary>
1833 ///
1834 /// </summary>
1835 public void TriggerTainted()
1836 {
1837 handlerPrimCountTainted = OnPrimCountTainted;
1838 if (handlerPrimCountTainted != null)
1839 {
1840 handlerPrimCountTainted();
1841 }
1842 }
1843
1844 /// <summary>
1845 /// Processes backup
1846 /// </summary>
1847 /// <param name="datastore"></param>
1848 public void ProcessBackup(IRegionDataStore datastore)
1849 {
1850 if (HasGroupChanged)
1851 {
1852 datastore.StoreObject(this, m_scene.RegionInfo.RegionID);
1853 HasGroupChanged = false;
1854 }
1855
1856 ForEachPart(delegate(SceneObjectPart part) { part.ProcessInventoryBackup(datastore); });
1857 }
1858
1859 #endregion
1860
1861 #region Client Updating
1862
1863 public void SendFullUpdateToClient(IClientAPI remoteClient, uint clientFlags)
1864 {
1865 lock (m_parts)
1866 {
1867 foreach (SceneObjectPart part in m_parts.Values)
1868 {
1869 SendPartFullUpdate(remoteClient, part, clientFlags);
1870 }
1871 }
1872 }
1873
1874 /// <summary>
1875 /// Send a full update to the client for the given part
1876 /// </summary>
1877 /// <param name="remoteClient"></param>
1878 /// <param name="part"></param>
1879 internal void SendPartFullUpdate(IClientAPI remoteClient, SceneObjectPart part, uint clientFlags)
1880 {
1881 if (m_rootPart.UUID == part.UUID)
1882 {
1883 part.SendFullUpdateToClient(remoteClient, AbsolutePosition, clientFlags);
1884 }
1885 else
1886 {
1887 part.SendFullUpdateToClient(remoteClient, clientFlags);
1888 }
1889 }
1890
1891 /// <summary>
1892 /// Send a terse update to the client for the given part
1893 /// </summary>
1894 /// <param name="remoteClient"></param>
1895 /// <param name="part"></param>
1896 internal void SendPartTerseUpdate(IClientAPI remoteClient, SceneObjectPart part)
1897 {
1898 if (m_rootPart.UUID == part.UUID)
1899 {
1900 part.SendTerseUpdateToClient(remoteClient, AbsolutePosition);
1901 }
1902 else
1903 {
1904 part.SendTerseUpdateToClient(remoteClient);
1905 }
1906 } 2229 }
1907 2230
1908 #endregion 2231 #endregion
1909
1910 public override void UpdateMovement()
1911 {
1912 lock (m_parts)
1913 {
1914 foreach (SceneObjectPart part in m_parts.Values)
1915 {
1916 part.UpdateMovement();
1917 }
1918 }
1919 }
1920
1921 public float GetTimeDilation()
1922 {
1923 return m_scene.TimeDilation;
1924 }
1925
1926 /// <summary>
1927 /// Added as a way for the storage provider to reset the scene,
1928 /// most likely a better way to do this sort of thing but for now...
1929 /// </summary>
1930 /// <param name="scene"></param>
1931 public void SetScene(Scene scene)
1932 {
1933 m_scene = scene;
1934 AttachToBackup();
1935 }
1936
1937 /// <summary>
1938 ///
1939 /// </summary>
1940 /// <param name="part"></param>
1941 public void AddPart(SceneObjectPart part)
1942 {
1943 lock (m_parts)
1944 {
1945 part.SetParent(this);
1946 part.LinkNum = m_parts.Count;
1947
1948 try
1949 {
1950 m_parts.Add(part.UUID, part);
1951 }
1952 catch (Exception e)
1953 {
1954 m_log.Error("Failed to add scened object part", e);
1955 }
1956 }
1957 }
1958
1959 /// <summary>
1960 ///
1961 /// </summary>
1962 public void UpdateParentIDs()
1963 {
1964 lock (m_parts)
1965 {
1966 foreach (SceneObjectPart part in m_parts.Values)
1967 {
1968 if (part.UUID != m_rootPart.UUID)
1969 {
1970 part.ParentID = m_rootPart.LocalId;
1971 }
1972 }
1973 }
1974 }
1975
1976 public void RegenerateFullIDs()
1977 {
1978 lock (m_parts)
1979 {
1980 foreach (SceneObjectPart part in m_parts.Values)
1981 {
1982 part.UUID = LLUUID.Random();
1983 }
1984 }
1985 }
1986
1987 public void ResetChildPrimPhysicsPositions()
1988 {
1989 AbsolutePosition = AbsolutePosition;
1990 HasGroupChanged = false;
1991 }
1992
1993 public LLUUID GetPartsFullID(uint localID)
1994 {
1995 SceneObjectPart part = GetChildPart(localID);
1996 if (part != null)
1997 {
1998 return part.UUID;
1999 }
2000 return null;
2001 }
2002
2003 public void ObjectGrabHandler(uint localId, LLVector3 offsetPos, IClientAPI remoteClient)
2004 {
2005 if (m_rootPart.LocalId == localId)
2006 {
2007 OnGrabGroup(offsetPos, remoteClient);
2008 }
2009 else
2010 {
2011 SceneObjectPart part = GetChildPart(localId);
2012 OnGrabPart(part, offsetPos, remoteClient);
2013 }
2014 }
2015
2016 public virtual void OnGrabPart(SceneObjectPart part, LLVector3 offsetPos, IClientAPI remoteClient)
2017 {
2018 part.OnGrab(offsetPos, remoteClient);
2019 }
2020
2021 public virtual void OnGrabGroup(LLVector3 offsetPos, IClientAPI remoteClient)
2022 {
2023 m_scene.EventManager.TriggerGroupGrab(UUID, offsetPos, remoteClient.AgentId);
2024 }
2025
2026 /// <summary>
2027 /// Completely delete this group and tell all the scene presences about that deletion.
2028 /// </summary>
2029 public void DeleteGroup()
2030 {
2031 DetachFromBackup(this);
2032
2033 lock (m_parts)
2034 {
2035 foreach (SceneObjectPart part in m_parts.Values)
2036 {
2037 List<ScenePresence> avatars = GetScenePresences();
2038 for (int i = 0; i < avatars.Count; i++)
2039 {
2040 if (avatars[i].ParentID == LocalId)
2041 {
2042 avatars[i].StandUp();
2043 }
2044
2045 avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId);
2046 }
2047 }
2048 }
2049 }
2050
2051 /// <summary>
2052 /// Delete all the parts in this group.
2053 /// </summary>
2054 public void DeleteParts()
2055 {
2056 lock (m_parts)
2057 {
2058 foreach (SceneObjectPart part in m_parts.Values)
2059 {
2060 part.StopScripts();
2061 }
2062
2063 m_rootPart = null;
2064 m_parts.Clear();
2065 }
2066 }
2067
2068 public void AddScriptLPS(int count)
2069 {
2070 InnerScene d = m_scene.m_innerScene;
2071 d.AddToScriptLPS(count);
2072 }
2073
2074 public void AddActiveScriptCount(int count)
2075 {
2076 InnerScene d = m_scene.m_innerScene;
2077 d.AddActiveScripts(count);
2078 }
2079
2080 public void RemoveScriptEvents(LLUUID scriptid)
2081 {
2082 lock (m_scriptEvents)
2083 {
2084 if (m_scriptEvents.ContainsKey(scriptid))
2085 {
2086 scriptEvents oldparts = scriptEvents.None;
2087 oldparts = (scriptEvents)m_scriptEvents[scriptid];
2088
2089 // remove values from aggregated script events
2090 m_aggregateScriptEvents &= ~oldparts;
2091 m_scriptEvents.Remove(scriptid);
2092 }
2093
2094 }
2095 aggregateScriptEvents();
2096 }
2097
2098 public void SetScriptEvents(LLUUID scriptid, int events)
2099 {
2100
2101 scriptEvents oldparts = scriptEvents.None;
2102 lock (m_scriptEvents)
2103 {
2104 if (m_scriptEvents.ContainsKey(scriptid))
2105 {
2106 oldparts = (scriptEvents)m_scriptEvents[scriptid];
2107
2108 // remove values from aggregated script events
2109 m_aggregateScriptEvents &= ~oldparts;
2110 m_scriptEvents[scriptid] = (scriptEvents)events;
2111 }
2112 else
2113 {
2114 m_scriptEvents.Add(scriptid, (scriptEvents)events);
2115 }
2116
2117 }
2118
2119 aggregateScriptEvents();
2120 }
2121 public void aggregateScriptEvents()
2122 {
2123 // Aggregate script events
2124 lock (m_scriptEvents)
2125 {
2126 foreach (scriptEvents s in m_scriptEvents.Values)
2127 {
2128 m_aggregateScriptEvents |= s;
2129 }
2130 }
2131 uint objectflagupdate = m_rootPart.ObjectFlags;
2132
2133 if (
2134 ((m_aggregateScriptEvents & scriptEvents.touch) != 0) ||
2135 ((m_aggregateScriptEvents & scriptEvents.touch_end) != 0) ||
2136 ((m_aggregateScriptEvents & scriptEvents.touch_start) != 0)
2137 )
2138 {
2139 objectflagupdate |= (uint)LLObject.ObjectFlags.Touch;
2140 }
2141 else
2142 {
2143 objectflagupdate &= ~(uint)LLObject.ObjectFlags.Touch;
2144 }
2145
2146 if ((m_aggregateScriptEvents & scriptEvents.money) != 0)
2147 {
2148 objectflagupdate |= (uint)LLObject.ObjectFlags.Money;
2149 }
2150 else
2151 {
2152 objectflagupdate &= ~(uint)LLObject.ObjectFlags.Money;
2153 }
2154
2155 if (
2156 ((m_aggregateScriptEvents & scriptEvents.collision) != 0) ||
2157 ((m_aggregateScriptEvents & scriptEvents.collision_end) != 0) ||
2158 ((m_aggregateScriptEvents & scriptEvents.collision_start) != 0)
2159 )
2160 {
2161 // subscribe to physics updates.
2162 }
2163 else
2164 {
2165 // unsubscribe to physics updates.
2166 }
2167 lock (m_parts)
2168 {
2169 foreach (SceneObjectPart part in m_parts.Values)
2170 {
2171 part.ObjectFlags = objectflagupdate;
2172 }
2173 }
2174 ScheduleGroupForFullUpdate();
2175
2176 }
2177
2178 public override void SetText(string text, Vector3 color, double alpha)
2179 {
2180 Color = Color.FromArgb(0xff - (int) (alpha*0xff),
2181 (int) (color.x*0xff),
2182 (int) (color.y*0xff),
2183 (int) (color.z*0xff));
2184 Text = text;
2185
2186 m_rootPart.ScheduleFullUpdate();
2187 }
2188
2189 public void ApplyPhysics(bool m_physicalPrim)
2190 {
2191 lock (m_parts)
2192 {
2193 if (m_parts.Count > 1)
2194 {
2195 m_rootPart.ApplyPhysics(m_rootPart.ObjectFlags, m_physicalPrim);
2196 foreach (SceneObjectPart part in m_parts.Values)
2197 {
2198 if (part.LocalId != m_rootPart.LocalId)
2199 {
2200 part.ApplyPhysics(m_rootPart.ObjectFlags, m_physicalPrim);
2201 }
2202 // Hack to get the physics scene geometries in the right spot
2203 ResetChildPrimPhysicsPositions();
2204
2205 }
2206 }
2207 else
2208 {
2209 m_rootPart.ApplyPhysics(m_rootPart.ObjectFlags, m_physicalPrim);
2210 }
2211 }
2212 }
2213
2214 public void SetOwnerId(LLUUID userId)
2215 {
2216 ForEachPart(delegate(SceneObjectPart part)
2217 { part.OwnerID = userId; });
2218 }
2219
2220 public void ForEachPart(Action<SceneObjectPart> whatToDo)
2221 {
2222 lock (m_parts)
2223 {
2224 foreach (SceneObjectPart part in m_parts.Values)
2225 {
2226 whatToDo(part);
2227 }
2228 }
2229 }
2230
2231
2232 } 2232 }
2233} 2233} \ No newline at end of file