Ejemplo n.º 1
0
        /// <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);
            }
        }
Ejemplo n.º 2
0
        /// <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);
        }
Ejemplo n.º 3
0
        /// <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);
        }
Ejemplo n.º 4
0
        /// <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);
        }
Ejemplo n.º 5
0
        /// <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[] { });
        }
Ejemplo n.º 6
0
        /// <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);
        }
Ejemplo n.º 7
0
        /// <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);
        }
Ejemplo n.º 8
0
        /// <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);
        }
Ejemplo n.º 9
0
        /// <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);
        }
Ejemplo n.º 10
0
        /// <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);
        }
Ejemplo n.º 11
0
        /// <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);
        }
Ejemplo n.º 12
0
        /// <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));
        }