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); }
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); }