예제 #1
0
        public bool DistanceCulling(IScenePresence client, IEntity entity, IScene scene)
        {
            float DD = client.DrawDistance;

            if (DD < 32) //Limit to a small distance
            {
                DD = 32;
            }
            if (DD > scene.RegionInfo.RegionSizeX &&
                DD > scene.RegionInfo.RegionSizeY)
            {
                return(true); //Its larger than the region, no culling check even necessary
            }
            Vector3 posToCheckFrom       = client.GetAbsolutePosition();
            Vector3 entityPosToCheckFrom = Vector3.Zero;
            bool    doHeavyCulling       = false;

            if (entity is ISceneEntity)
            {
                doHeavyCulling = true;
                //We need to check whether this object is an attachment, and if so, set it so that we check from the avatar's
                // position, rather than from the offset of the attachment
                ISceneEntity sEntity = (ISceneEntity)entity;
                if (sEntity.RootChild.IsAttachment)
                {
                    IScenePresence attachedAvatar = scene.GetScenePresence(sEntity.RootChild.AttachedAvatar);
                    if (attachedAvatar != null)
                    {
                        entityPosToCheckFrom = attachedAvatar.AbsolutePosition;
                    }
                }
                else
                {
                    entityPosToCheckFrom = sEntity.RootChild.GetGroupPosition();
                }
            }
            else if (entity is IScenePresence)
            {
                //We need to check whether this presence is sitting on anything, so that we can check from the object's
                // position, rather than the offset position of the object that the avatar is sitting on
                IScenePresence pEntity = (IScenePresence)entity;
                if (pEntity.Sitting)
                {
                    ISceneChildEntity sittingEntity = scene.GetSceneObjectPart(pEntity.SittingOnUUID);
                    if (sittingEntity != null)
                    {
                        entityPosToCheckFrom = sittingEntity.GetGroupPosition();
                    }
                }
                else
                {
                    entityPosToCheckFrom = pEntity.GetAbsolutePosition();
                }
            }
            //If the distance is greater than the clients draw distance, its out of range
            if (Vector3.DistanceSquared(posToCheckFrom, entityPosToCheckFrom) >
                DD * DD) //Use squares to make it faster than having to do the sqrt
            {
                if (!doHeavyCulling)
                {
                    return(false); //Don't do the hardcore checks
                }
                ISceneEntity childEntity = (entity as ISceneEntity);
                if (childEntity != null && HardCullingCheck(childEntity))
                {
                    #region Side culling check (X, Y, Z) plane checks

                    if (
                        Vector3.DistanceSquared(posToCheckFrom,
                                                entityPosToCheckFrom + new Vector3(childEntity.OOBsize.X, 0, 0)) <
                        DD * DD) //Use squares to make it faster than having to do the sqrt
                    {
                        return(true);
                    }
                    if (
                        Vector3.DistanceSquared(posToCheckFrom,
                                                entityPosToCheckFrom - new Vector3(childEntity.OOBsize.X, 0, 0)) <
                        DD * DD) //Use squares to make it faster than having to do the sqrt
                    {
                        return(true);
                    }
                    if (
                        Vector3.DistanceSquared(posToCheckFrom,
                                                entityPosToCheckFrom + new Vector3(0, childEntity.OOBsize.Y, 0)) <
                        DD * DD) //Use squares to make it faster than having to do the sqrt
                    {
                        return(true);
                    }
                    if (
                        Vector3.DistanceSquared(posToCheckFrom,
                                                entityPosToCheckFrom - new Vector3(0, childEntity.OOBsize.Y, 0)) <
                        DD * DD) //Use squares to make it faster than having to do the sqrt
                    {
                        return(true);
                    }
                    if (
                        Vector3.DistanceSquared(posToCheckFrom,
                                                entityPosToCheckFrom + new Vector3(0, 0, childEntity.OOBsize.Z)) <
                        DD * DD) //Use squares to make it faster than having to do the sqrt
                    {
                        return(true);
                    }
                    if (
                        Vector3.DistanceSquared(posToCheckFrom,
                                                entityPosToCheckFrom - new Vector3(0, 0, childEntity.OOBsize.Z)) <
                        DD * DD) //Use squares to make it faster than having to do the sqrt
                    {
                        return(true);
                    }

                    #endregion

                    #region Corner checks ((x,y),(-x,-y),(x,-y),(-x,y), (y,z),(-y,-z),(y,-z),(-y,z), (x,z),(-x,-z),(x,-z),(-x,z))

                    if (
                        Vector3.DistanceSquared(posToCheckFrom,
                                                entityPosToCheckFrom +
                                                new Vector3(childEntity.OOBsize.X, childEntity.OOBsize.Y, 0)) <
                        DD * DD) //Use squares to make it faster than having to do the sqrt
                    {
                        return(true);
                    }
                    if (
                        Vector3.DistanceSquared(posToCheckFrom,
                                                entityPosToCheckFrom -
                                                new Vector3(childEntity.OOBsize.X, childEntity.OOBsize.Y, 0)) <
                        DD * DD) //Use squares to make it faster than having to do the sqrt
                    {
                        return(true);
                    }
                    if (
                        Vector3.DistanceSquared(posToCheckFrom,
                                                entityPosToCheckFrom +
                                                new Vector3(childEntity.OOBsize.X, -childEntity.OOBsize.Y, 0)) <
                        DD * DD) //Use squares to make it faster than having to do the sqrt
                    {
                        return(true);
                    }
                    if (
                        Vector3.DistanceSquared(posToCheckFrom,
                                                entityPosToCheckFrom -
                                                new Vector3(childEntity.OOBsize.X, -childEntity.OOBsize.Y, 0)) <
                        DD * DD) //Use squares to make it faster than having to do the sqrt
                    {
                        return(true);
                    }
                    if (
                        Vector3.DistanceSquared(posToCheckFrom,
                                                entityPosToCheckFrom +
                                                new Vector3(0, childEntity.OOBsize.Y, childEntity.OOBsize.Z)) <
                        DD * DD) //Use squares to make it faster than having to do the sqrt
                    {
                        return(true);
                    }
                    if (
                        Vector3.DistanceSquared(posToCheckFrom,
                                                entityPosToCheckFrom -
                                                new Vector3(0, childEntity.OOBsize.Y, childEntity.OOBsize.Z)) <
                        DD * DD) //Use squares to make it faster than having to do the sqrt
                    {
                        return(true);
                    }
                    if (
                        Vector3.DistanceSquared(posToCheckFrom,
                                                entityPosToCheckFrom +
                                                new Vector3(0, childEntity.OOBsize.Y, -childEntity.OOBsize.Z)) <
                        DD * DD) //Use squares to make it faster than having to do the sqrt
                    {
                        return(true);
                    }
                    if (
                        Vector3.DistanceSquared(posToCheckFrom,
                                                entityPosToCheckFrom -
                                                new Vector3(0, childEntity.OOBsize.Y, -childEntity.OOBsize.Z)) <
                        DD * DD) //Use squares to make it faster than having to do the sqrt
                    {
                        return(true);
                    }
                    if (
                        Vector3.DistanceSquared(posToCheckFrom,
                                                entityPosToCheckFrom +
                                                new Vector3(childEntity.OOBsize.X, 0, childEntity.OOBsize.Z)) <
                        DD * DD) //Use squares to make it faster than having to do the sqrt
                    {
                        return(true);
                    }
                    if (
                        Vector3.DistanceSquared(posToCheckFrom,
                                                entityPosToCheckFrom -
                                                new Vector3(childEntity.OOBsize.X, 0, childEntity.OOBsize.Z)) <
                        DD * DD) //Use squares to make it faster than having to do the sqrt
                    {
                        return(true);
                    }
                    if (
                        Vector3.DistanceSquared(posToCheckFrom,
                                                entityPosToCheckFrom +
                                                new Vector3(-childEntity.OOBsize.X, 0, childEntity.OOBsize.Z)) <
                        DD * DD) //Use squares to make it faster than having to do the sqrt
                    {
                        return(true);
                    }
                    if (
                        Vector3.DistanceSquared(posToCheckFrom,
                                                entityPosToCheckFrom -
                                                new Vector3(-childEntity.OOBsize.X, 0, childEntity.OOBsize.Z)) <
                        DD * DD) //Use squares to make it faster than having to do the sqrt
                    {
                        return(true);
                    }

                    #endregion
                }
                return(false);
            }

            return(true);
        }
예제 #2
0
        public bool DistanceCulling(IScenePresence client, IEntity entity, IScene scene)
        {
            float DD = client.DrawDistance;

            if (DD < 32) //Limit to a small distance
            {
                DD = 32;
            }
            if (DD > scene.RegionInfo.RegionSizeX &&
                DD > scene.RegionInfo.RegionSizeY)
            {
                return(true); //Its larger than the region, no culling check even necessary
            }
            Vector3 posToCheckFrom = client.GetAbsolutePosition();

            if (client.IsChildAgent)
            {
                if (m_cachedXOffset == 0 && m_cachedYOffset == 0) //Not found yet
                {
                    IAgentInfoService agentInfoService = scene.RequestModuleInterface <IAgentInfoService>();
                    if (agentInfoService != null)
                    {
                        UserInfo info = agentInfoService.GetUserInfo(client.UUID.ToString());
                        if (info != null)
                        {
                            GridRegion r = scene.GridService.GetRegionByUUID(scene.RegionInfo.ScopeID,
                                                                             info.CurrentRegionID);
                            if (r != null)
                            {
                                m_cachedXOffset = scene.RegionInfo.RegionLocX - r.RegionLocX;
                                m_cachedYOffset = scene.RegionInfo.RegionLocY - r.RegionLocY;
                            }
                        }
                    }
                }
                //We need to add the offset so that we can check from the right place in child regions
                if (m_cachedXOffset < 0)
                {
                    posToCheckFrom.X = scene.RegionInfo.RegionSizeX -
                                       (scene.RegionInfo.RegionSizeX + client.AbsolutePosition.X + m_cachedXOffset);
                }
                if (m_cachedYOffset < 0)
                {
                    posToCheckFrom.Y = scene.RegionInfo.RegionSizeY -
                                       (scene.RegionInfo.RegionSizeY + client.AbsolutePosition.Y + m_cachedYOffset);
                }
                if (m_cachedXOffset > scene.RegionInfo.RegionSizeX)
                {
                    posToCheckFrom.X = scene.RegionInfo.RegionSizeX -
                                       (scene.RegionInfo.RegionSizeX - (client.AbsolutePosition.X + m_cachedXOffset));
                }
                if (m_cachedYOffset > scene.RegionInfo.RegionSizeY)
                {
                    posToCheckFrom.Y = scene.RegionInfo.RegionSizeY -
                                       (scene.RegionInfo.RegionSizeY - (client.AbsolutePosition.Y + m_cachedYOffset));
                }
            }
            Vector3 entityPosToCheckFrom = Vector3.Zero;
            bool    doHeavyCulling       = false;

            if (entity is ISceneEntity)
            {
                doHeavyCulling = true;
                //We need to check whether this object is an attachment, and if so, set it so that we check from the avatar's
                // position, rather than from the offset of the attachment
                ISceneEntity sEntity = (ISceneEntity)entity;
                if (sEntity.RootChild.IsAttachment)
                {
                    IScenePresence attachedAvatar = scene.GetScenePresence(sEntity.RootChild.AttachedAvatar);
                    if (attachedAvatar != null)
                    {
                        entityPosToCheckFrom = attachedAvatar.AbsolutePosition;
                    }
                }
                else
                {
                    entityPosToCheckFrom = sEntity.RootChild.GetGroupPosition();
                }
            }
            else if (entity is IScenePresence)
            {
                //We need to check whether this presence is sitting on anything, so that we can check from the object's
                // position, rather than the offset position of the object that the avatar is sitting on
                IScenePresence pEntity = (IScenePresence)entity;
                if (pEntity.Sitting)
                {
                    ISceneChildEntity sittingEntity = scene.GetSceneObjectPart(pEntity.SittingOnUUID);
                    if (sittingEntity != null)
                    {
                        entityPosToCheckFrom = sittingEntity.GetGroupPosition();
                    }
                }
                else
                {
                    entityPosToCheckFrom = pEntity.GetAbsolutePosition();
                }
            }
            //If the distance is greater than the clients draw distance, its out of range
            if (Vector3.DistanceSquared(posToCheckFrom, entityPosToCheckFrom) >
                DD * DD) //Use squares to make it faster than having to do the sqrt
            {
                if (!doHeavyCulling)
                {
                    return(false); //Don't do the hardcore checks
                }
                ISceneEntity childEntity = (entity as ISceneEntity);
                if (childEntity != null && HardCullingCheck(childEntity))
                {
                    #region Side culling check (X, Y, Z) plane checks

                    if (
                        Vector3.DistanceSquared(posToCheckFrom,
                                                entityPosToCheckFrom + new Vector3(childEntity.OOBsize.X, 0, 0)) <
                        DD * DD) //Use squares to make it faster than having to do the sqrt
                    {
                        return(true);
                    }
                    if (
                        Vector3.DistanceSquared(posToCheckFrom,
                                                entityPosToCheckFrom - new Vector3(childEntity.OOBsize.X, 0, 0)) <
                        DD * DD) //Use squares to make it faster than having to do the sqrt
                    {
                        return(true);
                    }
                    if (
                        Vector3.DistanceSquared(posToCheckFrom,
                                                entityPosToCheckFrom + new Vector3(0, childEntity.OOBsize.Y, 0)) <
                        DD * DD) //Use squares to make it faster than having to do the sqrt
                    {
                        return(true);
                    }
                    if (
                        Vector3.DistanceSquared(posToCheckFrom,
                                                entityPosToCheckFrom - new Vector3(0, childEntity.OOBsize.Y, 0)) <
                        DD * DD) //Use squares to make it faster than having to do the sqrt
                    {
                        return(true);
                    }
                    if (
                        Vector3.DistanceSquared(posToCheckFrom,
                                                entityPosToCheckFrom + new Vector3(0, 0, childEntity.OOBsize.Z)) <
                        DD * DD) //Use squares to make it faster than having to do the sqrt
                    {
                        return(true);
                    }
                    if (
                        Vector3.DistanceSquared(posToCheckFrom,
                                                entityPosToCheckFrom - new Vector3(0, 0, childEntity.OOBsize.Z)) <
                        DD * DD) //Use squares to make it faster than having to do the sqrt
                    {
                        return(true);
                    }

                    #endregion

                    #region Corner checks ((x,y),(-x,-y),(x,-y),(-x,y), (y,z),(-y,-z),(y,-z),(-y,z), (x,z),(-x,-z),(x,-z),(-x,z))

                    if (
                        Vector3.DistanceSquared(posToCheckFrom,
                                                entityPosToCheckFrom +
                                                new Vector3(childEntity.OOBsize.X, childEntity.OOBsize.Y, 0)) <
                        DD * DD) //Use squares to make it faster than having to do the sqrt
                    {
                        return(true);
                    }
                    if (
                        Vector3.DistanceSquared(posToCheckFrom,
                                                entityPosToCheckFrom -
                                                new Vector3(childEntity.OOBsize.X, childEntity.OOBsize.Y, 0)) <
                        DD * DD) //Use squares to make it faster than having to do the sqrt
                    {
                        return(true);
                    }
                    if (
                        Vector3.DistanceSquared(posToCheckFrom,
                                                entityPosToCheckFrom +
                                                new Vector3(childEntity.OOBsize.X, -childEntity.OOBsize.Y, 0)) <
                        DD * DD) //Use squares to make it faster than having to do the sqrt
                    {
                        return(true);
                    }
                    if (
                        Vector3.DistanceSquared(posToCheckFrom,
                                                entityPosToCheckFrom -
                                                new Vector3(childEntity.OOBsize.X, -childEntity.OOBsize.Y, 0)) <
                        DD * DD) //Use squares to make it faster than having to do the sqrt
                    {
                        return(true);
                    }
                    if (
                        Vector3.DistanceSquared(posToCheckFrom,
                                                entityPosToCheckFrom +
                                                new Vector3(0, childEntity.OOBsize.Y, childEntity.OOBsize.Z)) <
                        DD * DD) //Use squares to make it faster than having to do the sqrt
                    {
                        return(true);
                    }
                    if (
                        Vector3.DistanceSquared(posToCheckFrom,
                                                entityPosToCheckFrom -
                                                new Vector3(0, childEntity.OOBsize.Y, childEntity.OOBsize.Z)) <
                        DD * DD) //Use squares to make it faster than having to do the sqrt
                    {
                        return(true);
                    }
                    if (
                        Vector3.DistanceSquared(posToCheckFrom,
                                                entityPosToCheckFrom +
                                                new Vector3(0, childEntity.OOBsize.Y, -childEntity.OOBsize.Z)) <
                        DD * DD) //Use squares to make it faster than having to do the sqrt
                    {
                        return(true);
                    }
                    if (
                        Vector3.DistanceSquared(posToCheckFrom,
                                                entityPosToCheckFrom -
                                                new Vector3(0, childEntity.OOBsize.Y, -childEntity.OOBsize.Z)) <
                        DD * DD) //Use squares to make it faster than having to do the sqrt
                    {
                        return(true);
                    }
                    if (
                        Vector3.DistanceSquared(posToCheckFrom,
                                                entityPosToCheckFrom +
                                                new Vector3(childEntity.OOBsize.X, 0, childEntity.OOBsize.Z)) <
                        DD * DD) //Use squares to make it faster than having to do the sqrt
                    {
                        return(true);
                    }
                    if (
                        Vector3.DistanceSquared(posToCheckFrom,
                                                entityPosToCheckFrom -
                                                new Vector3(childEntity.OOBsize.X, 0, childEntity.OOBsize.Z)) <
                        DD * DD) //Use squares to make it faster than having to do the sqrt
                    {
                        return(true);
                    }
                    if (
                        Vector3.DistanceSquared(posToCheckFrom,
                                                entityPosToCheckFrom +
                                                new Vector3(-childEntity.OOBsize.X, 0, childEntity.OOBsize.Z)) <
                        DD * DD) //Use squares to make it faster than having to do the sqrt
                    {
                        return(true);
                    }
                    if (
                        Vector3.DistanceSquared(posToCheckFrom,
                                                entityPosToCheckFrom -
                                                new Vector3(-childEntity.OOBsize.X, 0, childEntity.OOBsize.Z)) <
                        DD * DD) //Use squares to make it faster than having to do the sqrt
                    {
                        return(true);
                    }

                    #endregion
                }
                return(false);
            }

            return(true);
        }