Exemplo n.º 1
0
        public static IBasicShape MapApiToDomain(ShapeDto input)
        {
            IBasicShape output = null;

            switch (input.Type)
            {
            case ShapeDto.ShapeType.Sphere:
                // TODO: worth normalizing Shape instantiation e.g. new()
                output = Sphere.CreateDefaultInstance();
                break;

            case ShapeDto.ShapeType.Plane:
                output = new Plane();
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(input.Type), "Unrecognized shape type: " + input.Type);
            }

            if (input.Material != null)
            {
                output.Material = MaterialFactory.MapApiToDomain(input.Material);
            }

            if (input.Transformations != null && input.Transformations.Any())
            {
                foreach (var transform in input.Transformations)
                {
                    var domainTransformAction = TransformationFactory.MapApiTransformToDomainAction(transform);
                    domainTransformAction(output.Transformation);
                }
            }

            return(output);
        }
Exemplo n.º 2
0
        private void InitializationValues_SetupDefaultWorld_Overload(float?fixedAmbient = null)
        {
            _outerSphere = Sphere.CreateDefaultInstance();
            _innerSphere = Sphere.CreateDefaultInstance();
            _outerSphere
            .UpdateColor(Color.FromScRgb(Material.DefaultColorA, 0.8F, 1.0F, 0.6F))
            .UpdateDiffuse(0.7F)
            .UpdateSpecular(0.2F)
            .UpdateAmbient(fixedAmbient ?? _outerSphere.Material.Ambient);
            _innerSphere
            .UpdateAmbient(fixedAmbient ?? _innerSphere.Material.Ambient);

            // As feature file: concentric circles with inner sphere scaled down.
            _innerSphere.Transformation = new MatrixTransformationBuilder()
                                          .Scale(new Vector3(0.5F, 0.5F, 0.5F));

            _world = new World(
                new List <IBasicShape> {
                _outerSphere, _innerSphere
            },
                new Model.Light
            {
                Position  = new Vector4(-10.0F, 10.0F, -10.0F, 1.0F),
                Intensity = Color.White
            }
                );
        }
Exemplo n.º 3
0
        private static World CreateDefaultWorldLarger()
        {
            var outerSphere = Sphere.CreateDefaultInstance();
            var innerSphere = Sphere.CreateDefaultInstance();

            outerSphere
            .UpdateColor(Color.FromScRgb(Material.DefaultColorA, 0.8F, 1.0F, 0.6F))
            .UpdateDiffuse(0.7F)
            .UpdateSpecular(0.2F);

            // As feature file: concentric circles with inner sphere scaled down.
            innerSphere.Transformation = new MatrixTransformationBuilder()
                                         .Scale(new Vector3(10.0F, 10.0F, 10.0F));
            innerSphere.Transformation = new MatrixTransformationBuilder()
                                         .Scale(new Vector3(5.0F, 5.0F, 5.0F));

            return(new World(
                       new List <IBasicShape> {
                outerSphere, innerSphere
            },
                       new Domain.Model.Light
            {
                Position = new Vector4(-30.0F, 30.0F, -30.0F, 1.0F),
                Intensity = Color.White
            }
                       ));
        }
Exemplo n.º 4
0
        public static void DrawSphere(string outputBitmapFilePath, IMatrixTransformationBuilder transformation)
        {
            // Rough and ready. Fully following the pseudocode from the text.
            // Basically:
            //   For each pixel on the canvas, figure out the ray (direction) from there
            //   back to the origin of the emitting ray (light source).
            //   Then calculate the hit (first intersection), if any. If it's a hit then
            //   that pixel on the canvas gets drawn.
            //   The rest of the code is just pixel conversion e.g. determining what "1"
            //   represents in terms of numbers of pixels and also converting the half above /
            //   half below of the sphere to a non-negative set of pixels for drawing.

            // inputs: could encapsulate in class to cleanup the code.
            var         ray_origin = new Vector4(0F, 0F, -5F, 1F);
            var         wall_z     = 10F;
            var         wall_size  = 7.0F;
            IBasicShape shape      = Sphere.CreateDefaultInstance();

            shape.Transformation = transformation;
#pragma warning disable CS0618 // Type or member is obsolete
            var xs = new SceneIntersectionCalculator(new List <IBasicShape> {
                shape
            });
#pragma warning restore CS0618 // Type or member is obsolete
            var canvas_pixels = 100;
            var pixel_size    = wall_size / canvas_pixels;
            var half          = wall_size / 2;
            var color         = Color.FromScRgb(1.0F, 0.0F, 0.0F, 1.0F).Simplify();



            using var canvas = new System.Drawing.Bitmap(canvas_pixels, canvas_pixels);

            for (int y = 0; y < canvas_pixels; y++)
            {
                var world_y = half - pixel_size * y;

                for (int x = 0; x < canvas_pixels; x++)
                {
                    var world_x = -half + pixel_size * x;

                    var position = new Vector4(world_x, world_y, wall_z, 1F);

                    var r = new Domain.Model.Ray(
                        ray_origin,
                        Vector4.Normalize(position - ray_origin));


                    if (xs.CalculateHit(r).HasValue)
                    {
                        canvas.SetPixel(x, y, color);
                    }
                }
            }


            canvas.Save(outputBitmapFilePath);
        }
Exemplo n.º 5
0
        public static SceneDto GetSphereCentralWithPlanesExample()
        {
            // Templates
            var defaultSphere   = Sphere.CreateDefaultInstance();
            var defaultMaterial = Material.CreateDefaultInstance();
            var white           = Color.White;

            // Copying ReRenderSphereCentralWithPlanes code using serializable DTOs.

            // Planes

            var floor = new ShapeDto
            {
                Type     = ShapeDto.ShapeType.Plane,
                Material = new MaterialDto
                {
                    Color = new ColorDto
                    {
                        A = Material.DefaultColorA,
                        R = 1F,
                        G = 0.9F,
                        B = 0.9F
                    },
                    Specular  = 0F,
                    Ambient   = defaultMaterial.Ambient,
                    Diffuse   = defaultMaterial.Diffuse,
                    Shininess = defaultMaterial.Shininess
                }
            };

            var left_wall = new ShapeDto
            {
                Type            = ShapeDto.ShapeType.Plane,
                Material        = floor.Material,
                Transformations = new List <TransformDto>
                {
                    new TransformDto
                    {
                        TransformType   = TransformDto.TransformationType.RotateX,
                        RotationRadians = MathF.PI / 2
                    },
                    new TransformDto
                    {
                        TransformType   = TransformDto.TransformationType.RotateY,
                        RotationRadians = -MathF.PI / 4
                    },
                    new TransformDto
                    {
                        TransformType        = TransformDto.TransformationType.Translate,
                        VectorTransformation = new VectorDto
                        {
                            X = 0F, Y = 0F, Z = 5F
                        }
                    }
                }
            };

            var right_wall = new ShapeDto
            {
                Type            = ShapeDto.ShapeType.Plane,
                Material        = floor.Material,
                Transformations = new List <TransformDto>
                {
                    new TransformDto
                    {
                        TransformType   = TransformDto.TransformationType.RotateX,
                        RotationRadians = MathF.PI / 2
                    },
                    new TransformDto
                    {
                        TransformType   = TransformDto.TransformationType.RotateY,
                        RotationRadians = MathF.PI / 4
                    },
                    new TransformDto
                    {
                        TransformType        = TransformDto.TransformationType.Translate,
                        VectorTransformation = new VectorDto
                        {
                            X = 0F, Y = 0F, Z = 5F
                        }
                    }
                }
            };


            // Spheres

            var middle = new ShapeDto
            {
                Type     = ShapeDto.ShapeType.Sphere,
                Material = new MaterialDto
                {
                    Color = new ColorDto
                    {
                        A = Material.DefaultColorA,
                        R = 0.1F,
                        G = 1F,
                        B = 0.5F
                    },
                    Diffuse   = 0.7F,
                    Specular  = 0.3F,
                    Ambient   = defaultMaterial.Ambient,
                    Shininess = defaultMaterial.Shininess
                },
                Transformations = new List <TransformDto>
                {
                    new TransformDto
                    {
                        TransformType        = TransformDto.TransformationType.Translate,
                        VectorTransformation = new VectorDto
                        {
                            X = -0.5F, Y = 1F, Z = 0.5F
                        }
                    }
                }
            };

            var right = new ShapeDto
            {
                Type     = ShapeDto.ShapeType.Sphere,
                Material = new MaterialDto
                {
                    Color = new ColorDto
                    {
                        A = Material.DefaultColorA,
                        R = 0.5F,
                        G = 1F,
                        B = 0.1F
                    },
                    Diffuse   = 0.7F,
                    Specular  = 0.3F,
                    Ambient   = defaultMaterial.Ambient,
                    Shininess = defaultMaterial.Shininess
                },
                Transformations = new List <TransformDto>
                {
                    new TransformDto
                    {
                        TransformType        = TransformDto.TransformationType.Scale,
                        VectorTransformation = new VectorDto
                        {
                            X = 0.5F, Y = 0.5F, Z = 0.5F
                        }
                    },
                    new TransformDto
                    {
                        TransformType        = TransformDto.TransformationType.Translate,
                        VectorTransformation = new VectorDto
                        {
                            X = 1.5F, Y = 0.5F, Z = -0.5F
                        }
                    }
                }
            };

            var left = new ShapeDto
            {
                Type     = ShapeDto.ShapeType.Sphere,
                Material = new MaterialDto
                {
                    Color = new ColorDto
                    {
                        A = Material.DefaultColorA,
                        R = 1F,
                        G = 0.8F,
                        B = 0.1F
                    },
                    Diffuse   = 0.7F,
                    Specular  = 0.3F,
                    Ambient   = defaultMaterial.Ambient,
                    Shininess = defaultMaterial.Shininess
                },
                Transformations = new List <TransformDto>
                {
                    new TransformDto
                    {
                        TransformType        = TransformDto.TransformationType.Scale,
                        VectorTransformation = new VectorDto
                        {
                            X = 0.33F, Y = 0.33F, Z = 0.33F
                        }
                    },
                    new TransformDto
                    {
                        TransformType        = TransformDto.TransformationType.Translate,
                        VectorTransformation = new VectorDto
                        {
                            X = -1.5F, Y = 0.33F, Z = -0.75F
                        }
                    }
                }
            };


            // Scene - pull together shapes into root serializable object

            // Use low res until happy, then crank up. Takes a lot of clock cycles!
#pragma warning disable CS0219 // Variable is assigned but its value is never used
            int high   = 1000;
            int medium = 500;
            int low    = 250;
            int res    = medium;
#pragma warning restore CS0219 // Variable is assigned but its value is never used

            var scene = new SceneDto
            {
                Shapes = new List <ShapeDto>
                {
                    floor, left_wall, right_wall,
                    left, middle, right
                },
                LightSource = new LightDto
                {
                    Position = new VectorDto
                    {
                        X = -10F,
                        Y = 10F,
                        Z = -10F
                    },
                    Intensity = new ColorDto
                    {
                        A = white.ScA,
                        R = white.ScR,
                        G = white.ScG,
                        B = white.ScB
                    }
                },
                Camera = new CameraDto
                {
                    HSize       = res,
                    VSize       = res / 2,
                    FieldOfView = MathF.PI / 3,
                    From        = new VectorDto {
                        X = 0F, Y = 1.5F, Z = -5F
                    },
                    To = new VectorDto {
                        X = 0F, Y = 1F, Z = 0F
                    },
                    Up = new VectorDto {
                        X = 0F, Y = 1F, Z = 0F
                    }
                }
            };

            return(scene);
        }
Exemplo n.º 6
0
 public void InitializationValues_SetOnSphereInstance()
 {
     _sphereInstance = Sphere.CreateDefaultInstance(false);
 }
Exemplo n.º 7
0
        public static void RenderSphereCentral(string outputBitmapFilePath, bool useAcneEffect = false)
        {
            // Define world

            var floor = Sphere.CreateDefaultInstance();

            floor.Transformation = new MatrixTransformationBuilder()
                                   .Scale(new Vector3(10F, 0.01F, 10F));
            floor.UpdateColor(Color.FromScRgb(Material.DefaultColorA, 1F, 0.9F, 0.9F))
            .UpdateSpecular(0F);

            var left_wall = Sphere.CreateDefaultInstance();

            left_wall.Transformation = new MatrixTransformationBuilder()
                                       .Scale(new Vector3(10F, 0.01F, 10F))
                                       .RotateX(MathF.PI / 2)
                                       .RotateY(-MathF.PI / 4)
                                       .Translate(new Vector3(0F, 0F, 5F))
            ;
            left_wall.Material = floor.Material;

            var right_wall = Sphere.CreateDefaultInstance();

            right_wall.Transformation = new MatrixTransformationBuilder()
                                        .Scale(new Vector3(10F, 0.01F, 10F))
                                        .RotateX(MathF.PI / 2)
                                        .RotateY(MathF.PI / 4)
                                        .Translate(new Vector3(0F, 0F, 5F))
            ;
            right_wall.Material = floor.Material;

            var middle = Sphere.CreateDefaultInstance();

            middle.Transformation = new MatrixTransformationBuilder()
                                    .Translate(new Vector3(-0.5F, 1F, 0.5F));
            middle.UpdateColor(Color.FromScRgb(Material.DefaultColorA, 0.1F, 1F, 0.5F))
            .UpdateDiffuse(0.7F)
            .UpdateSpecular(0.3F);

            var right = Sphere.CreateDefaultInstance();

            right.Transformation = new MatrixTransformationBuilder()
                                   .Scale(new Vector3(0.5F, 0.5F, 0.5F))
                                   .Translate(new Vector3(1.5F, 0.5F, -0.5F))
            ;
            right.UpdateColor(Color.FromScRgb(Material.DefaultColorA, 0.5F, 1F, 0.1F))
            .UpdateDiffuse(0.7F)
            .UpdateSpecular(0.3F);

            var left = Sphere.CreateDefaultInstance();

            left.Transformation = new MatrixTransformationBuilder()
                                  .Scale(new Vector3(0.33F, 0.33F, 0.33F))
                                  .Translate(new Vector3(-1.5F, 0.33F, -0.75F))
            ;
            left.UpdateColor(Color.FromScRgb(Material.DefaultColorA, 1F, 0.8F, 0.1F))
            .UpdateDiffuse(0.7F)
            .UpdateSpecular(0.3F);

            var world = new World(new List <IBasicShape>
            {
                floor, left_wall, right_wall,
                left, middle, right
            },
                                  new Light
            {
                Position  = new Vector4(-10.0F, 10.0F, -10.0F, 1.0F),
                Intensity = Color.White
            });

            // Use low res until happy, then crank up. Takes a lot of clock cycles!
#pragma warning disable CS0219 // Variable is assigned but its value is never used
            int high   = 1000;
            int medium = 500;
            int low    = 250;
            int res    = medium;
#pragma warning restore CS0219 // Variable is assigned but its value is never used

            var camera = new Camera(res, res / 2, MathF.PI / 3);
            camera.SetViewTransformation(
                from: new Vector4(0F, 1.5F, -5F, 1F),
                to: new Vector4(0F, 1F, 0F, 1F),
                up: new Vector4(0F, 1F, 0F, 0F)
                );


            // Render image

            using var canvas = new System.Drawing.Bitmap(camera.HorizontalSize, camera.VerticalSize);

            for (int y = 0; y < camera.VerticalSize - 1; y++)
            {
                for (int x = 0; x < camera.HorizontalSize - 1; x++)
                {
                    var   ray   = camera.GetRay(x, y);
                    Color color = Lighting.CalculateColorWithPhongReflection(world, ray, useAcneEffect);

                    canvas.SetPixel(x, y, color.Simplify(255));
                }
            }

            canvas.Save(outputBitmapFilePath);
        }