/// <summary>
        /// Setup constructor
        /// </summary>
        public UniRenderer( ISolarSystem scene, IUniCamera camera, ISolarSystemRenderer sceneRenderer )
        {
            Arguments.CheckNotNull( scene, "scene" );
            Arguments.CheckNotNull( camera, "camera" );
            Arguments.CheckNotNull( sceneRenderer, "sceneRenderer" );

            m_Scene = scene;
            m_Camera = camera;
            m_Renderer = sceneRenderer;
        }
 /// <summary>
 /// Sets the default camera position above a planet
 /// </summary>
 /// <param name="camera"></param>
 protected override void SetDefaultCameraPosition( IUniCamera camera )
 {
     //	Move the camera up to the surface of the planet
     Units.Metres cameraHeight;
     IPlanetTerrainModel terrain = Planet.Model.GetModel<IPlanetTerrainModel>( );
     if ( terrain != null )
     {
         cameraHeight = terrain.MaximumHeight;
     }
     else
     {
         cameraHeight = new Units.Metres( 1000 );
     }
     cameraHeight += m_Planet.Model.Radius;
     camera.Position.Set( cameraHeight.ToUniUnits, 0, 0 );
 }
        /// <summary>
        /// Renders a solar system
        /// </summary>
        /// <param name="solarSystem">The scene</param>
        /// <param name="camera">Scene camera</param>
        /// <param name="context">Rendering context</param>
        public virtual void Render( ISolarSystem solarSystem, IUniCamera camera, IRenderContext context )
        {
            Arguments.CheckNotNull( solarSystem, "solarSystem" );
            Arguments.CheckNotNull( camera, "camera" );

            UniRenderContext uniContext = new UniRenderContext( camera, context );
            uniContext.Camera = camera;

            //	Render far objects
            uniContext.CurrentPass = UniRenderPass.FarObjects;
            solarSystem.Render( uniContext );

            Graphics.Renderer.ClearDepth( 1.0f );

            //	Render close objects
            uniContext.CurrentPass = UniRenderPass.CloseObjects;
            solarSystem.Render( uniContext );
        }
        /// <summary>
        /// Renders the scene
        /// </summary>
        /// <param name="solarSystem">The scene</param>
        /// <param name="camera">Scene camera</param>
        /// <param name="context">Rendering context</param>
        public override void Render( ISolarSystem solarSystem, IUniCamera camera, IRenderContext context )
        {
            Arguments.CheckNotNull( solarSystem, "solarSystem" );
            Arguments.CheckNotNull( camera, "camera" );

            PreRender( );

            UniRenderContext uniContext = new UniRenderContext( camera, context );
            uniContext.SetRenderTarget( UniRenderTargets.OceanReflections, m_OceanReflections );
            uniContext.Camera = camera;

            //	TODO: Render close geometry into stencil buffer or Z buffer to early-out far object rendering)
            //	(careful with alpha blending)
            //	Useful only really for very expensive atmosphere rendering - we only want to calculate
            //	scattering equations for visible pixels.
            //	Have separate far/close methods for rendering atmospheres?

            //	Render far away objects into the back buffer
            uniContext.CurrentPass = UniRenderPass.FarObjects;
            solarSystem.Render( uniContext );

            //	Clear the depth buffer before rendering close objects
            RbGraphics.Renderer.ClearDepth( 1.0f );

            //	Render close object reflection geometry into a render target
            if ( EnableReflections )
            {
                RenderReflections( uniContext, solarSystem );
            }

            //	Render close object shadow geometry into a render target
            //	TODO: ...

            uniContext.Camera.Begin( );
            //	Render close objects
            uniContext.CurrentPass = UniRenderPass.CloseObjects;
            solarSystem.Render( uniContext );
            uniContext.Camera.End( );

            //	TODO: Render fullscreen quad over back buffer, for post-process effects
        }
        /// <summary>
        /// Handles loading this control. Creates a viewer that can render the terrain model
        /// </summary>
        private void UniCameraViewControl_Load( object sender, EventArgs e )
        {
            m_Camera = CreateCamera( );

            Viewer viewer = new Viewer( );
            display.AddViewer( viewer );

            display.AllowArrowKeyInputs = true;

            viewer.Camera = m_Camera;

            CommandControlInputSource.StartMonitoring( CommandUser.Default, display, FirstPersonCameraCommands.DefaultBindings );
            CommandUser.Default.CommandTriggered += OnCommandTriggered;

            //	If planet was already assigned prior to Load, add it to all views
            AddRenderableToViewers( );

            //	TODO: AP: Horrible bodge to work around InteractionUpdateTimer not working properly without manual intervention
            display.OnBeginRender += delegate { InteractionUpdateTimer.Instance.OnUpdate( ); };

            if ( InitializeRendering != null )
            {
                InitializeRendering( this, EventArgs.Empty );
            }
        }
        /// <summary>
        /// Updates patches prior to rendering
        /// </summary>
        /// <param name="camera">Camera that LOD is calculated relative to</param>
        private void UpdatePatches( IUniCamera camera )
        {
            Point3 localPos = Units.RenderUnits.MakeRelativePoint( Planet.Transform.Position, camera.Position );

            ITerrainPatchGenerator generator = ( ITerrainPatchGenerator )Planet.PlanetModel.TerrainModel;
            foreach ( TerrainPatch patch in m_RootPatches )
            {
                patch.UpdateLod( localPos, generator, camera );
            }
            foreach ( TerrainPatch patch in m_RootPatches )
            {
                patch.Update( camera, generator );
            }
        }
        private void SetupRenderUnitAtmosphereEffectParameters( IUniCamera camera, IEffect effect )
        {
            Point3 localPos = Units.RenderUnits.MakeRelativePoint( Planet.Transform.Position, camera.Position );
            float planetRadius = SpherePlanet.PlanetModel.Radius.ToRenderUnits;
            float atmosphereRadius = SpherePlanet.PlanetModel.AtmosphereModel.AtmosphereThickness.ToRenderUnits;
            float height = localPos.DistanceTo( Point3.Origin ) - planetRadius;
            float clampedHeight = Utils.Clamp( height, 0, atmosphereRadius );
            float normHeight = clampedHeight / atmosphereRadius;

            float clampedLength = planetRadius + clampedHeight;
            Vector3 groundVec = localPos.ToVector3( ).MakeLength( clampedLength );
            Point3 atmPos = Point3.Origin + groundVec;

            Vector3 viewDir = UniCamera.Current.Frame.ZAxis;
            effect.Parameters[ "AtmViewPosLength" ].Set( atmPos.DistanceTo( Point3.Origin ) );
            effect.Parameters[ "AtmViewPos" ].Set( atmPos.X, atmPos.Y, atmPos.Z );
            effect.Parameters[ "AtmViewDir" ].Set( viewDir.X, viewDir.Y, viewDir.Z );
            effect.Parameters[ "AtmViewHeight" ].Set( normHeight );
            effect.Parameters[ "AtmInnerRadius" ].Set( planetRadius );
            effect.Parameters[ "AtmThickness" ].Set( atmosphereRadius );
            effect.Parameters[ "AtmOuterRadius" ].Set( planetRadius + atmosphereRadius );
        }
 /// <summary>
 /// Finds the closest planet in the solar system
 /// </summary>
 private static IPlanet FindClosestPlanet( IUniCamera camera, ISolarSystem solarSystem, double maxDistance )
 {
     IPlanet closestPlanet = null;
     double closestDistance = maxDistance;
     foreach ( IUniObject uniObject in solarSystem.Components )
     {
         IPlanet planet = uniObject as IPlanet;
         if ( planet != null )
         {
             double distanceToCamera = planet.Transform.Position.DistanceTo( camera.Position );
             if ( distanceToCamera < closestDistance )
             {
                 closestPlanet = planet;
                 closestDistance = distanceToCamera;
             }
         }
     }
     return closestPlanet;
 }
 /// <summary>
 /// Sets up an effect used to render objects as seen through this atmosphere
 /// </summary>
 /// <param name="camera">Current camera</param>
 /// <param name="effect">Effect to set up</param>
 /// <param name="farObject">Effect is set up for a far away object</param>
 /// <remarks>
 /// Will expect certain variables to be available in the effect
 /// </remarks>
 public void SetupObjectEffect( IUniCamera camera, IEffect effect, bool farObject )
 {
     SetupAtmosphereEffectParameters( camera, effect, true, farObject );
 }
        private void SetupRenderUnitAtmosphereEffectParameters( IPlanetAtmosphereScatteringModel model, IUniCamera camera, IEffect effect )
        {
            Point3 localPos = Units.RenderUnits.MakeRelativePoint( Planet.Transform.Position, camera.Position );
            float planetRadius = Planet.Model.Radius.ToRenderUnits;
            float atmosphereRadius = model.Thickness.ToRenderUnits;
            float height = localPos.DistanceTo( Point3.Origin ) - planetRadius;
            float normHeight = height > atmosphereRadius ? 1 : ( height / atmosphereRadius );

            Vector3 viewDir = camera.Frame.ZAxis;
            effect.Parameters[ "AtmViewVec" ].Set( localPos.ToVector3( ).MakeNormal( ) );
            //	effect.Parameters[ "AtmViewPos" ].Set( atmPos );
            effect.Parameters[ "AtmViewPos" ].Set( localPos );
            effect.Parameters[ "AtmViewDir" ].Set( viewDir );
            effect.Parameters[ "AtmViewHeight" ].Set( normHeight );
            effect.Parameters[ "AtmInnerRadius" ].Set( planetRadius );
            effect.Parameters[ "AtmThickness" ].Set( atmosphereRadius );
            effect.Parameters[ "AtmOuterRadius" ].Set( planetRadius + atmosphereRadius );
        }
        /// <summary>
        /// Sets up parameters for effects that use atmospheric rendering
        /// </summary>
        /// <param name="camera">Current camera</param>
        /// <param name="effect">Effect to set up</param>
        /// <param name="objectRendering">True if the effect is being used to render an object in the atmosphere</param>
        /// <param name="farObject">If true, distances are passed to the effect in astro render units. Otherwise, render units are used.</param>
        private void SetupAtmosphereEffectParameters( IUniCamera camera, IEffect effect, bool objectRendering, bool farObject )
        {
            IPlanetAtmosphereScatteringModel model = GetModel<IPlanetAtmosphereScatteringModel>( );
            if ( model == null )
            {
                return;
            }
            if ( farObject )
            {
                SetupAstroRenderUnitAtmosphereEffectParameters( model, camera, effect );
            }
            else
            {
                SetupRenderUnitAtmosphereEffectParameters( model, camera, effect );
            }

            //	Set up parameters shared between astro and close atmosphere rendering
            effect.Parameters[ "AtmObjectColourOutput" ].Set( ( int )model.ObjectColourOutput );
            effect.Parameters[ "AtmHgCoeff" ].Set( model.PhaseCoefficient );
            effect.Parameters[ "AtmPhaseWeight" ].Set( model.PhaseWeight );
            effect.Parameters[ "ScatteringTexture" ].Set( model.ScatteringTexture );
            effect.Parameters[ "AtmMiePhaseWeight" ].Set( model.MiePhaseWeight );
            if ( objectRendering )
            {
                effect.Parameters[ "OpticalDepthTexture" ].Set( model.OpticalDepthTexture );
            }
        }
 /// <summary>
 /// Setup constructor
 /// </summary>
 public UniRenderContext( IUniCamera camera, IRenderContext originalContext )
 {
     m_Camera = camera;
     RenderTime = originalContext.RenderTime;
     RenderFrameCounter = originalContext.RenderFrameCounter;
 }
Exemplo n.º 13
0
 /// <summary>
 /// Pushes a rendering transform suitable for astronomical distances
 /// </summary>
 public static void PushAstroRenderTransform( IUniCamera camera, TransformType transformType, UniTransform transform )
 {
     Graphics.Renderer.PushTransform( transformType );
     SetAstroRenderTransform( camera, transformType, transform );
 }
Exemplo n.º 14
0
        /// <summary>
        /// Sets the rendering transform (<see cref="IRenderer.SetTransform(TransformType,InvariantMatrix44)"/>)
        /// </summary>
        public static void SetRenderTransform( IUniCamera camera, TransformType transformType, UniTransform transform )
        {
            float x = ( float )Units.Convert.UniToRender( transform.Position.X - camera.Position.X );
            float y = ( float )Units.Convert.UniToRender( transform.Position.Y - camera.Position.Y );
            float z = ( float )Units.Convert.UniToRender( transform.Position.Z - camera.Position.Z );

            Graphics.Renderer.SetTransform( transformType, new Point3( x, y, z ), transform.XAxis, transform.YAxis, transform.ZAxis );
        }