Beispiel #1
0
 public Vertex(RTPoint vertex, RTVector normal)
 {
     Location = vertex;
     if (normal != null)
     {
         Normal = new Normal(normal);
     }
 }
Beispiel #2
0
        public void MoveCamera(RTPoint lookFrom, RTPoint lookAt, RTVector up)
        {
            Eye = new RTPoint(lookFrom);

            W = (lookFrom - lookAt).Normalize();
            U = RTVector.CrossProduct(up, W).Normalize();
            V = RTVector.CrossProduct(W, U);
        }
Beispiel #3
0
        public Sphere(RTPoint center, float radius, Transformation transformation)
        {
            Center         = center;
            Radius         = radius;
            Transformation = transformation;

            _boundingBox = new BoundingBox(Transformation.ApplyTo(new RTPoint(Center.X - Radius, Center.Y - Radius, Center.Z - Radius)),
                                           Transformation.ApplyTo(new RTPoint(Center.X + Radius, Center.Y + Radius, Center.Z + Radius)));
        }
Beispiel #4
0
        public Ray GenerateRay(RTPoint p)
        {
            float alpha = (float)Math.Tan(FovX / 2.0f) * ((p.X - (Width / 2.0f)) / (Width / 2.0f));
            float beta  = (float)Math.Tan(FovY / 2.0f) * (((Height / 2.0f) - p.Y) / (Height / 2.0f));

            RTVector rayVec = new RTVector(alpha * U + beta * V - W).Normalize();

            return(new Ray(Eye, rayVec, 0, float.MaxValue, false));
        }
Beispiel #5
0
        public Camera(RTPoint lookFrom, RTPoint lookAt, RTVector up, float fovy, int width, int height)
        {
            MoveCamera(lookFrom, lookAt, up);

            Width  = width;
            Height = height;

            FovY = fovy.ToRadians();
            FovX = 2.0f * (float)Math.Atan((float)Math.Tan(FovY / 2.0f) * (width / (float)height));
        }
Beispiel #6
0
        public Triangle(List <Vertex> vertices, Transformation transformation)
        {
            Vertices = new List <Vertex>();

            float minX = float.MaxValue;
            float minY = float.MaxValue;
            float minZ = float.MaxValue;
            float maxX = float.MinValue;
            float maxY = float.MinValue;
            float maxZ = float.MinValue;

            foreach (Vertex v in vertices)
            {
                RTPoint point = transformation.ApplyTo(v.Location);
                //point /= point.W;

                Normal normal = null;

                if (v.Normal != null)
                {
                    normal = new Normal(transformation.ApplyTo(v.Normal));
                }

                Vertices.Add(new Vertex(point, normal));

                if (point.X < minX)
                {
                    minX = point.X;
                }
                if (point.Y < minY)
                {
                    minY = point.Y;
                }
                if (point.Z < minZ)
                {
                    minZ = point.Z;
                }
                if (point.X > maxX)
                {
                    maxX = point.X;
                }
                if (point.Y > maxY)
                {
                    maxY = point.Y;
                }
                if (point.Z > maxZ)
                {
                    maxZ = point.Z;
                }
            }

            Normal       = ComputeNormal();
            _boundingBox = new BoundingBox(minX, maxX, minY, maxY, minZ, maxZ);
        }
Beispiel #7
0
        public SceneBuilder SetCameraPosition(RTPoint lookFrom, RTPoint lookAt, RTVector up)
        {
            if (_camera == null)
            {
                InitCameraDefault();
            }

            _camera.MoveCamera(lookFrom, lookAt, up);

            return(this);
        }
Beispiel #8
0
        public SceneBuilder SetCamera(RTPoint lookFrom, RTPoint lookAt, RTVector up, float fovy)
        {
            if (_sampler == null)
            {
                throw new InvalidOperationException("La taille doit être définie avant la caméra.");
            }

            _camera = new Camera(lookFrom, lookAt, up, fovy, _sampler.Width, _sampler.Height);

            return(this);
        }
Beispiel #9
0
        public Ray(RTPoint point, RTVector vector, float tMin, float tMax, bool directional)
        {
            Point       = point;
            Vector      = vector;
            TMin        = tMin;
            TMax        = tMax;
            Directional = directional;

            InvDir = 1f / Vector;
            Signs  = new int[] { InvDir.X < 0 ? 1 : 0,
                                 InvDir.Y < 0 ? 1 : 0,
                                 InvDir.Z < 0 ? 1 : 0 };
        }
Beispiel #10
0
        public bool Intersect(Ray ray, bool computeGeo, out LocalGeo geo, out float pos)
        {
            RTPoint A = Vertices[0].Location;
            RTPoint B = Vertices[1].Location;
            RTPoint C = Vertices[2].Location;

            RTVector p0 = new RTVector(ray.Point);

            pos = RTVector.DotProduct(A - ray.Point, Normal) / RTVector.DotProduct(ray.Vector, Normal);

            geo = new LocalGeo();
            if (pos >= ray.TMin && pos <= ray.TMax)
            {
                geo.Point  = ray.Point + pos * ray.Vector;
                geo.Normal = Normal;

                RTVector u = B - A;
                RTVector v = C - A;
                RTVector w = geo.Point - A;

                RTVector vCrossW = RTVector.CrossProduct(v, w);
                RTVector vCrossU = RTVector.CrossProduct(v, u);

                if (RTVector.DotProduct(vCrossW, vCrossU) < 0)
                {
                    return(false);
                }

                RTVector uCrossW = RTVector.CrossProduct(u, w);
                RTVector uCrossV = RTVector.CrossProduct(u, v);

                if (RTVector.DotProduct(uCrossW, uCrossV) < 0)
                {
                    return(false);
                }

                float denom = uCrossV.Length;
                float r     = vCrossW.Length / denom;
                float t     = uCrossW.Length / denom;

                return(r + t <= 1);
            }

            return(false);
        }
Beispiel #11
0
        public void Commit(RTPoint point, Color color)
        {
            lock (_lock)
            {
                // TODO : "accumuler" valeur si dans même pixel
                _film.SetPixel((int)(float)Math.Floor(point.X), (int)(float)Math.Floor(point.Y), color);
            }
            Interlocked.Increment(ref _commited);

            long time = _sw.ElapsedMilliseconds;

            if (time - _lastCommit > 500L)
            {
                long total = Width * Height;
                _lastCommit = time;

                float    pps       = (_commited / (float)time) * 1000f;
                TimeSpan elapsed   = TimeSpan.FromMilliseconds(time);
                TimeSpan remaining = TimeSpan.FromSeconds((total - _commited) / pps);

                Console.Write($"\rElapsed : {elapsed.TotalHours:0}:{elapsed.Minutes:00}:{elapsed.Seconds:00} - {_commited}/{total} - {pps:0.00} pixel/s - Est. remaining : {remaining.TotalHours:0}:{remaining.Minutes:00}:{remaining.Seconds:00} <>");
            }
        }
Beispiel #12
0
        private Normal ComputeNormal()
        {
            Normal res;
            bool   normVertex = Vertices[0].Normal != null;

            if (normVertex)
            {
                // TODO
                res = new Normal(0, 1, 0);
            }
            else
            {
                RTPoint A = Vertices[0].Location;
                RTPoint B = Vertices[1].Location;
                RTPoint C = Vertices[2].Location;

                RTVector U = B - A;
                RTVector V = C - A;

                res = new Normal(RTVector.CrossProduct(U, V));
            }

            return(res);
        }
Beispiel #13
0
        public Scene BuildScene()
        {
            SceneBuilder sb = new SceneBuilder();

            string line;

            InitPrimitiveProperties();
            _transStack            = new Stack <Transformation>();
            _currentTransformation = new Transformation();

            using (FileStream fs = new FileStream(_path, FileMode.Open, FileAccess.Read, FileShare.Read))
                using (StreamReader sr = new StreamReader(fs))
                {
                    while (!sr.EndOfStream)
                    {
                        line = sr.ReadLine().TrimStart(" \t".ToCharArray()).ToLowerInvariant();

                        if (string.IsNullOrWhiteSpace(line) || line[0] == '#')
                        {
                            continue;
                        }

                        string[] split = line.Split(" \t".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);

                        switch (split[0])
                        {
                            #region General/Camera
                        case "size":
                            int width  = int.Parse(split[1]);
                            int height = int.Parse(split[2]);
                            sb.SetSize(width, height);
                            break;

                        case "maxdepth":
                            int maxDepth = int.Parse(split[1]);
                            sb.SetMaxDepth(maxDepth);
                            break;

                        case "output":
                            sb.SetOutputPath(split[1]);
                            break;

                        case "camera":
                            RTPoint  lFrom = PointFromConfig(split);
                            RTPoint  lAt   = PointFromConfig(split, 4);
                            RTVector up    = VectorFromConfig(split, 7);
                            float    fovy  = float.Parse(split[10]);
                            sb.SetCamera(lFrom, lAt, up, fovy);
                            break;
                            #endregion

                            #region Geometry
                        case "sphere":
                            RTPoint center = PointFromConfig(split);
                            float   radius = float.Parse(split[4]);
                            Sphere  s      = new Sphere(center, radius, _currentTransformation);

                            sb.AddGeoPrimitive(s, _currentMaterial);
                            InitPrimitiveProperties();
                            break;

                        case "maxverts":
                            int maxverts = int.Parse(split[1]);
                            _currentVertex = new List <Vertex>(maxverts);
                            break;

                        case "maxvertsnorms":
                            int maxvertsnorms = int.Parse(split[1]);
                            _currentVertex = new List <Vertex>(maxvertsnorms);
                            break;

                        case "vertex":
                            RTPoint vertex = PointFromConfig(split);
                            _currentVertex.Add(new Vertex(vertex));
                            break;

                        case "vertexnormal":
                            RTPoint  vertexnorm = PointFromConfig(split);
                            RTVector normal     = VectorFromConfig(split, 3);
                            _currentVertex.Add(new Vertex(vertexnorm, normal));
                            break;

                        case "tri":
                        case "trinormal":
                            int v1 = int.Parse(split[1]);
                            int v2 = int.Parse(split[2]);
                            int v3 = int.Parse(split[3]);

                            List <Vertex> vList = new List <Vertex>();
                            vList.Add(_currentVertex[v1]);
                            vList.Add(_currentVertex[v2]);
                            vList.Add(_currentVertex[v3]);

                            Triangle tri = new Triangle(vList, _currentTransformation);
                            sb.AddGeoPrimitive(tri, _currentMaterial);
                            InitPrimitiveProperties();
                            break;
                            #endregion

                            #region Transforms
                        case "translate":
                            RTVector transvec = VectorFromConfig(split);
                            _currentTransformation.AddTransform(new Translation(transvec));
                            break;

                        case "rotate":
                            RTVector rotaxis = VectorFromConfig(split);
                            float    degrees = float.Parse(split[4]);
                            _currentTransformation.AddTransform(new Rotation(rotaxis, degrees));
                            break;

                        case "scale":
                            _currentTransformation.AddTransform(new Scaling(float.Parse(split[1]), float.Parse(split[2]), float.Parse(split[3])));
                            break;

                        case "pushtransform":
                            _transStack.Push(new Transformation(_currentTransformation));
                            break;

                        case "poptransform":
                            _currentTransformation = _transStack.Pop();
                            break;
                            #endregion

                            #region Lights
                        case "directional":
                            RTVector dir    = VectorFromConfig(split);
                            RTColor  dirCol = ColorFromConfig(split, 4);
                            sb.AddLight(new DirLight(dir, dirCol));
                            break;

                        case "point":
                            RTPoint source   = PointFromConfig(split);
                            RTColor pointCol = ColorFromConfig(split, 4);
                            sb.AddLight(new PointLight(source, pointCol));
                            break;

                        case "attenuation":
                            Attenuation att = new Attenuation
                            {
                                Constant  = float.Parse(split[1]),
                                Linear    = float.Parse(split[2]),
                                Quadratic = float.Parse(split[3])
                            };
                            sb.SetAttenuation(att);
                            break;

                        case "ambient":
                            RTColor ambient = ColorFromConfig(split);
                            _currentMaterial.Properties.Ambient = ambient;
                            break;
                            #endregion

                            #region Materials
                        case "diffuse":
                            RTColor diffuse = ColorFromConfig(split);
                            _currentMaterial.Properties.Diffuse = diffuse;
                            break;

                        case "specular":
                            RTColor spec = ColorFromConfig(split);
                            _currentMaterial.Properties.Specular = spec;
                            break;

                        case "shininess":
                            float shine = float.Parse(split[1]);
                            _currentMaterial.Properties.Shininess = shine;
                            break;

                        case "emission":
                            RTColor emission = ColorFromConfig(split);
                            _currentMaterial.Properties.Emission = emission;
                            break;
                            #endregion
                        }
                    }
                }

            return(sb.Build());
        }
Beispiel #14
0
 public RTVector(RTPoint p)
 {
     Vector = new Vector4(p.X, p.Y, p.Z, 0);
 }
Beispiel #15
0
        public bool Intersect(Ray ray, bool computeGeo, out LocalGeo geo, out float t)
        {
            RTPoint  tPoint = Transformation.ApplyInverseTo(new RTPoint(ray.Point.X, ray.Point.Y, ray.Point.Z));
            RTVector tVec   = Transformation.ApplyInverseTo(new RTVector(ray.Vector.X, ray.Vector.Y, ray.Vector.Z));

            RTVector ec = tPoint - Center;

            float a = RTVector.DotProduct(tVec, tVec);
            float b = 2.0f * RTVector.DotProduct(tVec, ec);
            float c = RTVector.DotProduct(ec, ec) - (float)Math.Pow(Radius, 2);

            float det = (float)Math.Pow(b, 2) - 4.0f * a * c;

            t = float.MaxValue;

            bool intersect = false;

            if (det == 0d)
            {
                intersect = true;
                t         = -b / (2.0f * a);
            }
            else if (det > 0d)
            {
                float t1 = (-b + (float)Math.Sqrt(det)) / (2.0f * a);
                float t2 = (-b - (float)Math.Sqrt(det)) / (2.0f * a);

                if ((t1 > 0 && t2 < 0) || (t1 < 0 && t2 > 0))
                {
                    intersect = true;
                    if (t1 > 0)
                    {
                        t = t1;
                    }
                    else
                    {
                        t = t2;
                    }
                }
                else if (t1 > 0 && t2 > 0)
                {
                    intersect = true;
                    if (t1 < t2)
                    {
                        t = t1;
                    }
                    else
                    {
                        t = t2;
                    }
                }
            }

            geo = new LocalGeo();
            if (intersect && t >= ray.TMin && t <= ray.TMax)
            {
                if (computeGeo)
                {
                    geo.Point  = tPoint + t * tVec;
                    geo.Normal = new Normal(geo.Point - Center);

                    geo.Point = Transformation.ApplyTo(geo.Point);

                    geo.Normal = new Normal(Transformation.ApplyInverseTransposeTo(geo.Normal));
                }

                return(true);
            }

            return(false);
        }
Beispiel #16
0
 public RTPoint ApplyTo(RTPoint p)
 {
     return(p.ApplyMatrix(Compute()));
 }
Beispiel #17
0
 public BoundingBox()
 {
     Min = new RTPoint(0f, 0f, 0f);
     Max = new RTPoint(0f, 0f, 0f);
 }
Beispiel #18
0
 public BoundingBox(float xMin, float xMax, float yMin, float yMax, float zMin, float zMax)
 {
     Min = new RTPoint(xMin, yMin, zMin);
     Max = new RTPoint(xMax, yMax, zMax);
 }
Beispiel #19
0
 public PointLight(RTPoint source, RTColor color)
 {
     Source = source;
     Color  = color;
 }
Beispiel #20
0
 public Vertex(RTPoint vertex)
 {
     Location = vertex;
     Normal   = null;
 }
Beispiel #21
0
 public RTPoint ApplyInverseTo(RTPoint p)
 {
     return(p.ApplyMatrix(ComputeInverse()));
 }
Beispiel #22
0
 public Vertex(float x, float y, float z)
 {
     Location = new RTPoint(x, y, z);
     Normal   = null;
 }
Beispiel #23
0
 public BoundingBox(RTPoint min, RTPoint max)
 {
     Min = min;
     Max = max;
 }
Beispiel #24
0
 public Vertex(float x, float y, float z, float nx, float ny, float nz)
 {
     Location = new RTPoint(x, y, z);
     Normal   = new Normal(nx, ny, nz);
 }
Beispiel #25
0
 public RTPoint(RTPoint p)
 {
     Vector = new Vector4(p.X, p.Y, p.Z, p.W);
 }