/// <summary>
        /// Builds marble geometry
        /// </summary>
        private void BuildGeometry( Units.Metres radius )
        {
            DestroyGeometry( );

            Graphics.Draw.StartCache( );
            Graphics.Draw.Sphere( null, Point3.Origin, ( float )radius.ToAstroRenderUnits, 20, 20 );
            m_Geometry = Graphics.Draw.StopCache( );
            m_GeometryRadius = radius;
        }
 /// <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>
        /// Rebuilds the ring goemetry
        /// </summary>
        private bool RebuildRingGeometry( )
        {
            DestroyVertices( );
            ISpherePlanetRingModel model = Planet.Model.GetModel<ISpherePlanetRingModel>( );
            if ( model == null )
            {
                return false;
            }

            int subdivisionCount = 256;

            List<RingVertex> vertices = new List<RingVertex>( );

            m_BuildInnerRadius = model.InnerRadius;
            m_BuildWidth = model.Width;

            float innerRadius = ( float )model.InnerRadius.ToAstroRenderUnits;
            float outerRadius = ( float )( model.InnerRadius + model.Width ).ToAstroRenderUnits;
            float angle = 0;
            float angleInc = Constants.TwoPi / ( subdivisionCount - 1 );
            bool toggle = false;
            for ( int subdivision = 0; subdivision < subdivisionCount; ++subdivision )
            {
                float x = Functions.Sin( angle );
                float y = 0;
                float z = Functions.Cos( angle );

                vertices.Add( new RingVertex( x * innerRadius, y * innerRadius, z * innerRadius, toggle ? 0 : 1, 0 ) );
                vertices.Add( new RingVertex( x * outerRadius, y * outerRadius, z * outerRadius, toggle ? 0 : 1, 1 ) );

                toggle = !toggle;
                angle += angleInc;
            }

            m_Vertices = Graphics.Factory.CreateVertexBuffer( );
            m_Vertices.Create( vertices.ToArray( ) );

            return true;
        }
 /// <summary>
 /// Setup constructor
 /// </summary>
 /// <param name="oldRadius">Old radius</param>
 /// <param name="newRadius">New radius</param>
 public RadiusChangedEventArgs( Units.Metres oldRadius, Units.Metres newRadius )
 {
     m_OldRadius = oldRadius;
     m_NewRadius = newRadius;
 }
        /// <summary>
        /// Creates a cloud shell renderable from a cloud model
        /// </summary>
        private void BuildCloudShell( IPlanetSimpleCloudModel simpleCloudModel )
        {
            DestroyCloudShell( );

            m_BuildRadius = ( simpleCloudModel.CloudLayerHeight + Planet.Model.Radius );

            Graphics.Draw.StartCache( );
            Graphics.Draw.Sphere( null, Point3.Origin, m_BuildRadius.ToRenderUnits, 50, 50 );
            m_CloudShell = Graphics.Draw.StopCache( );
        }
        /// <summary>
        /// Creates cloud sphere geometry
        /// </summary>
        private IRenderable CreateCloudSphere( )
        {
            m_BuildRadius = SpherePlanet.PlanetModel.Radius + SpherePlanet.PlanetModel.CloudModel.CloudLayerMinHeight;

            float radius = m_BuildRadius.ToRenderUnits;

            Graphics.Draw.StartCache( );
            Graphics.Draw.Sphere( null, Point3.Origin, radius, 50, 50 );
            return Graphics.Draw.StopCache( );
        }
        /// <summary>
        /// Creates the camera used by the main display
        /// </summary>
        private ICamera CreateCamera( ICommandUser user )
        {
            FirstPersonCamera camera = new FirstPersonCamera( );
            camera.PerspectiveZNear = 1.0f;
            camera.PerspectiveZFar = 15000.0f;

            Units.Metres cameraPos = BuilderState.Instance.SpherePlanet.PlanetModel.Radius;
            if ( BuilderState.Instance.SpherePlanet.PlanetModel.TerrainModel != null )
            {
                cameraPos += BuilderState.Instance.SpherePlanet.PlanetModel.TerrainModel.MaximumHeight;
            }
            else
            {
                cameraPos += new Units.Metres( 1000000 );
            }

            camera.Position = new UniPoint3( cameraPos.ToUniUnits, 0, 0 );
            new FirstPersonCameraController( user, camera );

            testDisplay.OnBeginRender += delegate { InteractionUpdateTimer.Instance.OnUpdate( ); };

            CommandControlInputSource.StartMonitoring( user, testDisplay, FirstPersonCameraCommands.DefaultBindings );

            return camera;
        }
        /// <summary>
        /// Creates a geo sphere
        /// </summary>
        private IRenderable CreateGeoSphere( Units.Metres radius, int subdivisions )
        {
            m_GeometryRadius = radius;
            Vector3[] sideNormals = new Vector3[ 6 ]
                {
                    new Vector3( 1, 0, 0 ), new Vector3( 0, 1, 0 ), new Vector3( 0, 0, 1 ),
                    new Vector3( -1, 0, 0 ), new Vector3( 0, -1, 0 ), new Vector3( 0, 0, -1 )
                };
            VertexBufferFormat format = new VertexBufferFormat( );
            format.Add<float>( VertexFieldSemantic.Position, 3 );
            format.Add<float>( VertexFieldSemantic.Normal, 3 );
            format.Add<float>( VertexFieldSemantic.Texture0, 2 );

            float renderRadius = radius.ToRenderUnits;
            float modelSideLength = 10.0f;
            float uvMul = 1.0f / subdivisions;

            VertexBufferBuilder vbBuilder = new VertexBufferBuilder( format );
            for ( int sideNormalIndex = 0; sideNormalIndex < sideNormals.Length; ++sideNormalIndex )
            {
                Vector3 sideNormal = sideNormals[ sideNormalIndex ];
                Vector3 xAxis = sideNormals[ ( sideNormalIndex + 1 ) % sideNormals.Length ];
                Vector3 yAxis = sideNormals[ ( sideNormalIndex + 2 ) % sideNormals.Length ];
                Vector3 xStride = xAxis * modelSideLength;
                Vector3 yStride = yAxis * modelSideLength;
                Vector3 xStep = xStride / subdivisions;
                Vector3 yStep = yStride / subdivisions;

                Point3 mid = Point3.Origin + sideNormal * modelSideLength / 2;

                Point3 topLeft = mid - ( xStride / 2 ) - ( yStride / 2 );
                Point3 sidePos = topLeft;
                for ( int y = 0; y < subdivisions; ++y )
                {
                    Point3 curPos = sidePos;
                    float v = y * uvMul;
                    float nV = ( y + 1 ) * uvMul;

                    for ( int x = 0; x < subdivisions; ++x )
                    {
                        Vector3 sphereNormal = curPos.ToVector3( ).MakeNormal( );
                        Vector3 sphereNxNormal = ( curPos + xStep ).ToVector3( ).MakeNormal( );
                        Vector3 sphereNyNormal = ( curPos + yStep ).ToVector3( ).MakeNormal( );
                        Vector3 sphereNxNyNormal = ( curPos + xStep + yStep ).ToVector3( ).MakeNormal( );

                        Point3 spherePos = ( sphereNormal * renderRadius ).ToPoint3( );
                        Point3 sphereNxPos = ( sphereNxNormal * renderRadius ).ToPoint3( );
                        Point3 sphereNyPos = ( sphereNyNormal * renderRadius ).ToPoint3( );
                        Point3 sphereNxNyPos = ( sphereNxNyNormal * renderRadius ).ToPoint3( );

                        float u = x * uvMul;
                        float nU = ( x + 1 ) * uvMul;

                        vbBuilder.Add( VertexFieldSemantic.Position, spherePos );
                        vbBuilder.Add( VertexFieldSemantic.Normal, sphereNormal );
                        vbBuilder.Add( VertexFieldSemantic.Texture0, u, v );

                        vbBuilder.Add( VertexFieldSemantic.Position, sphereNxPos );
                        vbBuilder.Add( VertexFieldSemantic.Normal, sphereNxNormal );
                        vbBuilder.Add( VertexFieldSemantic.Texture0, nU, v );

                        vbBuilder.Add( VertexFieldSemantic.Position, sphereNyPos );
                        vbBuilder.Add( VertexFieldSemantic.Normal, sphereNyNormal );
                        vbBuilder.Add( VertexFieldSemantic.Texture0, u, nV );

                        vbBuilder.Add( VertexFieldSemantic.Position, sphereNxPos );
                        vbBuilder.Add( VertexFieldSemantic.Normal, sphereNxNormal );
                        vbBuilder.Add( VertexFieldSemantic.Texture0, nU, v );

                        vbBuilder.Add( VertexFieldSemantic.Position, sphereNxNyPos );
                        vbBuilder.Add( VertexFieldSemantic.Normal, sphereNxNyNormal );
                        vbBuilder.Add( VertexFieldSemantic.Texture0, nU, nV );

                        vbBuilder.Add( VertexFieldSemantic.Position, sphereNyPos );
                        vbBuilder.Add( VertexFieldSemantic.Normal, sphereNyNormal );
                        vbBuilder.Add( VertexFieldSemantic.Texture0, u, nV );

                        curPos += xStep;
                    }
                    sidePos += yStep;
                }
            }

            return new VertexBufferRenderer( vbBuilder.Build( ), PrimitiveType.TriList );
        }
 /// <summary>
 /// Setup constructor
 /// </summary>
 public SpherePlanetRingModel( Units.Metres innerRadius, Units.Metres width )
 {
     m_InnerRadius = innerRadius;
     Width = width;
 }
 private void radiusRangeSlider_ValueChanged( object sender, System.EventArgs e )
 {
     if ( ModelRadiusChanged != null )
     {
         Units.Metres radius = new Units.Metres( ( double )radiusRangeSlider.Value * 1000.0 );
         ModelRadiusChanged( radius );
     }
 }