Example #1
0
        /// <inheritdoc />
        public IHitable GetWorld()
        {
            var red   = new LambertianMaterial(new ColorTexture(0.65f, 0.05f, 0.05f));
            var white = new LambertianMaterial(new ColorTexture(0.73f, 0.73f, 0.73f));
            var green = new LambertianMaterial(new ColorTexture(0.12f, 0.45f, 0.15f));

            var b1 = new Translate(
                new RotateY(new Box(new Vector3(0.0f, 0.0f, 0.0f), new Vector3(165.0f, 165.0f, 165.0f), white), -18.0f),
                new Vector3(130.0f, 0.0f, 65.0f));
            var b2 = new Translate(
                new RotateY(new Box(new Vector3(0.0f, 0.0f, 0.0f), new Vector3(165.0f, 330.0f, 165.0f), white), 15.0f),
                new Vector3(265.0f, 0.0f, 295.0f));

            var list = new HitableList()
            {
                new FlipNormals(new YzRect(0.0f, 555.0f, 0.0f, 555.0f, 555.0f, green)),
                new YzRect(0.0f, 555.0f, 0.0f, 555.0f, 0.0f, red),
                new FlipNormals(_light),
                new FlipNormals(new XzRect(0.0f, 555.0f, 0.0f, 555.0f, 555.0f, white)),
                new XzRect(0.0f, 555.0f, 0.0f, 555.0f, 0.0f, white),
                new FlipNormals(new XyRect(0.0f, 555.0f, 0.0f, 555.0f, 555.0f, white)),

                new ConstantMedium(b1, 0.01f, new ColorTexture(1.0f, 1.0f, 1.0f)),
                new ConstantMedium(b2, 0.01f, new ColorTexture(0.0f, 0.0f, 0.0f))
            };

            return(new BvhNode(list, 0.0f, 1.0f));
        }
Example #2
0
        /// <inheritdoc />
        public IHitable GetWorld()
        {
            var red      = new LambertianMaterial(new ColorTexture(0.65f, 0.05f, 0.05f));
            var white    = new LambertianMaterial(new ColorTexture(0.73f, 0.73f, 0.73f));
            var green    = new LambertianMaterial(new ColorTexture(0.12f, 0.45f, 0.15f));
            var aluminum = new MetalMaterial(new ColorVector(0.8f, 0.85f, 0.88f), 0.0f);

            var list = new HitableList()
            {
                new FlipNormals(new YzRect(0.0f, 555.0f, 0.0f, 555.0f, 555.0f, green)),
                new YzRect(0.0f, 555.0f, 0.0f, 555.0f, 0.0f, red),
                new FlipNormals(_light),
                new FlipNormals(new XzRect(0.0f, 555.0f, 0.0f, 555.0f, 555.0f, white)),
                new XzRect(0.0f, 555.0f, 0.0f, 555.0f, 0.0f, white),
                new FlipNormals(new XyRect(0.0f, 555.0f, 0.0f, 555.0f, 555.0f, white)),

                // new Translate(new RotateY(new Box(new Vector3(0.0f, 0.0f, 0.0f), new Vector3(165.0f, 165.0f, 165.0f), white), -18.0f), new Vector3(130.0f, 0.0f, 65.0f)),
                new Translate(new RotateY(new Box(new Vector3(0.0f, 0.0f, 0.0f), new Vector3(165.0f, 330.0f, 165.0f), white), 15.0f), new Vector3(265.0f, 0.0f, 295.0f)),
                _glassSphere,
            };

            return(new BvhNode(list, 0.0f, 1.0f));
        }
Example #3
0
        public static IScene ParseFile(string filePath, int imageWidth, int imageHeight)
        {
            var background = new Func <Ray, ColorVector>(ray => new ColorVector(0.0f, 0.0f, 0.0f));
            var lights     = new HitableList();
            var world      = new HitableList();
            var cameraAt   = new Vector3(0.0f, 0.0f, 0.0f);
            var cameraFrom = new Vector3(0.0f, 0.0f, 0.0f);
            var cameraUp   = new Vector3(0.0f, 0.0f, 0.0f);

            var lookingFor = LookingFor.Instruction;

            IMaterial currentMaterial = new LambertianMaterial(new ColorTexture(0.0f, 0.0f, 0.0f));

            var polyVectors        = new List <Vector3>();
            var currentItemCounter = 0;

            var lines = File.ReadAllLines(filePath);

            foreach (var line in lines)
            {
                var split = line.Split(' ', '\t');

                switch (lookingFor)
                {
                case LookingFor.Instruction:
                {
                    var instruction = split[0];

                    if (instruction == "b")
                    {
                        // background color
                        background = ray => new ColorVector(float.Parse(split[1]), float.Parse(split[2]), float.Parse(split[3]));
                    }
                    else if (instruction == "v")
                    {
                        // viewpoint location
                        lookingFor = LookingFor.ViewpointFrom;
                    }
                    else if (instruction == "l")
                    {
                        // positional light
                        //var colorVector = split.Length == 7
                        //                    ? new ColorVector(
                        //                      float.Parse(split[4]),
                        //                      float.Parse(split[5]),
                        //                      float.Parse(split[6]))
                        //                    : new ColorVector(7.0f, 7.0f, 7.0f);
                        var colorVector = new ColorVector(7.0f, 7.0f, 7.0f);
                        var sphere      = new Sphere(
                            new Vector3(float.Parse(split[1]), float.Parse(split[2]), float.Parse(split[3])),
                            1.5f,
                            new DiffuseLight(new ColorTexture(colorVector)));
                        lights.Add(sphere);
                        world.Add(sphere);
                    }
                    else if (instruction == "f")
                    {
                        // println!("reading f: {}", num);
                        // object material properties
                        // "f" red green blue Kd Ks Shine T index_of_refraction
                        // Kd Diffuse component
                        // Ks Specular
                        // Shine Phong cosine power for highlights
                        // T Transmittance (fraction of contribution of the transmitting ray).
                        // Usually, 0 <= Kd <= 1 and 0 <= Ks <= 1, though it is not required that Kd + Ks = 1. Note that transmitting objects (T > 0) are considered to have two sides for algorithms that need these (normally, objects have one side).
                        // todo: i don't think i'm assigning the correct values into my solidmaterial yet
                        //currentMaterial = new SolidMaterial(
                        //  0.0f, // kAmbient
                        //  float.Parse(split[4]),  // kDiffuse
                        //  float.Parse(split[5]),  // kSpecular
                        //  float.Parse(split[7]),  // kReflection
                        //  float.Parse(split[8]),  // kTransparent
                        //  float.Parse(split[8]),  // refraction    -- todo: which is which here?
                        //  float.Parse(split[6]),  // gloss
                        //  new ColorVector(float.Parse(split[1]), float.Parse(split[2]), float.Parse(split[3]))
                        //);
                        // todo: need to look at diffuse/specular/reflection/transparent and pick an appropriate material for it...
                        //currentMaterial = new LambertianMaterial(
                        //  new ColorTexture(
                        //    new ColorVector(float.Parse(split[1]), float.Parse(split[2]), float.Parse(split[3]))));
                        if (float.Parse(split[5]) > 0.01)
                        {
                            currentMaterial = new MetalMaterial(
                                new ColorVector(float.Parse(split[1]), float.Parse(split[2]), float.Parse(split[3])),
                                1.5f);
                        }
                        else
                        {
                            currentMaterial = new LambertianMaterial(
                                new ColorTexture(
                                    new ColorVector(float.Parse(split[1]), float.Parse(split[2]), float.Parse(split[3]))));
                        }
                    }
                    else if (instruction == "c")
                    {
                        // cone or cylinder
                    }
                    else if (instruction == "s")
                    {
                        // sphere
                        world.Add(
                            new Sphere(
                                new Vector3(float.Parse(split[1]), float.Parse(split[2]), float.Parse(split[3])),
                                float.Parse(split[4]),
                                currentMaterial));
                    }
                    else if (instruction == "p")
                    {
                        // polygon
                        currentItemCounter = int.Parse(split[1]);
                        polyVectors        = new List <Vector3>();
                        lookingFor         = LookingFor.Polygon;
                    }
                    else if (instruction == "pp")
                    {
                        // polygon patch
                    }
                    else if (instruction == "#")
                    {
                        // comment
                    }
                }
                break;

                case LookingFor.Polygon:
                {
                    if (currentItemCounter > 0)
                    {
                        currentItemCounter--;
                        polyVectors.Add(new Vector3(float.Parse(split[0]), float.Parse(split[1]), float.Parse(split[2])));
                    }

                    if (currentItemCounter == 0)
                    {
                        if (polyVectors.Count >= 3)
                        {
                            var firstVert = polyVectors[0];
                            var prevVert  = polyVectors[1];
                            var thisVert  = polyVectors[2];
                            world.Add(
                                new Triangle(
                                    new List <Vector3>
                                {
                                    firstVert,
                                    prevVert,
                                    thisVert
                                },
                                    currentMaterial));

                            for (var i = 3; i < polyVectors.Count; i++)
                            {
                                prevVert = thisVert;
                                thisVert = polyVectors[i];
                                world.Add(
                                    new Triangle(
                                        new List <Vector3>
                                    {
                                        firstVert,
                                        prevVert,
                                        thisVert
                                    },
                                        currentMaterial));
                            }
                        }

                        lookingFor = LookingFor.Instruction;
                    }
                }
                break;

                case LookingFor.ViewpointFrom:
                {
                    cameraFrom = new Vector3(float.Parse(split[1]), float.Parse(split[2]), float.Parse(split[3]));
                    lookingFor = LookingFor.ViewpointAt;
                }
                break;

                case LookingFor.ViewpointAt:
                {
                    cameraAt   = new Vector3(float.Parse(split[1]), float.Parse(split[2]), float.Parse(split[3]));
                    lookingFor = LookingFor.ViewpointUp;
                }
                break;

                case LookingFor.ViewpointUp:
                {
                    cameraUp   = new Vector3(float.Parse(split[1]), float.Parse(split[2]), float.Parse(split[3]));
                    lookingFor = LookingFor.ViewpointAngle;
                }
                break;

                case LookingFor.ViewpointAngle:
                {
                    // todo: implement
                    lookingFor = LookingFor.ViewpointHither;
                }
                break;

                case LookingFor.ViewpointHither:
                {
                    // todo: implement
                    lookingFor = LookingFor.ViewpointResolution;
                }
                break;

                case LookingFor.ViewpointResolution:
                {
                    //resolutionX = int.Parse(split[1]);
                    //resolutionY = int.Parse(split[2]);

                    lookingFor = LookingFor.Instruction;
                }
                break;
                }
            }

            return(new NffParserScene(
                       new Camera(
                           cameraFrom,
                           cameraAt,
                           cameraUp,
                           50.0f,
                           Convert.ToSingle(imageWidth) / Convert.ToSingle(imageHeight),
                           0.0f,
                           10.0f),
                       new BvhNode(world, 0.0f, 1.0f),
                       lights,
                       background));
        }