/// <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); }
/// <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); }
/// <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); }
/// <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); } }
/// <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)); }
/// <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(); } }
/// <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; }
/// <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); }
internal void Store(ref HistoryRecord other) { this.aabb = other.aabb; this.position = other.position; this.facing = other.facing; }