public void Add(Batch batch) { if (State != State_Initialized) { throw new InvalidOperationException(); } lock (Batches) { #if DEBUG && PARANOID if (Batches.Contains(batch)) { throw new InvalidOperationException("Batch already added to this frame"); } #endif Batches.Add(batch); batch.Container = this; } }
/// <summary> /// Updates the status of the entity inside of the cache; ie, if the entity is now /// passing the filter but was not before, then it will be added to the cache. /// </summary> /// <returns>The change in cache status for the entity</returns> public CacheChangeResult UpdateCache(RuntimeEntity entity) { UnorderedListMetadata metadata = GetMetadata(entity); bool passed = _filter.Check(entity); bool contains = CachedEntities.Contains(entity, metadata); // The entity is not in the cache it now passes the filter, so add it to the cache if (contains == false && passed) { CachedEntities.Add(entity, metadata); return(CacheChangeResult.Added); } // The entity is in the cache but it no longer passes the filter, so remove it if (contains && passed == false) { CachedEntities.Remove(entity, metadata); return(CacheChangeResult.Removed); } // no change to the cache return(CacheChangeResult.NoChange); }
/// <summary> /// Move the transform trying to stop being overlaping other colliders /// </summary> /// <param name="position">start position. Bottom of the collider</param> /// <returns>Final position</returns> protected virtual Vector3 FixOverlaps(Vector3 position, Vector3 direction, float distance) { Vector3 movement = VectorFixer(direction * distance); float dist, dot; dist = dot = 0f; foundLadder = false; LayerMask overlapMask = Profile.SurfaceLayers & ~ignoredLayers; int nColls = fixedOverlapBoxNonAlloc(movement, overlapingColliders, overlapMask, QueryTriggerInteraction.Collide); for (int i = 0; i < nColls; i++) { Collider c = overlapingColliders[i]; // skip collider if it's in the ignored list if (ignoredColliders.Contains(c)) { continue; } if (c.isTrigger) { if (c.tag == Profile.WaterTag) { CheckWater(c); } } else { if (Physics.ComputePenetration(_boxCollider, position, Quaternion.identity, c, c.transform.position, c.transform.rotation, out penetrationNormal, out dist)) { // if this occur, it's a bug in the PhysX engine if (float.IsNaN(penetrationNormal.x) || float.IsNaN(penetrationNormal.y) || float.IsNaN(penetrationNormal.y)) { continue; } // adjust floating point imprecision dist = (float)Math.Round(dist, 3, MidpointRounding.ToEven); penetrationNormal = VectorFixer(penetrationNormal); dist += Profile.Depenetration; dot = Vector3.Dot(penetrationNormal, Vector3.up); // COLLISIONS BELOW if (dot > SlopeDot && dot <= 1) { Collisions |= CC_Collision.CollisionBelow; position += Vector3.up * dist; surfaceNormals.floor = penetrationNormal; CheckPlatform(c); OnCCHit(penetrationNormal); } // COLLISIONS ON SIDES if (dot >= 0 && dot < SlopeDot) { Collisions |= CC_Collision.CollisionSides; if (c.tag == Profile.LadderTag) { foundLadder = true; // pick the first normal on contact if (!OnLadder) { surfaceNormals.ladder = penetrationNormal; } } else { bool foundStep = false; position = MoveOnSteps(position, direction, out foundStep); if (!foundStep) { position += penetrationNormal * dist; surfaceNormals.wall = penetrationNormal; OnCCHit(penetrationNormal); WaterEdgePush(penetrationNormal); } } } // COLLISIONS ABOVE if (dot < -0.001) { Collisions |= CC_Collision.CollisionAbove; position += penetrationNormal * dist; OnCCHit(penetrationNormal); } } } } if (foundLadder) { State |= CC_State.OnLadder; } else { State &= ~CC_State.OnLadder; detachLadder = false; } return(position); }