Пример #1
0
        /// <summary>
        /// Create the corresponding <see cref="LightsState.Light"/> for this object.
        /// </summary>
        /// <returns>
        /// It returns the <see cref="LightsState.Light"/> equivalent to this SceneObjectLight.
        /// </returns>
        public override LightsState.Light ToLight(GraphicsContext ctx, SceneGraphContext sceneCtx)
        {
            TransformStateBase transformState = (TransformStateBase)sceneCtx.GraphicsStateStack.Current[TransformStateBase.StateSetIndex];

            LightsState.LightSpot light = new LightsState.LightSpot();

            SetLightParameters(sceneCtx, light);

            IModelMatrix worldModel   = transformState.LocalModelView;
            IMatrix3x3   normalMatrix = worldModel.GetComplementMatrix(3, 3).GetInverseMatrix().Transpose();

            light.Direction          = ((Vertex3f)normalMatrix.Multiply((Vertex3f)Direction)).Normalized;
            light.Position           = (Vertex3f)worldModel.Multiply(Vertex3f.Zero);
            light.AttenuationFactors = AttenuationFactors;
            light.FallOff            = new Vertex2f((float)Math.Cos(Angle.ToRadians(FalloffAngle)), FalloffExponent);

            // Shadow mapping
            if (_ShadowMap != null && _ShadowViewMatrix != null)
            {
                // Determined later: light.ShadowMapIndex
                light.ShadowMapMvp.Set(_ShadowViewMatrix);
                light.ShadowMap2D = _ShadowMap;
            }
            else
            {
                light.ShadowMapIndex = -1;
                light.ShadowMap2D    = null;
            }

            return(light);
        }
Пример #2
0
        /// <summary>
        /// Get geometries related to this object.
        /// </summary>
        /// <param name="ctx"></param>
        /// <param name="ctxScene"></param>
        /// <returns></returns>
        internal override IEnumerable <SceneObjectBatch> GetGeometries(GraphicsContext ctx, SceneGraphContext ctxScene)
        {
            List <SceneObjectBatch> geometries = new List <SceneObjectBatch>();

            GraphicsStateSet   sceneGeometryState = ctxScene.GraphicsStateStack.Current.Push();
            TransformStateBase sceneGeometryModel = (TransformStateBase)sceneGeometryState[TransformStateBase.StateSetIndex];

            if ((ctxScene.Scene.SceneFlags & SceneGraphFlags.CullingViewFrustum) != 0)
            {
                // View-frustum culling
                geometries.AddRange(GetGeometriesViewFrustum(ctxScene));
            }
            else
            {
                // All geometries
                geometries.AddRange(GetGeometries(sceneGeometryState));
            }

            // Bounding volumes
            if ((ctxScene.Scene.SceneFlags & SceneGraphFlags.BoundingVolumes) != 0)
            {
                if ((ctxScene.Scene.SceneFlags & SceneGraphFlags.CullingViewFrustum) != 0)
                {
                    // View-frustum culling
                    geometries.AddRange(GetBoundingVolumes(ctxScene));
                }
            }

            return(geometries);
        }
Пример #3
0
        internal override IEnumerable <SceneObjectBatch> GetGeometries(GraphicsContext ctx, SceneGraphContext ctxScene)
        {
            if ((ctxScene.Scene.SceneFlags & SceneGraphFlags.BoundingVolumes) != 0)
            {
                GraphicsStateSet boundingVolumeState = ctxScene.GraphicsStateStack.Current.Push();

                // Transform
                TransformStateBase boundingVolumeModel = (TransformStateBase)boundingVolumeState[TransformStateBase.StateSetIndex];

                float lightVolumeDepth = 100.0f;
                float lightVolumeSize  = lightVolumeDepth * (float)Math.Tan(Angle.ToRadians(FalloffAngle));

                boundingVolumeModel.LocalModelViewProjection.Set(boundingVolumeModel.LocalModelViewProjection.Multiply(LightMatrix));
                boundingVolumeModel.LocalModelViewProjection.Translate(0.0f, 0.0f, lightVolumeDepth);
                boundingVolumeModel.LocalModelViewProjection.Scale(lightVolumeSize, lightVolumeSize, lightVolumeDepth);

                // Uniform color
                ShaderUniformState uniformState = new ShaderUniformState("UniformState");
                uniformState.SetUniformState("glo_UniformColor", new ColorRGBAF(1.0f, 1.0f, 0.0f, 0.5f));
                boundingVolumeState.DefineState(uniformState);
                // Alpha blending
                boundingVolumeState.DefineState(BlendState.AlphaBlending);

                yield return(new SceneObjectBatch(
                                 _BoundingVolumeArrays,
                                 boundingVolumeState,
                                 _BoundingVolumeProgram
                                 ));
            }

            yield break;
        }
Пример #4
0
        /// <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();
            TransformStateBase sceneGeometryModel = (TransformStateBase)currentState[TransformStateBase.StateSetIndex];
            IMatrix4x4         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));
            }
        }
Пример #5
0
        /// <summary>
        /// Create the corresponding <see cref="LightsState.Light"/> for this object.
        /// </summary>
        /// <returns>
        /// It returns the <see cref="LightsState.Light"/> equivalent to this SceneObjectLight.
        /// </returns>
        public override LightsState.Light ToLight(GraphicsContext ctx, SceneGraphContext sceneCtx)
        {
            LightsState.LightDirectional light = new LightsState.LightDirectional();

            SetLightParameters(sceneCtx, light);

            TransformStateBase transformState = (TransformStateBase)sceneCtx.GraphicsStateStack.Current[TransformStateBase.StateSetIndex];
            IMatrix3x3         normalMatrix   = transformState.NormalMatrix;

            light.Direction  = ((Vertex3f)normalMatrix.Multiply((Vertex3f)Direction)).Normalized;
            light.HalfVector = (Vertex3f.UnitZ + light.Direction).Normalized;

            return(light);
        }
Пример #6
0
        private static void SetBoundingVolumeState(BoundingBox boundingVolume, GraphicsStateSet volumeState)
        {
            // Set transform state
            TransformStateBase transformState = (TransformStateBase)volumeState[TransformStateBase.StateSetIndex];

            if (transformState == null)
            {
                return;
            }

            Vertex3f min = boundingVolume.MinPosition, max = boundingVolume.MaxPosition;
            Vertex3f size = boundingVolume.Size;

            // Scale model matrix in order to represent the bounding box with the correct size and barycenter
            transformState.LocalModelViewProjection.Translate((max + min) / 2.0f);
            transformState.LocalModelViewProjection.Scale(size);
        }
Пример #7
0
        /// <summary>
        /// Traverse delegate for collecting geometries to be drawn.
        /// </summary>
        /// <param name="ctx">
        /// The <see cref="GraphicsContext"/> used for drawing.
        /// </param>
        /// <param name="ctxScene"></param>
        /// <param name="sceneObject"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        private static bool GraphDrawDelegate(GraphicsContext ctx, SceneGraphContext ctxScene, SceneObject sceneObject, object data)
        {
            ObjectBatchContext objectBatchContext = (ObjectBatchContext)data;

            if (sceneObject.ObjectType == SceneObjectGeometry.ClassObjectType)
            {
                SceneObjectGeometry sceneGeometry      = (SceneObjectGeometry)sceneObject;
                GraphicsStateSet    sceneGeometryState = ctxScene.GraphicsStateStack.Current;
                TransformStateBase  sceneGeometryModel = (TransformStateBase)sceneGeometryState[TransformStateBase.StateSetIndex];

                IEnumerable <SceneObjectBatch> geometries;

                if ((ctxScene.Scene.SceneFlags & SceneGraphFlags.CullingViewFrustum) != 0)
                {
                    // View-frustum culling
                    geometries = sceneGeometry.GetGeometries(sceneGeometryState, objectBatchContext.ViewFrustumPlanes, sceneGeometryModel.ModelView);
                }
                else
                {
                    // All geometries
                    geometries = sceneGeometry.GetGeometries(sceneGeometryState);
                }

                objectBatchContext.Objects.AddRange(geometries);

                // Bounding volumes
                if ((ctxScene.Scene.SceneFlags & SceneGraphFlags.BoundingVolumes) != 0)
                {
                }
            }
            else if (sceneObject.ObjectType == SceneObjectLightZone.ClassObjectType)
            {
                SceneObjectLightZone sceneObjectLightZone = (SceneObjectLightZone)sceneObject;

                // TODO: Push instead of Clear to support stacked zones
                objectBatchContext.Lights.Clear();
                objectBatchContext.LightZone = sceneObjectLightZone;
            }
            else if (sceneObject.ObjectType == SceneObjectLight.ClassObjectType)
            {
                objectBatchContext.Lights.Add((SceneObjectLight)sceneObject);
            }

            return(true);
        }
Пример #8
0
        internal IEnumerable <SceneObjectBatch> GetBoundingVolumes(SceneGraphContext ctxScene)
        {
            GraphicsStateSet   currentState       = ctxScene.GraphicsStateStack.Current.Push();
            TransformStateBase sceneGeometryModel = (TransformStateBase)currentState[TransformStateBase.StateSetIndex];
            IMatrix4x4         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));
            }
        }