Ejemplo n.º 1
0
        public void Render(Bitmap output, SceneBrep scene)
        {
            if (output == null ||
                scene == null)
            {
                return;
            }

            Vector3 center;
            float   diameter = scene.GetDiameter(out center);

            if (Distance < diameter)
            {
                Distance = diameter;
            }

            // and the rest of projection matrix goes here:
            int    width  = output.Width;
            int    height = output.Height;
            float  aspect = width / (float)height;
            double az     = Azimuth / 180.0 * Math.PI;
            double el     = Elevation / 180.0 * Math.PI;

            Vector3 eye = new Vector3((float)(center.X + Distance * Math.Sin(az) * Math.Cos(el)),
                                      (float)(center.Y + Distance * Math.Sin(el)),
                                      (float)(center.Z + Distance * Math.Cos(az) * Math.Cos(el)));
            Matrix4 modelView = Matrix4.LookAt(eye, center, Vector3.UnitY);
            Matrix4 proj;

            if (Perspective)
            {
                float vv = (float)(2.0 * Math.Atan2(diameter * 0.5, Distance));
                proj = Matrix4.CreatePerspectiveFieldOfView(vv, aspect, 1.0f, 50.0f);
            }
            else
            {
                float vHalf = diameter * 0.52f;
                proj = Matrix4.CreateOrthographicOffCenter(-vHalf, vHalf,
                                                           -vHalf / aspect, vHalf / aspect,
                                                           1.0f, 50.0f);
            }

            Matrix4 compound = Matrix4.Mult(modelView, proj);
            Matrix4 viewport = Geometry.SetViewport(0, 0, width, height);

            compound = Matrix4.Mult(compound, viewport);

            // wireframe rendering:
            Graphics gr  = Graphics.FromImage(output);
            Pen      pen = new Pen(Color.FromArgb(255, 255, 80), 1.0f);
            int      n   = scene.Triangles;

            for (int i = 0; i < n; i++)
            {
                Vector4 A, B, C;
                scene.GetTriangleVertices(i, out A, out B, out C);
                A = Vector4.Transform(A, compound);
                B = Vector4.Transform(B, compound);
                C = Vector4.Transform(C, compound);
                Vector2 a = new Vector2(A.X / A.W, A.Y / A.W);
                Vector2 b = new Vector2(B.X / B.W, B.Y / B.W);
                Vector2 c = new Vector2(C.X / C.W, C.Y / C.W);
                gr.DrawLine(pen, a.X, a.Y, b.X, b.Y);
                gr.DrawLine(pen, b.X, b.Y, c.X, c.Y);
                gr.DrawLine(pen, c.X, c.Y, a.X, a.Y);
            }

            if (DrawNormals && scene.Normals > 0)
            {
                pen = new Pen(Color.FromArgb(255, 80, 80), 1.0f);
                n   = scene.Vertices;
                for (int i = 0; i < n; i++)
                {
                    Vector4 V = new Vector4(scene.GetVertex(i), 1.0f);
                    Vector3 N = scene.GetNormal(i);
                    N.Normalize();
                    N *= diameter * 0.03f;
                    Vector4 W = V + new Vector4(N);
                    V = Vector4.Transform(V, compound);
                    W = Vector4.Transform(W, compound);
                    Vector2 v = new Vector2(V.X / V.W, V.Y / V.W);
                    Vector2 w = new Vector2(W.X / W.W, W.Y / W.W);
                    gr.DrawLine(pen, v.X, v.Y, w.X, w.Y);
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Generic OBJ-loading scene definition routine.
        /// </summary>
        /// <param name="dir">Viewing direction of a camera.</param>
        /// <param name="FoVy">Field of View in degrees.</param>
        /// <param name="correction">Value less than 1.0 brings camera nearer.</param>
        /// <param name="name">OBJ file-name.</param>
        /// <param name="names">Substitute file-name[s].</param>
        /// <returns>Number of triangles.</returns>
        protected static long SceneObj( IRayScene sc, Vector3d dir, double FoVy, double correction, string name, string[] names, double[] surfaceColor )
        {
            Debug.Assert( sc != null );

              Vector3 center = Vector3.Zero;   // center of the mesh
              dir.Normalize();                 // normalized viewing vector of the camera
              float diameter = 2.0f;           // default scene diameter
              int faces = 0;

              // CSG scene:
              CSGInnerNode root = new CSGInnerNode( SetOperation.Union );

              // OBJ file to read:
              if ( names.Length == 0 ||
               names[ 0 ].Length == 0 )
            names = new string[] { name };

              string[] paths = Scenes.SmartFindFiles( names );
              if ( paths[ 0 ] == null || paths[ 0 ].Length == 0 )
              {
            for ( int i = 0; i < names.Length; i++ )
              if ( names[ i ].Length > 0 )
            names[ i ] += ".gz";
            paths = Scenes.SmartFindFiles( names );
              }
              if ( paths[ 0 ] == null || paths[ 0 ].Length == 0 )
            root.InsertChild( new Sphere(), Matrix4d.Identity );
              else
              {
            // B-rep scene construction:
            WavefrontObj objReader = new WavefrontObj();
            objReader.MirrorConversion = false;
            SceneBrep brep = new SceneBrep();
            faces = objReader.ReadBrep( paths[ 0 ], brep );
            brep.BuildCornerTable();
            diameter = brep.GetDiameter( out center );
            TriangleMesh m = new TriangleMesh( brep );
            root.InsertChild( m, Matrix4d.Identity );
              }

              root.SetAttribute( PropertyName.REFLECTANCE_MODEL, new PhongModel() );
              root.SetAttribute( PropertyName.MATERIAL, new PhongMaterial( surfaceColor, 0.2, 0.5, 0.4, 32 ) );
              root.SetAttribute( PropertyName.COLOR, surfaceColor );
              sc.Intersectable = root;

              // Background color:
              sc.BackgroundColor = new double[] { 0.0, 0.05, 0.07 };

              // Camera:
              double dist = (0.5 * diameter * correction) / Math.Tan( MathHelper.DegreesToRadians( (float)(0.5 * FoVy) ) );
              Vector3d cam = (Vector3d)center - dist * dir;
              sc.Camera = new StaticCamera( cam, dir, FoVy );

              // Light sources:
              sc.Sources = new LinkedList<ILightSource>();
              sc.Sources.Add( new AmbientLightSource( 0.8 ) );
              Vector3d lightDir = Vector3d.TransformVector( dir, Matrix4d.CreateRotationY( -2.0 ) );
              lightDir = Vector3d.TransformVector( lightDir, Matrix4d.CreateRotationZ( -0.8 ) );
              sc.Sources.Add( new PointLightSource( (Vector3d)center + diameter * lightDir, 1.0 ) );

              return faces;
        }
Ejemplo n.º 3
0
        public void Render( Bitmap output, SceneBrep scene )
        {
            if ( output == null ||
               scene  == null ) return;

              Vector3 center;
              float diameter = scene.GetDiameter( out center );
              if ( Distance < diameter ) Distance = diameter;

              // and the rest of projection matrix goes here:
              int width    = output.Width;
              int height   = output.Height;
              float aspect = width / (float)height;
              double az    = Azimuth / 180.0 * Math.PI;
              double el    = Elevation / 180.0 * Math.PI;

              Vector3 eye   = new Vector3( (float)(center.X + Distance * Math.Sin( az ) * Math.Cos( el )),
                                   (float)(center.Y + Distance * Math.Sin( el )),
                                   (float)(center.Z + Distance * Math.Cos( az ) * Math.Cos( el )) );
              Matrix4 modelView = Matrix4.LookAt( eye, center, Vector3.UnitY );
              Matrix4 proj;

              if ( Perspective )
              {
            float vv = (float)(2.0 * Math.Atan2( diameter * 0.5, Distance ));
            proj = Matrix4.CreatePerspectiveFieldOfView( vv, aspect, 1.0f, 50.0f );
              }
              else
              {
            float vHalf = diameter * 0.52f;
            proj = Matrix4.CreateOrthographicOffCenter( -vHalf, vHalf,
                                                    -vHalf / aspect, vHalf / aspect,
                                                    1.0f, 50.0f );
              }

              Matrix4 compound = Matrix4.Mult( modelView, proj );
              Matrix4 viewport = Geometry.SetViewport( 0, 0, width, height );
              compound = Matrix4.Mult( compound, viewport );

              // wireframe rendering:
              Graphics gr = Graphics.FromImage( output );
              Pen pen = new Pen( Color.FromArgb( 255, 255, 80 ), 1.0f );
              int n = scene.Triangles;
              for ( int i = 0; i < n; i++ )
              {
            Vector4 A, B, C;
            scene.GetTriangleVertices( i, out A, out B, out C );
            A = Vector4.Transform( A, compound );
            B = Vector4.Transform( B, compound );
            C = Vector4.Transform( C, compound );
            Vector2 a = new Vector2( A.X / A.W, A.Y / A.W );
            Vector2 b = new Vector2( B.X / B.W, B.Y / B.W );
            Vector2 c = new Vector2( C.X / C.W, C.Y / C.W );
            gr.DrawLine( pen, a.X, a.Y, b.X, b.Y );
            gr.DrawLine( pen, b.X, b.Y, c.X, c.Y );
            gr.DrawLine( pen, c.X, c.Y, a.X, a.Y );
              }

              if ( DrawNormals && scene.Normals > 0 )
              {
            pen = new Pen( Color.FromArgb( 255, 80, 80 ), 1.0f );
            n = scene.Vertices;
            for ( int i = 0; i < n; i++ )
            {
              Vector4 V = new Vector4( scene.GetVertex( i ), 1.0f );
              Vector3 N = scene.GetNormal( i );
              N.Normalize();
              N *= diameter * 0.03f;
              Vector4 W = V + new Vector4( N );
              V = Vector4.Transform( V, compound );
              W = Vector4.Transform( W, compound );
              Vector2 v = new Vector2( V.X / V.W, V.Y / V.W );
              Vector2 w = new Vector2( W.X / W.W, W.Y / W.W );
              gr.DrawLine( pen, v.X, v.Y, w.X, w.Y );
            }
              }
        }