/// <summary> /// Cull test for spot lights /// </summary> /// <param name="volume">Volume</param> /// <param name="viewerPosition">Viewer position</param> private void CullSpotLights(ICullingVolume volume, Vector3 viewerPosition) { var sLights = this.spotLights.FindAll(l => { if (l.Enabled && volume.Contains(l.BoundingSphere) != ContainmentType.Disjoint) { float d = Vector3.Distance(viewerPosition, l.Position); return((l.Radius / d) >= (1f / GameEnvironment.LODDistanceLow)); } return(false); }); if (sLights.Count > 0) { sLights.Sort((l1, l2) => { float d1 = Vector3.Distance(viewerPosition, l1.Position); float d2 = Vector3.Distance(viewerPosition, l2.Position); float f1 = l1.Radius / d1 == 0 ? 1 : d1; float f2 = l2.Radius / d2 == 0 ? 1 : d2; return(f1.CompareTo(f2)); }); this.visibleLights.AddRange(sLights); } }
/// <summary> /// Performs culling with the active emitters /// </summary> /// <param name="volume">Culling volume</param> /// <param name="distance">If the at least one of the internal emitters is visible, returns the distance to the item</param> /// <returns>Returns true if all emitters were culled</returns> public override bool Cull(ICullingVolume volume, out float distance) { bool cull = true; distance = float.MaxValue; float minDistance = float.MaxValue; this.ParticleSystems.ForEach(p => { var c = p.Emitter.Cull(volume, out float d); if (!c) { cull = false; minDistance = Math.Min(d, minDistance); } }); if (!cull) { distance = minDistance; } return(cull); }
/// <summary> /// Performs culling test /// </summary> /// <param name="volume">Culling volume</param> /// <param name="distance">If the object is inside the volume, returns the distance</param> /// <returns>Returns true if the object is outside of the frustum</returns> public override bool Cull(ICullingVolume volume, out float distance) { distance = float.MaxValue; if (base.Cull(volume, out distance)) { return(true); } this.visibleNodes = this.groundPickingQuadtree.GetNodesInVolume(volume).ToArray(); if (!this.visibleNodes.Any()) { return(true); } if (this.visibleNodes.Length > 1) { //Sort nodes by center distance to the culling volume position - nearest nodes first Array.Sort(this.visibleNodes, (n1, n2) => { float d1 = (n1.Center - volume.Position).LengthSquared(); float d2 = (n2.Center - volume.Position).LengthSquared(); return(d1.CompareTo(d2)); }); } distance = Vector3.DistanceSquared(volume.Position, this.visibleNodes[0].Center); return(false); }
/// <summary> /// Cull test /// </summary> /// <param name="volume">Volume</param> /// <param name="viewerPosition">Viewer position</param> public void Cull(ICullingVolume volume, Vector3 viewerPosition) { this.visibleLights.Clear(); this.CullDirectionalLights(); this.CullPointLights(volume, viewerPosition); this.CullSpotLights(volume, viewerPosition); }
/// <summary> /// Gets the node list suitable for foliage planting /// </summary> /// <param name="volume">Culling volume</param> /// <param name="sph">Foliagle bounding sphere</param> /// <returns>Returns a node list</returns> private IEnumerable <QuadTreeNode> GetFoliageNodes(ICullingVolume volume, BoundingSphere sph) { var nodes = this.foliageQuadtree.GetNodesInVolume(ref sph); if (nodes?.Any() == true) { return(nodes.Where(n => volume.Contains(n.BoundingBox) != ContainmentType.Disjoint)); } return(new QuadTreeNode[] { }); }
/// <summary> /// Performs a culling test against the specified frustum /// </summary> /// <param name="volume">Culling volume</param> /// <param name="distance">If the object is inside the volume, returns the distance</param> /// <returns>Returns true if the emitter is outside of the frustum</returns> public bool Cull(ICullingVolume volume, out float distance) { distance = float.MaxValue; var bbox = this.GetBoundingBox(); var inside = volume.Contains(bbox) != ContainmentType.Disjoint; if (inside) { distance = Vector3.DistanceSquared(volume.Position, this.Position); } return(this.Culled = !inside); }
/// <summary> /// Performs culling test /// </summary> /// <param name="volume">Culling volume</param> /// <param name="distance">If the object is inside the volume, returns the distance</param> /// <returns>Returns true if the object is outside of the frustum</returns> public override bool Cull(ICullingVolume volume, out float distance) { distance = float.MaxValue; if (groundPickingQuadtree == null) { return(false); } bool cull = volume.Contains(groundPickingQuadtree.BoundingBox) == ContainmentType.Disjoint; if (!cull) { distance = 0; } return(cull); }
/// <summary> /// Performs culling test /// </summary> /// <param name="volume">Culling volume</param> /// <param name="distance">If any instance is inside the volume, returns zero</param> /// <returns>Returns true if all of the instances were outside of the frustum</returns> public override bool Cull(ICullingVolume volume, out float distance) { if (this.instancesTmp?.Length > 0) { var item = this.instancesTmp.FirstOrDefault(i => { return(i.Visible && !i.Cull(volume, out float iDistance)); }); if (item != null) { distance = 0; return(false); } } distance = float.MaxValue; return(true); }
/// <summary> /// Performs culling test /// </summary> /// <param name="volume">Culling volume</param> /// <param name="distance">If the object is inside the volume, returns the distance</param> /// <returns>Returns true if the object is outside of the frustum</returns> public override bool Cull(ICullingVolume volume, out float distance) { bool cull; distance = float.MaxValue; if (this.HasVolumes) { if (this.coarseBoundingSphere.HasValue) { cull = volume.Contains(this.coarseBoundingSphere.Value) == ContainmentType.Disjoint; } else if (this.SphericVolume) { cull = volume.Contains(this.GetBoundingSphere()) == ContainmentType.Disjoint; } else { cull = volume.Contains(this.GetBoundingBox()) == ContainmentType.Disjoint; } } else { cull = false; } if (!cull) { var eyePosition = volume.Position; distance = Vector3.DistanceSquared(this.Manipulator.Position, eyePosition); this.LevelOfDetail = GameEnvironment.GetLOD( eyePosition, this.coarseBoundingSphere, this.Manipulator.LocalTransform, this.Manipulator.AveragingScale); } return(cull); }
/// <summary> /// Performs cull test in the object list against the culling volume /// </summary> /// <param name="volume">Culling volume</param> /// <param name="index">Results index</param> /// <param name="objects">Objects list</param> /// <returns>Returns true if any object results inside the volume</returns> public bool Cull(ICullingVolume volume, int index, IEnumerable <ICullable> objects) { bool res = false; foreach (var item in objects) { var cull = item.Cull(volume, out float distance); var cullData = new CullData { Culled = cull, Distance = distance, }; this.SetCullValue(cullData, index, item, false); if (!cullData.Culled) { res = true; } } return(res); }
/// <summary> /// Performs culling test /// </summary> /// <param name="volume">Volume</param> /// <param name="distance">If the object is inside the volume, returns the distance</param> /// <returns>Returns true if the object is outside of the frustum</returns> /// <remarks>By default, returns true and distance = float.MaxValue</remarks> public virtual bool Cull(ICullingVolume volume, out float distance) { distance = float.MaxValue; return(false); }
/// <summary> /// Performs culling test /// </summary> /// <param name="volume">Culling volume</param> /// <param name="distance">If the object is inside the volume, returns the distance</param> /// <returns>Returns true if the object is outside of the frustum</returns> /// <remarks>By default, returns true and distance = float.MaxValue</remarks> public override bool Cull(ICullingVolume volume, out float distance) { this.drawContext.Lights.Cull(volume, this.drawContext.EyePosition); return(base.Cull(volume, out distance)); }