diff --git a/OpenSim/Data/Tests/RegionTests.cs b/OpenSim/Data/Tests/RegionTests.cs index 2b8fa5941e..cac8cac3ef 100644 --- a/OpenSim/Data/Tests/RegionTests.cs +++ b/OpenSim/Data/Tests/RegionTests.cs @@ -304,9 +304,9 @@ namespace OpenSim.Data.Tests regionInfo.RegionLocX = 0; regionInfo.RegionLocY = 0; -// Scene scene = new Scene(regionInfo); - SceneObjectPart sop = new SceneObjectPart(); + SceneObjectGroup sog = new SceneObjectGroup(sop); + sop.RegionHandle = regionh; sop.UUID = uuid; sop.LocalId = localid; @@ -373,8 +373,6 @@ namespace OpenSim.Data.Tests // This is necessary or object will not be inserted in DB sop.Flags = PrimFlags.None; - - SceneObjectGroup sog = new SceneObjectGroup(sop); // Inserts group in DB db.StoreObject(sog,region3); diff --git a/OpenSim/Framework/PrimitiveBaseShape.cs b/OpenSim/Framework/PrimitiveBaseShape.cs index d873071b37..1b6a1d2e58 100644 --- a/OpenSim/Framework/PrimitiveBaseShape.cs +++ b/OpenSim/Framework/PrimitiveBaseShape.cs @@ -859,6 +859,67 @@ namespace OpenSim.Framework } } + public ulong GetMeshKey(Vector3 size, float lod) + { + ulong hash = 5381; + + hash = djb2(hash, this.PathCurve); + hash = djb2(hash, (byte)((byte)this.HollowShape | (byte)this.ProfileShape)); + hash = djb2(hash, this.PathBegin); + hash = djb2(hash, this.PathEnd); + hash = djb2(hash, this.PathScaleX); + hash = djb2(hash, this.PathScaleY); + hash = djb2(hash, this.PathShearX); + hash = djb2(hash, this.PathShearY); + hash = djb2(hash, (byte)this.PathTwist); + hash = djb2(hash, (byte)this.PathTwistBegin); + hash = djb2(hash, (byte)this.PathRadiusOffset); + hash = djb2(hash, (byte)this.PathTaperX); + hash = djb2(hash, (byte)this.PathTaperY); + hash = djb2(hash, this.PathRevolutions); + hash = djb2(hash, (byte)this.PathSkew); + hash = djb2(hash, this.ProfileBegin); + hash = djb2(hash, this.ProfileEnd); + hash = djb2(hash, this.ProfileHollow); + + // TODO: Separate scale out from the primitive shape data (after + // scaling is supported at the physics engine level) + byte[] scaleBytes = size.GetBytes(); + for (int i = 0; i < scaleBytes.Length; i++) + hash = djb2(hash, scaleBytes[i]); + + // Include LOD in hash, accounting for endianness + byte[] lodBytes = new byte[4]; + Buffer.BlockCopy(BitConverter.GetBytes(lod), 0, lodBytes, 0, 4); + if (!BitConverter.IsLittleEndian) + { + Array.Reverse(lodBytes, 0, 4); + } + for (int i = 0; i < lodBytes.Length; i++) + hash = djb2(hash, lodBytes[i]); + + // include sculpt UUID + if (this.SculptEntry) + { + scaleBytes = this.SculptTexture.GetBytes(); + for (int i = 0; i < scaleBytes.Length; i++) + hash = djb2(hash, scaleBytes[i]); + } + + return hash; + } + + private ulong djb2(ulong hash, byte c) + { + return ((hash << 5) + hash) + (ulong)c; + } + + private ulong djb2(ulong hash, ushort c) + { + hash = ((hash << 5) + hash) + (ulong)((byte)c); + return ((hash << 5) + hash) + (ulong)(c >> 8); + } + public byte[] ExtraParamsToBytes() { // 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 8189518f9b..c07fc73069 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 grp.AbsolutePosition = obj.Position; prim.RotationOffset = obj.Rotation; - grp.RootPart.IsAttachment = false; + grp.IsAttachment = false; // Required for linking grp.RootPart.UpdateFlag = 0; diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index f71871e1c7..dc9a6ed077 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 { SceneObjectPart part = (SceneObjectPart)entity; - attachPoint = part.AttachmentPoint; + if (part.ParentGroup != null) + attachPoint = part.ParentGroup.AttachmentPoint; + else + attachPoint = 0; + collisionPlane = Vector4.Zero; position = part.RelativePosition; velocity = part.Velocity; @@ -4913,10 +4917,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP //update.JointType = 0; update.Material = data.Material; update.MediaURL = Utils.EmptyBytes; // FIXME: Support this in OpenSim - if (data.IsAttachment) + if (data.ParentGroup != null && data.ParentGroup.IsAttachment) { update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + data.FromItemID); - update.State = (byte)((data.AttachmentPoint % 16) * 16 + (data.AttachmentPoint / 16)); + update.State = (byte)((data.ParentGroup.AttachmentPoint % 16) * 16 + (data.ParentGroup.AttachmentPoint / 16)); } else { diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 3e1cb026f0..2d5eb18f50 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 return AttachObject(sp, group, AttachmentPt, silent); } - private bool AttachObject(ScenePresence sp, SceneObjectGroup group, uint AttachmentPt, bool silent) + private bool AttachObject(ScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent) { // m_log.DebugFormat( // "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})", // group.Name, group.LocalId, sp.Name, AttachmentPt, silent); - if (sp.GetAttachments(AttachmentPt).Contains(group)) + if (sp.GetAttachments(attachmentPt).Contains(group)) { // m_log.WarnFormat( // "[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 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should // be removed when that functionality is implemented in opensim - AttachmentPt &= 0x7f; + attachmentPt &= 0x7f; // If the attachment point isn't the same as the one previously used // set it's offset position = 0 so that it appears on the attachment point // and not in a weird location somewhere unknown. - if (AttachmentPt != 0 && AttachmentPt != (uint)group.GetAttachmentPoint()) + if (attachmentPt != 0 && attachmentPt != group.AttachmentPoint) { attachPos = Vector3.Zero; } // AttachmentPt 0 means the client chose to 'wear' the attachment. - if (AttachmentPt == 0) + if (attachmentPt == 0) { // Check object for stored attachment point - AttachmentPt = (uint)group.GetAttachmentPoint(); + attachmentPt = group.AttachmentPoint; } // if we still didn't find a suitable attachment point....... - if (AttachmentPt == 0) + if (attachmentPt == 0) { // Stick it on left hand with Zero Offset from the attachment point. - AttachmentPt = (uint)AttachmentPoint.LeftHand; + attachmentPt = (uint)AttachmentPoint.LeftHand; attachPos = Vector3.Zero; } - group.SetAttachmentPoint((byte)AttachmentPt); + group.AttachmentPoint = attachmentPt; group.AbsolutePosition = attachPos; // Remove any previous attachments UUID itemID = UUID.Zero; foreach (SceneObjectGroup grp in sp.Attachments) { - if (grp.GetAttachmentPoint() == (byte)AttachmentPt) + if (grp.AttachmentPoint == attachmentPt) { itemID = grp.GetFromItemID(); break; @@ -232,9 +232,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (itemID == UUID.Zero) itemID = AddSceneObjectAsAttachment(sp.ControllingClient, group).ID; - ShowAttachInUserInventory(sp, AttachmentPt, itemID, group); + ShowAttachInUserInventory(sp, attachmentPt, itemID, group); - AttachToAgent(sp, group, AttachmentPt, attachPos, silent); + AttachToAgent(sp, group, attachmentPt, attachPos, silent); return true; } @@ -293,7 +293,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments } private SceneObjectGroup RezSingleAttachmentFromInventoryInternal( - ScenePresence sp, UUID itemID, uint AttachmentPt) + ScenePresence sp, UUID itemID, uint attachmentPt) { IInventoryAccessModule invAccess = m_scene.RequestModuleInterface(); if (invAccess != null) @@ -313,13 +313,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // since scripts aren't running yet. So, clear it here. objatt.HasGroupChanged = false; bool tainted = false; - if (AttachmentPt != 0 && AttachmentPt != objatt.GetAttachmentPoint()) + if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint) tainted = true; // This will throw if the attachment fails try { - AttachObject(sp, objatt, AttachmentPt, false); + AttachObject(sp, objatt, attachmentPt, false); } catch (Exception e) { @@ -348,7 +348,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments { m_log.WarnFormat( "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}", - itemID, sp.Name, AttachmentPt); + itemID, sp.Name, attachmentPt); } return objatt; @@ -363,22 +363,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments /// /// /// - /// + /// /// private UUID ShowAttachInUserInventory( - SceneObjectGroup att, ScenePresence sp, UUID itemID, uint AttachmentPt) + SceneObjectGroup att, ScenePresence sp, UUID itemID, uint attachmentPoint) { // m_log.DebugFormat( -// "[ATTACHMENTS MODULE]: Updating inventory of {0} to show attachment of {1} (item ID {2})", -// remoteClient.Name, att.Name, itemID); +// "[ATTACHMENTS MODULE]: Updating inventory of {0} to show attachment of {1} {2} (item ID {3}) at {4}", +// sp.Name, att.Name, att.LocalId, itemID, AttachmentPt); if (!att.IsDeleted) - AttachmentPt = att.RootPart.AttachmentPoint; + attachmentPoint = att.AttachmentPoint; InventoryItemBase item = new InventoryItemBase(itemID, sp.UUID); item = m_scene.InventoryService.GetItem(item); - bool changed = sp.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID); + bool changed = sp.Appearance.SetAttachment((int)attachmentPoint, itemID, item.AssetID); if (changed && m_scene.AvatarFactory != null) m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); @@ -547,7 +547,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments ); group.RootPart.SetParentLocalId(0); - group.RootPart.IsAttachment = false; + group.IsAttachment = false; group.AbsolutePosition = group.RootPart.AttachedPos; UpdateKnownItem(sp.ControllingClient, group, group.GetFromItemID(), group.OwnerID); @@ -567,11 +567,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // attachment. This is necessary in order to correctly save // and retrieve GroupPosition information for the attachment. // Finally, we restore the object's attachment status. - byte attachmentPoint = sog.GetAttachmentPoint(); + uint attachmentPoint = sog.AttachmentPoint; sog.UpdateGroupPosition(pos); - sog.RootPart.IsAttachment = false; + sog.IsAttachment = false; sog.AbsolutePosition = sog.RootPart.AttachedPos; - sog.SetAttachmentPoint(attachmentPoint); + sog.AttachmentPoint = attachmentPoint; sog.HasGroupChanged = true; } @@ -594,14 +594,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments { m_log.DebugFormat( "[ATTACHMENTS MODULE]: Don't need to update asset for unchanged attachment {0}, attachpoint {1}", - grp.UUID, grp.GetAttachmentPoint()); + grp.UUID, grp.AttachmentPoint); return; } m_log.DebugFormat( "[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}", - grp.UUID, grp.GetAttachmentPoint()); + grp.UUID, grp.AttachmentPoint); string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp); @@ -666,10 +666,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments so.AbsolutePosition = attachOffset; so.RootPart.AttachedPos = attachOffset; - so.RootPart.IsAttachment = true; - + so.IsAttachment = true; so.RootPart.SetParentLocalId(avatar.LocalId); - so.SetAttachmentPoint(Convert.ToByte(attachmentpoint)); + so.AttachmentPoint = attachmentpoint; avatar.AddAttachment(so); diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index b7d21fd4ff..bb536013fa 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 Assert.That(attachments.Count, Is.EqualTo(1)); SceneObjectGroup attSo = attachments[0]; Assert.That(attSo.Name, Is.EqualTo(attName)); - Assert.That(attSo.GetAttachmentPoint(), Is.EqualTo((byte)AttachmentPoint.Chest)); + Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest)); Assert.That(attSo.IsAttachment); Assert.That(attSo.UsesPhysics, Is.False); Assert.That(attSo.IsTemporary, Is.False); @@ -132,9 +132,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests UUID attAssetId = TestHelpers.ParseTail(0x3); string attName = "att"; - InventoryItemBase attItem - = UserInventoryHelpers.CreateInventoryItem( - scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object); + UserInventoryHelpers.CreateInventoryItem( + scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object); m_attMod.RezSingleAttachmentFromInventory( m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest); @@ -145,7 +144,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests Assert.That(attachments.Count, Is.EqualTo(1)); SceneObjectGroup attSo = attachments[0]; Assert.That(attSo.Name, Is.EqualTo(attName)); - Assert.That(attSo.GetAttachmentPoint(), Is.EqualTo((byte)AttachmentPoint.Chest)); + Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest)); Assert.That(attSo.IsAttachment); Assert.That(attSo.UsesPhysics, Is.False); Assert.That(attSo.IsTemporary, Is.False); @@ -166,9 +165,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests UUID attAssetId = TestHelpers.ParseTail(0x3); string attName = "att"; - InventoryItemBase attItem - = UserInventoryHelpers.CreateInventoryItem( - scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object); + UserInventoryHelpers.CreateInventoryItem( + scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object); UUID attSoId = m_attMod.RezSingleAttachmentFromInventory( m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest); @@ -198,9 +196,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests UUID attAssetId = TestHelpers.ParseTail(0x3); string attName = "att"; - InventoryItemBase attItem - = UserInventoryHelpers.CreateInventoryItem( - scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object); + UserInventoryHelpers.CreateInventoryItem( + scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object); m_attMod.RezSingleAttachmentFromInventory( m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest); @@ -242,7 +239,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests Assert.That(attachments.Count, Is.EqualTo(1)); SceneObjectGroup attSo = attachments[0]; Assert.That(attSo.Name, Is.EqualTo(attName)); - Assert.That(attSo.GetAttachmentPoint(), Is.EqualTo((byte)AttachmentPoint.Chest)); + Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest)); Assert.That(attSo.IsAttachment); Assert.That(attSo.UsesPhysics, Is.False); 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 f5d49c5985..7963e530ab 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 // Set the parent localID to 0 so it transfers over properly. gobj.RootPart.SetParentLocalId(0); gobj.AbsolutePosition = gobj.RootPart.AttachedPos; - gobj.RootPart.IsAttachment = false; + gobj.IsAttachment = false; //gobj.RootPart.LastOwnerID = gobj.GetFromAssetID(); m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending attachment {0} to region {1}", gobj.UUID, destination.RegionName); CrossPrimGroupIntoNewRegion(destination, gobj, silent); diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 65ba87b16f..fcb7eea0ea 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 if (attachment) { group.RootPart.Flags |= PrimFlags.Phantom; - group.RootPart.IsAttachment = true; + group.IsAttachment = true; } // 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 09c0ebb17f..22ffcd6335 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 if (grp.IsAttachment) { - if (grp.GetAttachmentPoint() > 30) // HUD + if (grp.AttachmentPoint > 30) // HUD { if (sp.ControllingClient.AgentId != grp.OwnerID) return; @@ -115,7 +115,7 @@ namespace OpenSim.Region.CoreModules.World.Sound { SceneObjectGroup grp = part.ParentGroup; - if (grp.IsAttachment && grp.GetAttachmentPoint() > 30) + if (grp.IsAttachment && grp.AttachmentPoint > 30) { objectID = ownerID; parentID = ownerID; diff --git a/OpenSim/Region/Framework/Scenes/Prioritizer.cs b/OpenSim/Region/Framework/Scenes/Prioritizer.cs index 2a7675534b..33407ec842 100644 --- a/OpenSim/Region/Framework/Scenes/Prioritizer.cs +++ b/OpenSim/Region/Framework/Scenes/Prioritizer.cs @@ -122,7 +122,7 @@ namespace OpenSim.Region.Framework.Scenes if (entity is SceneObjectPart) { SceneObjectPart sop = (SceneObjectPart)entity; - if (sop.ParentGroup.RootPart.IsAttachment && client.AgentId == sop.ParentGroup.AttachedAvatar) + if (sop.ParentGroup.IsAttachment && client.AgentId == sop.ParentGroup.AttachedAvatar) return 1; } @@ -135,7 +135,7 @@ namespace OpenSim.Region.Framework.Scenes if (entity is SceneObjectPart) { SceneObjectPart sop = (SceneObjectPart)entity; - if (sop.ParentGroup.RootPart.IsAttachment && client.AgentId == sop.ParentGroup.AttachedAvatar) + if (sop.ParentGroup.IsAttachment && client.AgentId == sop.ParentGroup.AttachedAvatar) return 1; } @@ -148,7 +148,7 @@ namespace OpenSim.Region.Framework.Scenes if (entity is SceneObjectPart) { SceneObjectPart sop = (SceneObjectPart)entity; - if (sop.ParentGroup.RootPart.IsAttachment && client.AgentId == sop.ParentGroup.AttachedAvatar) + if (sop.ParentGroup.IsAttachment && client.AgentId == sop.ParentGroup.AttachedAvatar) return 1; } @@ -171,7 +171,7 @@ namespace OpenSim.Region.Framework.Scenes if (entity is SceneObjectPart) { // Attachments are high priority, - if (((SceneObjectPart)entity).ParentGroup.RootPart.IsAttachment) + if (((SceneObjectPart)entity).ParentGroup.IsAttachment) return 1; // 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 9358e7b3d3..addc20c811 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 // Retrieve group SceneObjectPart part = GetSceneObjectPart(primId); + if (part == null) + return new ArrayList(); SceneObjectGroup group = part.ParentGroup; if (null == group) { @@ -967,6 +969,8 @@ namespace OpenSim.Region.Framework.Scenes public void RemoveTaskInventory(IClientAPI remoteClient, UUID itemID, uint localID) { SceneObjectPart part = GetSceneObjectPart(localID); + if (part == null) + return; SceneObjectGroup group = part.ParentGroup; if (group != null) { @@ -2028,6 +2032,8 @@ namespace OpenSim.Region.Framework.Scenes foreach (uint localID in localIDs) { SceneObjectPart part = GetSceneObjectPart(localID); + if (part == null) + continue; if (!groups.Contains(part.ParentGroup)) groups.Add(part.ParentGroup); } @@ -2073,6 +2079,8 @@ namespace OpenSim.Region.Framework.Scenes foreach (uint localID in localIDs) { SceneObjectPart part = GetSceneObjectPart(localID); + if (part == null) + continue; part.GetProperties(remoteClient); } } diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 513c0ea7a8..45d1a0ecdf 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -4223,7 +4223,7 @@ namespace OpenSim.Region.Framework.Scenes // their scripts will actually run. // -- Leaf, Tue Aug 12 14:17:05 EDT 2008 SceneObjectPart parent = part.ParentGroup.RootPart; - if (parent != null && parent.IsAttachment) + if (parent != null && part.ParentGroup.IsAttachment) return ScriptDanger(parent, parent.GetWorldPosition()); else return ScriptDanger(part, part.GetWorldPosition()); @@ -5030,7 +5030,7 @@ namespace OpenSim.Region.Framework.Scenes delete = true; } - if (delete && !rootPart.IsAttachment && !deletes.Contains(g)) + if (delete && !g.IsAttachment && !deletes.Contains(g)) deletes.Add(g); }); break; diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index f40b373e15..058258695d 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1546,8 +1546,11 @@ namespace OpenSim.Region.Framework.Scenes if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId)) { SceneObjectPart part = m_parentScene.GetSceneObjectPart(primLocalID); - part.ClickAction = Convert.ToByte(clickAction); - group.HasGroupChanged = true; + if (part != null) + { + part.ClickAction = Convert.ToByte(clickAction); + group.HasGroupChanged = true; + } } } } @@ -1560,8 +1563,11 @@ namespace OpenSim.Region.Framework.Scenes if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId)) { SceneObjectPart part = m_parentScene.GetSceneObjectPart(primLocalID); - part.Material = Convert.ToByte(material); - group.HasGroupChanged = true; + if (part != null) + { + part.Material = Convert.ToByte(material); + group.HasGroupChanged = true; + } } } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index fada68863f..c453366050 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -146,27 +146,11 @@ namespace OpenSim.Region.Framework.Scenes return true; return false; } - + /// /// Is this scene object acting as an attachment? /// - /// - /// We return false if the group has already been deleted. - /// - /// TODO: At the moment set must be done on the part itself. There may be a case for doing it here since I - /// presume either all or no parts in a linkset can be part of an attachment (in which - /// case the value would get proprogated down into all the descendent parts). - /// - public bool IsAttachment - { - get - { - if (!IsDeleted) - return m_rootPart.IsAttachment; - - return false; - } - } + public bool IsAttachment { get; set; } /// /// The avatar to which this scene object is attached. @@ -176,6 +160,31 @@ namespace OpenSim.Region.Framework.Scenes /// public UUID AttachedAvatar { get; set; } + /// + /// Attachment point of this scene object to an avatar. + /// + /// + /// 0 if we're not attached to anything + /// + public uint AttachmentPoint + { + get + { + return m_rootPart.Shape.State; + } + + set + { + IsAttachment = value != 0; + m_rootPart.Shape.State = (byte)value; + } + } + + public void ClearPartAttachmentData() + { + AttachmentPoint = 0; + } + /// /// Is this scene object phantom? /// @@ -354,11 +363,13 @@ namespace OpenSim.Region.Framework.Scenes /// /// Check both the attachment property and the relevant properties of the underlying root part. /// + /// /// This is necessary in some cases, particularly when a scene object has just crossed into a region and doesn't /// have the IsAttachment property yet checked. /// /// FIXME: However, this should be fixed so that this property /// propertly reflects the underlying status. + /// /// public bool IsAttachmentCheckFull() { @@ -982,23 +993,6 @@ namespace OpenSim.Region.Framework.Scenes } } - public byte GetAttachmentPoint() - { - return m_rootPart.Shape.State; - } - - public void SetAttachmentPoint(byte point) - { - SceneObjectPart[] parts = m_parts.GetArray(); - for (int i = 0; i < parts.Length; i++) - parts[i].SetAttachmentPoint(point); - } - - public void ClearPartAttachmentData() - { - SetAttachmentPoint((Byte)0); - } - /// /// /// @@ -1424,16 +1418,16 @@ namespace OpenSim.Region.Framework.Scenes // This is only necessary when userExposed is false! - bool previousAttachmentStatus = dupe.RootPart.IsAttachment; + bool previousAttachmentStatus = dupe.IsAttachment; if (!userExposed) - dupe.RootPart.IsAttachment = true; + dupe.IsAttachment = true; dupe.AbsolutePosition = new Vector3(AbsolutePosition.X, AbsolutePosition.Y, AbsolutePosition.Z); if (!userExposed) { - dupe.RootPart.IsAttachment = previousAttachmentStatus; + dupe.IsAttachment = previousAttachmentStatus; } dupe.CopyRootPart(m_rootPart, OwnerID, GroupID, userExposed); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index e510611156..71023a9a43 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -213,10 +213,7 @@ namespace OpenSim.Region.Framework.Scenes { get { return m_fromUserInventoryItemID; } } - - public bool IsAttachment; - public scriptEvents AggregateScriptEvents; @@ -224,9 +221,6 @@ namespace OpenSim.Region.Framework.Scenes public Vector3 AttachedPos; - public uint AttachmentPoint; - - public Vector3 RotationAxis = Vector3.One; @@ -723,7 +717,7 @@ namespace OpenSim.Region.Framework.Scenes m_groupPosition = actor.Position; } - if (IsAttachment) + if (m_parentGroup.IsAttachment) { ScenePresence sp = m_parentGroup.Scene.GetScenePresence(ParentGroup.AttachedAvatar); if (sp != null) @@ -807,7 +801,7 @@ namespace OpenSim.Region.Framework.Scenes { if (IsRoot) { - if (IsAttachment) + if (m_parentGroup.IsAttachment) return AttachedPos; else return AbsolutePosition; @@ -1090,7 +1084,7 @@ namespace OpenSim.Region.Framework.Scenes { get { - if (IsAttachment) + if (m_parentGroup.IsAttachment) return GroupPosition; return m_offsetPosition + m_groupPosition; @@ -1588,7 +1582,7 @@ namespace OpenSim.Region.Framework.Scenes // 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 // or flexible - if (!isPhantom && !IsAttachment && !(Shape.PathCurve == (byte) Extrusion.Flexible)) + if (!isPhantom && !m_parentGroup.IsAttachment && !(Shape.PathCurve == (byte) Extrusion.Flexible)) { try { @@ -2880,7 +2874,7 @@ namespace OpenSim.Region.Framework.Scenes public void rotLookAt(Quaternion target, float strength, float damping) { - if (IsAttachment) + if (m_parentGroup.IsAttachment) { /* ScenePresence avatar = m_scene.GetScenePresence(rootpart.AttachedAvatar); @@ -3014,7 +3008,7 @@ namespace OpenSim.Region.Framework.Scenes if (IsRoot) { - if (IsAttachment) + if (m_parentGroup.IsAttachment) { SendFullUpdateToClient(remoteClient, AttachedPos, clientFlags); } @@ -3076,7 +3070,7 @@ namespace OpenSim.Region.Framework.Scenes { // Suppress full updates during attachment editing // - if (ParentGroup.IsSelected && IsAttachment) + if (ParentGroup.IsSelected && ParentGroup.IsAttachment) return; if (ParentGroup.IsDeleted) @@ -3254,26 +3248,6 @@ namespace OpenSim.Region.Framework.Scenes }); } - public void SetAttachmentPoint(uint AttachmentPoint) - { - this.AttachmentPoint = AttachmentPoint; - - if (AttachmentPoint != 0) - { - IsAttachment = true; - } - else - { - IsAttachment = false; - } - - // save the attachment point. - //if (AttachmentPoint != 0) - //{ - m_shape.State = (byte)AttachmentPoint; - //} - } - public void SetAxisRotation(int axis, int rotate) { if (m_parentGroup != null) @@ -4497,7 +4471,9 @@ namespace OpenSim.Region.Framework.Scenes } } - if (SetPhantom || IsAttachment || (Shape.PathCurve == (byte)Extrusion.Flexible)) // note: this may have been changed above in the case of joints + if (SetPhantom + || ParentGroup.IsAttachment + || (Shape.PathCurve == (byte)Extrusion.Flexible)) // note: this may have been changed above in the case of joints { AddFlag(PrimFlags.Phantom); if (PhysActor != null) @@ -4928,7 +4904,7 @@ namespace OpenSim.Region.Framework.Scenes if (ParentGroup == null || ParentGroup.IsDeleted) return; - if (IsAttachment && ParentGroup.RootPart != this) + if (ParentGroup.IsAttachment && ParentGroup.RootPart != this) return; // 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 3b60f8c6da..108089e870 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -201,7 +201,7 @@ namespace OpenSim.Region.Framework.Scenes // Don't let this set the HasGroupChanged flag for attachments // as this happens during rez and we don't want a new asset // for each attachment each time - if (!m_part.ParentGroup.RootPart.IsAttachment) + if (!m_part.ParentGroup.IsAttachment) { HasInventoryChanged = true; m_part.ParentGroup.HasGroupChanged = true; diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index fc89473230..4148d4b2e8 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -965,6 +965,11 @@ namespace OpenSim.Region.Framework.Scenes presence.Animator.SendAnimPackToClient(ControllingClient); }); + // If we don't reset the movement flag here, an avatar that crosses to a neighbouring sim and returns will + // stall on the border crossing since the existing child agent will still have the last movement + // recorded, which stops the input from being processed. + m_movementflag = 0; + m_scene.EventManager.TriggerOnMakeRootAgent(this); } @@ -1247,6 +1252,8 @@ namespace OpenSim.Region.Framework.Scenes /// public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) { +// m_log.DebugFormat("[SCENE PRESENCE]: Received agent update from {0}", remoteClient.Name); + //if (m_isChildAgent) //{ // // m_log.Debug("DEBUG: HandleAgentUpdate: child agent"); @@ -1445,6 +1452,8 @@ namespace OpenSim.Region.Framework.Scenes { m_movementflag |= (byte)nudgehack; } + +// m_log.DebugFormat("[SCENE PRESENCE]: Updating m_movementflag for {0} with {1}", Name, DCF); m_movementflag += (byte)(uint)DCF; update_movementflag = true; } @@ -1456,6 +1465,7 @@ namespace OpenSim.Region.Framework.Scenes && ((m_movementflag & (byte)nudgehack) == nudgehack)) ) // This or is for Nudge forward { +// m_log.DebugFormat("[SCENE PRESENCE]: Updating m_movementflag for {0} with lack of {1}", Name, DCF); m_movementflag -= ((byte)(uint)DCF); update_movementflag = true; @@ -1520,12 +1530,21 @@ namespace OpenSim.Region.Framework.Scenes // which occurs later in the main scene loop if (update_movementflag || (update_rotation && DCFlagKeyPressed)) { - // m_log.DebugFormat("{0} {1}", update_movementflag, (update_rotation && DCFlagKeyPressed)); - // m_log.DebugFormat( - // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); +// m_log.DebugFormat( +// "[SCENE PRESENCE]: In {0} adding velocity of {1} to {2}, umf = {3}, ur = {4}", +// m_scene.RegionInfo.RegionName, agent_control_v3, Name, update_movementflag, update_rotation); AddNewMovement(agent_control_v3); } +// else +// { +// if (!update_movementflag) +// { +// m_log.DebugFormat( +// "[SCENE PRESENCE]: In {0} ignoring requested update of {1} for {2} as update_movementflag = false", +// m_scene.RegionInfo.RegionName, agent_control_v3, Name); +// } +// } if (update_movementflag && m_parentID == 0) Animator.UpdateMovementAnimations(); @@ -3178,7 +3197,7 @@ namespace OpenSim.Region.Framework.Scenes ISceneObject clone = sog.CloneForNewScene(); // Attachment module assumes that GroupPosition holds the offsets...! ((SceneObjectGroup)clone).RootPart.GroupPosition = sog.RootPart.AttachedPos; - ((SceneObjectGroup)clone).RootPart.IsAttachment = false; + ((SceneObjectGroup)clone).IsAttachment = false; cAgent.AttachmentObjects.Add(clone); string state = sog.GetStateSnapshot(); cAgent.AttachmentObjectStates.Add(state); @@ -3477,7 +3496,7 @@ namespace OpenSim.Region.Framework.Scenes { foreach (SceneObjectGroup so in m_attachments) { - if (attachmentPoint == so.RootPart.AttachmentPoint) + if (attachmentPoint == so.AttachmentPoint) attachments.Add(so); } } @@ -3869,12 +3888,12 @@ namespace OpenSim.Region.Framework.Scenes { if (grp.HasGroupChanged) // Resizer scripts? { - grp.RootPart.IsAttachment = false; + grp.IsAttachment = false; grp.AbsolutePosition = grp.RootPart.AttachedPos; // grp.DetachToInventoryPrep(); attachmentsModule.UpdateKnownItem(ControllingClient, grp, grp.GetFromItemID(), grp.OwnerID); - grp.RootPart.IsAttachment = true; + grp.IsAttachment = true; } } } diff --git a/OpenSim/Region/Framework/Scenes/SceneViewer.cs b/OpenSim/Region/Framework/Scenes/SceneViewer.cs index 7c067ca148..997845b4e2 100644 --- a/OpenSim/Region/Framework/Scenes/SceneViewer.cs +++ b/OpenSim/Region/Framework/Scenes/SceneViewer.cs @@ -120,8 +120,7 @@ namespace OpenSim.Region.Framework.Scenes // We deal with the possibility that two updates occur at // the same unix time at the update point itself. - if ((update.LastFullUpdateTime < part.TimeStampFull) || - part.IsAttachment) + if ((update.LastFullUpdateTime < part.TimeStampFull) || part.ParentGroup.IsAttachment) { // m_log.DebugFormat( // "[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 1181b8ddd8..3a9ca1bd34 100644 --- a/OpenSim/Region/Physics/Manager/IMesher.cs +++ b/OpenSim/Region/Physics/Manager/IMesher.cs @@ -38,6 +38,17 @@ namespace OpenSim.Region.Physics.Manager IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical); } + // Values for level of detail to be passed to the mesher. + // Values origionally chosen for the LOD of sculpties (the sqrt(width*heigth) of sculpt texture) + // Lower level of detail reduces the number of vertices used to represent the meshed shape. + public enum LevelOfDetail + { + High = 32, + Medium = 16, + Low = 8, + VeryLow = 4 + } + public interface IVertex { } diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs index e81b98238d..53d5e4c33f 100644 --- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs @@ -193,67 +193,6 @@ namespace OpenSim.Region.Physics.Meshing m_log.Error("****** PrimMesh Parameters ******\n" + primMesh.ParamsToDisplayString()); } - private ulong GetMeshKey(PrimitiveBaseShape pbs, Vector3 size, float lod) - { - ulong hash = 5381; - - hash = djb2(hash, pbs.PathCurve); - hash = djb2(hash, (byte)((byte)pbs.HollowShape | (byte)pbs.ProfileShape)); - hash = djb2(hash, pbs.PathBegin); - hash = djb2(hash, pbs.PathEnd); - hash = djb2(hash, pbs.PathScaleX); - hash = djb2(hash, pbs.PathScaleY); - hash = djb2(hash, pbs.PathShearX); - hash = djb2(hash, pbs.PathShearY); - hash = djb2(hash, (byte)pbs.PathTwist); - hash = djb2(hash, (byte)pbs.PathTwistBegin); - hash = djb2(hash, (byte)pbs.PathRadiusOffset); - hash = djb2(hash, (byte)pbs.PathTaperX); - hash = djb2(hash, (byte)pbs.PathTaperY); - hash = djb2(hash, pbs.PathRevolutions); - hash = djb2(hash, (byte)pbs.PathSkew); - hash = djb2(hash, pbs.ProfileBegin); - hash = djb2(hash, pbs.ProfileEnd); - hash = djb2(hash, pbs.ProfileHollow); - - // TODO: Separate scale out from the primitive shape data (after - // scaling is supported at the physics engine level) - byte[] scaleBytes = size.GetBytes(); - for (int i = 0; i < scaleBytes.Length; i++) - hash = djb2(hash, scaleBytes[i]); - - // Include LOD in hash, accounting for endianness - byte[] lodBytes = new byte[4]; - Buffer.BlockCopy(BitConverter.GetBytes(lod), 0, lodBytes, 0, 4); - if (!BitConverter.IsLittleEndian) - { - Array.Reverse(lodBytes, 0, 4); - } - for (int i = 0; i < lodBytes.Length; i++) - hash = djb2(hash, lodBytes[i]); - - // include sculpt UUID - if (pbs.SculptEntry) - { - scaleBytes = pbs.SculptTexture.GetBytes(); - for (int i = 0; i < scaleBytes.Length; i++) - hash = djb2(hash, scaleBytes[i]); - } - - return hash; - } - - private ulong djb2(ulong hash, byte c) - { - return ((hash << 5) + hash) + (ulong)c; - } - - private ulong djb2(ulong hash, ushort c) - { - hash = ((hash << 5) + hash) + (ulong)((byte)c); - return ((hash << 5) + hash) + (ulong)(c >> 8); - } - /// /// Add a submesh to an existing list of coords and faces. /// @@ -336,7 +275,7 @@ namespace OpenSim.Region.Physics.Meshing } else { - if (!GenerateCoordsAndFacesFromPrimShapeData(primName, primShape, size, out coords, out faces)) + if (!GenerateCoordsAndFacesFromPrimShapeData(primName, primShape, size, lod, out coords, out faces)) return null; } @@ -616,7 +555,7 @@ namespace OpenSim.Region.Physics.Meshing /// Faces are added to this list by the method. /// true if coords and faces were successfully generated, false if not private bool GenerateCoordsAndFacesFromPrimShapeData( - string primName, PrimitiveBaseShape primShape, Vector3 size, out List coords, out List faces) + string primName, PrimitiveBaseShape primShape, Vector3 size, float lod, out List coords, out List faces) { PrimMesh primMesh; coords = new List(); @@ -636,13 +575,30 @@ namespace OpenSim.Region.Physics.Meshing profileHollow = 0.95f; int sides = 4; + LevelOfDetail iLOD = (LevelOfDetail)lod; if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle) sides = 3; else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.Circle) - sides = 24; + { + switch (iLOD) + { + case LevelOfDetail.High: sides = 24; break; + case LevelOfDetail.Medium: sides = 12; break; + case LevelOfDetail.Low: sides = 6; break; + case LevelOfDetail.VeryLow: sides = 3; break; + default: sides = 24; break; + } + } else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle) { // half circle, prim is a sphere - sides = 24; + switch (iLOD) + { + case LevelOfDetail.High: sides = 24; break; + case LevelOfDetail.Medium: sides = 12; break; + case LevelOfDetail.Low: sides = 6; break; + case LevelOfDetail.VeryLow: sides = 3; break; + default: sides = 24; break; + } profileBegin = 0.5f * profileBegin + 0.5f; profileEnd = 0.5f * profileEnd + 0.5f; @@ -650,7 +606,16 @@ namespace OpenSim.Region.Physics.Meshing int hollowSides = sides; if (primShape.HollowShape == HollowShape.Circle) - hollowSides = 24; + { + switch (iLOD) + { + case LevelOfDetail.High: hollowSides = 24; break; + case LevelOfDetail.Medium: hollowSides = 12; break; + case LevelOfDetail.Low: hollowSides = 6; break; + case LevelOfDetail.VeryLow: hollowSides = 3; break; + default: hollowSides = 24; break; + } + } else if (primShape.HollowShape == HollowShape.Square) hollowSides = 4; else if (primShape.HollowShape == HollowShape.Triangle) @@ -751,7 +716,7 @@ namespace OpenSim.Region.Physics.Meshing // If this mesh has been created already, return it instead of creating another copy // For large regions with 100k+ prims and hundreds of copies of each, this can save a GB or more of memory - key = GetMeshKey(primShape, size, lod); + key = primShape.GetMeshKey(size, lod); if (m_uniqueMeshes.TryGetValue(key, out mesh)) return mesh; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 81f1f3883f..a7f08d90cb 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 if (part.ParentGroup.RootPart == part) { - if ((targetPos.z < ground) && disable_underground_movement && m_host.AttachmentPoint == 0) + if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0) targetPos.z = ground; SceneObjectGroup parent = part.ParentGroup; LSL_Vector real_vec = SetPosAdjust(currentPos, targetPos); @@ -2097,7 +2097,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api Quaternion q; if (part.LinkNum == 0 || part.LinkNum == 1) // unlinked or root prim { - if (part.ParentGroup.RootPart.AttachmentPoint != 0) + if (part.ParentGroup.AttachmentPoint != 0) { ScenePresence avatar = World.GetScenePresence(part.ParentGroup.AttachedAvatar); if (avatar != null) @@ -2241,7 +2241,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api Vector3 vel; - if (m_host.IsAttachment) + if (m_host.ParentGroup.IsAttachment) { ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); vel = avatar.Velocity; @@ -2997,7 +2997,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - if (m_host.ParentGroup.RootPart.AttachmentPoint == 0) + if (m_host.ParentGroup.AttachmentPoint == 0) return; TaskInventoryItem item; @@ -3587,7 +3587,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api SceneObjectPart targetPart = World.GetSceneObjectPart((UUID)targetID); - if (targetPart.ParentGroup.RootPart.AttachmentPoint != 0) + if (targetPart.ParentGroup.AttachmentPoint != 0) return; // Fail silently if attached SceneObjectGroup parentPrim = null, childPrim = null; @@ -3640,7 +3640,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api SceneObjectGroup parentPrim = m_host.ParentGroup; - if (parentPrim.RootPart.AttachmentPoint != 0) + if (parentPrim.AttachmentPoint != 0) return; // Fail silently if attached SceneObjectPart childPrim = null; @@ -3710,7 +3710,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); SceneObjectGroup parentPrim = m_host.ParentGroup; - if (parentPrim.RootPart.AttachmentPoint != 0) + if (parentPrim.AttachmentPoint != 0) return; // Fail silently if attached List parts = new List(parentPrim.Parts); @@ -4349,7 +4349,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return; // Object not pushable. Not an attachment and has no physics component - if (!pusheeob.IsAttachment && pusheeob.PhysActor == null) + if (!pusheeob.ParentGroup.IsAttachment && pusheeob.PhysActor == null) return; PusheePos = pusheeob.AbsolutePosition; @@ -5857,7 +5857,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Integer llGetAttached() { m_host.AddScriptLPS(1); - return m_host.ParentGroup.RootPart.AttachmentPoint; + return m_host.ParentGroup.AttachmentPoint; } public LSL_Integer llGetFreeMemory() @@ -7458,7 +7458,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); Quaternion q; - if (m_host.ParentGroup.RootPart.AttachmentPoint != 0) + if (m_host.ParentGroup.AttachmentPoint != 0) { ScenePresence avatar = World.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 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 bf74760f40..4ac7f8bdbd 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 float dz; Quaternion q = SensePoint.RotationOffset; - if (SensePoint.ParentGroup.RootPart.IsAttachment) + if (SensePoint.ParentGroup.IsAttachment) { // In attachments, the sensor cone always orients with the // avatar rotation. This may include a nonzero elevation if @@ -352,7 +352,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins objtype = 0; part = ((SceneObjectGroup)ent).RootPart; - if (part.AttachmentPoint != 0) // Attached so ignore + if (part.ParentGroup.AttachmentPoint != 0) // Attached so ignore continue; if (part.Inventory.ContainsScripts()) @@ -423,7 +423,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins Vector3 fromRegionPos = SensePoint.AbsolutePosition; Quaternion q = SensePoint.RotationOffset; - if (SensePoint.ParentGroup.RootPart.IsAttachment) + if (SensePoint.ParentGroup.IsAttachment) { // In attachments, the sensor cone always orients with the // avatar rotation. This may include a nonzero elevation if @@ -435,7 +435,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r); double mag_fwd = LSL_Types.Vector3.Mag(forward_dir); - bool attached = (SensePoint.AttachmentPoint != 0); + bool attached = (SensePoint.ParentGroup.AttachmentPoint != 0); Vector3 toRegionPos; double dis;