예제 #1
0
 public override bool IsHit(Ray ray, HitRecord record, float near, float far)
 {
     throw new NotImplementedException();
 }
예제 #2
0
        public override bool IsHit(Ray ray, HitRecord record, float near, float far)
        {
            Vector newCenter;
            if (Velocity.IsBlack())
                newCenter = Center;
            else
            {
                newCenter = this.Center + ray.Time * this.Velocity;
            }

            //e - c
            Vector eMinusC = ray.Start - newCenter;
            //d.(e-c)
            float dDotEMinusC = Vector.Dot3(ray.Direction, eMinusC);
            float dDotD = Vector.Dot3(ray.Direction, ray.Direction);
            //d.(e-c)^2 - (d.d)((e-c).(e-c) - R^2))
            float discriminant = dDotEMinusC * dDotEMinusC - dDotD * (Vector.Dot3(eMinusC, eMinusC) - this.Radius * this.Radius);
            //Intersection occurs
            float t1 = 0, t2 = 0, first_t = 0;
            if (discriminant >= 0)
            {
                t1 = (-dDotEMinusC + (float)Math.Sqrt(discriminant)) / dDotD;
                t2 = (-dDotEMinusC - (float)Math.Sqrt(discriminant)) / dDotD;
                Vector diff;
                Vector worldCoords;

                if (t2 >= 0)
                    first_t = t2;
                else if (t1 >= 0)
                    first_t = t1;
                else
                    return false;

                // t*d
                diff = ray.Direction * first_t;
                // e + t*d
                worldCoords = diff + ray.Start;
                float distance = diff.Magnitude3();

                if (distance <= record.Distance && distance <= ray.MaximumTravelDistance)
                {

                    if (ray.UseBounds)
                    {
                        float cameraOrthogonalDistance = Math.Abs(Vector.Dot3(diff, ray.CameraLookDirection));
                        if (cameraOrthogonalDistance > far && cameraOrthogonalDistance < near)
                        {
                            return false;
                        }
                    }

                    record.T = first_t;
                    record.HitPoint = ray.Start + diff;
                    record.Distance = distance;
                    record.Material = this.Material;
                    record.SurfaceNormal = SurfaceNormal(record.HitPoint, ray.Direction);
                    if (Material.TextureImage != null)
                    {
                        double cos = (record.HitPoint.z - newCenter.z) / Radius;
                        if (cos < -1)
                            cos = -1;
                        else if (cos > 1)
                            cos = 1;

                        double theta = Math.Acos(cos);
                        double phi = Math.Atan2(record.HitPoint.y - newCenter.y, record.HitPoint.x - newCenter.x);
                        if (phi < 0)
                            phi += 2 * Math.PI;

                        float u = (float)(phi / (2 * Math.PI));
                        float v = (float)((Math.PI - theta) / Math.PI);
                        //Console.WriteLine(this.textureWidth);
                        //Console.WriteLine(this.Material.TextureImage.Height);
                        //int i = (int)(u * (this.textureWidth - 1) + 0.5);
                        //int j = (int)(v * (this.textureHeight - 1) + 0.5);
                        record.TextureColor = this.Material.GetTexturePixelColor(u, v);
                    }

                    return true;
                }

            }
            return false;
        }
예제 #3
0
        public override bool IsHit(Ray ray, HitRecord record, float near, float far)
        {
            //(d.h)h
            Vector dDotHTimesH = Vector.Dot3(ray.Direction, HeightDirection) * HeightDirection;
            Vector deltaP = ray.Start - this.BasePoint;
            Vector deltaPDotHTimesH = Vector.Dot3(deltaP, HeightDirection) * HeightDirection;
            Vector deltaPMinusdeltaPDotHTimesH = deltaP - deltaPDotHTimesH;
            Vector dMinusdDotHTimesH = ray.Direction - dDotHTimesH;

            float B = 2 * Vector.Dot3(dMinusdDotHTimesH, deltaPMinusdeltaPDotHTimesH);
            float A = Vector.Dot3(dMinusdDotHTimesH, dMinusdDotHTimesH);
            float C = Vector.Dot3(deltaPMinusdeltaPDotHTimesH, deltaPMinusdeltaPDotHTimesH) - this.Radius * this.Radius;
            Vector diff, worldCoords;
            float discriminant = B * B - 4 * A * C;
            float t1 = 0, t2 = 0, first_t = float.MaxValue;
            List<float> candidates = new List<float>();
            IntersectionType intersectionType = IntersectionType.Cylinder;

            if (discriminant >= 0)
            {
                t1 = (-B - (float)Math.Sqrt(discriminant)) / (2 * A);
                t2 = (-B + (float)Math.Sqrt(discriminant)) / (2 * A);

                if (t1 >= 0 && IsInside(ray.Start + ray.Direction*t1))
                {
                    first_t = t1;
                }
                if (t2 >= 0 && IsInside(ray.Start + ray.Direction*t2) && t2 < first_t)
                {
                    first_t = t2;
                }
            }

            float hDotd = Vector.Dot3(this.HeightDirection, ray.Direction);
            if (hDotd != 0)
            {
                float basePlaneT = Vector.Dot3(this.HeightDirection, this.BasePoint) - Vector.Dot3(this.HeightDirection, ray.Start);
                basePlaneT = basePlaneT / hDotd;
                if (basePlaneT > 0 && IsCap(this.BasePoint, basePlaneT * ray.Direction + ray.Start) && basePlaneT < first_t)
                {
                    intersectionType = IntersectionType.Base;
                    first_t = basePlaneT;
                }

                float endPlaneT = Vector.Dot3(this.HeightDirection, this.EndPoint) - Vector.Dot3(this.HeightDirection, ray.Start);
                endPlaneT = endPlaneT / hDotd;
                if (endPlaneT > 0 && IsCap(this.EndPoint, endPlaneT * ray.Direction + ray.Start) && endPlaneT < first_t)
                {
                    intersectionType = IntersectionType.End;
                    first_t = endPlaneT;
                }
            }

            if (first_t == float.MaxValue)
                return false;

            // t*d
            diff = ray.Direction * first_t;
            // e + t*d
            worldCoords = diff + ray.Start;

            float distance = diff.Magnitude3();

            if (distance <= record.Distance && distance <= ray.MaximumTravelDistance)
            {

                if (ray.UseBounds)
                {
                    float cameraOrthogonalDistance = Math.Abs(Vector.Dot3(diff, ray.CameraLookDirection));
                    if (cameraOrthogonalDistance > far && cameraOrthogonalDistance < near)
                    {
                        return false;
                    }
                }

                record.T = first_t;
                record.HitPoint = ray.Start + diff;
                record.Distance = distance;
                record.Material = this.Material;
                if (intersectionType == IntersectionType.Cylinder)
                {
                    record.SurfaceNormal = SurfaceNormal(record.HitPoint, ray.Direction);
                    if (Material.TextureImage != null)
                    {
                        float heightReached = Vector.Dot3(HeightDirection, record.HitPoint - this.BasePoint);
                        float u = heightReached / Height;
                        Vector circCenter = BasePoint + HeightDirection * heightReached;
                        Vector projection = record.HitPoint - circCenter;
                        projection.Normalize3();
                        float similarity = Vector.Dot3(projection, Tangent);
                        float theta = (float)Math.Acos(similarity);
                        float v = (float)((Math.PI - theta) / Math.PI);
                        v = v < 0 ? -v : v;
                        record.TextureColor = this.Material.GetTexturePixelColor(u, v);
                         // float v =
                    }
                }
                else
                {
                    record.SurfaceNormal = PlaneNormal(record.HitPoint, ray.Direction);
                    if (Material.TextureImage != null)
                    {
                        Vector circCenter = intersectionType == IntersectionType.Base ? BasePoint : EndPoint;
                        Vector projection = record.HitPoint - circCenter;
                        float length = projection.Magnitude3();
                        projection.Normalize3();
                        float similarity = Vector.Dot3(projection, Tangent);
                        float theta = (float)Math.Acos(similarity);
                        float u = length / Radius;
                        float v = (float)((Math.PI - theta) / Math.PI);
                        v = v < 0 ? -v : v;
                        record.TextureColor = this.Material.GetTexturePixelColor(u, v);
                        // float v =
                    }
                }
               // record.SurfaceNormal = SurfaceNormal(record.HitPoint, ray.Direction);
                return true;
            }
            return false;
        }
예제 #4
0
        public override bool IsHit(Ray ray, HitRecord record, float near, float far)
        {
            bool isHit = false;

            foreach (SceneTriangle triangle in triangles)
            {
                isHit = triangle.IsHit(ray, record, near, far) || isHit;
            }
            if (isHit)
            {
                record.ObjectName = this.Name;
                if (Material.TextureImage != null)
                {
                    Vector l1 = Vertex[1] - Vertex[0];
                    Vector l2 = Vertex[3] - Vertex[0];
                    float f = l1.x;
                    float g = l2.x;
                    float h = record.HitPoint.x;
                    float i = Vertex[0].x;

                    float j = l1.y;
                    float k = l2.y;
                    float l = record.HitPoint.y;
                    float m = Vertex[0].y;

                    float n = l1.z;
                    float o = l2.z;
                    float p = record.HitPoint.z;
                    float q = Vertex[0].z;

                    float det = g * j - f * k;
                    if (det == 0)
                    {
                        det = o * j - n * k;
                        if (det == 0)
                        {
                            det = g * n - f * o;
                            j = n;
                            k = o;
                            l = p;
                            m = q;
                        }
                        else
                        {
                            f = n;
                            h = o;
                            h = p;
                            i = q;
                        }
                    }
                    if (det != 0)
                    {
                        float alpha = (g * l - g * m - h * k + i * k) / det;
                        float beta = (-f * l + f * m + h * j - i * j) / det;
                        //if (RenderingParameters.showMouse)
                        //{
                        //Console.WriteLine("alpha: " + alpha + "\tbeta: " + beta);

                        record.TextureColor = this.Material.GetTexturePixelColor(alpha, beta);
                    }
                   // }
                }

            }
            return isHit;
        }
예제 #5
0
 public abstract bool IsHit(Ray ray, HitRecord record, float near, float far);
예제 #6
0
        public override bool IsHit(Ray ray, HitRecord record, float near, float far)
        {
            //Vamos precalculando variables auxiliares para facilitar el calculo y aumentar eficiencia
            //Convencion de nombres usada es la misma del libro "Fundamentals of Computer Graphics":
            /*
             * | a d g | | beta  |   | j |
             * | b e h | | gamma | = | k |
             * | c f i | |   t   | = | l |
            */

            float a = Vertex[0].x - Vertex[1].x;
            float b = Vertex[0].y - Vertex[1].y;
            float c = Vertex[0].z - Vertex[1].z;

            float d = Vertex[0].x - Vertex[2].x;
            float e = Vertex[0].y - Vertex[2].y;
            float f = Vertex[0].z - Vertex[2].z;

            float g = ray.Direction.x;
            float h = ray.Direction.y;
            float i = ray.Direction.z;

            float j = Vertex[0].x - ray.Start.x;
            float k = Vertex[0].y - ray.Start.y;
            float l = Vertex[0].z - ray.Start.z;

            float eiMinushf = e * i - h * f;
            float gfMinusdi = g * f - d * i;
            float dhMinuseg = d * h - e * g;

            float akMinusjb = a * k - j * b;
            float jcMinusal = j * c - a * l;
            float blMinuskc = b * l - k * c;

            float M = a * eiMinushf + b * gfMinusdi + c * dhMinuseg;
            //e + td = punto triangulo
            float t = -(f * akMinusjb + e * jcMinusal + d * blMinuskc) / M;
            if (t >= 0)
            {
                float gamma = (i * akMinusjb + h * jcMinusal + g * blMinuskc) / M;
                if (gamma >= 0)
                {
                    float beta = (j * eiMinushf + k * gfMinusdi + l * dhMinuseg) / M;
                    //alpha = 1 - beta - gamma
                    if (beta >= 0 && 1 - beta - gamma >= 0)
                    {
                        Vector diff = t * ray.Direction;
                        float distance = diff.Magnitude3();
                        if (distance <= record.Distance && distance <= ray.MaximumTravelDistance)
                        {

                            if (ray.UseBounds)
                            {
                                float cameraOrthogonalDistance = Math.Abs(Vector.Dot3(diff, ray.CameraLookDirection));
                                if (cameraOrthogonalDistance > far && cameraOrthogonalDistance < near)
                                {
                                    return false;
                                }
                            }
                            record.T = t;
                            record.HitPoint = ray.Start + diff;
                            record.Distance = distance;
                            record.Material = Materials[0];
                            record.SurfaceNormal = SurfaceNormal(record.HitPoint, ray.Direction);

                            if (record.Material.TextureImage != null)
                            {
                                float alpha = 1 - beta - gamma;
                                float u = alpha * U[0] + beta * U[1] + gamma * U[2];
                                float v = alpha * V[0] + beta * V[1] + gamma * V[2];
                                record.TextureColor = record.Material.GetTexturePixelColor(u, v);
                            }

                            return true;
                        }
                    }
                }
            }
            return false;
        }