private void UpdateInstances(TrileUpdateAction action) { switch (action) { case TrileUpdateAction.None: return; case TrileUpdateAction.SingleFaceCullPartial: this.LevelManager.WaitForScreenInvalidation(); for (int right = this.cullingBounds.Right; right < this.lastCullingBounds.Right; ++right) { for (int top = this.lastCullingBounds.Top; top < this.lastCullingBounds.Bottom; ++top) this.FreeScreenSpace(right, top); } for (int right = this.lastCullingBounds.Right; right < this.cullingBounds.Right; ++right) { for (int top = this.cullingBounds.Top; top < this.cullingBounds.Bottom; ++top) this.FillScreenSpace(right, top); } for (int left = this.lastCullingBounds.Left; left < this.cullingBounds.Left; ++left) { for (int top = this.lastCullingBounds.Top; top < this.lastCullingBounds.Bottom; ++top) this.FreeScreenSpace(left, top); } for (int left = this.cullingBounds.Left; left < this.lastCullingBounds.Left; ++left) { for (int top = this.cullingBounds.Top; top < this.cullingBounds.Bottom; ++top) this.FillScreenSpace(left, top); } for (int top = this.lastCullingBounds.Top; top < this.cullingBounds.Top; ++top) { for (int left = this.lastCullingBounds.Left; left < this.lastCullingBounds.Right; ++left) this.FreeScreenSpace(left, top); } for (int top = this.cullingBounds.Top; top < this.lastCullingBounds.Top; ++top) { for (int left = this.cullingBounds.Left; left < this.cullingBounds.Right; ++left) this.FillScreenSpace(left, top); } for (int bottom = this.cullingBounds.Bottom; bottom < this.lastCullingBounds.Bottom; ++bottom) { for (int left = this.lastCullingBounds.Left; left < this.lastCullingBounds.Right; ++left) this.FreeScreenSpace(left, bottom); } for (int bottom = this.lastCullingBounds.Bottom; bottom < this.cullingBounds.Bottom; ++bottom) { for (int left = this.cullingBounds.Left; left < this.cullingBounds.Right; ++left) this.FillScreenSpace(left, bottom); } break; case TrileUpdateAction.SingleFaceCullFull: foreach (TrileMaterializer trileMaterializer in this.trileMaterializers.Values) trileMaterializer.ResetBatch(); this.fallbackMaterializer.ResetBatch(); foreach (TrileInstance instance in (IEnumerable<TrileInstance>) this.LevelManager.Triles.Values) { if (instance.SkipCulling) this.SafeAddToBatch(instance, false); else instance.InstanceId = -1; } this.viewedInstances.Clear(); if (!this.rowsCleared) this.UnRowify(true); this.LevelManager.WaitForScreenInvalidation(); for (int left = this.cullingBounds.Left; left < this.cullingBounds.Right; ++left) { for (int top = this.cullingBounds.Top; top < this.cullingBounds.Bottom; ++top) this.FillScreenSpace(left, top); } break; case TrileUpdateAction.TwoFaceCullPartial: int top1 = this.lastCullingBounds.Top; int top2 = this.cullingBounds.Top; int bottom1 = this.cullingBounds.Bottom; int bottom2 = this.lastCullingBounds.Bottom; for (int key = top1; key < top2; ++key) { List<TrileInstance> list; if (this.trileRows.TryGetValue(key, out list)) { foreach (TrileInstance instance in list) { if (instance.InstanceId != -1) this.SafeRemoveFromBatchWithOverlaps(instance); } } } for (int key = top2; key < top1; ++key) { List<TrileInstance> list; if (this.trileRows.TryGetValue(key, out list)) { foreach (TrileInstance instance in list) { TrileEmplacement emplacement = instance.Emplacement; if (instance.Enabled && !instance.Hidden && (instance.ForceSeeThrough || this.LevelManager.IsCornerTrile(ref emplacement, ref this.xOrientation, ref this.zOrientation)) && instance.Trile.Id >= 0) this.SafeAddToBatchWithOverlaps(instance, false); } } } for (int key = bottom1; key < bottom2; ++key) { List<TrileInstance> list; if (this.trileRows.TryGetValue(key, out list)) { foreach (TrileInstance instance in list) { if (instance.InstanceId != -1) this.SafeRemoveFromBatchWithOverlaps(instance); } } } for (int key = bottom2; key < bottom1; ++key) { List<TrileInstance> list; if (this.trileRows.TryGetValue(key, out list)) { foreach (TrileInstance instance in list) { TrileEmplacement emplacement = instance.Emplacement; if (instance.Enabled && !instance.Hidden && (instance.ForceSeeThrough || this.LevelManager.IsCornerTrile(ref emplacement, ref this.xOrientation, ref this.zOrientation)) && instance.Trile.Id >= 0) this.SafeAddToBatchWithOverlaps(instance, false); } } } break; case TrileUpdateAction.TwoFaceCullFull: foreach (TrileMaterializer trileMaterializer in this.trileMaterializers.Values) trileMaterializer.ResetBatch(); this.fallbackMaterializer.ResetBatch(); if (this.rowsCleared) this.Rowify(); this.viewedInstances.Clear(); for (int top3 = this.cullingBounds.Top; top3 <= this.cullingBounds.Bottom; ++top3) { List<TrileInstance> list; if (this.trileRows.TryGetValue(top3, out list)) { foreach (TrileInstance instance in list) { TrileEmplacement emplacement = instance.Emplacement; if (instance.Enabled && !instance.Hidden && (instance.ForceSeeThrough || this.LevelManager.IsCornerTrile(ref emplacement, ref this.xOrientation, ref this.zOrientation)) && instance.Trile.Id >= 0) this.SafeAddToBatchWithOverlaps(instance, false); } } } break; case TrileUpdateAction.TriFaceCull: foreach (TrileMaterializer trileMaterializer in this.trileMaterializers.Values) trileMaterializer.ResetBatch(); this.fallbackMaterializer.ResetBatch(); this.UnregisterAllViewedInstances(); float num1 = (float) ((double) this.CameraManager.Radius / (double) this.CameraManager.AspectRatio / 2.0 + 1.0); int num2 = this.EngineState.InEditor ? 8 : 0; using (IEnumerator<TrileInstance> enumerator = this.LevelManager.Triles.Values.GetEnumerator()) { while (enumerator.MoveNext()) { TrileInstance current = enumerator.Current; TrileEmplacement emplacement = current.Emplacement; FaceOrientation face = FaceOrientation.Top; Vector3 position = current.Position; if (current.Enabled && !current.Hidden && (current.VisualTrile.Geometry == null || !current.VisualTrile.Geometry.Empty || current.Overlaps) && ((double) position.Y > (double) this.lastHeight - (double) num1 - 1.0 - (double) num2 && (double) position.Y < (double) this.lastHeight + (double) num1 + (double) num2 && (this.LevelManager.IsBorderTrileFace(ref emplacement, ref this.xOrientation) || this.LevelManager.IsBorderTrileFace(ref emplacement, ref this.zOrientation) || this.LevelManager.IsBorderTrileFace(ref emplacement, ref face)))) this.SafeAddToBatchWithOverlaps(current, false); } break; } case TrileUpdateAction.NoCull: foreach (TrileMaterializer trileMaterializer in this.trileMaterializers.Values) trileMaterializer.ResetBatch(); this.fallbackMaterializer.ResetBatch(); this.UnregisterAllViewedInstances(); using (IEnumerator<TrileInstance> enumerator = this.LevelManager.Triles.Values.GetEnumerator()) { while (enumerator.MoveNext()) { TrileInstance current = enumerator.Current; TrileEmplacement emplacement = current.Emplacement; if (current.Enabled && !current.Hidden && ((double) current.Position.Y > (double) this.lastHeight - 50.0 && (double) current.Position.Y < (double) this.lastHeight + 50.0) && this.LevelManager.IsBorderTrile(ref emplacement)) this.SafeAddToBatchWithOverlaps(current, false); } break; } } this.CommitBatchesIfNeeded(); }
public void CullInstances() { this.lastUpdateAction = TrileUpdateAction.None; this.CullInstances(false); }
private void CullInstances(bool viewChanged) { if (this.CameraManager.ProjectionTransition && (FezMath.IsOrthographic(this.CameraManager.Viewpoint) || this.lastUpdateAction == TrileUpdateAction.NoCull) || this.EngineState.SkipRendering) return; if (this.EngineState.LoopRender) this.lastUpdateAction = TrileUpdateAction.None; TrileUpdateAction action = this.DetermineCullType(); bool flag1 = false; float viewScale = SettingsManager.GetViewScale(this.GraphicsDevice); switch (action) { case TrileUpdateAction.SingleFaceCullPartial: case TrileUpdateAction.SingleFaceCullFull: Vector3 vector3_1 = FezMath.SideMask(this.CameraManager.Viewpoint); BoundingFrustum frustum1 = this.CameraManager.Frustum; BoundingBox boundingBox1 = new BoundingBox() { Min = { X = -frustum1.Left.D * frustum1.Left.DotNormal(vector3_1), Y = -frustum1.Bottom.D * frustum1.Bottom.Normal.Y }, Max = { X = -frustum1.Right.D * frustum1.Right.DotNormal(vector3_1), Y = -frustum1.Top.D * frustum1.Top.Normal.Y } }; Vector3 vector3_2 = FezMath.Min(boundingBox1.Min, boundingBox1.Max); Vector3 vector3_3 = FezMath.Max(boundingBox1.Min, boundingBox1.Max); this.cullingBounds = new Rectangle() { X = (int) Math.Floor((double) vector3_2.X) - 1, Y = (int) Math.Floor((double) vector3_2.Y) - 1, Width = (int) Math.Ceiling((double) vector3_3.X - (double) vector3_2.X) + 3, Height = (int) Math.Ceiling((double) vector3_3.Y - (double) vector3_2.Y) + 3 }; if (this.cullingBounds.Width < 0 || this.cullingBounds.Height < 0 || (double) this.CameraManager.Radius > 120.0 * (double) viewScale) this.cullingBounds = this.lastCullingBounds; flag1 = ((flag1 ? 1 : 0) | (Math.Abs(this.lastCullingBounds.X - this.cullingBounds.X) > 0 ? 1 : (Math.Abs(this.lastCullingBounds.Y - this.cullingBounds.Y) > 0 ? 1 : 0))) != 0; break; case TrileUpdateAction.TwoFaceCullPartial: case TrileUpdateAction.TwoFaceCullFull: Vector3 vector3_4 = FezMath.SideMask(this.CameraManager.Viewpoint); BoundingFrustum frustum2 = this.CameraManager.Frustum; Vector3 vector3_5 = FezMath.Sign(this.CameraManager.View.Forward); FaceOrientation faceOrientation1 = FezMath.OrientationFromDirection(vector3_5.X * Vector3.UnitX); FaceOrientation faceOrientation2 = FezMath.OrientationFromDirection(-vector3_5.Z * Vector3.UnitZ); bool flag2 = ((flag1 ? 1 : 0) | (faceOrientation1 != this.xOrientation ? 1 : (faceOrientation2 != this.zOrientation ? 1 : 0))) != 0; this.xOrientation = faceOrientation1; this.zOrientation = faceOrientation2; BoundingBox boundingBox2 = new BoundingBox() { Min = { X = -frustum2.Left.D * frustum2.Left.DotNormal(vector3_4), Y = -frustum2.Bottom.D * frustum2.Bottom.Normal.Y }, Max = { X = -frustum2.Right.D * frustum2.Right.DotNormal(vector3_4), Y = -frustum2.Top.D * frustum2.Top.Normal.Y } }; Vector3 vector3_6 = FezMath.Min(boundingBox2.Min, boundingBox2.Max); Vector3 vector3_7 = FezMath.Max(boundingBox2.Min, boundingBox2.Max); this.cullingBounds = new Rectangle() { X = (int) Math.Floor((double) vector3_6.X) - 1, Y = (int) Math.Floor((double) vector3_6.Y) - 1, Width = (int) Math.Ceiling((double) vector3_7.X - (double) vector3_6.X) + 3, Height = (int) Math.Ceiling((double) vector3_7.Y - (double) vector3_6.Y) + 3 }; if (this.cullingBounds.Width < 0 || this.cullingBounds.Height < 0 || (double) this.CameraManager.Radius > 120.0 * (double) viewScale) this.cullingBounds = this.lastCullingBounds; flag1 = flag2 | Math.Abs(this.lastCullingBounds.Y - this.cullingBounds.Y) > 0; break; case TrileUpdateAction.TriFaceCull: Vector3 vector3_8 = FezMath.Sign(this.CameraManager.View.Forward); FaceOrientation faceOrientation3 = FezMath.OrientationFromDirection(vector3_8.X * Vector3.UnitX); FaceOrientation faceOrientation4 = FezMath.OrientationFromDirection(-vector3_8.Z * Vector3.UnitZ); flag1 = ((flag1 ? 1 : 0) | (faceOrientation3 != this.xOrientation ? 1 : (faceOrientation4 != this.zOrientation ? 1 : 0))) != 0; this.xOrientation = faceOrientation3; this.zOrientation = faceOrientation4; if ((double) Math.Abs(this.CameraManager.InterpolatedCenter.Y - this.lastCullHeight) >= 1.0 || (double) this.lastRadius != (double) this.CameraManager.Radius) { flag1 = true; break; } else break; case TrileUpdateAction.NoCull: if ((double) Math.Abs(this.CameraManager.InterpolatedCenter.Y - this.lastCullHeight) >= 5.0) { flag1 = true; break; } else break; } this.lastHeight = this.CameraManager.InterpolatedCenter.Y; this.lastRadius = this.CameraManager.Radius; if (((flag1 | viewChanged ? 1 : 0) | (this.lastUpdateAction == action || this.lastUpdateAction == TrileUpdateAction.SingleFaceCullFull && action == TrileUpdateAction.SingleFaceCullPartial ? 0 : (this.lastUpdateAction != TrileUpdateAction.TwoFaceCullFull ? 1 : (action != TrileUpdateAction.TwoFaceCullPartial ? 1 : 0)))) != 0) { this.UpdateInstances(action); this.lastCullingBounds = this.cullingBounds; this.lastCullHeight = this.CameraManager.InterpolatedCenter.Y; } this.lastUpdateAction = action; }
public void PrepareFullCull() { this.lastUpdateAction = TrileUpdateAction.None; }