Beispiel #1
0
        /// <summary>
        /// Full reset. Clears out all data for pooling. Call FreeShapes() first.
        /// </summary>
        private void Reset()
        {
            VoltDebug.Assert(this.shapeCount == 0);

#if DEBUG
            this.IsInitialized = false;
#endif

            this.UserData        = null;
            this.World           = null;
            this.BodyType        = VoltBodyType.Invalid;
            this.CollisionFilter = null;

            this.Angle           = 0.0f;
            this.LinearVelocity  = TSVector2.zero;
            this.AngularVelocity = 0.0f;

            this.Force  = TSVector2.zero;
            this.Torque = 0.0f;

            this.Mass       = 0.0f;
            this.Inertia    = 0.0f;
            this.InvMass    = 0.0f;
            this.InvInertia = 0.0f;

            this.BiasVelocity = TSVector2.zero;
            this.BiasRotation = 0.0f;

            this.history      = null;
            this.currentState = default(HistoryRecord);
        }
Beispiel #2
0
        /// <summary>
        /// Checks if a point is contained in this body.
        /// Begins with AABB checks unless bypassed.
        /// </summary>
        internal bool QueryPoint(
            Vector2 point,
            int ticksBehind,
            bool bypassAABB = false)
        {
            HistoryRecord record = this.GetState(ticksBehind);

            // AABB check done in world space (because it keeps changing)
            if (bypassAABB == false)
            {
                if (record.aabb.QueryPoint(point) == false)
                {
                    return(false);
                }
            }

            // Actual query on shapes done in body space
            Vector2 bodySpacePoint = record.WorldToBodyPoint(point);

            for (int i = 0; i < this.shapeCount; i++)
            {
                if (this.shapes[i].QueryPoint(bodySpacePoint))
                {
                    return(true);
                }
            }
            return(false);
        }
Beispiel #3
0
        /// <summary>
        /// Checks if a circle overlaps with this body.
        /// Begins with AABB checks.
        /// </summary>
        internal bool QueryCircle(
            TSVector2 origin,
            FP radius,
            int ticksBehind,
            bool bypassAABB = false)
        {
            HistoryRecord record = this.GetState(ticksBehind);

            // AABB check done in world space (because it keeps changing)
            if (bypassAABB == false)
            {
                if (record.aabb.QueryCircleApprox(origin, radius) == false)
                {
                    return(false);
                }
            }

            // Actual query on shapes done in body space
            TSVector2 bodySpaceOrigin = record.WorldToBodyPoint(origin);

            for (int i = 0; i < this.shapeCount; i++)
            {
                if (this.shapes[i].QueryCircle(bodySpaceOrigin, radius))
                {
                    return(true);
                }
            }
            return(false);
        }
Beispiel #4
0
        /// <summary>
        /// Tries to get a value with a given number of frames behind the last
        /// value stored. If the value can't be found, this function will find
        /// the closest and return false, indicating a clamp.
        /// </summary>
        public bool TryGet(int numBehind, out HistoryRecord value)
        {
            if (numBehind < 0)
            {
                throw new ArgumentOutOfRangeException("numBehind");
            }

            if (this.count < this.capacity)
            {
                if (numBehind >= this.count)
                {
                    value = this.data[0];
                    return(false);
                }

                value = this.data[this.count - numBehind - 1];
                return(true);
            }
            else
            {
                bool found = true;
                if (numBehind >= this.capacity)
                {
                    numBehind = this.capacity - 1;
                    found     = false;
                }

                int index =
                    ((this.start - numBehind - 1) + this.capacity)
                    % this.capacity;
                value = this.data[index];
                return(found);
            }
        }
Beispiel #5
0
        /// <summary>
        /// Checks if an AABB overlaps with our AABB.
        /// </summary>
        internal bool QueryAABBOnly(
            VoltAABB worldBounds,
            int ticksBehind)
        {
            HistoryRecord record = this.GetState(ticksBehind);

            // AABB check done in world space (because it keeps changing)
            return(record.aabb.Intersect(worldBounds));
        }
Beispiel #6
0
 /// <summary>
 /// Stores a value as latest.
 /// </summary>
 public void Store(HistoryRecord value)
 {
     if (this.count < this.capacity)
     {
         this.data[this.count++] = value;
         this.IncrementStart();
     }
     else
     {
         this.data[this.start] = value;
         this.IncrementStart();
     }
 }
Beispiel #7
0
        /// <summary>
        /// Used for saving the body as part of another structure. The body
        /// will retain all geometry data and associated metrics, but its
        /// position, velocity, forces, and all related history will be cleared.
        /// </summary>
        internal void PartialReset()
        {
            this.history      = null;
            this.currentState = default(HistoryRecord);

            this.LinearVelocity  = TSVector2.zero;
            this.AngularVelocity = 0.0f;

            this.Force  = TSVector2.zero;
            this.Torque = 0.0f;

            this.BiasVelocity = TSVector2.zero;
            this.BiasRotation = 0.0f;
        }
Beispiel #8
0
        /// <summary>
        /// Performs a circle cast check on this body.
        /// Begins with AABB checks.
        /// </summary>
        internal bool CircleCast(
            ref VoltRayCast ray,
            FP radius,
            ref VoltRayResult result,
            int ticksBehind,
            bool bypassAABB = false)
        {
            HistoryRecord record = this.GetState(ticksBehind);

            // AABB check done in world space (because it keeps changing)
            if (bypassAABB == false)
            {
                if (record.aabb.CircleCastApprox(ref ray, radius) == false)
                {
                    return(false);
                }
            }

            // Actual tests on shapes done in body space
            VoltRayCast bodySpaceRay = record.WorldToBodyRay(ref ray);

            for (int i = 0; i < this.shapeCount; i++)
            {
                if (this.shapes[i].CircleCast(ref bodySpaceRay, radius, ref result))
                {
                    if (result.IsContained)
                    {
                        return(true);
                    }
                }
            }

            // We need to convert the results back to world space to be any use
            // (Doesn't matter if we were contained since there will be no normal)
            if (result.Body == this)
            {
                result.normal = record.BodyToWorldDirection(result.normal);
            }
            return(result.IsValid);
        }
Beispiel #9
0
 internal void Store(ref HistoryRecord other)
 {
     this.aabb     = other.aabb;
     this.position = other.position;
     this.facing   = other.facing;
 }
Beispiel #10
0
 internal void Store(ref HistoryRecord other)
 {
     this.aabb = other.aabb;
       this.position = other.position;
       this.facing = other.facing;
 }