internal IEnumerable <SceneObjectBatch> GetBoundingVolumes(SceneGraphContext ctxScene)
        {
            GraphicsStateSet currentState       = ctxScene.GraphicsStateStack.Current.Push();
            TransformState   sceneGeometryModel = (TransformState)currentState[TransformState.StateSetIndex];
            Matrix4x4f       viewModel          = sceneGeometryModel.ModelView;

            if (_GeometryInstances.Count > 0)
            {
                foreach (Geometry sceneObjectBatch in _GeometryInstances)
                {
                    IBoundingVolume instanceVolume = sceneObjectBatch.BoundingVolume ?? _BoundingVolume;

                    if (instanceVolume != null && instanceVolume.IsClipped(ctxScene.ViewFrustumPlanes, viewModel))
                    {
                        continue;
                    }

                    GraphicsStateSet volumeState = currentState.Push();

                    SetBoundingVolumeState(instanceVolume, volumeState);

                    yield return(new SceneObjectBatch(
                                     _BoundingVolumeArray,
                                     volumeState,
                                     _BoundingVolumeProgram
                                     ));
                }
            }
            else
            {
                if (_BoundingVolume == null || _BoundingVolume.IsClipped(ctxScene.ViewFrustumPlanes, viewModel))
                {
                    yield break;
                }

                GraphicsStateSet volumeState = currentState.Push();

                SetBoundingVolumeState(_BoundingVolume, volumeState);

                yield return(new SceneObjectBatch(_BoundingVolumeArray, volumeState, _BoundingVolumeProgram));
            }
        }
        /// <summary>
        /// Get all geometries compositing this SceneObjectGeometry, filtering them using view-frustum.
        /// </summary>
        /// <param name="currentState">
        /// A <see cref="State.GraphicsStateSet"/> that specifies the current graphics state to be merged with
        /// each returned geometry.
        /// </param>
        /// <param name="clippingPlanes">
        ///
        /// </param>
        /// <param name="viewModel">
        ///
        /// </param>
        /// <returns>
        /// It returns a <see cref="IEnumerable{SceneObjectBatch}"/>.
        /// </returns>
        private IEnumerable <SceneObjectBatch> GetGeometriesViewFrustum(SceneGraphContext ctxScene)
        {
            GraphicsStateSet currentState       = ctxScene.GraphicsStateStack.Current.Push();
            TransformState   sceneGeometryModel = (TransformState)currentState[TransformState.StateSetIndex];
            Matrix4x4f       viewModel          = sceneGeometryModel.ModelView;

            if (_GeometryInstances.Count > 0)
            {
                foreach (Geometry sceneObjectBatch in _GeometryInstances)
                {
                    IBoundingVolume instanceVolume = sceneObjectBatch.BoundingVolume ?? _BoundingVolume;

                    if (instanceVolume != null && instanceVolume.IsClipped(ctxScene.ViewFrustumPlanes, viewModel))
                    {
                        continue;
                    }

                    GraphicsStateSet geometryState;

                    if (sceneObjectBatch.State != null)
                    {
                        geometryState = currentState.Push();
                        geometryState.Merge(sceneObjectBatch.State);
                    }
                    else
                    {
                        geometryState = currentState;
                    }

                    yield return(new SceneObjectBatch(
                                     sceneObjectBatch.VertexArray ?? VertexArray,
                                     geometryState,
                                     sceneObjectBatch.Program ?? Program
                                     ));
                }
            }
            else
            {
                if (_BoundingVolume != null && _BoundingVolume.IsClipped(ctxScene.ViewFrustumPlanes, viewModel))
                {
                    yield break;
                }

                if (VertexArray == null)
                {
                    yield break;
                }

                yield return(new SceneObjectBatch(VertexArray, currentState, Program));
            }
        }
        /// <summary>
        /// Get all geometries compositing this SceneObjectGeometry.
        /// </summary>
        /// <param name="currentState">
        /// A <see cref="State.GraphicsStateSet"/> that specifies the current graphics state to be merged with
        /// each returned geometry.
        /// </param>
        /// <returns>
        /// It returns a <see cref="IEnumerable{SceneObjectBatch}"/>.
        /// </returns>
        private IEnumerable <SceneObjectBatch> GetGeometries(GraphicsStateSet currentState)
        {
            if (currentState == null)
            {
                throw new ArgumentNullException("currentState");
            }

            if (_GeometryInstances.Count > 0)
            {
                foreach (Geometry sceneObjectBatch in _GeometryInstances)
                {
                    GraphicsStateSet geometryState;

                    if (sceneObjectBatch.State != null)
                    {
                        geometryState = currentState.Push();
                        geometryState.Merge(sceneObjectBatch.State);
                    }
                    else
                    {
                        geometryState = currentState;
                    }

                    yield return(new SceneObjectBatch(
                                     sceneObjectBatch.VertexArray ?? VertexArray,
                                     geometryState,
                                     sceneObjectBatch.Program ?? Program
                                     ));
                }
            }
            else
            {
                if (VertexArray == null)
                {
                    yield break;
                }

                yield return(new SceneObjectBatch(VertexArray, currentState, Program));
            }
        }