Ejemplo n.º 1
0
        // Given a position relative to the current region (which has previously been tested to
        //    see that it is actually outside the current region), find the new region that the
        //    point is actually in.
        // Returns the coordinates and information of the new region or 'null' of it doesn't exist.
        public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos,
                                            out string version, out Vector3 newpos, out string failureReason)
        {
            version = String.Empty;
            newpos = pos;
            failureReason = string.Empty;
            string homeURI = scene.GetAgentHomeURI(agentID);

//            m_log.DebugFormat(
//                "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name);

            // Compute world location of the object's position
            double presenceWorldX = (double)scene.RegionInfo.WorldLocX + pos.X;
            double presenceWorldY = (double)scene.RegionInfo.WorldLocY + pos.Y;

            // Call the grid service to lookup the region containing the new position.
            GridRegion neighbourRegion = GetRegionContainingWorldLocation(scene.GridService, scene.RegionInfo.ScopeID,
                                                        presenceWorldX, presenceWorldY, 
                                                        Math.Max(scene.RegionInfo.RegionSizeX, scene.RegionInfo.RegionSizeY));

            if (neighbourRegion != null)
            {
                // Compute the entity's position relative to the new region
                newpos = new Vector3((float)(presenceWorldX - (double)neighbourRegion.RegionLocX),
                                      (float)(presenceWorldY - (double)neighbourRegion.RegionLocY),
                                      pos.Z);

                if (m_bannedRegionCache.IfBanned(neighbourRegion.RegionHandle, agentID))
                {
                    failureReason = "Cannot region cross into banned parcel";
                    neighbourRegion = null;
                }
                else
                {
                    // If not banned, make sure this agent is not in the list.
                    m_bannedRegionCache.Remove(neighbourRegion.RegionHandle, agentID);
                }

                // Check to see if we have access to the target region.
                string myversion = string.Format("{0}/{1}", OutgoingTransferVersionName, MaxOutgoingTransferVersion);
                if (neighbourRegion != null
                    && !scene.SimulationService.QueryAccess(neighbourRegion, agentID, homeURI, false, newpos, myversion, out version, out failureReason))
                {
                    // remember banned
                    m_bannedRegionCache.Add(neighbourRegion.RegionHandle, agentID);
                    neighbourRegion = null;
                }
            }
            else
            {
                // The destination region just doesn't exist
                failureReason = "Cannot cross into non-existent region";
            }

            if (neighbourRegion == null)
                m_log.DebugFormat("{0} GetDestination: region not found. Old region name={1} at <{2},{3}> of size <{4},{5}>. Old pos={6}",
                    LogHeader, scene.RegionInfo.RegionName,
                    scene.RegionInfo.RegionLocX, scene.RegionInfo.RegionLocY,
                    scene.RegionInfo.RegionSizeX, scene.RegionInfo.RegionSizeY,
                    pos);
            else
                m_log.DebugFormat("{0} GetDestination: new region={1} at <{2},{3}> of size <{4},{5}>, newpos=<{6},{7}>",
                    LogHeader, neighbourRegion.RegionName,
                    neighbourRegion.RegionLocX, neighbourRegion.RegionLocY, neighbourRegion.RegionSizeX, neighbourRegion.RegionSizeY,
                    newpos.X, newpos.Y);

            return neighbourRegion;
        }