public static void TestScene(IRayScene sc, string param) { Debug.Assert(sc != null); // CSG scene: CSGInnerNode root = new CSGInnerNode(SetOperation.Union); root.SetAttribute(PropertyName.REFLECTANCE_MODEL, new PhongModel()); root.SetAttribute(PropertyName.MATERIAL, new PhongMaterial(new double[] { 1.0, 0.8, 0.1 }, 0.1, 0.7, 0.2, 128)); sc.Intersectable = root; // Background color: sc.BackgroundColor = new double[] { 0.0, 0.05, 0.07 }; // Camera: sc.Camera = new StaticCamera(new Vector3d(0.7, 0.5, -5.0), new Vector3d(0.0, -0.28, 1.0), 50.0); // Light sources: sc.Sources = new LinkedList <ILightSource>(); sc.Sources.Add(new AmbientLightSource(0.8)); //sc.Sources.Add( new PointLightSource( new Vector3d( -5.0, 4.0, -3.0 ), 1.2 ) ); /* */ // horizontal stick source: //RectangleLightSource rls = new RectangleLightSource( new Vector3d( -5.0, 4.0, -6.0 ), // new Vector3d( 0.0, 0.0, 6.0 ), // new Vector3d( 0.0, 0.1, 0.0 ), 1.8 ); // vertical stick source: RectangleLightSource rls = new RectangleLightSource(new Vector3d(-5.0, 1.0, -3.0), new Vector3d(0.0, 0.0, 0.1), new Vector3d(0.0, 6.0, 0.0), 1.8); // rectangle source: //RectangleLightSource rls = new RectangleLightSource( new Vector3d( -5.0, 1.0, -6.0 ), // new Vector3d( 0.0, 0.0, 6.0 ), // new Vector3d( 0.0, 6.0, 0.0 ), 1.8 ); rls.Dim = new double[] { 1.0, 0.05, 0.0 }; sc.Sources.Add(rls); /* */ // --- NODE DEFINITIONS ---------------------------------------------------- // Sphere: Sphere s = new Sphere(); root.InsertChild(s, Matrix4d.Identity); // Infinite plane with checker: Plane pl = new Plane(); pl.SetAttribute(PropertyName.COLOR, new double[] { 0.3, 0.0, 0.0 }); pl.SetAttribute(PropertyName.TEXTURE, new CheckerTexture(0.6, 0.6, new double[] { 1.0, 1.0, 1.0 })); root.SetAttribute(PropertyName.MATERIAL, new PhongMaterial(new double[] { 1.0, 0.8, 0.1 }, 0.1, 0.3, 0.7, 16)); root.InsertChild(pl, Matrix4d.RotateX(-MathHelper.PiOver2) * Matrix4d.CreateTranslation(0.0, -1.0, 0.0)); }
public static void TestScene(IRayScene sc, string param) { Debug.Assert(sc != null); // CSG scene: CSGInnerNode root = new CSGInnerNode(SetOperation.Union); root.SetAttribute(PropertyName.REFLECTANCE_MODEL, new PhongModel()); root.SetAttribute(PropertyName.MATERIAL, new PhongMaterial(new double[] { 0.6, 0.0, 0.0 }, 0.15, 0.8, 0.15, 16)); sc.Intersectable = root; // Background color: sc.BackgroundColor = new double[] { 0.0, 0.05, 0.07 }; // Camera: sc.Camera = new StaticCamera(new Vector3d(0.7, 3.0, -10.0), new Vector3d(0.0, -0.2, 1.0), 50.0); // Light sources: sc.Sources = new LinkedList <ILightSource>(); sc.Sources.Add(new AmbientLightSource(0.8)); sc.Sources.Add(new PointLightSource(new Vector3d(-5.0, 3.0, -3.0), 1.0)); // --- NODE DEFINITIONS ---------------------------------------------------- // Base plane Plane pl = new Plane(); pl.SetAttribute(PropertyName.COLOR, new double[] { 0.0, 0.2, 0.0 }); pl.SetAttribute(PropertyName.TEXTURE, new CheckerTexture(0.5, 0.5, new double[] { 1.0, 1.0, 1.0 })); root.InsertChild(pl, Matrix4d.RotateX(-MathHelper.PiOver2) * Matrix4d.CreateTranslation(0.0, -1.0, 0.0)); // Cylinders Cylinder c = new Cylinder(); root.InsertChild(c, Matrix4d.RotateX(MathHelper.PiOver2) * Matrix4d.CreateTranslation(-2.1, 0.0, 1.0)); c = new Cylinder(); c.SetAttribute(PropertyName.COLOR, new double[] { 0.2, 0.0, 0.7 }); c.SetAttribute(PropertyName.TEXTURE, new CheckerTexture(12.0, 1.0, new double[] { 0.0, 0.0, 0.3 })); root.InsertChild(c, Matrix4d.RotateY(-0.4) * Matrix4d.CreateTranslation(1.0, 0.0, 1.0)); c = new Cylinder(0.0, 100.0); c.SetAttribute(PropertyName.COLOR, new double[] { 0.1, 0.7, 0.0 }); root.InsertChild(c, Matrix4d.RotateY(0.2) * Matrix4d.CreateTranslation(5.0, 0.3, 4.0)); c = new Cylinder(-0.5, 0.5); c.SetAttribute(PropertyName.COLOR, new double[] { 0.8, 0.6, 0.0 }); root.InsertChild(c, Matrix4d.Scale(2.0) * Matrix4d.RotateX(1.2) * Matrix4d.CreateTranslation(2.0, 1.8, 16.0)); }
/// <summary> /// Hedgehog in the Cage - by Michal Wirth, (c) 2012 /// </summary> public static void HedgehogInTheCage( IRayScene sc ) { Debug.Assert( sc != null ); // CSG scene: CSGInnerNode root = new CSGInnerNode( SetOperation.Union ); root.SetAttribute( PropertyName.REFLECTANCE_MODEL, new PhongModel() ); root.SetAttribute( PropertyName.MATERIAL, new PhongMaterial( new double[] { 0.5, 0.5, 0.5 }, 0.2, 0.6, 0.2, 16 ) ); sc.Intersectable = root; // Background color: sc.BackgroundColor = new double[] { 0.0, 0.05, 0.05 }; // Camera: sc.Camera = new StaticCamera( new Vector3d( 0.0, 2.0, -7.0 ), new Vector3d( 0.0, -0.32, 1.0 ), 40.0 ); // Light sources: sc.Sources = new LinkedList<ILightSource>(); sc.Sources.Add( new AmbientLightSource( 0.8 ) ); sc.Sources.Add( new PointLightSource( new Vector3d( -8.0, 5.0, -3.0 ), 1.0 ) ); // --- NODE DEFINITIONS ---------------------------------------------------- // cage CSGInnerNode cage = new CSGInnerNode( SetOperation.Difference ); cage.SetAttribute( PropertyName.COLOR, new double[] { 0.70, 0.93, 0.20 } ); // cylinder1 CSGInnerNode cylinder1 = new CSGInnerNode( SetOperation.Intersection ); Sphere s = new Sphere(); cylinder1.InsertChild( s, Matrix4d.Scale( 1.0, 1000.0, 1.0 ) ); s = new Sphere(); cylinder1.InsertChild( s, Matrix4d.Scale( 1000.0, 1.5, 1000.0 ) ); cage.InsertChild( cylinder1, Matrix4d.Identity ); // cylinder2 CSGInnerNode cylinder2 = new CSGInnerNode( SetOperation.Intersection ); s = new Sphere(); cylinder2.InsertChild( s, Matrix4d.Scale( 1.0, 1000.0, 1.0 ) ); s = new Sphere(); cylinder2.InsertChild( s, Matrix4d.Scale( 1000.0, 1.5, 1000.0 ) ); cage.InsertChild( cylinder2, Matrix4d.Scale( 0.9 ) ); // holeUpDown Sphere holeUpDown = new Sphere(); cage.InsertChild( holeUpDown, Matrix4d.Scale( 0.5, 1000.0, 0.5 ) ); // hole1 CSGInnerNode hole1 = new CSGInnerNode( SetOperation.Intersection ); s = new Sphere(); hole1.InsertChild( s, Matrix4d.Scale( 1000.0, 1.1, 1000.0 ) ); s = new Sphere(); hole1.InsertChild( s, Matrix4d.Scale( 0.4, 1000.0, 1000.0 ) ); cage.InsertChild( hole1, Matrix4d.Identity ); // hole2 CSGInnerNode hole2 = new CSGInnerNode( SetOperation.Intersection ); s = new Sphere(); hole2.InsertChild( s, Matrix4d.Scale( 1000.0, 1.1, 1000.0 ) ); s = new Sphere(); hole2.InsertChild( s, Matrix4d.Scale( 0.4, 1000.0, 1000.0 ) ); cage.InsertChild( hole2, Matrix4d.RotateY( Math.PI / 3 ) ); // hole3 CSGInnerNode hole3 = new CSGInnerNode( SetOperation.Intersection ); s = new Sphere(); hole3.InsertChild( s, Matrix4d.Scale( 1000.0, 1.1, 1000.0 ) ); s = new Sphere(); hole3.InsertChild( s, Matrix4d.Scale( 0.4, 1000.0, 1000.0 ) ); cage.InsertChild( hole3, Matrix4d.RotateY( Math.PI / -3 ) ); // hedgehog CSGInnerNode hedgehog = new CSGInnerNode( SetOperation.Union ); hedgehog.SetAttribute( PropertyName.COLOR, new double[] { 0.4, 0.05, 0.05 } ); s = new Sphere(); hedgehog.InsertChild( s, Matrix4d.Scale( 0.48 ) ); // spine1 CSGInnerNode spine1 = new CSGInnerNode( SetOperation.Intersection ); s = new Sphere(); spine1.InsertChild( s, Matrix4d.Scale( 0.06, 1000.0, 0.06 ) ); s = new Sphere(); spine1.InsertChild( s, Matrix4d.Scale( 1.2 ) ); hedgehog.InsertChild( spine1, Matrix4d.Identity ); // spine2 CSGInnerNode spine2 = new CSGInnerNode( SetOperation.Intersection ); s = new Sphere(); spine2.InsertChild( s, Matrix4d.Scale( 0.06, 1000.0, 0.06 ) ); s = new Sphere(); spine2.InsertChild( s, Matrix4d.Scale( 1.2 ) * Matrix4d.CreateTranslation( 0.0, 0.1, 0.0 ) ); hedgehog.InsertChild( spine2, Matrix4d.RotateX( Math.PI / -3 ) ); // spine3 CSGInnerNode spine3 = new CSGInnerNode( SetOperation.Intersection ); s = new Sphere(); spine3.InsertChild( s, Matrix4d.Scale( 0.06, 1000.0, 0.06 ) ); s = new Sphere(); spine3.InsertChild( s, Matrix4d.Scale( 1.2 ) * Matrix4d.CreateTranslation( 0.0, -0.25, 0.0 ) ); hedgehog.InsertChild( spine3, Matrix4d.RotateX( Math.PI / -3 ) * Matrix4d.RotateY( Math.PI * -0.4 ) ); // spine4 CSGInnerNode spine4 = new CSGInnerNode( SetOperation.Intersection ); s = new Sphere(); spine4.InsertChild( s, Matrix4d.Scale( 0.06, 1000.0, 0.06 ) ); s = new Sphere(); spine4.InsertChild( s, Matrix4d.Scale( 1.2 ) * Matrix4d.CreateTranslation( 0.0, 0.2, 0.0 ) ); hedgehog.InsertChild( spine4, Matrix4d.RotateX( Math.PI / -3 ) * Matrix4d.RotateY( Math.PI * -0.8 ) ); // spine5 CSGInnerNode spine5 = new CSGInnerNode( SetOperation.Intersection ); s = new Sphere(); spine5.InsertChild( s, Matrix4d.Scale( 0.06, 1000.0, 0.06 ) ); s = new Sphere(); spine5.InsertChild( s, Matrix4d.Scale( 1.2 ) * Matrix4d.CreateTranslation( 0.0, -0.2, 0.0 ) ); hedgehog.InsertChild( spine5, Matrix4d.RotateX( Math.PI / -3 ) * Matrix4d.RotateY( Math.PI * 0.4 ) ); // spine6 CSGInnerNode spine6 = new CSGInnerNode( SetOperation.Intersection ); s = new Sphere(); spine6.InsertChild( s, Matrix4d.Scale( 0.06, 1000.0, 0.06 ) ); s = new Sphere(); spine6.InsertChild( s, Matrix4d.Scale( 1.2 ) * Matrix4d.CreateTranslation( 0.0, -0.25, 0.0 ) ); hedgehog.InsertChild( spine6, Matrix4d.RotateX( Math.PI / -3 ) * Matrix4d.RotateY( Math.PI * 0.8 ) ); // all CSGInnerNode all = new CSGInnerNode( SetOperation.Union ); all.InsertChild( cage, Matrix4d.RotateY( 0.25 ) ); all.InsertChild( hedgehog, Matrix4d.Rotate( new Vector3d( 0.0, 1.0, 1.0 ), 0.1 ) * Matrix4d.CreateTranslation( 0.0, -0.1, 0.0 ) ); root.InsertChild( all, Matrix4d.RotateZ( 0.1 ) ); }
/// <summary> /// Six national flags (in artistic style) - by Jakub Vlcek, (c) 2012 /// </summary> public static void Flags( IRayScene sc ) { Debug.Assert( sc != null ); // CSG scene: CSGInnerNode flags = new CSGInnerNode( SetOperation.Union ); flags.SetAttribute( PropertyName.REFLECTANCE_MODEL, new PhongModel() ); flags.SetAttribute( PropertyName.MATERIAL, new PhongMaterial( new double[] { 0.5, 0.5, 0.5 }, 0.2, 0.7, 0.1, 16 ) ); sc.Intersectable = flags; Sphere s; Cube c; // Background color: sc.BackgroundColor = new double[] { 0.0, 0.05, 0.05 }; // Camera: sc.Camera = new StaticCamera( new Vector3d( 0.0, 0.0, -10.0 ), new Vector3d( 0.0, 0.0, 1.0 ), 60.0 ); // Light sources: sc.Sources = new LinkedList<ILightSource>(); sc.Sources.Add( new AmbientLightSource( 0.8 ) ); sc.Sources.Add( new PointLightSource( new Vector3d( -5.0, 3.0, -3.0 ), 1.0 ) ); sc.Sources.Add( new PointLightSource( new Vector3d( 5.0, 3.0, -3.0 ), 1.0 ) ); // --- NODE DEFINITIONS ---------------------------------------------------- // Latvian flag (intersection, difference and xor): CSGInnerNode latvia = new CSGInnerNode( SetOperation.Intersection ); c = new Cube(); c.SetAttribute( PropertyName.COLOR, new double[] { 0.3, 0.0, 0.0 } ); latvia.InsertChild( c, Matrix4d.Scale( 4.0, 2.0, 0.4 ) * Matrix4d.CreateTranslation( -2.0, -1.0, 0.0 ) ); CSGInnerNode latviaFlag = new CSGInnerNode( SetOperation.Xor ); c = new Cube(); c.SetAttribute( PropertyName.COLOR, new double[] { 0.3, 0.0, 0.0 } ); latviaFlag.InsertChild( c, Matrix4d.CreateTranslation( -0.5, -0.5, -0.5 ) * Matrix4d.Scale( 4.0, 2.0, 2.0 ) ); c = new Cube(); c.SetAttribute( PropertyName.COLOR, new double[] { 1.0, 1.0, 1.0 } ); latviaFlag.InsertChild( c, Matrix4d.CreateTranslation( -0.5, -0.5, -0.5 ) * Matrix4d.Scale( 4.2, 0.5, 0.5 ) ); latvia.InsertChild( latviaFlag, Matrix4d.Identity ); flags.InsertChild( latvia, Matrix4d.Scale( 0.7 ) * Matrix4d.CreateRotationX( Math.PI / 8 ) * Matrix4d.CreateTranslation( -3.5, 1.5, 0.0 ) ); // Czech flag (difference): CSGInnerNode czech = new CSGInnerNode( SetOperation.Difference ); s = new Sphere(); s.SetAttribute( PropertyName.COLOR, new double[] { 0.2, 0.2, 0.2 } ); czech.InsertChild( s, Matrix4d.Identity ); s = new Sphere(); s.SetAttribute( PropertyName.COLOR, new double[] { 1.0, 1.0, 1.0 } ); czech.InsertChild( s, Matrix4d.CreateTranslation( 0.0, 0.8, -1.0 ) ); s = new Sphere(); s.SetAttribute( PropertyName.COLOR, new double[] { 1.0, 0.0, 0.0 } ); czech.InsertChild( s, Matrix4d.CreateTranslation( 0.0, -0.8, -1.1 ) ); s = new Sphere(); s.SetAttribute( PropertyName.COLOR, new double[] { 0.0, 0.0, 1.0 } ); czech.InsertChild( s, Matrix4d.CreateTranslation( -1.0, 0.0, -0.8 ) ); flags.InsertChild( czech, Matrix4d.Scale( 1.6, 1.0, 1.0 ) * Matrix4d.CreateRotationY( Math.PI / 8 ) * Matrix4d.CreateTranslation( 4.0, -1.5, 0.0 ) ); // Croatian flag (union, intersection): CSGInnerNode croatianFlag = new CSGInnerNode( SetOperation.Union ); CSGInnerNode croatianSign = new CSGInnerNode( SetOperation.Intersection ); CSGInnerNode checkerBoard = new CSGInnerNode( SetOperation.Union ); c = new Cube(); c.SetAttribute( PropertyName.COLOR, new double[] { 1.0, 0.0, 0.0 } ); c.SetAttribute( PropertyName.TEXTURE, new CheckerTexture( 10.0, 10.0, new double[] { 1.0, 1.0, 1.0 } ) ); croatianSign.InsertChild( c, Matrix4d.CreateTranslation( -0.5, -0.5, -0.5 ) * Matrix4d.Scale( 2.0, 2.0, 0.4 ) ); CSGInnerNode sign = new CSGInnerNode( SetOperation.Union ); s = new Sphere(); s.SetAttribute( PropertyName.COLOR, new double[] { 1.0, 1.0, 1.0 } ); sign.InsertChild( s, Matrix4d.Identity ); c = new Cube(); c.SetAttribute( PropertyName.COLOR, new double[] { 1.0, 1.0, 1.0 } ); sign.InsertChild( c, Matrix4d.Scale( 1.8 ) * Matrix4d.CreateTranslation( -0.9, 0.1, -0.9 ) ); croatianSign.InsertChild( sign, Matrix4d.Scale( 0.5, 0.33, 0.5 ) * Matrix4d.CreateTranslation( 0.44, -0.5, 0.0 ) ); c = new Cube(); c.SetAttribute( PropertyName.COLOR, new double[] { 1.0, 0.0, 0.0 } ); croatianFlag.InsertChild( c, Matrix4d.CreateTranslation( -0.5, -0.5, -0.5 ) * Matrix4d.Scale( 4.0, 0.6, 0.6 ) * Matrix4d.RotateX( Math.PI / 4 ) * Matrix4d.CreateTranslation( 0.5, 1.0, 1.0 ) ); c = new Cube(); c.SetAttribute( PropertyName.COLOR, new double[] { 1.0, 1.0, 1.0 } ); croatianFlag.InsertChild( c, Matrix4d.CreateTranslation( -0.5, -0.5, -0.5 ) * Matrix4d.Scale( 4.0, 0.6, 0.6 ) * Matrix4d.RotateX( Math.PI / 4 ) * Matrix4d.CreateTranslation( 0.5, 0.3, 1.0 ) ); c = new Cube(); c.SetAttribute( PropertyName.COLOR, new double[] { 0.0, 0.0, 1.0 } ); croatianFlag.InsertChild( c, Matrix4d.CreateTranslation( -0.5, -0.5, -0.5 ) * Matrix4d.Scale( 4.0, 0.6, 0.6 ) * Matrix4d.RotateX( Math.PI / 4 ) * Matrix4d.CreateTranslation( 0.5, -0.4, 1.0 ) ); croatianFlag.InsertChild( croatianSign, Matrix4d.Scale( 0.8 ) * Matrix4d.CreateTranslation( 0.4, 0.5, 0.0 ) ); flags.InsertChild( croatianFlag, Matrix4d.Scale( 0.8 ) * Matrix4d.CreateRotationY( Math.PI / 8 ) * Matrix4d.CreateTranslation( -0.4, 1.5, 1.0 ) ); // Brazilian flag (union): CSGInnerNode brazilianFlag = new CSGInnerNode( SetOperation.Union ); c = new Cube(); c.SetAttribute( PropertyName.COLOR, new double[] { 0.0, 0.8, 0.0 } ); brazilianFlag.InsertChild( c, Matrix4d.CreateTranslation( -0.5, -0.5, -0.5 ) * Matrix4d.Scale( 4.0, 2.0, 0.2 ) ); c = new Cube(); c.SetAttribute( PropertyName.COLOR, new double[] { 1.0, 1.0, 0.0 } ); brazilianFlag.InsertChild( c, Matrix4d.CreateTranslation( -0.5, -0.5, -0.5 ) * Matrix4d.CreateRotationZ( Math.PI / 4 ) * Matrix4d.Scale( 2.0, 1.0, 0.4 ) ); s = new Sphere(); s.SetAttribute( PropertyName.COLOR, new double[] { 0.0, 0.0, 1.0 } ); brazilianFlag.InsertChild( s, Matrix4d.Scale( 0.5 ) * Matrix4d.CreateTranslation( 0.0, 0.0, 0.0 ) ); flags.InsertChild( brazilianFlag, Matrix4d.Scale( 0.9 ) * Matrix4d.RotateY( -Math.PI / 8 ) * Matrix4d.CreateTranslation( 0.0, -1.8, 1.0 ) ); // Finnish flag (intersection and difference): CSGInnerNode finlandFlag = new CSGInnerNode( SetOperation.Difference ); s = new Sphere(); s.SetAttribute( PropertyName.COLOR, new double[] { 1.0, 1.0, 1.0 } ); finlandFlag.InsertChild( s, Matrix4d.Scale( 2.0, 1.0, 0.5 ) * Matrix4d.CreateTranslation( 0.0, 0.0, 0.3 ) ); c = new Cube(); c.SetAttribute( PropertyName.COLOR, new double[] { 0.0, 0.0, 1.0 } ); finlandFlag.InsertChild( c, Matrix4d.CreateTranslation( -0.5, -0.5, -0.5 ) * Matrix4d.Scale( 4.2, 0.5, 0.5 ) ); c = new Cube(); c.SetAttribute( PropertyName.COLOR, new double[] { 0.0, 0.0, 1.0 } ); finlandFlag.InsertChild( c, Matrix4d.CreateTranslation( -0.5, -0.5, -0.5 ) * Matrix4d.Scale( 0.5, 4.2, 0.5 ) * Matrix4d.CreateTranslation( -0.5, 0.0, 0.0 ) ); flags.InsertChild( finlandFlag, Matrix4d.Scale( 0.7 ) * Matrix4d.CreateTranslation( 3.5, 1.5, 0.0 ) ); // Cuban flag (union and intersection): CSGInnerNode cubanFlag = new CSGInnerNode( SetOperation.Union ); for ( int i = 0; i < 5; i++ ) { c = new Cube(); if ( i % 2 == 0 ) c.SetAttribute( PropertyName.COLOR, new double[] { 0.0, 0.0, 1.0 } ); else c.SetAttribute( PropertyName.COLOR, new double[] { 1.0, 1.0, 1.0 } ); cubanFlag.InsertChild( c, Matrix4d.CreateTranslation( -0.5, -0.5, -0.5 ) * Matrix4d.Scale( 4.0, 0.4, 0.4 ) * Matrix4d.CreateTranslation( new Vector3d( 0.0, 0.0 - i * 0.4, 0.8 - i * 0.2 ) ) ); } CSGInnerNode wedge = new CSGInnerNode( SetOperation.Intersection ); c = new Cube(); c.SetAttribute( PropertyName.COLOR, new double[] { 1.0, 0.0, 0.0 } ); wedge.InsertChild( c, Matrix4d.CreateTranslation( -0.5, -0.5, -0.5 ) * Matrix4d.Scale( 2.0, 2.0, 2.0 ) * Matrix4d.CreateRotationZ( Math.PI / 4 ) ); c = new Cube(); c.SetAttribute( PropertyName.COLOR, new double[] { 1.0, 0.0, 0.0 } ); wedge.InsertChild( c, Matrix4d.Scale( 4.0 ) * Matrix4d.CreateTranslation( 0.0, -2.0, -2.0 ) ); cubanFlag.InsertChild( wedge, Matrix4d.Scale( 0.7 ) * Matrix4d.CreateTranslation( -2.0001, -0.8, 0.4999 ) ); flags.InsertChild( cubanFlag, Matrix4d.Scale( 0.7 ) * Matrix4d.RotateY( Math.PI / 8 ) * Matrix4d.CreateTranslation( -4.0, -1.0, 0.0 ) ); }
/// <summary> /// Simple scene containing five colored spheres. /// </summary> public static void FiveBalls( IRayScene sc ) { Debug.Assert( sc != null ); // CSG scene: CSGInnerNode root = new CSGInnerNode( SetOperation.Union ); root.SetAttribute( PropertyName.REFLECTANCE_MODEL, new PhongModel() ); root.SetAttribute( PropertyName.MATERIAL, new PhongMaterial( new double[] { 0.5, 0.5, 0.5 }, 0.1, 0.6, 0.3, 16 ) ); sc.Intersectable = root; // Background color: sc.BackgroundColor = new double[] { 0.0, 0.05, 0.05 }; // Camera: sc.Camera = new StaticCamera( new Vector3d( 0.0, 0.0, -10.0 ), new Vector3d( 0.0, 0.0, 1.0 ), 60.0 ); // Light sources: sc.Sources = new LinkedList<ILightSource>(); sc.Sources.Add( new AmbientLightSource( 0.8 ) ); sc.Sources.Add( new PointLightSource( new Vector3d( -5.0, 3.0, -3.0 ), 1.0 ) ); // --- NODE DEFINITIONS ---------------------------------------------------- // sphere 1: Sphere s = new Sphere(); s.SetAttribute( PropertyName.COLOR, new double[] { 1.0, 0.6, 0.0 } ); root.InsertChild( s, Matrix4d.Identity ); // sphere 2: s = new Sphere(); s.SetAttribute( PropertyName.COLOR, new double[] { 0.2, 0.9, 0.5 } ); root.InsertChild( s, Matrix4d.CreateTranslation( -2.2, 0.0, 0.0 ) ); // sphere 3: s = new Sphere(); s.SetAttribute( PropertyName.COLOR, new double[] { 0.1, 0.3, 1.0 } ); root.InsertChild( s, Matrix4d.CreateTranslation( -4.4, 0.0, 0.0 ) ); // sphere 4: s = new Sphere(); s.SetAttribute( PropertyName.COLOR, new double[] { 1.0, 0.2, 0.2 } ); root.InsertChild( s, Matrix4d.CreateTranslation( 2.2, 0.0, 0.0 ) ); // sphere 5: s = new Sphere(); s.SetAttribute( PropertyName.COLOR, new double[] { 0.1, 0.4, 0.0 } ); s.SetAttribute( PropertyName.TEXTURE, new CheckerTexture( 80.0, 40.0, new double[] { 1.0, 0.8, 0.2 } ) ); root.InsertChild( s, Matrix4d.CreateTranslation( 4.4, 0.0, 0.0 ) ); }
/// <summary> /// Test scene for cylinders /// </summary> public static void Cylinders( IRayScene sc ) { Debug.Assert( sc != null ); // CSG scene: CSGInnerNode root = new CSGInnerNode( SetOperation.Union ); root.SetAttribute( PropertyName.REFLECTANCE_MODEL, new PhongModel() ); root.SetAttribute( PropertyName.MATERIAL, new PhongMaterial( new double[] { 0.6, 0.0, 0.0 }, 0.15, 0.8, 0.15, 16 ) ); sc.Intersectable = root; // Background color: sc.BackgroundColor = new double[] { 0.0, 0.05, 0.07 }; // Camera: sc.Camera = new StaticCamera( new Vector3d( 0.7, 3.0, -10.0 ), new Vector3d( 0.0, -0.2, 1.0 ), 50.0 ); // Light sources: sc.Sources = new LinkedList<ILightSource>(); sc.Sources.Add( new AmbientLightSource( 1.0 ) ); sc.Sources.Add( new PointLightSource( new Vector3d( -5.0, 3.0, -3.0 ), 1.6 ) ); // --- NODE DEFINITIONS ---------------------------------------------------- // Base plane Plane pl = new Plane(); pl.SetAttribute( PropertyName.COLOR, new double[] { 0.0, 0.2, 0.0 } ); pl.SetAttribute( PropertyName.TEXTURE, new CheckerTexture( 0.5, 0.5, new double[] { 1.0, 1.0, 1.0 } ) ); root.InsertChild( pl, Matrix4d.RotateX( -MathHelper.PiOver2 ) * Matrix4d.CreateTranslation( 0.0, -1.0, 0.0 ) ); // Cylinders Cylinder c = new Cylinder(); root.InsertChild( c, Matrix4d.RotateX( MathHelper.PiOver2 ) * Matrix4d.CreateTranslation( -2.1, 0.0, 1.0 ) ); c = new Cylinder(); c.SetAttribute( PropertyName.COLOR, new double[] { 0.2, 0.0, 0.7 } ); c.SetAttribute( PropertyName.TEXTURE, new CheckerTexture( 12.0, 1.0, new double[] { 0.0, 0.0, 0.3 } ) ); root.InsertChild( c, Matrix4d.RotateY( -0.4 ) * Matrix4d.CreateTranslation( 1.0, 0.0, 1.0 ) ); c = new Cylinder( 0.0, 100.0 ); c.SetAttribute( PropertyName.COLOR, new double[] { 0.1, 0.7, 0.0 } ); root.InsertChild( c, Matrix4d.RotateY( 0.2 ) * Matrix4d.CreateTranslation( 5.0, 0.3, 4.0 ) ); c = new Cylinder( -0.5, 0.5 ); c.SetAttribute( PropertyName.COLOR, new double[] { 0.8, 0.6, 0.0 } ); root.InsertChild( c, Matrix4d.Scale( 2.0 ) * Matrix4d.RotateX( 1.2 ) * Matrix4d.CreateTranslation( 2.0, 1.8, 16.0 ) ); }
/// <summary> /// [Re]-renders the whole image (in separate thread). OLD VERSION!!! /// </summary> private void RenderImage_OLD() { Cursor.Current = Cursors.WaitCursor; // Determine output image size. int width = ImageWidth; if (width <= 0) { width = panel1.Width; } int height = ImageHeight; if (height <= 0) { height = panel1.Height; } Bitmap newImage = new Bitmap(width, height, PixelFormat.Format24bppRgb); int threads = CheckMultithreading.Checked ? Environment.ProcessorCount : 1; int t; // thread ordinal number int superSampling = (int)NumericSupersampling.Value; WorkerThreadInit[] wti = new WorkerThreadInit[threads]; // 1. preprocessing - compute simulation, animation data, etc. _ = FormSupport.getScene(true, out _, out _, superSampling, TextParam.Text); // Separate renderer, image function and the scene for each thread (safety precaution). for (t = 0; t < threads; t++) { // 2. initialize data for regular frames (using the pre-computed context). IRayScene sc = FormSupport.getScene( false, out IImageFunction imf, out IRenderer rend, superSampling, TextParam.Text); // IImageFunction. imf = getImageFunction(imf, sc); imf.Width = width; imf.Height = height; // IRenderer. if (rend == null) // not defined in the script { rend = getRenderer(); } rend.ImageFunction = imf; rend.Width = width; rend.Height = height; rend.Adaptive = 8; rend.ProgressData = progress; wti[t] = new WorkerThreadInit(rend, sc as ITimeDependent, imf as ITimeDependent, newImage, width, height, t, threads); } progress.SyncInterval = ((width * (long)height) > (2L << 20)) ? 3000L : 1000L; progress.Reset(); CSGInnerNode.ResetStatistics(); lock (sw) sw.Restart(); if (threads > 1) { Thread[] pool = new Thread[threads]; for (t = 0; t < threads; t++) { pool[t] = new Thread(new ParameterizedThreadStart(RenderWorker)); } for (t = threads; --t >= 0;) { pool[t].Start(wti[t]); } for (t = 0; t < threads; t++) { pool[t].Join(); pool[t] = null; } } else { MT.InitThreadData(); wti[0].rend.RenderRectangle(newImage, 0, 0, width, height); } long elapsed; lock (sw) { sw.Stop(); elapsed = sw.ElapsedMilliseconds; } string msg = string.Format(CultureInfo.InvariantCulture, "{0:f1}s [ {1}x{2}, mt{3}, r{4:#,#}k, i{5:#,#}k, bb{6:#,#}k, t{7:#,#}k ]", 1.0e-3 * elapsed, width, height, threads, (Intersection.countRays + 500L) / 1000L, (Intersection.countIntersections + 500L) / 1000L, (CSGInnerNode.countBoundingBoxes + 500L) / 1000L, (CSGInnerNode.countTriangles + 500L) / 1000L); SetText(msg); Console.WriteLine(@"Rendering finished: " + msg); SetImage(newImage); Cursor.Current = Cursors.Default; StopRendering(); }
/// <summary> /// [Re]-renders the whole image (in separate thread). OLD VERSION!!! /// </summary> private void RenderImage_OLD() { Cursor.Current = Cursors.WaitCursor; // determine output image size: int width = ImageWidth; if (width <= 0) { width = panel1.Width; } int height = ImageHeight; if (height <= 0) { height = panel1.Height; } Bitmap newImage = new Bitmap(width, height, PixelFormat.Format24bppRgb); int threads = CheckMultithreading.Checked ? Environment.ProcessorCount : 1; int t; // thread ordinal number WorkerThreadInit[] wti = new WorkerThreadInit[threads]; // separate renderer, image function and the scene for each thread (safety precaution) for (t = 0; t < threads; t++) { IRayScene sc = FormSupport.getScene(); IImageFunction imf = getImageFunction(sc, width, height); IRenderer r = getRenderer(imf, width, height); wti[t] = new WorkerThreadInit(r, sc as ITimeDependent, imf as ITimeDependent, newImage, width, height, t, threads); } progress.SyncInterval = ((width * (long)height) > (2L << 20)) ? 3000L : 1000L; progress.Reset(); CSGInnerNode.ResetStatistics(); lock (sw) sw.Restart(); if (threads > 1) { Thread[] pool = new Thread[threads]; for (t = 0; t < threads; t++) { pool[t] = new Thread(new ParameterizedThreadStart(RenderWorker)); } for (t = threads; --t >= 0;) { pool[t].Start(wti[t]); } for (t = 0; t < threads; t++) { pool[t].Join(); pool[t] = null; } } else { MT.InitThreadData(); wti[0].rend.RenderRectangle(newImage, 0, 0, width, height); } long elapsed; lock (sw) { sw.Stop(); elapsed = sw.ElapsedMilliseconds; } string msg = string.Format(CultureInfo.InvariantCulture, "{0:f1}s [ {1}x{2}, mt{3}, r{4:#,#}k, i{5:#,#}k, bb{6:#,#}k, t{7:#,#}k ]", 1.0e-3 * elapsed, width, height, threads, (Intersection.countRays + 500L) / 1000L, (Intersection.countIntersections + 500L) / 1000L, (CSGInnerNode.countBoundingBoxes + 500L) / 1000L, (CSGInnerNode.countTriangles + 500L) / 1000L); SetText(msg); Console.WriteLine(@"Rendering finished: " + msg); SetImage(newImage); Cursor.Current = Cursors.Default; StopRendering(); }
protected static CSGInnerNode head() { CSGInnerNode root = new CSGInnerNode( SetOperation.Union ); double[] skinColor = new double[] { 1, .8, .65 }; double[] whiteColor = new double[] { 1, 1, 1 }; double[] blackColor = new double[] { 0, 0, 0 }; double[] blueColor = new double[] { 0, 0, 1 }; double[] redColor = new double[] { 1, 0, 0 }; CSGInnerNode hlava = new CSGInnerNode( SetOperation.Difference ); root.InsertChild( hlava, Matrix4d.Identity ); Sphere s = new Sphere(); s.SetAttribute( PropertyName.COLOR, skinColor ); hlava.InsertChild( s, Matrix4d.Scale( 2.3 ) ); // klobouk CSGInnerNode klobouk = new CSGInnerNode( SetOperation.Union ); Cylinder klb = new Cylinder( -0.5, 0.5 ); klb.SetAttribute( PropertyName.COLOR, blackColor ); klobouk.InsertChild( klb, Matrix4d.Scale( 2, 2, 1.4 ) * Matrix4d.RotateX( Math.PI / 2 ) * Matrix4d.CreateTranslation( 0, 0.5, 0 ) ); Cylinder ksilt = new Cylinder( -0.5, 0.5 ); ksilt.SetAttribute( PropertyName.COLOR, blackColor ); klobouk.InsertChild( ksilt, Matrix4d.Scale( 3, 3, .1 ) * Matrix4d.RotateX( Math.PI / 2 ) ); root.InsertChild( klobouk, Matrix4d.CreateTranslation( 0, 1.25, 0 ) ); // levy ocni dulek s = new Sphere(); s.SetAttribute( PropertyName.COLOR, skinColor ); hlava.InsertChild( s, Matrix4d.Scale( 0.7 ) * Matrix4d.CreateTranslation( -0.7, .3, -1.8 ) ); // pravy ocni dulek s = new Sphere(); s.SetAttribute( PropertyName.COLOR, skinColor ); hlava.InsertChild( s, Matrix4d.Scale( 0.7 ) * Matrix4d.CreateTranslation( 0.7, .3, -1.8 ) ); // prave oko CSGInnerNode oko = new CSGInnerNode( SetOperation.Union ); root.InsertChild( oko, Matrix4d.CreateTranslation( 0.70, 0.3, -0.5 ) ); Sphere bulva = new Sphere(); bulva.SetAttribute( PropertyName.COLOR, whiteColor ); oko.InsertChild( bulva, Matrix4d.Scale( 1.3 ) ); Sphere cocka = new Sphere(); cocka.SetAttribute( PropertyName.COLOR, blueColor ); oko.InsertChild( cocka, Matrix4d.Scale( 0.3 ) * Matrix4d.CreateTranslation( 0, 0, -1.2 ) ); // leve oko oko = new CSGInnerNode( SetOperation.Union ); root.InsertChild( oko, Matrix4d.CreateTranslation( -0.70, 0.3, -0.5 ) ); bulva = new Sphere(); bulva.SetAttribute( PropertyName.COLOR, whiteColor ); oko.InsertChild( bulva, Matrix4d.Scale( 1.3 ) ); cocka = new Sphere(); cocka.SetAttribute( PropertyName.COLOR, blueColor ); oko.InsertChild( cocka, Matrix4d.Scale( 0.3 ) * Matrix4d.CreateTranslation( 0, 0, -1.2 ) ); // nos Cylinder nos = new Cylinder( -0.5, 0.5 ); nos.SetAttribute( PropertyName.COLOR, skinColor ); root.InsertChild( nos, Matrix4d.Scale( 0.2, 0.2, 0.6 ) * Matrix4d.CreateTranslation( 0, 0, -2.65 ) ); // usta CSGInnerNode usta = new CSGInnerNode( SetOperation.Xor ); Cylinder horniRet = new Cylinder( -0.5, 0.5 ); horniRet.SetAttribute( PropertyName.COLOR, redColor ); usta.InsertChild( horniRet, Matrix4d.CreateTranslation( 0, -0.3, 0 ) ); Cylinder dolniRet = new Cylinder( -0.5, 0.5 ); dolniRet.SetAttribute( PropertyName.COLOR, redColor ); usta.InsertChild( dolniRet, Matrix4d.CreateTranslation( 0, 0.3, 0 ) ); root.InsertChild( usta, Matrix4d.Scale( 0.7, 0.3, 1 ) * Matrix4d.CreateTranslation( 0, -0.7, -1.85 ) ); // vnitrek ust CSGInnerNode vnitrekUst = new CSGInnerNode( SetOperation.Intersection ); horniRet = new Cylinder( -0.5, 0.5 ); horniRet.SetAttribute( PropertyName.COLOR, blackColor ); vnitrekUst.InsertChild( horniRet, Matrix4d.CreateTranslation( 0, -0.3, 0 ) ); dolniRet = new Cylinder( -0.5, 0.5 ); dolniRet.SetAttribute( PropertyName.COLOR, blackColor ); vnitrekUst.InsertChild( dolniRet, Matrix4d.CreateTranslation( 0, 0.3, 0 ) ); usta.InsertChild( vnitrekUst, Matrix4d.CreateTranslation( 0, 0, 0.1 ) ); return root; }
protected static CSGInnerNode testWithCylinders( SetOperation op ) { // scene: CSGInnerNode root = new CSGInnerNode( op ); int num = 5; for ( int i = 0; i < num; ++i ) { double j = i; Cylinder c = new Cylinder( -0.5, 0.5 ); c.SetAttribute( PropertyName.COLOR, new double[] { j / num, 1.0 - j / num, 0 } ); root.InsertChild( c, Matrix4d.RotateX( Math.PI / 4 ) * Matrix4d.CreateTranslation( -1 + 0.6 * i, 0, 0 ) ); } return root; }
protected static CSGInnerNode test6Spheres( SetOperation op ) { // scene: CSGInnerNode root = new CSGInnerNode( op ); Sphere s = new Sphere(); s.SetAttribute( PropertyName.COLOR, new double[] { 1, 0.3, 1 } ); root.InsertChild( s, Matrix4d.Scale( 2 ) ); s = new Sphere(); s.SetAttribute( PropertyName.COLOR, new double[] { 0.5, 0.8, 0.2 } ); root.InsertChild( s, Matrix4d.CreateTranslation( 0, 0, -2 ) ); s = new Sphere(); s.SetAttribute( PropertyName.COLOR, new double[] { 1, 0.3, 0 } ); root.InsertChild( s, Matrix4d.CreateTranslation( 0, 1, -0.5 ) ); s = new Sphere(); s.SetAttribute( PropertyName.COLOR, new double[] { 1, 0.3, 0 } ); root.InsertChild( s, Matrix4d.CreateTranslation( 1, 0, -0.5 ) ); s = new Sphere(); s.SetAttribute( PropertyName.COLOR, new double[] { 1, 0.3, 0 } ); root.InsertChild( s, Matrix4d.CreateTranslation( 0, -1, -0.5 ) ); s = new Sphere(); s.SetAttribute( PropertyName.COLOR, new double[] { 1, 0.3, 0 } ); root.InsertChild( s, Matrix4d.CreateTranslation( -1, 0, -0.5 ) ); return root; }
/// <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; }
/// <summary> /// [Re]-renders the whole image (in separate thread) /// </summary> private void RenderImage() { Cursor.Current = Cursors.WaitCursor; // determine output image size: ActualWidth = ImageWidth; if (ActualWidth <= 0) { ActualWidth = panel1.Width; } ActualHeight = ImageHeight; if (ActualHeight <= 0) { ActualHeight = panel1.Height; } int superSampling = (int)NumericSupersampling.Value; // Force preprocessing. ctx = null; // 1. preprocessing - compute simulation, animation data, etc. _ = FormSupport.getScene( out _, out _, ref ActualWidth, ref ActualHeight, ref superSampling, TextParam.Text); // 2. compute regular frame (using the pre-computed context). IRayScene scene = FormSupport.getScene( out IImageFunction imf, out IRenderer rend, ref ActualWidth, ref ActualHeight, ref superSampling, TextParam.Text); // Update additional views. if (collectDataCheckBox.Checked) { additionalViews.SetNewDimensions(ActualWidth, ActualHeight); additionalViews.NewRenderInitialization(); } else if (!additionalViews.mapsEmpty) { additionalViews.form?.ExportDataButtonsEnabled(true); } if (ImageWidth > 0) // preserving default (form-size) resolution { ImageWidth = ActualWidth; ImageHeight = ActualHeight; UpdateResolutionButton(); } UpdateSupersampling(superSampling); // IImageFunction. if (imf == null) // not defined in the script { imf = getImageFunction(imf, scene); } else if (imf is RayCasting imfray) { imfray.Scene = scene; } imf.Width = ActualWidth; imf.Height = ActualHeight; // IRenderer. if (rend == null) // not defined in the script { rend = getRenderer(); } rend.ImageFunction = imf; rend.Width = ActualWidth; rend.Height = ActualHeight; rend.Adaptive = 0; // 8? rend.ProgressData = progress; // Almost ready for new image computation. rayVisualizer.UpdateScene(scene); Bitmap newImage = new Bitmap(ActualWidth, ActualHeight, PixelFormat.Format24bppRgb); int threads = CheckMultithreading.Checked ? Environment.ProcessorCount : 1; master = new Master( newImage, scene, imf, rend, RenderClientsForm.instance?.clients, threads, pointCloudCheckBox.Checked, ref AdditionalViews.singleton.pointCloud); master.progressData = progress; master.InitializeAssignments(newImage, scene, rend); if (pointCloudCheckBox.Checked) { master.pointCloud?.SetNecessaryFields(PointCloudSavingStart, PointCloudSavingEnd, Notification, Invoke); } progress.SyncInterval = ((ActualWidth * (long)ActualHeight) > (2L << 20)) ? 3000L : 1000L; progress.Reset(); CSGInnerNode.ResetStatistics(); lock (sw) sw.Restart(); master.StartThreads(); long elapsed; lock (sw) { sw.Stop(); elapsed = sw.ElapsedMilliseconds; } string msg = string.Format(CultureInfo.InvariantCulture, "{0:f1}s [ {1}x{2}, mt{3}, r{4:#,#}k, i{5:#,#}k, bb{6:#,#}k, t{7:#,#}k ]", 1.0e-3 * elapsed, ActualWidth, ActualHeight, threads, (Intersection.countRays + 500L) / 1000L, (Intersection.countIntersections + 500L) / 1000L, (CSGInnerNode.countBoundingBoxes + 500L) / 1000L, (CSGInnerNode.countTriangles + 500L) / 1000L); SetText(msg); Console.WriteLine(@"Rendering finished: " + msg); SetImage(newImage); Cursor.Current = Cursors.Default; StopRendering(); }
/// <summary> /// Creates default ray-rendering scene. /// </summary> public static IRayScene Init(IRayScene sc, string param) { // !!!{{ TODO: .. and use your time-dependent objects to construct the scene // This code is based on Scenes.TwoSpheres(): // CSG scene: CSGInnerNode root = new CSGInnerNode(SetOperation.Union); root.SetAttribute(PropertyName.REFLECTANCE_MODEL, new PhongModel()); root.SetAttribute(PropertyName.MATERIAL, new PhongMaterial(new double[] { 1.0, 0.8, 0.1 }, 0.1, 0.6, 0.4, 128)); sc.Intersectable = root; // Background color: sc.BackgroundColor = new double[] { 0.0, 0.05, 0.07 }; // Camera: AnimatedCamera cam = new AnimatedCamera(new Vector3d(0.7, -0.4, 0.0), new Vector3d(0.7, 0.8, -6.0), 50.0); cam.End = 20.0; // one complete turn takes 20.0 seconds AnimatedRayScene asc = sc as AnimatedRayScene; if (asc != null) { asc.End = 20.0; } sc.Camera = cam; //sc.Camera = new StaticCamera( new Vector3d( 0.7, 0.5, -5.0 ), // new Vector3d( 0.0, -0.18, 1.0 ), // 50.0 ); // Light sources: sc.Sources = new LinkedList <ILightSource>(); sc.Sources.Add(new AmbientLightSource(0.8)); sc.Sources.Add(new PointLightSource(new Vector3d(-5.0, 4.0, -3.0), 1.2)); // --- NODE DEFINITIONS ---------------------------------------------------- // Params dictionary: Dictionary <string, string> p = Util.ParseKeyValueList(param); // n = <index-of-refraction> double n = 1.6; Util.TryParse(p, "n", ref n); // Transparent sphere: Sphere s; s = new Sphere(); PhongMaterial pm = new PhongMaterial(new double[] { 0.0, 0.2, 0.1 }, 0.03, 0.03, 0.08, 128); pm.n = n; pm.Kt = 0.9; s.SetAttribute(PropertyName.MATERIAL, pm); root.InsertChild(s, Matrix4d.Identity); // Opaque sphere: s = new Sphere(); root.InsertChild(s, Matrix4d.Scale(1.2) * Matrix4d.CreateTranslation(1.5, 0.2, 2.4)); // Infinite plane with checker: Plane pl = new Plane(); pl.SetAttribute(PropertyName.COLOR, new double[] { 0.3, 0.0, 0.0 }); pl.SetAttribute(PropertyName.TEXTURE, new CheckerTexture(0.6, 0.6, new double[] { 1.0, 1.0, 1.0 })); root.InsertChild(pl, Matrix4d.RotateX(-MathHelper.PiOver2) * Matrix4d.CreateTranslation(0.0, -1.0, 0.0)); // !!!}} return(sc); }
public static long TestScene(IRayScene sc, string[] names) { Debug.Assert(sc != null); Vector3 center = Vector3.Zero; // center of the mesh Vector3d dir = new Vector3d(0.1, -0.3, 0.9); dir.Normalize(); // normalized viewing vector of the camera float diameter = 2.0f; // default scene diameter double FoVy = 60.0; // Field of View in degrees 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[] { "teapot.obj" } } ; 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 FastTriangleMesh(brep); root.InsertChild(m, Matrix4d.Identity); } root.SetAttribute(PropertyName.REFLECTANCE_MODEL, new PhongModel()); root.SetAttribute(PropertyName.MATERIAL, new PhongMaterial(new double[] { 0.5, 0.5, 0.5 }, 0.2, 0.5, 0.4, 12)); root.SetAttribute(PropertyName.COLOR, new double[] { 1.0, 0.6, 0.0 }); sc.Intersectable = root; // Background color: sc.BackgroundColor = new double[] { 0.0, 0.05, 0.07 }; // Camera: double dist = (0.6 * diameter) / 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)); sc.Sources.Add(new PointLightSource(new Vector3d(-20.0, 12.0, -12.0), 1.0)); return(faces); } }
/// <summary> /// Test scene for Toruses by Jan Navratil, (c) 2012 /// </summary> public static void Toroids( IRayScene sc ) { Debug.Assert( sc != null ); // CSG scene: CSGInnerNode root = new CSGInnerNode( SetOperation.Union ); root.SetAttribute( PropertyName.REFLECTANCE_MODEL, new PhongModel() ); root.SetAttribute( PropertyName.MATERIAL, new PhongMaterial( new double[] { 0.5, 0.5, 0.5 }, 0.2, 0.7, 0.2, 16 ) ); sc.Intersectable = root; // Background color: sc.BackgroundColor = new double[] { 0.0, 0.15, 0.2 }; // Camera: sc.Camera = new StaticCamera( new Vector3d( 0.0, 0.0, -10.0 ), new Vector3d( 0.0, -0.04, 1.0 ), 60.0 ); // Light sources: sc.Sources = new LinkedList<ILightSource>(); sc.Sources.Add( new AmbientLightSource( 1.8 ) ); sc.Sources.Add( new PointLightSource( new Vector3d( -5.0, 3.0, -3.0 ), 2.0 ) ); // --- NODE DEFINITIONS ---------------------------------------------------- Sphere s; Torus t; t = new Torus( 2.0, 1.0 ); t.SetAttribute( PropertyName.COLOR, new double[] { 0, 0, 0.7 } ); t.SetAttribute( PropertyName.TEXTURE, new CheckerTexture( 50, 20, new double[] { 0.9, 0.9, 0 } ) ); root.InsertChild( t, Matrix4d.Scale( 0.8 ) * Matrix4d.CreateRotationX( 0.9 ) * Matrix4d.CreateTranslation( 2.7, 0.6, 0.0 ) ); t = new Torus( 1.0, 1.5 ); t.SetAttribute( PropertyName.COLOR, new double[] { 1, 0, 0 } ); t.SetAttribute( PropertyName.TEXTURE, new CheckerTexture( 40, 40, new double[] { 0.8, 1.0, 1.0 } ) ); CSGInnerNode donut = new CSGInnerNode( SetOperation.Difference ); donut.InsertChild( t, Matrix4d.Identity ); s = new Sphere(); s.SetAttribute( PropertyName.COLOR, new double[] { 0.5, 0.5, 0.5 } ); s.SetAttribute( PropertyName.TEXTURE, new CheckerTexture( 100, 100, new double[] { 1, 0.5, 0 } ) ); donut.InsertChild( s, Matrix4d.Scale( 3 ) * Matrix4d.CreateTranslation( 0, -3, 0 ) ); root.InsertChild( donut, Matrix4d.CreateRotationX( 0.8 ) * Matrix4d.CreateTranslation( -2.5, 0.0, 0.0 ) ); int number = 14; for ( int i = 0; i < number; i++ ) { t = new Torus( 0.2, 0.01 + 0.185 * i / number ); t.SetAttribute( PropertyName.COLOR, new double[] { 1, 1, 1 } ); root.InsertChild( t, Matrix4d.CreateRotationX( 0.5 * i ) * Matrix4d.CreateTranslation( 10.0 * (1.0 * i / number) - 4.7, -2.5, 0 ) ); } }
/// <summary> /// Infinite plane with two spheres on it (one of them is transparent) /// </summary> public static void TwoSpheres( IRayScene sc ) { Debug.Assert( sc != null ); // CSG scene: CSGInnerNode root = new CSGInnerNode( SetOperation.Union ); root.SetAttribute( PropertyName.REFLECTANCE_MODEL, new PhongModel() ); root.SetAttribute( PropertyName.MATERIAL, new PhongMaterial( new double[] { 1.0, 0.8, 0.1 }, 0.1, 0.6, 0.4, 128 ) ); sc.Intersectable = root; // Background color: sc.BackgroundColor = new double[] { 0.0, 0.05, 0.07 }; // Camera: sc.Camera = new StaticCamera( new Vector3d( 0.7, 0.5, -5.0 ), new Vector3d( 0.0, -0.18, 1.0 ), 50.0 ); // Light sources: sc.Sources = new LinkedList<ILightSource>(); sc.Sources.Add( new AmbientLightSource( 0.8 ) ); sc.Sources.Add( new PointLightSource( new Vector3d( -5.0, 4.0, -3.0 ), 1.2 ) ); // --- NODE DEFINITIONS ---------------------------------------------------- // Transparent sphere: Sphere s; s = new Sphere(); PhongMaterial pm = new PhongMaterial( new double[] { 0.0, 0.2, 0.1 }, 0.05, 0.05, 0.1, 128 ); pm.n = 1.6; pm.Kt = 0.9; s.SetAttribute( PropertyName.MATERIAL, pm ); root.InsertChild( s, Matrix4d.Identity ); // Opaque sphere: s = new Sphere(); root.InsertChild( s, Matrix4d.Scale( 1.2 ) * Matrix4d.CreateTranslation( 1.5, 0.2, 2.4 ) ); // Infinite plane with checker: Plane pl = new Plane(); pl.SetAttribute( PropertyName.COLOR, new double[] { 0.3, 0.0, 0.0 } ); pl.SetAttribute( PropertyName.TEXTURE, new CheckerTexture( 0.6, 0.6, new double[] { 1.0, 1.0, 1.0 } ) ); root.InsertChild( pl, Matrix4d.RotateX( -MathHelper.PiOver2 ) * Matrix4d.CreateTranslation( 0.0, -1.0, 0.0 ) ); }
protected static CSGInnerNode testWithCylindersXor() { CSGInnerNode root = new CSGInnerNode( SetOperation.Difference ); root.InsertChild( testWithCylinders( SetOperation.Union ), Matrix4d.Identity ); root.InsertChild( testWithCylinders( SetOperation.Xor ), Matrix4d.Identity ); return root; }
/// <summary> /// Test scene for BezierSurface. /// </summary> public static void Bezier( IRayScene sc ) { Debug.Assert( sc != null ); // CSG scene: CSGInnerNode root = new CSGInnerNode( SetOperation.Union ); root.SetAttribute( PropertyName.REFLECTANCE_MODEL, new PhongModel() ); root.SetAttribute( PropertyName.MATERIAL, new PhongMaterial( new double[] { 1.0, 0.8, 0.1 }, 0.1, 0.5, 0.5, 64 ) ); sc.Intersectable = root; // Background color: sc.BackgroundColor = new double[] { 0.0, 0.05, 0.07 }; // Camera: sc.Camera = new StaticCamera( new Vector3d( 0.7, 0.5, -5.0 ), new Vector3d( 0.0, -0.18, 1.0 ), 50.0 ); // Light sources: sc.Sources = new LinkedList<ILightSource>(); sc.Sources.Add( new AmbientLightSource( 0.8 ) ); sc.Sources.Add( new PointLightSource( new Vector3d( -5.0, 3.0, -3.0 ), 1.0 ) ); // --- NODE DEFINITIONS ---------------------------------------------------- // Bezier patch (not yet): BezierSurface b = new BezierSurface( 1, 2, new double[] { 0.0, 0.0, 3.0, // row 0 1.0, 0.0, 3.0, 2.0, 0.0, 3.0, 3.0, 0.0, 3.0, 4.0, 0.0, 3.0, 5.0, 0.0, 3.0, 6.0, 0.0, 3.0, 0.0, 0.0, 2.0, // row 1 1.0, 0.0, 2.0, 2.0, 3.0, 2.0, 3.0, 3.0, 2.0, 4.0, 3.0, 2.0, 5.0, 0.0, 2.0, 6.0, 0.0, 2.0, 0.0, 0.0, 1.0, // row 2 1.0, 0.0, 1.0, 2.0, 0.0, 1.0, 3.0, 1.5, 1.0, 4.0, 3.0, 1.0, 5.0, 0.0, 1.0, 6.0, 0.0, 1.0, 0.0, 0.0, 0.0, // row 3 1.0, 0.0, 0.0, 2.0, 0.0, 0.0, 3.0, 0.0, 0.0, 4.0, 0.0, 0.0, 5.0, 0.0, 0.0, 6.0, 0.0, 0.0, } ); b.SetAttribute( PropertyName.TEXTURE, new CheckerTexture( 10.5, 12.0, new double[] { 0.0, 0.0, 0.1 } ) ); root.InsertChild( b, Matrix4d.RotateY( -0.4 ) * Matrix4d.CreateTranslation( -1.1, -0.9, 0.0 ) ); // Cylinders for reflections.. Cylinder c = new Cylinder(); c.SetAttribute( PropertyName.MATERIAL, new PhongMaterial( new double[] { 0.0, 0.6, 0.0 }, 0.2, 0.6, 0.3, 8 ) ); root.InsertChild( c, Matrix4d.Scale( 0.15 ) * Matrix4d.RotateX( MathHelper.PiOver2 ) * Matrix4d.CreateTranslation( -0.4, 0.0, 0.0 ) ); c = new Cylinder(); c.SetAttribute( PropertyName.MATERIAL, new PhongMaterial( new double[] { 0.8, 0.2, 0.0 }, 0.2, 0.6, 0.3, 8 ) ); root.InsertChild( c, Matrix4d.Scale( 0.2 ) * Matrix4d.RotateX( MathHelper.PiOver2 ) * Matrix4d.CreateTranslation( -1.9, 0.0, 3.0 ) ); // Infinite plane with checker: Plane pl = new Plane(); pl.SetAttribute( PropertyName.COLOR, new double[] { 0.3, 0.0, 0.0 } ); pl.SetAttribute( PropertyName.TEXTURE, new CheckerTexture( 0.6, 0.6, new double[] { 1.0, 1.0, 1.0 } ) ); root.InsertChild( pl, Matrix4d.RotateX( -MathHelper.PiOver2 ) * Matrix4d.CreateTranslation( 0.0, -1.0, 0.0 ) ); }
protected static CSGInnerNode testXor2() { // testovani probiha podle vzoru (a union b) - (a xor b) = (a and b) // takze udelame levou stranu rovnice a to nam da intersection CSGInnerNode root = new CSGInnerNode( SetOperation.Difference ); root.InsertChild( test6Spheres( SetOperation.Union ), Matrix4d.Identity ); root.InsertChild( test6Spheres( SetOperation.Xor ), Matrix4d.Identity ); return root; }
/// <summary> /// [Re]-renders the whole image (in separate thread) /// </summary> private void RenderImage() { Cursor.Current = Cursors.WaitCursor; // determine output image size: int width = ImageWidth; if (width <= 0) { width = panel1.Width; } int height = ImageHeight; if (height <= 0) { height = panel1.Height; } Bitmap newImage = new Bitmap(width, height, PixelFormat.Format24bppRgb); int threads = CheckMultithreading.Checked ? Environment.ProcessorCount : 1; IRayScene sc = FormSupport.getScene(); IImageFunction imf = getImageFunction(sc, width, height); IRenderer r = getRenderer(imf, width, height); rayVisualizer.UpdateScene(sc); master = new Master(newImage, sc, r, RenderClientsForm.instance?.clients, threads, pointCloudCheckBox.Checked, ref AdditionalViews.singleton.pointCloud); master.progressData = progress; master.InitializeAssignments(newImage, sc, r); if (pointCloudCheckBox.Checked) { master.pointCloud?.SetNecessaryFields(PointCloudSavingStart, PointCloudSavingEnd, Notification, Invoke); } progress.SyncInterval = ((width * (long)height) > (2L << 20)) ? 3000L : 1000L; progress.Reset(); CSGInnerNode.ResetStatistics(); lock (sw) sw.Restart(); master.StartThreads(); long elapsed; lock (sw) { sw.Stop(); elapsed = sw.ElapsedMilliseconds; } string msg = string.Format(CultureInfo.InvariantCulture, "{0:f1}s [ {1}x{2}, mt{3}, r{4:#,#}k, i{5:#,#}k, bb{6:#,#}k, t{7:#,#}k ]", 1.0e-3 * elapsed, width, height, threads, (Intersection.countRays + 500L) / 1000L, (Intersection.countIntersections + 500L) / 1000L, (CSGInnerNode.countBoundingBoxes + 500L) / 1000L, (CSGInnerNode.countTriangles + 500L) / 1000L); SetText(msg); Console.WriteLine(@"Rendering finished: " + msg); SetImage(newImage); Cursor.Current = Cursors.Default; StopRendering(); }
/// <summary> /// Test scene by Adam Hanka (c) 2012 /// </summary> public static void Circus( IRayScene sc ) { Debug.Assert( sc != null ); // CSG scene: CSGInnerNode root = new CSGInnerNode( SetOperation.Union ); root.SetAttribute( PropertyName.REFLECTANCE_MODEL, new PhongModel() ); root.SetAttribute( PropertyName.MATERIAL, new PhongMaterial( new double[] { 0.5, 0.5, 0.5 }, 0.2, 0.8, 0.1, 16 ) ); sc.Intersectable = root; // Background color: sc.BackgroundColor = new double[] { 0.5, 0.7, 0.6 }; // Camera: sc.Camera = new StaticCamera( new Vector3d( 0.0, 0.0, -11.0 ), new Vector3d( 0.0, 0.0, 1.0 ), 60.0 ); // Light sources: sc.Sources = new LinkedList<ILightSource>(); sc.Sources.Add( new AmbientLightSource( 1.0 ) ); sc.Sources.Add( new PointLightSource( new Vector3d( -5.0, 3.0, -3.0 ), 1.2 ) ); // --- NODE DEFINITIONS ---------------------------------------------------- // Vlevo nahore: hlava panacka - vyuziva implementace Xor na rty, vnitrek ust je tvoren pomoci Intersection, jinak je zalozena na Union a Difference root.InsertChild( head(), Matrix4d.CreateTranslation( -6, 1.5, 0 ) * Matrix4d.RotateY( Math.PI / 10 ) * Matrix4d.Scale( 0.7 ) ); // Uprostred nahode: testovani funkcnosti difference pro sest kouli root.InsertChild( test6Spheres( SetOperation.Difference ), Matrix4d.CreateTranslation( 0, 1.5, 0 ) * Matrix4d.Scale( 0.7 ) ); // Vpravo nahore: testovani operace Xor tak, ze se funkce test6Spheres vola jednou s Union, jednou s Xor a vysledky se odectou root.InsertChild( testXor2(), Matrix4d.CreateTranslation( 6, 1.5, 0 ) * Matrix4d.RotateX( Math.PI / 3 ) * Matrix4d.RotateY( Math.PI / 4 ) * Matrix4d.Scale( 0.6 ) ); // Vlevo dole: test xoru s Cylindry - opet jako Union - Xor = vysledek root.InsertChild( testWithCylindersXor(), Matrix4d.CreateTranslation( -5, -2.5, 0 ) * Matrix4d.Scale( 0.7 ) ); // Uprostred dole: prosty Xor valcu root.InsertChild( testWithCylinders( SetOperation.Xor ), Matrix4d.CreateTranslation( 0, -2.5, 0 ) * Matrix4d.Scale( 0.7 ) ); // Vpravo dole: testovani Intersection - prosty prusecik dvou kouli root.InsertChild( test2Spheres( SetOperation.Intersection ), Matrix4d.CreateTranslation( 4, -1.5, 0 ) ); }