Exemplo n.º 1
0
        private bool HandleCollision(SweepCallback callback)
        {
            // set up for callback
            cumulative_t += t;
            float dir = step[axis];

            // vector moved so far, and left to move
            float done = t / max_t;

            for (int i = 0; i < 3; i++)
            {
                float dv = vec[i] * done;
                bas[i] += dv;
                max[i] += dv;
                left[i] = vec[i] - dv;
            }

            // set leading edge of stepped axis exactly to voxel boundary
            // else we'll sometimes rounding error beyond it
            if (dir > 0)
            {
                max[axis] = (float)Math.Round(max[axis]);
            }
            else
            {
                bas[axis] = (float)Math.Round(bas[axis]);
            }

            // call back to let client update the "left to go" vector
            Vector3 leftVec = new Vector3(left[0], left[1], left[2]);
            bool    res     = callback(cumulative_t, axis, dir, ref leftVec);

            leftVec.CopyTo(left);

            // bail out out on truthy response
            if (res)
            {
                return(true);
            }

            // init for new sweep along vec
            for (int i = 0; i < 3; i++)
            {
                vec[i] = left[i];
            }
            Initialize();
            if (max_t == 0)
            {
                return(true);            // no vector left
            }
            return(false);
        }
Exemplo n.º 2
0
        // Return total distance moved
        // (not necessarily magnitude of [end]-[start])
        public float Execute(ref BoundingBox boundingBox,
                             Vector3 direction, SweepCallback callback, bool noTranslate)
        {
            Vector3 maximum = boundingBox.Maximum();

            direction.CopyTo(sdir);
            direction.CopyTo(vec);
            maximum.CopyTo(max);
            maximum.CopyTo(bmax);
            boundingBox.Position.CopyTo(bas);
            boundingBox.Position.CopyTo(bbas);

            cumulative_t = 0;
            axis         = 0;

            // init for the current sweep vector and take first step
            Initialize();
            if (max_t == 0)
            {
                return(0);
            }
            axis = StepForward();

            float dist = 0;

            bool done = false;

            // loop along raycast vector
            while (t <= max_t)
            {
                // sweeps over leading face of AABB
                if (CheckCollision(axis))
                {
                    // calls the callback and decides whether to continue
                    done = HandleCollision(callback);
                    if (done)
                    {
                        dist = cumulative_t;
                        break;
                    }
                }

                axis = StepForward();
            }

            if (!done)
            {
                cumulative_t += max_t;
                for (int i = 0; i < 3; i++)
                {
                    bas[i] += vec[i];
                    max[i] += vec[i];
                }

                dist = cumulative_t;
            }

            if (!noTranslate)
            {
                for (int i = 0; i < 3; i++)
                {
                    result[i] = (sdir[i] > 0) ?
                                (max[i] - bmax[i]) : (bas[i] - bbas[i]);
                }

                boundingBox = boundingBox.Translated(new Vector3(
                                                         result[0], result[1], result[2]));
            }

            return(dist);
        }