Ejemplo n.º 1
0
        /// <summary>
        /// Finds all bodies intersecting with a given circle.
        ///
        /// Subsequent calls to other Query functions (Point, Circle, Bounds) will
        /// invalidate the resulting enumeration from this function.
        /// </summary>
        public VoltBuffer <VoltBody> QueryCircle(
            VoltVector2 origin,
            Fix64 radius,
            VoltBodyFilter filter = null,
            int ticksBehind       = 0)
        {
            if (ticksBehind < 0)
            {
                throw new ArgumentOutOfRangeException("ticksBehind");
            }

            this.reusableBuffer.Clear();
            this.staticBroadphase.QueryCircle(origin, radius, this.reusableBuffer);
            this.dynamicBroadphase.QueryCircle(origin, radius, this.reusableBuffer);

            this.reusableOutput.Clear();
            for (int i = 0; i < this.reusableBuffer.Count; i++)
            {
                VoltBody body = this.reusableBuffer[i];
                if (VoltBody.Filter(body, filter))
                {
                    if (body.QueryCircle(origin, radius, ticksBehind))
                    {
                        this.reusableOutput.Add(body);
                    }
                }
            }

            return(this.reusableOutput);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Performs a circle cast on all world bodies.
        /// </summary>
        public bool CircleCast(
            ref VoltRayCast ray,
            Fix64 radius,
            ref VoltRayResult result,
            VoltBodyFilter filter = null,
            int ticksBehind       = 0)
        {
            if (ticksBehind < 0)
            {
                throw new ArgumentOutOfRangeException("ticksBehind");
            }

            this.reusableBuffer.Clear();
            this.staticBroadphase.CircleCast(ref ray, radius, this.reusableBuffer);
            this.dynamicBroadphase.CircleCast(ref ray, radius, this.reusableBuffer);

            for (int i = 0; i < this.reusableBuffer.Count; i++)
            {
                VoltBody body = this.reusableBuffer[i];
                if (VoltBody.Filter(body, filter))
                {
                    body.CircleCast(ref ray, radius, ref result, ticksBehind);
                    if (result.IsContained)
                    {
                        return(true);
                    }
                }
            }
            return(result.IsValid);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Finds all dynamic bodies that overlap with the explosion AABB
        /// and pass the target filter test. Does not test actual shapes.
        /// </summary>
        private void PopulateFiltered(
            TSVector2 origin,
            FP radius,
            VoltBodyFilter targetFilter,
            int ticksBehind,
            ref VoltBuffer <VoltBody> filterBuffer)
        {
            if (filterBuffer == null)
            {
                filterBuffer = new VoltBuffer <VoltBody>();
            }
            filterBuffer.Clear();

            this.reusableBuffer.Clear();
            this.staticBroadphase.QueryCircle(origin, radius, this.reusableBuffer);
            this.dynamicBroadphase.QueryCircle(origin, radius, this.reusableBuffer);

            VoltAABB aabb = new VoltAABB(origin, radius);

            for (int i = 0; i < this.reusableBuffer.Count; i++)
            {
                VoltBody body = this.reusableBuffer[i];
                if ((targetFilter == null) || targetFilter.Invoke(body))
                {
                    if (body.QueryAABBOnly(aabb, ticksBehind))
                    {
                        filterBuffer.Add(body);
                    }
                }
            }
        }
Ejemplo n.º 4
0
        public void PerformExplosion(
            TSVector2 origin,
            FP radius,
            VoltExplosionCallback callback,
            VoltBodyFilter targetFilter    = null,
            VoltBodyFilter occlusionFilter = null,
            int ticksBehind = 0,
            int rayCount    = 32)
        {
            if (ticksBehind < 0)
            {
                throw new ArgumentOutOfRangeException("ticksBehind");
            }

            // Get all target bodies
            this.PopulateFiltered(
                origin,
                radius,
                targetFilter,
                ticksBehind,
                ref this.targetBodies);

            // Get all occluding bodies
            this.PopulateFiltered(
                origin,
                radius,
                occlusionFilter,
                ticksBehind,
                ref this.occludingBodies);

            VoltRayCast ray;
            FP          rayWeight      = 1.0f / rayCount;
            FP          angleIncrement = (TSMath.Pi * 2.0f) * rayWeight;

            for (int i = 0; i < rayCount; i++)
            {
                TSVector2 normal = VoltMath.Polar(angleIncrement * i);
                ray = new VoltRayCast(origin, normal, radius);

                FP minDistance =
                    this.GetOccludingDistance(ray, ticksBehind);
                minDistance += VoltWorld.EXPLOSION_OCCLUDER_SLOP;

                this.TestTargets(ray, callback, ticksBehind, minDistance, rayWeight);
            }
        }
Ejemplo n.º 5
0
        public void PerformExplosion(
      Vector2 origin,
      float radius,
      VoltExplosionCallback callback,
      VoltBodyFilter targetFilter = null,
      VoltBodyFilter occlusionFilter = null,
      int ticksBehind = 0,
      int rayCount = 32)
        {
            if (ticksBehind < 0)
            throw new ArgumentOutOfRangeException("ticksBehind");

              // Get all target bodies
              this.PopulateFiltered(
            origin,
            radius,
            targetFilter,
            ticksBehind,
            ref this.targetBodies);

              // Get all occluding bodies
              this.PopulateFiltered(
            origin,
            radius,
            occlusionFilter,
            ticksBehind,
            ref this.occludingBodies);

              VoltRayCast ray;
              float rayWeight = 1.0f / rayCount;
              float angleIncrement = (Mathf.PI * 2.0f) * rayWeight;

              for (int i = 0; i < rayCount; i++)
              {
            Vector2 normal = VoltMath.Polar(angleIncrement * i);
            ray = new VoltRayCast(origin, normal, radius);

            float minDistance =
              this.GetOccludingDistance(ray, ticksBehind);
            minDistance += VoltWorld.EXPLOSION_OCCLUDER_SLOP;

            this.TestTargets(ray, callback, ticksBehind, minDistance, rayWeight);
              }
        }
Ejemplo n.º 6
0
 public static bool Filter(VoltBody body, VoltBodyFilter filter)
 {
     return((filter == null) || (filter.Invoke(body) == true));
 }
Ejemplo n.º 7
0
        /// <summary>
        /// Performs a raycast on all world bodies.
        /// </summary>
        public bool RayCast(
      ref VoltRayCast ray,
      ref VoltRayResult result,
      VoltBodyFilter filter = null,
      int ticksBehind = 0)
        {
            if (ticksBehind < 0)
            throw new ArgumentOutOfRangeException("ticksBehind");

              this.reusableBuffer.Clear();
              this.staticBroadphase.RayCast(ref ray, this.reusableBuffer);
              this.dynamicBroadphase.RayCast(ref ray, this.reusableBuffer);

              for (int i = 0; i < this.reusableBuffer.Count; i++)
              {
            VoltBody body = this.reusableBuffer[i];
            if (VoltBody.Filter(body, filter))
            {
              body.RayCast(ref ray, ref result, ticksBehind);
              if (result.IsContained)
            return true;
            }
              }

              return result.IsValid;
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Finds all bodies containing a given point.
        /// 
        /// Subsequent calls to other Query functions (Point, Circle, Bounds) will
        /// invalidate the resulting enumeration from this function.
        /// </summary>
        public VoltBuffer<VoltBody> QueryPoint(
      Vector2 point,
      VoltBodyFilter filter = null,
      int ticksBehind = 0)
        {
            if (ticksBehind < 0)
            throw new ArgumentOutOfRangeException("ticksBehind");

              this.reusableBuffer.Clear();
              this.staticBroadphase.QueryPoint(point, this.reusableBuffer);
              this.dynamicBroadphase.QueryPoint(point, this.reusableBuffer);

              this.reusableOutput.Clear();
              for (int i = 0; i < this.reusableBuffer.Count; i++)
              {
            VoltBody body = this.reusableBuffer[i];
            if (VoltBody.Filter(body, filter))
              if (body.QueryPoint(point, ticksBehind))
            this.reusableOutput.Add(body);
              }
              return this.reusableOutput;
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Finds all dynamic bodies that overlap with the explosion AABB
        /// and pass the target filter test. Does not test actual shapes.
        /// </summary>
        private void PopulateFiltered(
      Vector2 origin,
      float radius,
      VoltBodyFilter targetFilter,
      int ticksBehind,
      ref VoltBuffer<VoltBody> filterBuffer)
        {
            if (filterBuffer == null)
            filterBuffer = new VoltBuffer<VoltBody>();
              filterBuffer.Clear();

              this.reusableBuffer.Clear();
              this.staticBroadphase.QueryCircle(origin, radius, this.reusableBuffer);
              this.dynamicBroadphase.QueryCircle(origin, radius, this.reusableBuffer);

              VoltAABB aabb = new VoltAABB(origin, radius);
              for (int i = 0; i < this.reusableBuffer.Count; i++)
              {
            VoltBody body = this.reusableBuffer[i];
            if ((targetFilter == null) || targetFilter.Invoke(body))
              if (body.QueryAABBOnly(aabb, ticksBehind))
            filterBuffer.Add(body);
              }
        }