aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Data/Tests/RegionTests.cs6
-rw-r--r--OpenSim/Framework/PrimitiveBaseShape.cs61
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs2
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs10
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs61
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs21
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/World/Sound/SoundModule.cs4
-rw-r--r--OpenSim/Region/Framework/Scenes/Prioritizer.cs8
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs8
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs4
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs14
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs70
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs46
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs33
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneViewer.cs3
-rw-r--r--OpenSim/Region/Physics/Manager/IMesher.cs11
-rw-r--r--OpenSim/Region/Physics/Meshing/Meshmerizer.cs99
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs20
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs8
22 files changed, 266 insertions, 229 deletions
diff --git a/OpenSim/Data/Tests/RegionTests.cs b/OpenSim/Data/Tests/RegionTests.cs
index 2b8fa59..cac8cac 100644
--- a/OpenSim/Data/Tests/RegionTests.cs
+++ b/OpenSim/Data/Tests/RegionTests.cs
@@ -304,9 +304,9 @@ namespace OpenSim.Data.Tests
304 regionInfo.RegionLocX = 0; 304 regionInfo.RegionLocX = 0;
305 regionInfo.RegionLocY = 0; 305 regionInfo.RegionLocY = 0;
306 306
307// Scene scene = new Scene(regionInfo);
308
309 SceneObjectPart sop = new SceneObjectPart(); 307 SceneObjectPart sop = new SceneObjectPart();
308 SceneObjectGroup sog = new SceneObjectGroup(sop);
309
310 sop.RegionHandle = regionh; 310 sop.RegionHandle = regionh;
311 sop.UUID = uuid; 311 sop.UUID = uuid;
312 sop.LocalId = localid; 312 sop.LocalId = localid;
@@ -373,8 +373,6 @@ namespace OpenSim.Data.Tests
373 373
374 // This is necessary or object will not be inserted in DB 374 // This is necessary or object will not be inserted in DB
375 sop.Flags = PrimFlags.None; 375 sop.Flags = PrimFlags.None;
376
377 SceneObjectGroup sog = new SceneObjectGroup(sop);
378 376
379 // Inserts group in DB 377 // Inserts group in DB
380 db.StoreObject(sog,region3); 378 db.StoreObject(sog,region3);
diff --git a/OpenSim/Framework/PrimitiveBaseShape.cs b/OpenSim/Framework/PrimitiveBaseShape.cs
index d873071..1b6a1d2 100644
--- a/OpenSim/Framework/PrimitiveBaseShape.cs
+++ b/OpenSim/Framework/PrimitiveBaseShape.cs
@@ -859,6 +859,67 @@ namespace OpenSim.Framework
859 } 859 }
860 } 860 }
861 861
862 public ulong GetMeshKey(Vector3 size, float lod)
863 {
864 ulong hash = 5381;
865
866 hash = djb2(hash, this.PathCurve);
867 hash = djb2(hash, (byte)((byte)this.HollowShape | (byte)this.ProfileShape));
868 hash = djb2(hash, this.PathBegin);
869 hash = djb2(hash, this.PathEnd);
870 hash = djb2(hash, this.PathScaleX);
871 hash = djb2(hash, this.PathScaleY);
872 hash = djb2(hash, this.PathShearX);
873 hash = djb2(hash, this.PathShearY);
874 hash = djb2(hash, (byte)this.PathTwist);
875 hash = djb2(hash, (byte)this.PathTwistBegin);
876 hash = djb2(hash, (byte)this.PathRadiusOffset);
877 hash = djb2(hash, (byte)this.PathTaperX);
878 hash = djb2(hash, (byte)this.PathTaperY);
879 hash = djb2(hash, this.PathRevolutions);
880 hash = djb2(hash, (byte)this.PathSkew);
881 hash = djb2(hash, this.ProfileBegin);
882 hash = djb2(hash, this.ProfileEnd);
883 hash = djb2(hash, this.ProfileHollow);
884
885 // TODO: Separate scale out from the primitive shape data (after
886 // scaling is supported at the physics engine level)
887 byte[] scaleBytes = size.GetBytes();
888 for (int i = 0; i < scaleBytes.Length; i++)
889 hash = djb2(hash, scaleBytes[i]);
890
891 // Include LOD in hash, accounting for endianness
892 byte[] lodBytes = new byte[4];
893 Buffer.BlockCopy(BitConverter.GetBytes(lod), 0, lodBytes, 0, 4);
894 if (!BitConverter.IsLittleEndian)
895 {
896 Array.Reverse(lodBytes, 0, 4);
897 }
898 for (int i = 0; i < lodBytes.Length; i++)
899 hash = djb2(hash, lodBytes[i]);
900
901 // include sculpt UUID
902 if (this.SculptEntry)
903 {
904 scaleBytes = this.SculptTexture.GetBytes();
905 for (int i = 0; i < scaleBytes.Length; i++)
906 hash = djb2(hash, scaleBytes[i]);
907 }
908
909 return hash;
910 }
911
912 private ulong djb2(ulong hash, byte c)
913 {
914 return ((hash << 5) + hash) + (ulong)c;
915 }
916
917 private ulong djb2(ulong hash, ushort c)
918 {
919 hash = ((hash << 5) + hash) + (ulong)((byte)c);
920 return ((hash << 5) + hash) + (ulong)(c >> 8);
921 }
922
862 public byte[] ExtraParamsToBytes() 923 public byte[] ExtraParamsToBytes()
863 { 924 {
864// m_log.DebugFormat("[EXTRAPARAMS]: Called ExtraParamsToBytes()"); 925// m_log.DebugFormat("[EXTRAPARAMS]: Called ExtraParamsToBytes()");
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs
index 8189518..c07fc73 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs
@@ -330,7 +330,7 @@ namespace OpenSim.Region.ClientStack.Linden
330 grp.AbsolutePosition = obj.Position; 330 grp.AbsolutePosition = obj.Position;
331 prim.RotationOffset = obj.Rotation; 331 prim.RotationOffset = obj.Rotation;
332 332
333 grp.RootPart.IsAttachment = false; 333 grp.IsAttachment = false;
334 // Required for linking 334 // Required for linking
335 grp.RootPart.UpdateFlag = 0; 335 grp.RootPart.UpdateFlag = 0;
336 336
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index f71871e..dc9a6ed 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -4756,7 +4756,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4756 { 4756 {
4757 SceneObjectPart part = (SceneObjectPart)entity; 4757 SceneObjectPart part = (SceneObjectPart)entity;
4758 4758
4759 attachPoint = part.AttachmentPoint; 4759 if (part.ParentGroup != null)
4760 attachPoint = part.ParentGroup.AttachmentPoint;
4761 else
4762 attachPoint = 0;
4763
4760 collisionPlane = Vector4.Zero; 4764 collisionPlane = Vector4.Zero;
4761 position = part.RelativePosition; 4765 position = part.RelativePosition;
4762 velocity = part.Velocity; 4766 velocity = part.Velocity;
@@ -4913,10 +4917,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4913 //update.JointType = 0; 4917 //update.JointType = 0;
4914 update.Material = data.Material; 4918 update.Material = data.Material;
4915 update.MediaURL = Utils.EmptyBytes; // FIXME: Support this in OpenSim 4919 update.MediaURL = Utils.EmptyBytes; // FIXME: Support this in OpenSim
4916 if (data.IsAttachment) 4920 if (data.ParentGroup != null && data.ParentGroup.IsAttachment)
4917 { 4921 {
4918 update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + data.FromItemID); 4922 update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + data.FromItemID);
4919 update.State = (byte)((data.AttachmentPoint % 16) * 16 + (data.AttachmentPoint / 16)); 4923 update.State = (byte)((data.ParentGroup.AttachmentPoint % 16) * 16 + (data.ParentGroup.AttachmentPoint / 16));
4920 } 4924 }
4921 else 4925 else
4922 { 4926 {
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
index 3e1cb02..2d5eb18 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
@@ -167,13 +167,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
167 return AttachObject(sp, group, AttachmentPt, silent); 167 return AttachObject(sp, group, AttachmentPt, silent);
168 } 168 }
169 169
170 private bool AttachObject(ScenePresence sp, SceneObjectGroup group, uint AttachmentPt, bool silent) 170 private bool AttachObject(ScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent)
171 { 171 {
172// m_log.DebugFormat( 172// m_log.DebugFormat(
173// "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})", 173// "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})",
174// group.Name, group.LocalId, sp.Name, AttachmentPt, silent); 174// group.Name, group.LocalId, sp.Name, AttachmentPt, silent);
175 175
176 if (sp.GetAttachments(AttachmentPt).Contains(group)) 176 if (sp.GetAttachments(attachmentPt).Contains(group))
177 { 177 {
178// m_log.WarnFormat( 178// m_log.WarnFormat(
179// "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached", 179// "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached",
@@ -186,39 +186,39 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
186 186
187 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should 187 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should
188 // be removed when that functionality is implemented in opensim 188 // be removed when that functionality is implemented in opensim
189 AttachmentPt &= 0x7f; 189 attachmentPt &= 0x7f;
190 190
191 // If the attachment point isn't the same as the one previously used 191 // If the attachment point isn't the same as the one previously used
192 // set it's offset position = 0 so that it appears on the attachment point 192 // set it's offset position = 0 so that it appears on the attachment point
193 // and not in a weird location somewhere unknown. 193 // and not in a weird location somewhere unknown.
194 if (AttachmentPt != 0 && AttachmentPt != (uint)group.GetAttachmentPoint()) 194 if (attachmentPt != 0 && attachmentPt != group.AttachmentPoint)
195 { 195 {
196 attachPos = Vector3.Zero; 196 attachPos = Vector3.Zero;
197 } 197 }
198 198
199 // AttachmentPt 0 means the client chose to 'wear' the attachment. 199 // AttachmentPt 0 means the client chose to 'wear' the attachment.
200 if (AttachmentPt == 0) 200 if (attachmentPt == 0)
201 { 201 {
202 // Check object for stored attachment point 202 // Check object for stored attachment point
203 AttachmentPt = (uint)group.GetAttachmentPoint(); 203 attachmentPt = group.AttachmentPoint;
204 } 204 }
205 205
206 // if we still didn't find a suitable attachment point....... 206 // if we still didn't find a suitable attachment point.......
207 if (AttachmentPt == 0) 207 if (attachmentPt == 0)
208 { 208 {
209 // Stick it on left hand with Zero Offset from the attachment point. 209 // Stick it on left hand with Zero Offset from the attachment point.
210 AttachmentPt = (uint)AttachmentPoint.LeftHand; 210 attachmentPt = (uint)AttachmentPoint.LeftHand;
211 attachPos = Vector3.Zero; 211 attachPos = Vector3.Zero;
212 } 212 }
213 213
214 group.SetAttachmentPoint((byte)AttachmentPt); 214 group.AttachmentPoint = attachmentPt;
215 group.AbsolutePosition = attachPos; 215 group.AbsolutePosition = attachPos;
216 216
217 // Remove any previous attachments 217 // Remove any previous attachments
218 UUID itemID = UUID.Zero; 218 UUID itemID = UUID.Zero;
219 foreach (SceneObjectGroup grp in sp.Attachments) 219 foreach (SceneObjectGroup grp in sp.Attachments)
220 { 220 {
221 if (grp.GetAttachmentPoint() == (byte)AttachmentPt) 221 if (grp.AttachmentPoint == attachmentPt)
222 { 222 {
223 itemID = grp.GetFromItemID(); 223 itemID = grp.GetFromItemID();
224 break; 224 break;
@@ -232,9 +232,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
232 if (itemID == UUID.Zero) 232 if (itemID == UUID.Zero)
233 itemID = AddSceneObjectAsAttachment(sp.ControllingClient, group).ID; 233 itemID = AddSceneObjectAsAttachment(sp.ControllingClient, group).ID;
234 234
235 ShowAttachInUserInventory(sp, AttachmentPt, itemID, group); 235 ShowAttachInUserInventory(sp, attachmentPt, itemID, group);
236 236
237 AttachToAgent(sp, group, AttachmentPt, attachPos, silent); 237 AttachToAgent(sp, group, attachmentPt, attachPos, silent);
238 238
239 return true; 239 return true;
240 } 240 }
@@ -293,7 +293,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
293 } 293 }
294 294
295 private SceneObjectGroup RezSingleAttachmentFromInventoryInternal( 295 private SceneObjectGroup RezSingleAttachmentFromInventoryInternal(
296 ScenePresence sp, UUID itemID, uint AttachmentPt) 296 ScenePresence sp, UUID itemID, uint attachmentPt)
297 { 297 {
298 IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>(); 298 IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>();
299 if (invAccess != null) 299 if (invAccess != null)
@@ -313,13 +313,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
313 // since scripts aren't running yet. So, clear it here. 313 // since scripts aren't running yet. So, clear it here.
314 objatt.HasGroupChanged = false; 314 objatt.HasGroupChanged = false;
315 bool tainted = false; 315 bool tainted = false;
316 if (AttachmentPt != 0 && AttachmentPt != objatt.GetAttachmentPoint()) 316 if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint)
317 tainted = true; 317 tainted = true;
318 318
319 // This will throw if the attachment fails 319 // This will throw if the attachment fails
320 try 320 try
321 { 321 {
322 AttachObject(sp, objatt, AttachmentPt, false); 322 AttachObject(sp, objatt, attachmentPt, false);
323 } 323 }
324 catch (Exception e) 324 catch (Exception e)
325 { 325 {
@@ -348,7 +348,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
348 { 348 {
349 m_log.WarnFormat( 349 m_log.WarnFormat(
350 "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}", 350 "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}",
351 itemID, sp.Name, AttachmentPt); 351 itemID, sp.Name, attachmentPt);
352 } 352 }
353 353
354 return objatt; 354 return objatt;
@@ -363,22 +363,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
363 /// <param name="att"></param> 363 /// <param name="att"></param>
364 /// <param name="sp"></param> 364 /// <param name="sp"></param>
365 /// <param name="itemID"></param> 365 /// <param name="itemID"></param>
366 /// <param name="AttachmentPt"></param> 366 /// <param name="attachmentPoint"></param>
367 /// <returns></returns> 367 /// <returns></returns>
368 private UUID ShowAttachInUserInventory( 368 private UUID ShowAttachInUserInventory(
369 SceneObjectGroup att, ScenePresence sp, UUID itemID, uint AttachmentPt) 369 SceneObjectGroup att, ScenePresence sp, UUID itemID, uint attachmentPoint)
370 { 370 {
371// m_log.DebugFormat( 371// m_log.DebugFormat(
372// "[ATTACHMENTS MODULE]: Updating inventory of {0} to show attachment of {1} (item ID {2})", 372// "[ATTACHMENTS MODULE]: Updating inventory of {0} to show attachment of {1} {2} (item ID {3}) at {4}",
373// remoteClient.Name, att.Name, itemID); 373// sp.Name, att.Name, att.LocalId, itemID, AttachmentPt);
374 374
375 if (!att.IsDeleted) 375 if (!att.IsDeleted)
376 AttachmentPt = att.RootPart.AttachmentPoint; 376 attachmentPoint = att.AttachmentPoint;
377 377
378 InventoryItemBase item = new InventoryItemBase(itemID, sp.UUID); 378 InventoryItemBase item = new InventoryItemBase(itemID, sp.UUID);
379 item = m_scene.InventoryService.GetItem(item); 379 item = m_scene.InventoryService.GetItem(item);
380 380
381 bool changed = sp.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID); 381 bool changed = sp.Appearance.SetAttachment((int)attachmentPoint, itemID, item.AssetID);
382 if (changed && m_scene.AvatarFactory != null) 382 if (changed && m_scene.AvatarFactory != null)
383 m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); 383 m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID);
384 384
@@ -547,7 +547,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
547 ); 547 );
548 548
549 group.RootPart.SetParentLocalId(0); 549 group.RootPart.SetParentLocalId(0);
550 group.RootPart.IsAttachment = false; 550 group.IsAttachment = false;
551 group.AbsolutePosition = group.RootPart.AttachedPos; 551 group.AbsolutePosition = group.RootPart.AttachedPos;
552 552
553 UpdateKnownItem(sp.ControllingClient, group, group.GetFromItemID(), group.OwnerID); 553 UpdateKnownItem(sp.ControllingClient, group, group.GetFromItemID(), group.OwnerID);
@@ -567,11 +567,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
567 // attachment. This is necessary in order to correctly save 567 // attachment. This is necessary in order to correctly save
568 // and retrieve GroupPosition information for the attachment. 568 // and retrieve GroupPosition information for the attachment.
569 // Finally, we restore the object's attachment status. 569 // Finally, we restore the object's attachment status.
570 byte attachmentPoint = sog.GetAttachmentPoint(); 570 uint attachmentPoint = sog.AttachmentPoint;
571 sog.UpdateGroupPosition(pos); 571 sog.UpdateGroupPosition(pos);
572 sog.RootPart.IsAttachment = false; 572 sog.IsAttachment = false;
573 sog.AbsolutePosition = sog.RootPart.AttachedPos; 573 sog.AbsolutePosition = sog.RootPart.AttachedPos;
574 sog.SetAttachmentPoint(attachmentPoint); 574 sog.AttachmentPoint = attachmentPoint;
575 sog.HasGroupChanged = true; 575 sog.HasGroupChanged = true;
576 } 576 }
577 577
@@ -594,14 +594,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
594 { 594 {
595 m_log.DebugFormat( 595 m_log.DebugFormat(
596 "[ATTACHMENTS MODULE]: Don't need to update asset for unchanged attachment {0}, attachpoint {1}", 596 "[ATTACHMENTS MODULE]: Don't need to update asset for unchanged attachment {0}, attachpoint {1}",
597 grp.UUID, grp.GetAttachmentPoint()); 597 grp.UUID, grp.AttachmentPoint);
598 598
599 return; 599 return;
600 } 600 }
601 601
602 m_log.DebugFormat( 602 m_log.DebugFormat(
603 "[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}", 603 "[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}",
604 grp.UUID, grp.GetAttachmentPoint()); 604 grp.UUID, grp.AttachmentPoint);
605 605
606 string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp); 606 string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp);
607 607
@@ -666,10 +666,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
666 666
667 so.AbsolutePosition = attachOffset; 667 so.AbsolutePosition = attachOffset;
668 so.RootPart.AttachedPos = attachOffset; 668 so.RootPart.AttachedPos = attachOffset;
669 so.RootPart.IsAttachment = true; 669 so.IsAttachment = true;
670
671 so.RootPart.SetParentLocalId(avatar.LocalId); 670 so.RootPart.SetParentLocalId(avatar.LocalId);
672 so.SetAttachmentPoint(Convert.ToByte(attachmentpoint)); 671 so.AttachmentPoint = attachmentpoint;
673 672
674 avatar.AddAttachment(so); 673 avatar.AddAttachment(so);
675 674
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
index b7d21fd..bb53601 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
@@ -110,7 +110,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
110 Assert.That(attachments.Count, Is.EqualTo(1)); 110 Assert.That(attachments.Count, Is.EqualTo(1));
111 SceneObjectGroup attSo = attachments[0]; 111 SceneObjectGroup attSo = attachments[0];
112 Assert.That(attSo.Name, Is.EqualTo(attName)); 112 Assert.That(attSo.Name, Is.EqualTo(attName));
113 Assert.That(attSo.GetAttachmentPoint(), Is.EqualTo((byte)AttachmentPoint.Chest)); 113 Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest));
114 Assert.That(attSo.IsAttachment); 114 Assert.That(attSo.IsAttachment);
115 Assert.That(attSo.UsesPhysics, Is.False); 115 Assert.That(attSo.UsesPhysics, Is.False);
116 Assert.That(attSo.IsTemporary, Is.False); 116 Assert.That(attSo.IsTemporary, Is.False);
@@ -132,9 +132,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
132 UUID attAssetId = TestHelpers.ParseTail(0x3); 132 UUID attAssetId = TestHelpers.ParseTail(0x3);
133 string attName = "att"; 133 string attName = "att";
134 134
135 InventoryItemBase attItem 135 UserInventoryHelpers.CreateInventoryItem(
136 = UserInventoryHelpers.CreateInventoryItem( 136 scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object);
137 scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object);
138 137
139 m_attMod.RezSingleAttachmentFromInventory( 138 m_attMod.RezSingleAttachmentFromInventory(
140 m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest); 139 m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest);
@@ -145,7 +144,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
145 Assert.That(attachments.Count, Is.EqualTo(1)); 144 Assert.That(attachments.Count, Is.EqualTo(1));
146 SceneObjectGroup attSo = attachments[0]; 145 SceneObjectGroup attSo = attachments[0];
147 Assert.That(attSo.Name, Is.EqualTo(attName)); 146 Assert.That(attSo.Name, Is.EqualTo(attName));
148 Assert.That(attSo.GetAttachmentPoint(), Is.EqualTo((byte)AttachmentPoint.Chest)); 147 Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest));
149 Assert.That(attSo.IsAttachment); 148 Assert.That(attSo.IsAttachment);
150 Assert.That(attSo.UsesPhysics, Is.False); 149 Assert.That(attSo.UsesPhysics, Is.False);
151 Assert.That(attSo.IsTemporary, Is.False); 150 Assert.That(attSo.IsTemporary, Is.False);
@@ -166,9 +165,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
166 UUID attAssetId = TestHelpers.ParseTail(0x3); 165 UUID attAssetId = TestHelpers.ParseTail(0x3);
167 string attName = "att"; 166 string attName = "att";
168 167
169 InventoryItemBase attItem 168 UserInventoryHelpers.CreateInventoryItem(
170 = UserInventoryHelpers.CreateInventoryItem( 169 scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object);
171 scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object);
172 170
173 UUID attSoId = m_attMod.RezSingleAttachmentFromInventory( 171 UUID attSoId = m_attMod.RezSingleAttachmentFromInventory(
174 m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest); 172 m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest);
@@ -198,9 +196,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
198 UUID attAssetId = TestHelpers.ParseTail(0x3); 196 UUID attAssetId = TestHelpers.ParseTail(0x3);
199 string attName = "att"; 197 string attName = "att";
200 198
201 InventoryItemBase attItem 199 UserInventoryHelpers.CreateInventoryItem(
202 = UserInventoryHelpers.CreateInventoryItem( 200 scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object);
203 scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object);
204 201
205 m_attMod.RezSingleAttachmentFromInventory( 202 m_attMod.RezSingleAttachmentFromInventory(
206 m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest); 203 m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest);
@@ -242,7 +239,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
242 Assert.That(attachments.Count, Is.EqualTo(1)); 239 Assert.That(attachments.Count, Is.EqualTo(1));
243 SceneObjectGroup attSo = attachments[0]; 240 SceneObjectGroup attSo = attachments[0];
244 Assert.That(attSo.Name, Is.EqualTo(attName)); 241 Assert.That(attSo.Name, Is.EqualTo(attName));
245 Assert.That(attSo.GetAttachmentPoint(), Is.EqualTo((byte)AttachmentPoint.Chest)); 242 Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest));
246 Assert.That(attSo.IsAttachment); 243 Assert.That(attSo.IsAttachment);
247 Assert.That(attSo.UsesPhysics, Is.False); 244 Assert.That(attSo.UsesPhysics, Is.False);
248 Assert.That(attSo.IsTemporary, Is.False); 245 Assert.That(attSo.IsTemporary, Is.False);
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index f5d49c5..7963e53 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -1782,7 +1782,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1782 // Set the parent localID to 0 so it transfers over properly. 1782 // Set the parent localID to 0 so it transfers over properly.
1783 gobj.RootPart.SetParentLocalId(0); 1783 gobj.RootPart.SetParentLocalId(0);
1784 gobj.AbsolutePosition = gobj.RootPart.AttachedPos; 1784 gobj.AbsolutePosition = gobj.RootPart.AttachedPos;
1785 gobj.RootPart.IsAttachment = false; 1785 gobj.IsAttachment = false;
1786 //gobj.RootPart.LastOwnerID = gobj.GetFromAssetID(); 1786 //gobj.RootPart.LastOwnerID = gobj.GetFromAssetID();
1787 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending attachment {0} to region {1}", gobj.UUID, destination.RegionName); 1787 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending attachment {0} to region {1}", gobj.UUID, destination.RegionName);
1788 CrossPrimGroupIntoNewRegion(destination, gobj, silent); 1788 CrossPrimGroupIntoNewRegion(destination, gobj, silent);
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
index 65ba87b..fcb7eea 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
@@ -841,7 +841,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
841 if (attachment) 841 if (attachment)
842 { 842 {
843 group.RootPart.Flags |= PrimFlags.Phantom; 843 group.RootPart.Flags |= PrimFlags.Phantom;
844 group.RootPart.IsAttachment = true; 844 group.IsAttachment = true;
845 } 845 }
846 846
847 // If we're rezzing an attachment then don't ask 847 // If we're rezzing an attachment then don't ask
diff --git a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs
index 09c0ebb..22ffcd6 100644
--- a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs
+++ b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs
@@ -81,7 +81,7 @@ namespace OpenSim.Region.CoreModules.World.Sound
81 81
82 if (grp.IsAttachment) 82 if (grp.IsAttachment)
83 { 83 {
84 if (grp.GetAttachmentPoint() > 30) // HUD 84 if (grp.AttachmentPoint > 30) // HUD
85 { 85 {
86 if (sp.ControllingClient.AgentId != grp.OwnerID) 86 if (sp.ControllingClient.AgentId != grp.OwnerID)
87 return; 87 return;
@@ -115,7 +115,7 @@ namespace OpenSim.Region.CoreModules.World.Sound
115 { 115 {
116 SceneObjectGroup grp = part.ParentGroup; 116 SceneObjectGroup grp = part.ParentGroup;
117 117
118 if (grp.IsAttachment && grp.GetAttachmentPoint() > 30) 118 if (grp.IsAttachment && grp.AttachmentPoint > 30)
119 { 119 {
120 objectID = ownerID; 120 objectID = ownerID;
121 parentID = ownerID; 121 parentID = ownerID;
diff --git a/OpenSim/Region/Framework/Scenes/Prioritizer.cs b/OpenSim/Region/Framework/Scenes/Prioritizer.cs
index 2a76755..33407ec 100644
--- a/OpenSim/Region/Framework/Scenes/Prioritizer.cs
+++ b/OpenSim/Region/Framework/Scenes/Prioritizer.cs
@@ -122,7 +122,7 @@ namespace OpenSim.Region.Framework.Scenes
122 if (entity is SceneObjectPart) 122 if (entity is SceneObjectPart)
123 { 123 {
124 SceneObjectPart sop = (SceneObjectPart)entity; 124 SceneObjectPart sop = (SceneObjectPart)entity;
125 if (sop.ParentGroup.RootPart.IsAttachment && client.AgentId == sop.ParentGroup.AttachedAvatar) 125 if (sop.ParentGroup.IsAttachment && client.AgentId == sop.ParentGroup.AttachedAvatar)
126 return 1; 126 return 1;
127 } 127 }
128 128
@@ -135,7 +135,7 @@ namespace OpenSim.Region.Framework.Scenes
135 if (entity is SceneObjectPart) 135 if (entity is SceneObjectPart)
136 { 136 {
137 SceneObjectPart sop = (SceneObjectPart)entity; 137 SceneObjectPart sop = (SceneObjectPart)entity;
138 if (sop.ParentGroup.RootPart.IsAttachment && client.AgentId == sop.ParentGroup.AttachedAvatar) 138 if (sop.ParentGroup.IsAttachment && client.AgentId == sop.ParentGroup.AttachedAvatar)
139 return 1; 139 return 1;
140 } 140 }
141 141
@@ -148,7 +148,7 @@ namespace OpenSim.Region.Framework.Scenes
148 if (entity is SceneObjectPart) 148 if (entity is SceneObjectPart)
149 { 149 {
150 SceneObjectPart sop = (SceneObjectPart)entity; 150 SceneObjectPart sop = (SceneObjectPart)entity;
151 if (sop.ParentGroup.RootPart.IsAttachment && client.AgentId == sop.ParentGroup.AttachedAvatar) 151 if (sop.ParentGroup.IsAttachment && client.AgentId == sop.ParentGroup.AttachedAvatar)
152 return 1; 152 return 1;
153 } 153 }
154 154
@@ -171,7 +171,7 @@ namespace OpenSim.Region.Framework.Scenes
171 if (entity is SceneObjectPart) 171 if (entity is SceneObjectPart)
172 { 172 {
173 // Attachments are high priority, 173 // Attachments are high priority,
174 if (((SceneObjectPart)entity).ParentGroup.RootPart.IsAttachment) 174 if (((SceneObjectPart)entity).ParentGroup.IsAttachment)
175 return 1; 175 return 1;
176 176
177 // Non physical prims are lower priority than physical prims 177 // Non physical prims are lower priority than physical prims
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 9358e7b..addc20c 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -223,6 +223,8 @@ namespace OpenSim.Region.Framework.Scenes
223 223
224 // Retrieve group 224 // Retrieve group
225 SceneObjectPart part = GetSceneObjectPart(primId); 225 SceneObjectPart part = GetSceneObjectPart(primId);
226 if (part == null)
227 return new ArrayList();
226 SceneObjectGroup group = part.ParentGroup; 228 SceneObjectGroup group = part.ParentGroup;
227 if (null == group) 229 if (null == group)
228 { 230 {
@@ -967,6 +969,8 @@ namespace OpenSim.Region.Framework.Scenes
967 public void RemoveTaskInventory(IClientAPI remoteClient, UUID itemID, uint localID) 969 public void RemoveTaskInventory(IClientAPI remoteClient, UUID itemID, uint localID)
968 { 970 {
969 SceneObjectPart part = GetSceneObjectPart(localID); 971 SceneObjectPart part = GetSceneObjectPart(localID);
972 if (part == null)
973 return;
970 SceneObjectGroup group = part.ParentGroup; 974 SceneObjectGroup group = part.ParentGroup;
971 if (group != null) 975 if (group != null)
972 { 976 {
@@ -2028,6 +2032,8 @@ namespace OpenSim.Region.Framework.Scenes
2028 foreach (uint localID in localIDs) 2032 foreach (uint localID in localIDs)
2029 { 2033 {
2030 SceneObjectPart part = GetSceneObjectPart(localID); 2034 SceneObjectPart part = GetSceneObjectPart(localID);
2035 if (part == null)
2036 continue;
2031 if (!groups.Contains(part.ParentGroup)) 2037 if (!groups.Contains(part.ParentGroup))
2032 groups.Add(part.ParentGroup); 2038 groups.Add(part.ParentGroup);
2033 } 2039 }
@@ -2073,6 +2079,8 @@ namespace OpenSim.Region.Framework.Scenes
2073 foreach (uint localID in localIDs) 2079 foreach (uint localID in localIDs)
2074 { 2080 {
2075 SceneObjectPart part = GetSceneObjectPart(localID); 2081 SceneObjectPart part = GetSceneObjectPart(localID);
2082 if (part == null)
2083 continue;
2076 part.GetProperties(remoteClient); 2084 part.GetProperties(remoteClient);
2077 } 2085 }
2078 } 2086 }
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 513c0ea..45d1a0e 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -4223,7 +4223,7 @@ namespace OpenSim.Region.Framework.Scenes
4223 // their scripts will actually run. 4223 // their scripts will actually run.
4224 // -- Leaf, Tue Aug 12 14:17:05 EDT 2008 4224 // -- Leaf, Tue Aug 12 14:17:05 EDT 2008
4225 SceneObjectPart parent = part.ParentGroup.RootPart; 4225 SceneObjectPart parent = part.ParentGroup.RootPart;
4226 if (parent != null && parent.IsAttachment) 4226 if (parent != null && part.ParentGroup.IsAttachment)
4227 return ScriptDanger(parent, parent.GetWorldPosition()); 4227 return ScriptDanger(parent, parent.GetWorldPosition());
4228 else 4228 else
4229 return ScriptDanger(part, part.GetWorldPosition()); 4229 return ScriptDanger(part, part.GetWorldPosition());
@@ -5030,7 +5030,7 @@ namespace OpenSim.Region.Framework.Scenes
5030 delete = true; 5030 delete = true;
5031 } 5031 }
5032 5032
5033 if (delete && !rootPart.IsAttachment && !deletes.Contains(g)) 5033 if (delete && !g.IsAttachment && !deletes.Contains(g))
5034 deletes.Add(g); 5034 deletes.Add(g);
5035 }); 5035 });
5036 break; 5036 break;
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index f40b373..0582586 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -1546,8 +1546,11 @@ namespace OpenSim.Region.Framework.Scenes
1546 if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId)) 1546 if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId))
1547 { 1547 {
1548 SceneObjectPart part = m_parentScene.GetSceneObjectPart(primLocalID); 1548 SceneObjectPart part = m_parentScene.GetSceneObjectPart(primLocalID);
1549 part.ClickAction = Convert.ToByte(clickAction); 1549 if (part != null)
1550 group.HasGroupChanged = true; 1550 {
1551 part.ClickAction = Convert.ToByte(clickAction);
1552 group.HasGroupChanged = true;
1553 }
1551 } 1554 }
1552 } 1555 }
1553 } 1556 }
@@ -1560,8 +1563,11 @@ namespace OpenSim.Region.Framework.Scenes
1560 if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId)) 1563 if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId))
1561 { 1564 {
1562 SceneObjectPart part = m_parentScene.GetSceneObjectPart(primLocalID); 1565 SceneObjectPart part = m_parentScene.GetSceneObjectPart(primLocalID);
1563 part.Material = Convert.ToByte(material); 1566 if (part != null)
1564 group.HasGroupChanged = true; 1567 {
1568 part.Material = Convert.ToByte(material);
1569 group.HasGroupChanged = true;
1570 }
1565 } 1571 }
1566 } 1572 }
1567 } 1573 }
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index fada688..c453366 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -146,27 +146,11 @@ namespace OpenSim.Region.Framework.Scenes
146 return true; 146 return true;
147 return false; 147 return false;
148 } 148 }
149 149
150 /// <summary> 150 /// <summary>
151 /// Is this scene object acting as an attachment? 151 /// Is this scene object acting as an attachment?
152 /// </summary> 152 /// </summary>
153 /// <remarks> 153 public bool IsAttachment { get; set; }
154 /// We return false if the group has already been deleted.
155 ///
156 /// TODO: At the moment set must be done on the part itself. There may be a case for doing it here since I
157 /// presume either all or no parts in a linkset can be part of an attachment (in which
158 /// case the value would get proprogated down into all the descendent parts).
159 /// </remarks>
160 public bool IsAttachment
161 {
162 get
163 {
164 if (!IsDeleted)
165 return m_rootPart.IsAttachment;
166
167 return false;
168 }
169 }
170 154
171 /// <summary> 155 /// <summary>
172 /// The avatar to which this scene object is attached. 156 /// The avatar to which this scene object is attached.
@@ -177,6 +161,31 @@ namespace OpenSim.Region.Framework.Scenes
177 public UUID AttachedAvatar { get; set; } 161 public UUID AttachedAvatar { get; set; }
178 162
179 /// <summary> 163 /// <summary>
164 /// Attachment point of this scene object to an avatar.
165 /// </summary>
166 /// <remarks>
167 /// 0 if we're not attached to anything
168 /// </remarks>
169 public uint AttachmentPoint
170 {
171 get
172 {
173 return m_rootPart.Shape.State;
174 }
175
176 set
177 {
178 IsAttachment = value != 0;
179 m_rootPart.Shape.State = (byte)value;
180 }
181 }
182
183 public void ClearPartAttachmentData()
184 {
185 AttachmentPoint = 0;
186 }
187
188 /// <summary>
180 /// Is this scene object phantom? 189 /// Is this scene object phantom?
181 /// </summary> 190 /// </summary>
182 /// <remarks> 191 /// <remarks>
@@ -354,11 +363,13 @@ namespace OpenSim.Region.Framework.Scenes
354 /// <summary> 363 /// <summary>
355 /// Check both the attachment property and the relevant properties of the underlying root part. 364 /// Check both the attachment property and the relevant properties of the underlying root part.
356 /// </summary> 365 /// </summary>
366 /// <remarks>
357 /// This is necessary in some cases, particularly when a scene object has just crossed into a region and doesn't 367 /// This is necessary in some cases, particularly when a scene object has just crossed into a region and doesn't
358 /// have the IsAttachment property yet checked. 368 /// have the IsAttachment property yet checked.
359 /// 369 ///
360 /// FIXME: However, this should be fixed so that this property 370 /// FIXME: However, this should be fixed so that this property
361 /// propertly reflects the underlying status. 371 /// propertly reflects the underlying status.
372 /// </remarks>
362 /// <returns></returns> 373 /// <returns></returns>
363 public bool IsAttachmentCheckFull() 374 public bool IsAttachmentCheckFull()
364 { 375 {
@@ -982,23 +993,6 @@ namespace OpenSim.Region.Framework.Scenes
982 } 993 }
983 } 994 }
984 995
985 public byte GetAttachmentPoint()
986 {
987 return m_rootPart.Shape.State;
988 }
989
990 public void SetAttachmentPoint(byte point)
991 {
992 SceneObjectPart[] parts = m_parts.GetArray();
993 for (int i = 0; i < parts.Length; i++)
994 parts[i].SetAttachmentPoint(point);
995 }
996
997 public void ClearPartAttachmentData()
998 {
999 SetAttachmentPoint((Byte)0);
1000 }
1001
1002 /// <summary> 996 /// <summary>
1003 /// 997 ///
1004 /// </summary> 998 /// </summary>
@@ -1424,16 +1418,16 @@ namespace OpenSim.Region.Framework.Scenes
1424 1418
1425 // This is only necessary when userExposed is false! 1419 // This is only necessary when userExposed is false!
1426 1420
1427 bool previousAttachmentStatus = dupe.RootPart.IsAttachment; 1421 bool previousAttachmentStatus = dupe.IsAttachment;
1428 1422
1429 if (!userExposed) 1423 if (!userExposed)
1430 dupe.RootPart.IsAttachment = true; 1424 dupe.IsAttachment = true;
1431 1425
1432 dupe.AbsolutePosition = new Vector3(AbsolutePosition.X, AbsolutePosition.Y, AbsolutePosition.Z); 1426 dupe.AbsolutePosition = new Vector3(AbsolutePosition.X, AbsolutePosition.Y, AbsolutePosition.Z);
1433 1427
1434 if (!userExposed) 1428 if (!userExposed)
1435 { 1429 {
1436 dupe.RootPart.IsAttachment = previousAttachmentStatus; 1430 dupe.IsAttachment = previousAttachmentStatus;
1437 } 1431 }
1438 1432
1439 dupe.CopyRootPart(m_rootPart, OwnerID, GroupID, userExposed); 1433 dupe.CopyRootPart(m_rootPart, OwnerID, GroupID, userExposed);
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index e510611..71023a9 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -213,10 +213,7 @@ namespace OpenSim.Region.Framework.Scenes
213 { 213 {
214 get { return m_fromUserInventoryItemID; } 214 get { return m_fromUserInventoryItemID; }
215 } 215 }
216
217 216
218 public bool IsAttachment;
219
220 217
221 public scriptEvents AggregateScriptEvents; 218 public scriptEvents AggregateScriptEvents;
222 219
@@ -224,9 +221,6 @@ namespace OpenSim.Region.Framework.Scenes
224 public Vector3 AttachedPos; 221 public Vector3 AttachedPos;
225 222
226 223
227 public uint AttachmentPoint;
228
229
230 public Vector3 RotationAxis = Vector3.One; 224 public Vector3 RotationAxis = Vector3.One;
231 225
232 226
@@ -723,7 +717,7 @@ namespace OpenSim.Region.Framework.Scenes
723 m_groupPosition = actor.Position; 717 m_groupPosition = actor.Position;
724 } 718 }
725 719
726 if (IsAttachment) 720 if (m_parentGroup.IsAttachment)
727 { 721 {
728 ScenePresence sp = m_parentGroup.Scene.GetScenePresence(ParentGroup.AttachedAvatar); 722 ScenePresence sp = m_parentGroup.Scene.GetScenePresence(ParentGroup.AttachedAvatar);
729 if (sp != null) 723 if (sp != null)
@@ -807,7 +801,7 @@ namespace OpenSim.Region.Framework.Scenes
807 { 801 {
808 if (IsRoot) 802 if (IsRoot)
809 { 803 {
810 if (IsAttachment) 804 if (m_parentGroup.IsAttachment)
811 return AttachedPos; 805 return AttachedPos;
812 else 806 else
813 return AbsolutePosition; 807 return AbsolutePosition;
@@ -1090,7 +1084,7 @@ namespace OpenSim.Region.Framework.Scenes
1090 { 1084 {
1091 get 1085 get
1092 { 1086 {
1093 if (IsAttachment) 1087 if (m_parentGroup.IsAttachment)
1094 return GroupPosition; 1088 return GroupPosition;
1095 1089
1096 return m_offsetPosition + m_groupPosition; 1090 return m_offsetPosition + m_groupPosition;
@@ -1588,7 +1582,7 @@ namespace OpenSim.Region.Framework.Scenes
1588 1582
1589 // The only time the physics scene shouldn't know about the prim is if it's phantom or an attachment, which is phantom by definition 1583 // The only time the physics scene shouldn't know about the prim is if it's phantom or an attachment, which is phantom by definition
1590 // or flexible 1584 // or flexible
1591 if (!isPhantom && !IsAttachment && !(Shape.PathCurve == (byte) Extrusion.Flexible)) 1585 if (!isPhantom && !m_parentGroup.IsAttachment && !(Shape.PathCurve == (byte) Extrusion.Flexible))
1592 { 1586 {
1593 try 1587 try
1594 { 1588 {
@@ -2880,7 +2874,7 @@ namespace OpenSim.Region.Framework.Scenes
2880 2874
2881 public void rotLookAt(Quaternion target, float strength, float damping) 2875 public void rotLookAt(Quaternion target, float strength, float damping)
2882 { 2876 {
2883 if (IsAttachment) 2877 if (m_parentGroup.IsAttachment)
2884 { 2878 {
2885 /* 2879 /*
2886 ScenePresence avatar = m_scene.GetScenePresence(rootpart.AttachedAvatar); 2880 ScenePresence avatar = m_scene.GetScenePresence(rootpart.AttachedAvatar);
@@ -3014,7 +3008,7 @@ namespace OpenSim.Region.Framework.Scenes
3014 3008
3015 if (IsRoot) 3009 if (IsRoot)
3016 { 3010 {
3017 if (IsAttachment) 3011 if (m_parentGroup.IsAttachment)
3018 { 3012 {
3019 SendFullUpdateToClient(remoteClient, AttachedPos, clientFlags); 3013 SendFullUpdateToClient(remoteClient, AttachedPos, clientFlags);
3020 } 3014 }
@@ -3076,7 +3070,7 @@ namespace OpenSim.Region.Framework.Scenes
3076 { 3070 {
3077 // Suppress full updates during attachment editing 3071 // Suppress full updates during attachment editing
3078 // 3072 //
3079 if (ParentGroup.IsSelected && IsAttachment) 3073 if (ParentGroup.IsSelected && ParentGroup.IsAttachment)
3080 return; 3074 return;
3081 3075
3082 if (ParentGroup.IsDeleted) 3076 if (ParentGroup.IsDeleted)
@@ -3254,26 +3248,6 @@ namespace OpenSim.Region.Framework.Scenes
3254 }); 3248 });
3255 } 3249 }
3256 3250
3257 public void SetAttachmentPoint(uint AttachmentPoint)
3258 {
3259 this.AttachmentPoint = AttachmentPoint;
3260
3261 if (AttachmentPoint != 0)
3262 {
3263 IsAttachment = true;
3264 }
3265 else
3266 {
3267 IsAttachment = false;
3268 }
3269
3270 // save the attachment point.
3271 //if (AttachmentPoint != 0)
3272 //{
3273 m_shape.State = (byte)AttachmentPoint;
3274 //}
3275 }
3276
3277 public void SetAxisRotation(int axis, int rotate) 3251 public void SetAxisRotation(int axis, int rotate)
3278 { 3252 {
3279 if (m_parentGroup != null) 3253 if (m_parentGroup != null)
@@ -4497,7 +4471,9 @@ namespace OpenSim.Region.Framework.Scenes
4497 } 4471 }
4498 } 4472 }
4499 4473
4500 if (SetPhantom || IsAttachment || (Shape.PathCurve == (byte)Extrusion.Flexible)) // note: this may have been changed above in the case of joints 4474 if (SetPhantom
4475 || ParentGroup.IsAttachment
4476 || (Shape.PathCurve == (byte)Extrusion.Flexible)) // note: this may have been changed above in the case of joints
4501 { 4477 {
4502 AddFlag(PrimFlags.Phantom); 4478 AddFlag(PrimFlags.Phantom);
4503 if (PhysActor != null) 4479 if (PhysActor != null)
@@ -4928,7 +4904,7 @@ namespace OpenSim.Region.Framework.Scenes
4928 if (ParentGroup == null || ParentGroup.IsDeleted) 4904 if (ParentGroup == null || ParentGroup.IsDeleted)
4929 return; 4905 return;
4930 4906
4931 if (IsAttachment && ParentGroup.RootPart != this) 4907 if (ParentGroup.IsAttachment && ParentGroup.RootPart != this)
4932 return; 4908 return;
4933 4909
4934 // Causes this thread to dig into the Client Thread Data. 4910 // Causes this thread to dig into the Client Thread Data.
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index 3b60f8c..108089e 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -201,7 +201,7 @@ namespace OpenSim.Region.Framework.Scenes
201 // Don't let this set the HasGroupChanged flag for attachments 201 // Don't let this set the HasGroupChanged flag for attachments
202 // as this happens during rez and we don't want a new asset 202 // as this happens during rez and we don't want a new asset
203 // for each attachment each time 203 // for each attachment each time
204 if (!m_part.ParentGroup.RootPart.IsAttachment) 204 if (!m_part.ParentGroup.IsAttachment)
205 { 205 {
206 HasInventoryChanged = true; 206 HasInventoryChanged = true;
207 m_part.ParentGroup.HasGroupChanged = true; 207 m_part.ParentGroup.HasGroupChanged = true;
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index fc89473..4148d4b 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -965,6 +965,11 @@ namespace OpenSim.Region.Framework.Scenes
965 presence.Animator.SendAnimPackToClient(ControllingClient); 965 presence.Animator.SendAnimPackToClient(ControllingClient);
966 }); 966 });
967 967
968 // If we don't reset the movement flag here, an avatar that crosses to a neighbouring sim and returns will
969 // stall on the border crossing since the existing child agent will still have the last movement
970 // recorded, which stops the input from being processed.
971 m_movementflag = 0;
972
968 m_scene.EventManager.TriggerOnMakeRootAgent(this); 973 m_scene.EventManager.TriggerOnMakeRootAgent(this);
969 } 974 }
970 975
@@ -1247,6 +1252,8 @@ namespace OpenSim.Region.Framework.Scenes
1247 /// </summary> 1252 /// </summary>
1248 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) 1253 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
1249 { 1254 {
1255// m_log.DebugFormat("[SCENE PRESENCE]: Received agent update from {0}", remoteClient.Name);
1256
1250 //if (m_isChildAgent) 1257 //if (m_isChildAgent)
1251 //{ 1258 //{
1252 // // m_log.Debug("DEBUG: HandleAgentUpdate: child agent"); 1259 // // m_log.Debug("DEBUG: HandleAgentUpdate: child agent");
@@ -1445,6 +1452,8 @@ namespace OpenSim.Region.Framework.Scenes
1445 { 1452 {
1446 m_movementflag |= (byte)nudgehack; 1453 m_movementflag |= (byte)nudgehack;
1447 } 1454 }
1455
1456// m_log.DebugFormat("[SCENE PRESENCE]: Updating m_movementflag for {0} with {1}", Name, DCF);
1448 m_movementflag += (byte)(uint)DCF; 1457 m_movementflag += (byte)(uint)DCF;
1449 update_movementflag = true; 1458 update_movementflag = true;
1450 } 1459 }
@@ -1456,6 +1465,7 @@ namespace OpenSim.Region.Framework.Scenes
1456 && ((m_movementflag & (byte)nudgehack) == nudgehack)) 1465 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1457 ) // This or is for Nudge forward 1466 ) // This or is for Nudge forward
1458 { 1467 {
1468// m_log.DebugFormat("[SCENE PRESENCE]: Updating m_movementflag for {0} with lack of {1}", Name, DCF);
1459 m_movementflag -= ((byte)(uint)DCF); 1469 m_movementflag -= ((byte)(uint)DCF);
1460 update_movementflag = true; 1470 update_movementflag = true;
1461 1471
@@ -1520,12 +1530,21 @@ namespace OpenSim.Region.Framework.Scenes
1520 // which occurs later in the main scene loop 1530 // which occurs later in the main scene loop
1521 if (update_movementflag || (update_rotation && DCFlagKeyPressed)) 1531 if (update_movementflag || (update_rotation && DCFlagKeyPressed))
1522 { 1532 {
1523 // m_log.DebugFormat("{0} {1}", update_movementflag, (update_rotation && DCFlagKeyPressed)); 1533// m_log.DebugFormat(
1524 // m_log.DebugFormat( 1534// "[SCENE PRESENCE]: In {0} adding velocity of {1} to {2}, umf = {3}, ur = {4}",
1525 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); 1535// m_scene.RegionInfo.RegionName, agent_control_v3, Name, update_movementflag, update_rotation);
1526 1536
1527 AddNewMovement(agent_control_v3); 1537 AddNewMovement(agent_control_v3);
1528 } 1538 }
1539// else
1540// {
1541// if (!update_movementflag)
1542// {
1543// m_log.DebugFormat(
1544// "[SCENE PRESENCE]: In {0} ignoring requested update of {1} for {2} as update_movementflag = false",
1545// m_scene.RegionInfo.RegionName, agent_control_v3, Name);
1546// }
1547// }
1529 1548
1530 if (update_movementflag && m_parentID == 0) 1549 if (update_movementflag && m_parentID == 0)
1531 Animator.UpdateMovementAnimations(); 1550 Animator.UpdateMovementAnimations();
@@ -3178,7 +3197,7 @@ namespace OpenSim.Region.Framework.Scenes
3178 ISceneObject clone = sog.CloneForNewScene(); 3197 ISceneObject clone = sog.CloneForNewScene();
3179 // Attachment module assumes that GroupPosition holds the offsets...! 3198 // Attachment module assumes that GroupPosition holds the offsets...!
3180 ((SceneObjectGroup)clone).RootPart.GroupPosition = sog.RootPart.AttachedPos; 3199 ((SceneObjectGroup)clone).RootPart.GroupPosition = sog.RootPart.AttachedPos;
3181 ((SceneObjectGroup)clone).RootPart.IsAttachment = false; 3200 ((SceneObjectGroup)clone).IsAttachment = false;
3182 cAgent.AttachmentObjects.Add(clone); 3201 cAgent.AttachmentObjects.Add(clone);
3183 string state = sog.GetStateSnapshot(); 3202 string state = sog.GetStateSnapshot();
3184 cAgent.AttachmentObjectStates.Add(state); 3203 cAgent.AttachmentObjectStates.Add(state);
@@ -3477,7 +3496,7 @@ namespace OpenSim.Region.Framework.Scenes
3477 { 3496 {
3478 foreach (SceneObjectGroup so in m_attachments) 3497 foreach (SceneObjectGroup so in m_attachments)
3479 { 3498 {
3480 if (attachmentPoint == so.RootPart.AttachmentPoint) 3499 if (attachmentPoint == so.AttachmentPoint)
3481 attachments.Add(so); 3500 attachments.Add(so);
3482 } 3501 }
3483 } 3502 }
@@ -3869,12 +3888,12 @@ namespace OpenSim.Region.Framework.Scenes
3869 { 3888 {
3870 if (grp.HasGroupChanged) // Resizer scripts? 3889 if (grp.HasGroupChanged) // Resizer scripts?
3871 { 3890 {
3872 grp.RootPart.IsAttachment = false; 3891 grp.IsAttachment = false;
3873 grp.AbsolutePosition = grp.RootPart.AttachedPos; 3892 grp.AbsolutePosition = grp.RootPart.AttachedPos;
3874// grp.DetachToInventoryPrep(); 3893// grp.DetachToInventoryPrep();
3875 attachmentsModule.UpdateKnownItem(ControllingClient, 3894 attachmentsModule.UpdateKnownItem(ControllingClient,
3876 grp, grp.GetFromItemID(), grp.OwnerID); 3895 grp, grp.GetFromItemID(), grp.OwnerID);
3877 grp.RootPart.IsAttachment = true; 3896 grp.IsAttachment = true;
3878 } 3897 }
3879 } 3898 }
3880 } 3899 }
diff --git a/OpenSim/Region/Framework/Scenes/SceneViewer.cs b/OpenSim/Region/Framework/Scenes/SceneViewer.cs
index 7c067ca..997845b 100644
--- a/OpenSim/Region/Framework/Scenes/SceneViewer.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneViewer.cs
@@ -120,8 +120,7 @@ namespace OpenSim.Region.Framework.Scenes
120 // We deal with the possibility that two updates occur at 120 // We deal with the possibility that two updates occur at
121 // the same unix time at the update point itself. 121 // the same unix time at the update point itself.
122 122
123 if ((update.LastFullUpdateTime < part.TimeStampFull) || 123 if ((update.LastFullUpdateTime < part.TimeStampFull) || part.ParentGroup.IsAttachment)
124 part.IsAttachment)
125 { 124 {
126 // m_log.DebugFormat( 125 // m_log.DebugFormat(
127 // "[SCENE PRESENCE]: Fully updating prim {0}, {1} - part timestamp {2}", 126 // "[SCENE PRESENCE]: Fully updating prim {0}, {1} - part timestamp {2}",
diff --git a/OpenSim/Region/Physics/Manager/IMesher.cs b/OpenSim/Region/Physics/Manager/IMesher.cs
index 1181b8d..3a9ca1b 100644
--- a/OpenSim/Region/Physics/Manager/IMesher.cs
+++ b/OpenSim/Region/Physics/Manager/IMesher.cs
@@ -38,6 +38,17 @@ namespace OpenSim.Region.Physics.Manager
38 IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical); 38 IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical);
39 } 39 }
40 40
41 // Values for level of detail to be passed to the mesher.
42 // Values origionally chosen for the LOD of sculpties (the sqrt(width*heigth) of sculpt texture)
43 // Lower level of detail reduces the number of vertices used to represent the meshed shape.
44 public enum LevelOfDetail
45 {
46 High = 32,
47 Medium = 16,
48 Low = 8,
49 VeryLow = 4
50 }
51
41 public interface IVertex 52 public interface IVertex
42 { 53 {
43 } 54 }
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
index e81b982..53d5e4c 100644
--- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
+++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
@@ -193,67 +193,6 @@ namespace OpenSim.Region.Physics.Meshing
193 m_log.Error("****** PrimMesh Parameters ******\n" + primMesh.ParamsToDisplayString()); 193 m_log.Error("****** PrimMesh Parameters ******\n" + primMesh.ParamsToDisplayString());
194 } 194 }
195 195
196 private ulong GetMeshKey(PrimitiveBaseShape pbs, Vector3 size, float lod)
197 {
198 ulong hash = 5381;
199
200 hash = djb2(hash, pbs.PathCurve);
201 hash = djb2(hash, (byte)((byte)pbs.HollowShape | (byte)pbs.ProfileShape));
202 hash = djb2(hash, pbs.PathBegin);
203 hash = djb2(hash, pbs.PathEnd);
204 hash = djb2(hash, pbs.PathScaleX);
205 hash = djb2(hash, pbs.PathScaleY);
206 hash = djb2(hash, pbs.PathShearX);
207 hash = djb2(hash, pbs.PathShearY);
208 hash = djb2(hash, (byte)pbs.PathTwist);
209 hash = djb2(hash, (byte)pbs.PathTwistBegin);
210 hash = djb2(hash, (byte)pbs.PathRadiusOffset);
211 hash = djb2(hash, (byte)pbs.PathTaperX);
212 hash = djb2(hash, (byte)pbs.PathTaperY);
213 hash = djb2(hash, pbs.PathRevolutions);
214 hash = djb2(hash, (byte)pbs.PathSkew);
215 hash = djb2(hash, pbs.ProfileBegin);
216 hash = djb2(hash, pbs.ProfileEnd);
217 hash = djb2(hash, pbs.ProfileHollow);
218
219 // TODO: Separate scale out from the primitive shape data (after
220 // scaling is supported at the physics engine level)
221 byte[] scaleBytes = size.GetBytes();
222 for (int i = 0; i < scaleBytes.Length; i++)
223 hash = djb2(hash, scaleBytes[i]);
224
225 // Include LOD in hash, accounting for endianness
226 byte[] lodBytes = new byte[4];
227 Buffer.BlockCopy(BitConverter.GetBytes(lod), 0, lodBytes, 0, 4);
228 if (!BitConverter.IsLittleEndian)
229 {
230 Array.Reverse(lodBytes, 0, 4);
231 }
232 for (int i = 0; i < lodBytes.Length; i++)
233 hash = djb2(hash, lodBytes[i]);
234
235 // include sculpt UUID
236 if (pbs.SculptEntry)
237 {
238 scaleBytes = pbs.SculptTexture.GetBytes();
239 for (int i = 0; i < scaleBytes.Length; i++)
240 hash = djb2(hash, scaleBytes[i]);
241 }
242
243 return hash;
244 }
245
246 private ulong djb2(ulong hash, byte c)
247 {
248 return ((hash << 5) + hash) + (ulong)c;
249 }
250
251 private ulong djb2(ulong hash, ushort c)
252 {
253 hash = ((hash << 5) + hash) + (ulong)((byte)c);
254 return ((hash << 5) + hash) + (ulong)(c >> 8);
255 }
256
257 /// <summary> 196 /// <summary>
258 /// Add a submesh to an existing list of coords and faces. 197 /// Add a submesh to an existing list of coords and faces.
259 /// </summary> 198 /// </summary>
@@ -336,7 +275,7 @@ namespace OpenSim.Region.Physics.Meshing
336 } 275 }
337 else 276 else
338 { 277 {
339 if (!GenerateCoordsAndFacesFromPrimShapeData(primName, primShape, size, out coords, out faces)) 278 if (!GenerateCoordsAndFacesFromPrimShapeData(primName, primShape, size, lod, out coords, out faces))
340 return null; 279 return null;
341 } 280 }
342 281
@@ -616,7 +555,7 @@ namespace OpenSim.Region.Physics.Meshing
616 /// <param name="faces">Faces are added to this list by the method.</param> 555 /// <param name="faces">Faces are added to this list by the method.</param>
617 /// <returns>true if coords and faces were successfully generated, false if not</returns> 556 /// <returns>true if coords and faces were successfully generated, false if not</returns>
618 private bool GenerateCoordsAndFacesFromPrimShapeData( 557 private bool GenerateCoordsAndFacesFromPrimShapeData(
619 string primName, PrimitiveBaseShape primShape, Vector3 size, out List<Coord> coords, out List<Face> faces) 558 string primName, PrimitiveBaseShape primShape, Vector3 size, float lod, out List<Coord> coords, out List<Face> faces)
620 { 559 {
621 PrimMesh primMesh; 560 PrimMesh primMesh;
622 coords = new List<Coord>(); 561 coords = new List<Coord>();
@@ -636,13 +575,30 @@ namespace OpenSim.Region.Physics.Meshing
636 profileHollow = 0.95f; 575 profileHollow = 0.95f;
637 576
638 int sides = 4; 577 int sides = 4;
578 LevelOfDetail iLOD = (LevelOfDetail)lod;
639 if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle) 579 if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle)
640 sides = 3; 580 sides = 3;
641 else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.Circle) 581 else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.Circle)
642 sides = 24; 582 {
583 switch (iLOD)
584 {
585 case LevelOfDetail.High: sides = 24; break;
586 case LevelOfDetail.Medium: sides = 12; break;
587 case LevelOfDetail.Low: sides = 6; break;
588 case LevelOfDetail.VeryLow: sides = 3; break;
589 default: sides = 24; break;
590 }
591 }
643 else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle) 592 else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle)
644 { // half circle, prim is a sphere 593 { // half circle, prim is a sphere
645 sides = 24; 594 switch (iLOD)
595 {
596 case LevelOfDetail.High: sides = 24; break;
597 case LevelOfDetail.Medium: sides = 12; break;
598 case LevelOfDetail.Low: sides = 6; break;
599 case LevelOfDetail.VeryLow: sides = 3; break;
600 default: sides = 24; break;
601 }
646 602
647 profileBegin = 0.5f * profileBegin + 0.5f; 603 profileBegin = 0.5f * profileBegin + 0.5f;
648 profileEnd = 0.5f * profileEnd + 0.5f; 604 profileEnd = 0.5f * profileEnd + 0.5f;
@@ -650,7 +606,16 @@ namespace OpenSim.Region.Physics.Meshing
650 606
651 int hollowSides = sides; 607 int hollowSides = sides;
652 if (primShape.HollowShape == HollowShape.Circle) 608 if (primShape.HollowShape == HollowShape.Circle)
653 hollowSides = 24; 609 {
610 switch (iLOD)
611 {
612 case LevelOfDetail.High: hollowSides = 24; break;
613 case LevelOfDetail.Medium: hollowSides = 12; break;
614 case LevelOfDetail.Low: hollowSides = 6; break;
615 case LevelOfDetail.VeryLow: hollowSides = 3; break;
616 default: hollowSides = 24; break;
617 }
618 }
654 else if (primShape.HollowShape == HollowShape.Square) 619 else if (primShape.HollowShape == HollowShape.Square)
655 hollowSides = 4; 620 hollowSides = 4;
656 else if (primShape.HollowShape == HollowShape.Triangle) 621 else if (primShape.HollowShape == HollowShape.Triangle)
@@ -751,7 +716,7 @@ namespace OpenSim.Region.Physics.Meshing
751 716
752 // If this mesh has been created already, return it instead of creating another copy 717 // If this mesh has been created already, return it instead of creating another copy
753 // For large regions with 100k+ prims and hundreds of copies of each, this can save a GB or more of memory 718 // For large regions with 100k+ prims and hundreds of copies of each, this can save a GB or more of memory
754 key = GetMeshKey(primShape, size, lod); 719 key = primShape.GetMeshKey(size, lod);
755 if (m_uniqueMeshes.TryGetValue(key, out mesh)) 720 if (m_uniqueMeshes.TryGetValue(key, out mesh))
756 return mesh; 721 return mesh;
757 722
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 81f1f38..a7f08d9 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -1965,7 +1965,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1965 1965
1966 if (part.ParentGroup.RootPart == part) 1966 if (part.ParentGroup.RootPart == part)
1967 { 1967 {
1968 if ((targetPos.z < ground) && disable_underground_movement && m_host.AttachmentPoint == 0) 1968 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
1969 targetPos.z = ground; 1969 targetPos.z = ground;
1970 SceneObjectGroup parent = part.ParentGroup; 1970 SceneObjectGroup parent = part.ParentGroup;
1971 LSL_Vector real_vec = SetPosAdjust(currentPos, targetPos); 1971 LSL_Vector real_vec = SetPosAdjust(currentPos, targetPos);
@@ -2097,7 +2097,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2097 Quaternion q; 2097 Quaternion q;
2098 if (part.LinkNum == 0 || part.LinkNum == 1) // unlinked or root prim 2098 if (part.LinkNum == 0 || part.LinkNum == 1) // unlinked or root prim
2099 { 2099 {
2100 if (part.ParentGroup.RootPart.AttachmentPoint != 0) 2100 if (part.ParentGroup.AttachmentPoint != 0)
2101 { 2101 {
2102 ScenePresence avatar = World.GetScenePresence(part.ParentGroup.AttachedAvatar); 2102 ScenePresence avatar = World.GetScenePresence(part.ParentGroup.AttachedAvatar);
2103 if (avatar != null) 2103 if (avatar != null)
@@ -2241,7 +2241,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2241 2241
2242 Vector3 vel; 2242 Vector3 vel;
2243 2243
2244 if (m_host.IsAttachment) 2244 if (m_host.ParentGroup.IsAttachment)
2245 { 2245 {
2246 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 2246 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2247 vel = avatar.Velocity; 2247 vel = avatar.Velocity;
@@ -2997,7 +2997,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2997 { 2997 {
2998 m_host.AddScriptLPS(1); 2998 m_host.AddScriptLPS(1);
2999 2999
3000 if (m_host.ParentGroup.RootPart.AttachmentPoint == 0) 3000 if (m_host.ParentGroup.AttachmentPoint == 0)
3001 return; 3001 return;
3002 3002
3003 TaskInventoryItem item; 3003 TaskInventoryItem item;
@@ -3587,7 +3587,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3587 3587
3588 SceneObjectPart targetPart = World.GetSceneObjectPart((UUID)targetID); 3588 SceneObjectPart targetPart = World.GetSceneObjectPart((UUID)targetID);
3589 3589
3590 if (targetPart.ParentGroup.RootPart.AttachmentPoint != 0) 3590 if (targetPart.ParentGroup.AttachmentPoint != 0)
3591 return; // Fail silently if attached 3591 return; // Fail silently if attached
3592 SceneObjectGroup parentPrim = null, childPrim = null; 3592 SceneObjectGroup parentPrim = null, childPrim = null;
3593 3593
@@ -3640,7 +3640,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3640 3640
3641 SceneObjectGroup parentPrim = m_host.ParentGroup; 3641 SceneObjectGroup parentPrim = m_host.ParentGroup;
3642 3642
3643 if (parentPrim.RootPart.AttachmentPoint != 0) 3643 if (parentPrim.AttachmentPoint != 0)
3644 return; // Fail silently if attached 3644 return; // Fail silently if attached
3645 SceneObjectPart childPrim = null; 3645 SceneObjectPart childPrim = null;
3646 3646
@@ -3710,7 +3710,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3710 { 3710 {
3711 m_host.AddScriptLPS(1); 3711 m_host.AddScriptLPS(1);
3712 SceneObjectGroup parentPrim = m_host.ParentGroup; 3712 SceneObjectGroup parentPrim = m_host.ParentGroup;
3713 if (parentPrim.RootPart.AttachmentPoint != 0) 3713 if (parentPrim.AttachmentPoint != 0)
3714 return; // Fail silently if attached 3714 return; // Fail silently if attached
3715 3715
3716 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 3716 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
@@ -4349,7 +4349,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4349 return; 4349 return;
4350 4350
4351 // Object not pushable. Not an attachment and has no physics component 4351 // Object not pushable. Not an attachment and has no physics component
4352 if (!pusheeob.IsAttachment && pusheeob.PhysActor == null) 4352 if (!pusheeob.ParentGroup.IsAttachment && pusheeob.PhysActor == null)
4353 return; 4353 return;
4354 4354
4355 PusheePos = pusheeob.AbsolutePosition; 4355 PusheePos = pusheeob.AbsolutePosition;
@@ -5857,7 +5857,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5857 public LSL_Integer llGetAttached() 5857 public LSL_Integer llGetAttached()
5858 { 5858 {
5859 m_host.AddScriptLPS(1); 5859 m_host.AddScriptLPS(1);
5860 return m_host.ParentGroup.RootPart.AttachmentPoint; 5860 return m_host.ParentGroup.AttachmentPoint;
5861 } 5861 }
5862 5862
5863 public LSL_Integer llGetFreeMemory() 5863 public LSL_Integer llGetFreeMemory()
@@ -7458,7 +7458,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7458 { 7458 {
7459 m_host.AddScriptLPS(1); 7459 m_host.AddScriptLPS(1);
7460 Quaternion q; 7460 Quaternion q;
7461 if (m_host.ParentGroup.RootPart.AttachmentPoint != 0) 7461 if (m_host.ParentGroup.AttachmentPoint != 0)
7462 { 7462 {
7463 ScenePresence avatar = World.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 7463 ScenePresence avatar = World.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
7464 if (avatar != null) 7464 if (avatar != null)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index bf74760..4ac7f8b 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -303,7 +303,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
303 float dz; 303 float dz;
304 304
305 Quaternion q = SensePoint.RotationOffset; 305 Quaternion q = SensePoint.RotationOffset;
306 if (SensePoint.ParentGroup.RootPart.IsAttachment) 306 if (SensePoint.ParentGroup.IsAttachment)
307 { 307 {
308 // In attachments, the sensor cone always orients with the 308 // In attachments, the sensor cone always orients with the
309 // avatar rotation. This may include a nonzero elevation if 309 // avatar rotation. This may include a nonzero elevation if
@@ -352,7 +352,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
352 objtype = 0; 352 objtype = 0;
353 353
354 part = ((SceneObjectGroup)ent).RootPart; 354 part = ((SceneObjectGroup)ent).RootPart;
355 if (part.AttachmentPoint != 0) // Attached so ignore 355 if (part.ParentGroup.AttachmentPoint != 0) // Attached so ignore
356 continue; 356 continue;
357 357
358 if (part.Inventory.ContainsScripts()) 358 if (part.Inventory.ContainsScripts())
@@ -423,7 +423,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
423 Vector3 fromRegionPos = SensePoint.AbsolutePosition; 423 Vector3 fromRegionPos = SensePoint.AbsolutePosition;
424 424
425 Quaternion q = SensePoint.RotationOffset; 425 Quaternion q = SensePoint.RotationOffset;
426 if (SensePoint.ParentGroup.RootPart.IsAttachment) 426 if (SensePoint.ParentGroup.IsAttachment)
427 { 427 {
428 // In attachments, the sensor cone always orients with the 428 // In attachments, the sensor cone always orients with the
429 // avatar rotation. This may include a nonzero elevation if 429 // avatar rotation. This may include a nonzero elevation if
@@ -435,7 +435,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
435 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 435 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
436 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r); 436 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r);
437 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir); 437 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir);
438 bool attached = (SensePoint.AttachmentPoint != 0); 438 bool attached = (SensePoint.ParentGroup.AttachmentPoint != 0);
439 Vector3 toRegionPos; 439 Vector3 toRegionPos;
440 double dis; 440 double dis;
441 441