Esempio n. 1
0
        private uint ComputeAngleDistancePriority(ScenePresence presence, ISceneEntity entity)
        {
            // And convert the distance to a priority queue, this computation gives queues
            // at 10, 20, 40, 80, 160, 320, 640, and 1280m
//            uint minpqueue = PriorityQueue.NumberOfImmediateQueues;
            uint maxqueue = PriorityQueue.NumberOfQueues - PriorityQueue.NumberOfImmediateQueues - 1;
//            uint pqueue = minpqueue;
            uint  pqueue = PriorityQueue.NumberOfImmediateQueues;
            float distance;

            Vector3 presencePos = presence.AbsolutePosition;

            if (entity is ScenePresence)
            {
                ScenePresence sp = entity as ScenePresence;
                distance  = Vector3.Distance(presencePos, sp.AbsolutePosition);
                distance *= 0.5f;
            }
            else
            {
                SceneObjectGroup group   = (entity as SceneObjectPart).ParentGroup;
                float            bradius = group.GetBoundsRadius();
                Vector3          grppos  = group.AbsolutePosition + group.getBoundsCenter();
                distance  = Vector3.Distance(presencePos, grppos);
                distance -= bradius;
                distance *= group.getAreaFactor();
                if (group.IsAttachment)
                {
                    distance *= 0.5f;
                }
                else if (group.UsesPhysics)
                {
                    distance *= 0.6f;
                }
                else if (group.GetSittingAvatarsCount() > 0)
                {
                    distance *= 0.5f;
                }
            }

            if (distance > 10f)
            {
                float tmp = (float)Math.Log(distance) * 1.442695f - 3.321928f;
                // for a map identical to original:
                // now
                // 1st constant is 1/(log(2)) (natural log) so we get log2(distance)
                // 2st constant makes it be log2(distance/10)

                pqueue += (uint)tmp;
                if (pqueue > maxqueue)
                {
                    pqueue = maxqueue;
                }
            }

            return(pqueue);
        }
        /// <summary>
        /// Internal method which actually does all the work for attaching an object.
        /// </summary>
        /// <returns>The object attached.</returns>
        /// <param name='sp'></param>
        /// <param name='group'>The object to attach.</param>
        /// <param name='attachmentPt'></param>
        /// <param name='silent'></param>
        /// <param name='addToInventory'>If true then add object to user inventory.</param>
        /// <param name='resumeScripts'>If true then scripts are resumed on the attached object.</param>
        /// <param name='append'>Append to attachment point rather than replace.</param>
        private bool AttachObjectInternal(
            IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool addToInventory, bool resumeScripts, bool append)
        {
            if (group.GetSittingAvatarsCount() != 0)
            {
                if (DebugLevel > 0)
                    m_log.WarnFormat(
                        "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since {4} avatars are still sitting on it",
                        group.Name, group.LocalId, sp.Name, attachmentPt, group.GetSittingAvatarsCount());

                return false;
            }

            Vector3 attachPos = group.AbsolutePosition;
            // 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 != (uint)AttachmentPoint.Default && attachmentPt != group.AttachmentPoint)
            {
                attachPos = Vector3.Zero;
            }

            // if the attachment point is the same as previous, make sure we get the saved
            // position info.
            if (attachmentPt != 0 && attachmentPt == group.RootPart.Shape.LastAttachPoint)
            {
                attachPos = group.RootPart.AttachedPos;
            }

            // AttachmentPt 0 means the client chose to 'wear' the attachment.
            if (attachmentPt == (uint)AttachmentPoint.Default)
            {
                // Check object for stored attachment point
                attachmentPt = group.AttachmentPoint;
            }

            // if we didn't find an attach point, look for where it was last attached
            if (attachmentPt == 0)
            {
                attachmentPt = (uint)group.RootPart.Shape.LastAttachPoint;
                attachPos = group.RootPart.AttachedPos;
                group.HasGroupChanged = true;
            }

            // if we still didn't find a suitable attachment point.......
            if (attachmentPt == 0)
            {
                // Stick it on left hand with Zero Offset from the attachment point.
                attachmentPt = (uint)AttachmentPoint.LeftHand;
                attachPos = Vector3.Zero;
            }

            group.AttachmentPoint = attachmentPt;
            group.AbsolutePosition = attachPos;

            List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt);

            if (attachments.Contains(group))
            {
                if (DebugLevel > 0)
                    m_log.WarnFormat(
                        "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached",
                        group.Name, group.LocalId, sp.Name, attachmentPt);

                return false;
            }

            // If we already have 5, remove the oldest until only 4 are left. Skip over temp ones
            while (attachments.Count >= 5)
            {
                if (attachments[0].FromItemID != UUID.Zero)
                    DetachSingleAttachmentToInv(sp, attachments[0]);
                attachments.RemoveAt(0);
            }

            // If we're not appending, remove the rest as well
            if (attachments.Count != 0 && !append)
            {
                foreach (SceneObjectGroup g in attachments)
                {
                    if (g.FromItemID != UUID.Zero)
                        DetachSingleAttachmentToInv(sp, g);
                }
            }

            lock (sp.AttachmentsSyncLock)
            {
                if (addToInventory && sp.PresenceType != PresenceType.Npc)
                    UpdateUserInventoryWithAttachment(sp, group, attachmentPt, append);
    
                AttachToAgent(sp, group, attachmentPt, attachPos, silent);

                if (resumeScripts)
                {
                    // Fire after attach, so we don't get messy perms dialogs
                    // 4 == AttachedRez
                    group.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4);
                    group.ResumeScripts();
                }

                // Do this last so that event listeners have access to all the effects of the attachment
                m_scene.EventManager.TriggerOnAttach(group.LocalId, group.FromItemID, sp.UUID);
            }

            return true;
        }
Esempio n. 3
0
        private bool AttachObjectInternal(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool temp)
        {
            lock (sp.AttachmentsSyncLock)
            {
//                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 (group.GetSittingAvatarsCount() != 0)
                {
//                    m_log.WarnFormat(
//                        "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since {4} avatars are still sitting on it",
//                        group.Name, group.LocalId, sp.Name, attachmentPt, group.GetSittingAvatarsCount());
    
                    return false;
                }
    
                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",
    //                    group.Name, group.LocalId, sp.Name, AttachmentPt);
    
                    return false;
                }
    
                Vector3 attachPos = group.AbsolutePosition;
    
                // 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;
                
                // 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 != group.AttachmentPoint)
                {
                    attachPos = Vector3.Zero;
                }
    
                // AttachmentPt 0 means the client chose to 'wear' the attachment.
                if (attachmentPt == 0)
                {
                    // Check object for stored attachment point
                    attachmentPt = group.AttachmentPoint;
                }
    
                // if we still didn't find a suitable attachment point.......
                if (attachmentPt == 0)
                {
                    // Stick it on left hand with Zero Offset from the attachment point.
                    attachmentPt = (uint)AttachmentPoint.LeftHand;
                    attachPos = Vector3.Zero;
                }
    
                group.AttachmentPoint = attachmentPt;
                group.AbsolutePosition = attachPos;

                if (sp.PresenceType != PresenceType.Npc)
                    UpdateUserInventoryWithAttachment(sp, group, attachmentPt, temp);
    
                AttachToAgent(sp, group, attachmentPt, attachPos, silent);
            }

            return true;
        }
Esempio n. 4
0
        private int ComputeAngleDistancePriority(ScenePresence presence, ISceneEntity entity)
        {
            int   pqueue = PriorityQueue.NumberOfImmediateQueues;
            float distance;

            Vector3 presencePos = presence.AbsolutePosition;

            if (entity is ScenePresence)
            {
                ScenePresence sp = entity as ScenePresence;
                distance = Vector3.DistanceSquared(presencePos, sp.AbsolutePosition);
                if (distance > 400f)
                {
                    float tmp = (float)Math.Log(distance) * 0.7213475f - 4.321928f;
                    pqueue += (int)tmp;
                }
                return(pqueue);
            }

            SceneObjectPart  sop   = entity as SceneObjectPart;
            SceneObjectGroup group = sop.ParentGroup;

            if (presence.ParentPart != null)
            {
                if (presence.ParentPart.ParentGroup == group)
                {
                    return(pqueue);
                }
            }

            if (group.IsAttachment)
            {
                if (group.RootPart.LocalId == presence.LocalId)
                {
                    return(pqueue);
                }

                distance = Vector3.DistanceSquared(presencePos, group.AbsolutePosition);
                if (distance > 400f)
                {
                    float tmp = (float)Math.Log(distance) * 0.7213475f - 4.321928f;
                    pqueue += (int)tmp;
                }
                return(pqueue);
            }

            float   bradius = group.GetBoundsRadius();
            Vector3 grppos  = group.getCenterOffset();

            distance  = Vector3.Distance(presencePos, grppos);
            distance -= bradius;
            if (distance < 0)
            {
                return(pqueue);
            }

            distance *= group.getAreaFactor();
            if (group.IsAttachment)
            {
                distance *= 0.5f;
            }
            else if (group.UsesPhysics)
            {
                distance *= 0.6f;
            }
            else if (group.GetSittingAvatarsCount() > 0)
            {
                distance *= 0.5f;
            }

            if (distance > 10f)
            {
                float tmp = (float)Math.Log(distance) * 1.442695f - 3.321928f;
                // for a map identical to original:
                // now
                // 1st constant is 1/(log(2)) (natural log) so we get log2(distance)
                // 2st constant makes it be log2(distance/10)
                pqueue += (int)tmp;
            }

            return(pqueue);
        }