Ejemplo n.º 1
0
 /* Apply a user-supplied function to all objects in the database,
  * regardless of locality (cf lqMapOverAllObjectsInLocality) */
 public void MapOverAllObjects(LQCallBackFunction func, Object clientQueryState)
 {
     foreach (ClientProxy bin in _bins)
     {
         MapOverAllObjectsInBin(bin, func, clientQueryState);
     }
 }
Ejemplo n.º 2
0
 /* Apply a user-supplied function to all objects in the database,
  * regardless of locality (cf lqMapOverAllObjectsInLocality) */
 public void MapOverAllObjects(LQCallBackFunction func, Object clientQueryState)
 {
     for (int i = 0; i < _bins.Length; i++)
     {
         MapOverAllObjectsInBin(_bins[i], func, clientQueryState);
     }
 }
Ejemplo n.º 3
0
        /* If the query region (sphere) extends outside of the "super-brick"
         * we need to check for objects in the catch-all "other" bin which
         * holds any object which are not inside the regular sub-bricks  */
        public void MapOverAllOutsideObjects(Vector3 center, float radius, LQCallBackFunction func, Object clientQueryState)
        {
            ClientProxy co            = bins[bins.Length - 1];
            float       radiusSquared = radius * radius;

            // traverse the "other" bin's client object list
            TraverseBinClientObjectList(ref co, radiusSquared, func, clientQueryState, center);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// If the query region (sphere) extends outside of the "super-brick"
        /// we need to check for objects in the catch-all "other" bin which
        /// holds any object which are not inside the regular sub-bricks
        /// </summary>
        /// <param name="center"></param>
        /// <param name="radius"></param>
        /// <param name="func"></param>
        /// <param name="clientQueryState"></param>
        private void MapOverAllOutsideObjects(Point3D center, int radius, LQCallBackFunction func, Object clientQueryState)
        {
            ClientProxy co            = _bins[_bins.Length - 1];
            int         radiusSquared = radius * radius;

            // traverse the "other" bin's client object list
            TraverseBinClientObjectList(co, radiusSquared, func, clientQueryState, center);
        }
Ejemplo n.º 5
0
 /* public helper function */
 public void MapOverAllObjectsInBin(ClientProxy binProxyList, LQCallBackFunction func, Object clientQueryState)
 {
     // walk down proxy list, applying call-back function to each one
     while (binProxyList != null)
     {
         func(binProxyList.Obj, 0, clientQueryState);
         binProxyList = binProxyList.Next;
     }
 }
Ejemplo n.º 6
0
        /* This subroutine of lqMapOverAllObjectsInLocality efficiently
         * traverses of subset of bins specified by max and min bin
         * coordinates. */
        public void MapOverAllObjectsInLocalityClipped(Vector3 center, float radius,
                                                       LQCallBackFunction func,
                                                       Object clientQueryState,
                                                       int minBinX, int minBinY, int minBinZ,
                                                       int maxBinX, int maxBinY, int maxBinZ)
        {
            int         i, j, k;
            int         iindex, jindex, kindex;
            int         slab   = DivY * DivZ;
            int         row    = DivZ;
            int         istart = minBinX * slab;
            int         jstart = minBinY * row;
            int         kstart = minBinZ;
            ClientProxy co;
            ClientProxy bin;
            float       radiusSquared = radius * radius;

            /* loop for x bins across diameter of sphere */
            iindex = istart;
            for (i = minBinX; i <= maxBinX; i++)
            {
                /* loop for y bins across diameter of sphere */
                jindex = jstart;
                for (j = minBinY; j <= maxBinY; j++)
                {
                    /* loop for z bins across diameter of sphere */
                    kindex = kstart;
                    for (k = minBinZ; k <= maxBinZ; k++)
                    {
                        /* get current bin's client obj list */
                        bin = bins[iindex + jindex + kindex];
                        co  = bin;

                        /* traverse current bin's client obj list */
                        TraverseBinClientObjectList(ref co,
                                                    radiusSquared,
                                                    func,
                                                    clientQueryState,
                                                    center);
                        kindex += 1;
                    }
                    jindex += row;
                }
                iindex += slab;
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// This subroutine of lqMapOverAllObjectsInLocality efficiently
        /// traverses of subset of bins specified by max and min bin
        /// coordinates.
        /// </summary>
        /// <param name="center"></param>
        /// <param name="radius"></param>
        /// <param name="func"></param>
        /// <param name="clientQueryState"></param>
        /// <param name="minBinX"></param>
        /// <param name="minBinY"></param>
        /// <param name="minBinZ"></param>
        /// <param name="maxBinX"></param>
        /// <param name="maxBinY"></param>
        /// <param name="maxBinZ"></param>
        private void MapOverAllObjectsInLocalityClipped(Point3D center, int radius,
                                                        LQCallBackFunction func,
                                                        Object clientQueryState,
                                                        int minBinX, int minBinY, int minBinZ,
                                                        int maxBinX, int maxBinY, int maxBinZ)
        {
            int i;
            int slab          = _divY * _divZ;
            int row           = _divZ;
            int istart        = minBinX * slab;
            int jstart        = minBinY * row;
            int kstart        = minBinZ;
            int radiusSquared = radius * radius;

            /* loop for x bins across diameter of sphere */
            int iindex = istart;

            for (i = minBinX; i <= maxBinX; i++)
            {
                /* loop for y bins across diameter of sphere */
                int jindex = jstart;
                int j;
                for (j = minBinY; j <= maxBinY; j++)
                {
                    /* loop for z bins across diameter of sphere */
                    int kindex = kstart;
                    int k;
                    for (k = minBinZ; k <= maxBinZ; k++)
                    {
                        /* get current bin's client obj list */
                        ClientProxy bin = _bins[iindex + jindex + kindex];
                        ClientProxy co  = bin;

                        /* traverse current bin's client obj list */
                        TraverseBinClientObjectList(co,
                                                    radiusSquared,
                                                    func,
                                                    clientQueryState,
                                                    center);
                        kindex += 1;
                    }
                    jindex += row;
                }
                iindex += slab;
            }
        }
Ejemplo n.º 8
0
        /* Given a bin's list of client proxies, traverse the list and invoke
        the given lqCallBackFunction on each obj that falls within the
        search radius.  */
        public void TraverseBinClientObjectList(ref ClientProxy co, float radiusSquared, LQCallBackFunction func, Object state, Vector3 position)
        {
            while (co != null)
            {
                // compute distance (squared) from this client obj to given
                // locality sphere's centerpoint
                Vector3 d = position - co.Position;
                float distanceSquared = d.LengthSquared();

                // apply function if client obj within sphere
                if (distanceSquared < radiusSquared)
                    func(co.Obj, distanceSquared, state);

                // consider next client obj in bin list
                co = co.Next;
            }
        }
Ejemplo n.º 9
0
        /* If the query region (sphere) extends outside of the "super-brick"
           we need to check for objects in the catch-all "other" bin which
           holds any object which are not inside the regular sub-bricks  */
        public void MapOverAllOutsideObjects(Vector3 center, float radius, LQCallBackFunction func, Object clientQueryState)
        {
            ClientProxy co = bins[bins.Length - 1];
            float radiusSquared = radius * radius;

            // traverse the "other" bin's client object list
            TraverseBinClientObjectList(ref co, radiusSquared, func, clientQueryState, center);
        }
Ejemplo n.º 10
0
        /* This subroutine of lqMapOverAllObjectsInLocality efficiently
           traverses of subset of bins specified by max and min bin
           coordinates. */
        public void MapOverAllObjectsInLocalityClipped(Vector3 center, float radius,
							   LQCallBackFunction func,
							   Object clientQueryState,
							   int minBinX, int minBinY, int minBinZ,
							   int maxBinX, int maxBinY, int maxBinZ)
        {
            int i, j, k;
            int iindex, jindex, kindex;
            int slab = DivY * DivZ;
            int row = DivZ;
            int istart = minBinX * slab;
            int jstart = minBinY * row;
            int kstart = minBinZ;
            ClientProxy co;
            ClientProxy bin;
            float radiusSquared = radius * radius;

            /* loop for x bins across diameter of sphere */
            iindex = istart;
            for (i = minBinX; i <= maxBinX; i++)
            {
                /* loop for y bins across diameter of sphere */
                jindex = jstart;
                for (j = minBinY; j <= maxBinY; j++)
                {
                    /* loop for z bins across diameter of sphere */
                    kindex = kstart;
                    for (k = minBinZ; k <= maxBinZ; k++)
                    {
                        /* get current bin's client obj list */
                        bin = bins[iindex + jindex + kindex];
                        co = bin;

                        /* traverse current bin's client obj list */
                        TraverseBinClientObjectList(ref co,
                            radiusSquared,
                            func,
                            clientQueryState,
                            center);
                        kindex += 1;
                    }
                    jindex += row;
                }
                iindex += slab;
            }
        }
Ejemplo n.º 11
0
        /* Apply an application-specific function to all objects in a certain
           locality.  The locality is specified as a sphere with a given
           center and radius.  All objects whose location (key-point) is
           within this sphere are identified and the function is applied to
           them.  The application-supplied function takes three arguments:

             (1) a void* pointer to an lqClientProxy's "object".
             (2) the square of the distance from the center of the search
                 locality sphere (x,y,z) to object's key-point.
             (3) a void* pointer to the caller-supplied "client query state"
                 object -- typically NULL, but can be used to store state
                 between calls to the lqCallBackFunction.

           This routine uses the LQ database to quickly reject any objects in
           bins which do not overlap with the sphere of interest.  Incremental
           calculation of index values is used to efficiently traverse the
           bins of interest. */
        public void MapOverAllObjectsInLocality(Vector3 center, float radius, LQCallBackFunction func, Object clientQueryState)
        {
            int partlyOut = 0;
            bool completelyOutside =
                (((center.X + radius) < Origin.X) ||
                 ((center.Y + radius) < Origin.Y) ||
                 ((center.Z + radius) < Origin.Z) ||
                 ((center.X - radius) >= Origin.X + Size.X) ||
                 ((center.Y - radius) >= Origin.Y + Size.Y) ||
                 ((center.Z - radius) >= Origin.Z + Size.Z));
            int minBinX, minBinY, minBinZ, maxBinX, maxBinY, maxBinZ;

            /* is the sphere completely outside the "super brick"? */
            if (completelyOutside)
            {
                MapOverAllOutsideObjects(center, radius, func, clientQueryState);
                return;
            }

            /* compute min and max bin coordinates for each dimension */
            minBinX = (int)((((center.X - radius) - Origin.X) / Size.X) * DivX);
            minBinY = (int)((((center.Y - radius) - Origin.Y) / Size.Y) * DivY);
            minBinZ = (int)((((center.Z - radius) - Origin.Z) / Size.Z) * DivZ);
            maxBinX = (int)((((center.X + radius) - Origin.X) / Size.X) * DivX);
            maxBinY = (int)((((center.Y + radius) - Origin.Y) / Size.Y) * DivY);
            maxBinZ = (int)((((center.Z + radius) - Origin.Z) / Size.Z) * DivZ);

            /* clip bin coordinates */
            if (minBinX < 0) { partlyOut = 1; minBinX = 0; }
            if (minBinY < 0) { partlyOut = 1; minBinY = 0; }
            if (minBinZ < 0) { partlyOut = 1; minBinZ = 0; }
            if (maxBinX >= DivX) { partlyOut = 1; maxBinX = DivX - 1; }
            if (maxBinY >= DivY) { partlyOut = 1; maxBinY = DivY - 1; }
            if (maxBinZ >= DivZ) { partlyOut = 1; maxBinZ = DivZ - 1; }

            /* map function over outside objects if necessary (if clipped) */
            if (partlyOut != 0)
                MapOverAllOutsideObjects(center, radius, func, clientQueryState);

            /* map function over objects in bins */
            MapOverAllObjectsInLocalityClipped(
                center, radius,
                func,
                clientQueryState,
                minBinX, minBinY, minBinZ,
                maxBinX, maxBinY, maxBinZ);
        }
Ejemplo n.º 12
0
 /* public helper function */
 public void MapOverAllObjectsInBin(ClientProxy binProxyList, LQCallBackFunction func, Object clientQueryState)
 {
     // walk down proxy list, applying call-back function to each one
     while (binProxyList != null)
     {
         func(binProxyList.Obj, 0, clientQueryState);
         binProxyList = binProxyList.Next;
     }
 }
Ejemplo n.º 13
0
 /* Apply a user-supplied function to all objects in the database,
    regardless of locality (cf lqMapOverAllObjectsInLocality) */
 public void MapOverAllObjects(LQCallBackFunction func, Object clientQueryState)
 {
     for (int i = 0; i < bins.Length; i++)
     {
         MapOverAllObjectsInBin(bins[i], func, clientQueryState);
     }
     //MapOverAllObjectsInBin(other, func, clientQueryState);
 }
Ejemplo n.º 14
0
        /* Given a bin's list of client proxies, traverse the list and invoke
         * the given lqCallBackFunction on each obj that falls within the
         * search radius.  */
        public void TraverseBinClientObjectList(ref ClientProxy co, float radiusSquared, LQCallBackFunction func, Object state, Vector3 position)
        {
            while (co != null)
            {
                // compute distance (squared) from this client obj to given
                // locality sphere's centerpoint
                Vector3 d = position - co.Position;
                float   distanceSquared = d.LengthSquared();

                // apply function if client obj within sphere
                if (distanceSquared < radiusSquared)
                {
                    func(co.Obj, distanceSquared, state);
                }

                // consider next client obj in bin list
                co = co.Next;
            }
        }
Ejemplo n.º 15
0
        /* Apply an application-specific function to all objects in a certain
         * locality.  The locality is specified as a sphere with a given
         * center and radius.  All objects whose location (key-point) is
         * within this sphere are identified and the function is applied to
         * them.  The application-supplied function takes three arguments:
         *
         *       (1) a void* pointer to an lqClientProxy's "object".
         *       (2) the square of the distance from the center of the search
         *               locality sphere (x,y,z) to object's key-point.
         *       (3) a void* pointer to the caller-supplied "client query state"
         *               object -- typically NULL, but can be used to store state
         *               between calls to the lqCallBackFunction.
         *
         * This routine uses the LQ database to quickly reject any objects in
         * bins which do not overlap with the sphere of interest.  Incremental
         * calculation of index values is used to efficiently traverse the
         * bins of interest. */
        public void MapOverAllObjectsInLocality(Vector3 center, float radius, LQCallBackFunction func, Object clientQueryState)
        {
            int  partlyOut         = 0;
            bool completelyOutside =
                (((center.X + radius) < Origin.X) ||
                 ((center.Y + radius) < Origin.Y) ||
                 ((center.Z + radius) < Origin.Z) ||
                 ((center.X - radius) >= Origin.X + Size.X) ||
                 ((center.Y - radius) >= Origin.Y + Size.Y) ||
                 ((center.Z - radius) >= Origin.Z + Size.Z));
            int minBinX, minBinY, minBinZ, maxBinX, maxBinY, maxBinZ;

            /* is the sphere completely outside the "super brick"? */
            if (completelyOutside)
            {
                MapOverAllOutsideObjects(center, radius, func, clientQueryState);
                return;
            }

            /* compute min and max bin coordinates for each dimension */
            minBinX = (int)((((center.X - radius) - Origin.X) / Size.X) * DivX);
            minBinY = (int)((((center.Y - radius) - Origin.Y) / Size.Y) * DivY);
            minBinZ = (int)((((center.Z - radius) - Origin.Z) / Size.Z) * DivZ);
            maxBinX = (int)((((center.X + radius) - Origin.X) / Size.X) * DivX);
            maxBinY = (int)((((center.Y + radius) - Origin.Y) / Size.Y) * DivY);
            maxBinZ = (int)((((center.Z + radius) - Origin.Z) / Size.Z) * DivZ);

            /* clip bin coordinates */
            if (minBinX < 0)
            {
                partlyOut = 1; minBinX = 0;
            }
            if (minBinY < 0)
            {
                partlyOut = 1; minBinY = 0;
            }
            if (minBinZ < 0)
            {
                partlyOut = 1; minBinZ = 0;
            }
            if (maxBinX >= DivX)
            {
                partlyOut = 1; maxBinX = DivX - 1;
            }
            if (maxBinY >= DivY)
            {
                partlyOut = 1; maxBinY = DivY - 1;
            }
            if (maxBinZ >= DivZ)
            {
                partlyOut = 1; maxBinZ = DivZ - 1;
            }

            /* map function over outside objects if necessary (if clipped) */
            if (partlyOut != 0)
            {
                MapOverAllOutsideObjects(center, radius, func, clientQueryState);
            }

            /* map function over objects in bins */
            MapOverAllObjectsInLocalityClipped(
                center, radius,
                func,
                clientQueryState,
                minBinX, minBinY, minBinZ,
                maxBinX, maxBinY, maxBinZ);
        }
Ejemplo n.º 16
0
		/* Apply a user-supplied function to all objects in the database,
		   regardless of locality (cf lqMapOverAllObjectsInLocality) */
		public void MapOverAllObjects(LQCallBackFunction func, Object clientQueryState)
		{
		    foreach (ClientProxy bin in _bins)
		    {
		        MapOverAllObjectsInBin(bin, func, clientQueryState);
		    }
		}