Пример #1
0
        public override Color shade(RenderContext rc, Ray ray, HitRecord hrec, int depth)
        {
            Point hp = ray.pointOn(hrec.getT());
              Vector normal = hrec.getPrimitive().normal(hp);

              hp += 0.0001f * normal;

              Scene scene = rc.getScene();
              int numlights = scene.numberOfLights();
              Color finalc = new Color(0,0,0);
              for ( int i = 0; i < numlights; i++ ) {

              Vector ldir = new Vector();
             Color lcolor = new Color();
             float ldist = scene.getLight(i).getLight(ref lcolor, ref ldir, rc, hp);

             HitRecord shadowhr = new HitRecord();
             Ray shadowray = new Ray(hp, ldir);
             scene.getObject().intersect(ref shadowhr, rc, shadowray);
             if ( shadowhr.getT() >= ldist || shadowhr.getT() < 0.01 ) {

                float dp = Vector.dot(normal, ldir);
                if( dp > 0 ) {
                   finalc += dp*lcolor;
                }

             }
              }

              return color * ( finalc * kd + scene.getAmbient() * ka );
        }
Пример #2
0
        public Color renderPixel(int x, int y)
        {
            Color color;
              HitRecord hitRecord = new HitRecord();
              Ray ray;
              RenderContext renderContext = new RenderContext( this.scene );

              float step = 2 / (float)this.scene.getXResolution();
              float xStart = -1 + ( 0.5f * step );
              float yStart = (-(float)this.scene.getYResolution() * (0.5f * step)) + (0.5f * step);

              ray = this.scene.getCamera().generateRay( xStart + (x * step), yStart + (y * step) );
              this.scene.traceRay( ray, hitRecord, renderContext );

              if ( hitRecord.getT() == float.PositiveInfinity || hitRecord.getMaterial() == null || hitRecord.getPrimitive() == null ) {

             color = this.scene.getBackground().getColor( renderContext, ray );

              } else {

             color = hitRecord.getMaterial().shade( renderContext, ray, hitRecord, 1 );

              }

              return color;
        }
Пример #3
0
 public override void intersect(ref HitRecord hit, RenderContext rc, Ray ray)
 {
     float num = Vector.dot( -this.norm, ray.p() - this.point );
       float denom = Vector.dot( this.norm, ray.d() );
       float t = num/denom;
       if ( denom==0 || num==0 || t < 0 ) hit.hit( float.PositiveInfinity, this, this.material );
       else hit.hit( num/denom, this, this.material );
 }
Пример #4
0
        public override void intersect(ref HitRecord hit, RenderContext rc, Ray ray)
        {
            Vector dist = ray.p() - this.p;
            float b = Vector.dot(dist, ray.d());
            float c = Vector.dot(dist, dist) - this.r2();
            float d = b * b - c;
            float t = (d > 0) ? -b - (float)System.Math.Sqrt(d) : float.PositiveInfinity;

            hit.hit(t, this, this.material);
        }
        public override bool Scatter(Ray rayIn, HitRecord rec, out Vector3 attenuation, out Ray scattererd, ImSoRandom random)
        {
            Vector3 reflected = Vector3.Reflect(rayIn.Direction, rec.Normal);

            attenuation = new Vector3(1.0f);

            Vector3 outward_normal;
            float   niOverNt;
            float   cosine;

            if (Vector3.Dot(rayIn.Direction, rec.Normal) > 0)
            {
                outward_normal = -rec.Normal;
                niOverNt       = _refIndex;
                cosine         = _refIndex * Vector3.Dot(rayIn.Direction, rec.Normal) / rayIn.Direction.Length();
            }
            else
            {
                outward_normal = rec.Normal;
                niOverNt       = 1.0f / _refIndex;
                cosine         = -Vector3.Dot(rayIn.Direction, rec.Normal) / rayIn.Direction.Length();
            }

            Vector3 refracted;
            float   reflectProb;

            if (Refract(rayIn.Direction, outward_normal, niOverNt, out refracted))
            {
                reflectProb = Schlick(cosine, _refIndex);
            }
            else
            {
                reflectProb = 1.0f;
            }

            if (random.NextFloat() < reflectProb)
            {
                scattererd = new Ray(rec.P, reflected, rayIn.Time);
            }
            else
            {
                scattererd = new Ray(rec.P, refracted, rayIn.Time);
            }
            return(true);
        }
Пример #6
0
        public override bool Scatter(Ray r_in, HitRecord rec, out Vec3 attenuation, out Ray scattered)
        {
            Vec3 reflected = Vec3.Reflect(r_in.Direction, rec.Normal);

            attenuation = Vec3.Create(1.0);

            Vec3   outward_normal;
            double ni_over_nt;
            double consine;

            if (r_in.Direction.Dot(rec.Normal) > 0)
            {
                outward_normal = -rec.Normal;
                ni_over_nt     = _ref_idx;
                consine        = _ref_idx * r_in.Direction.Dot(rec.Normal) / r_in.Direction.Length;
            }
            else
            {
                outward_normal = rec.Normal;
                ni_over_nt     = 1 / _ref_idx;
                consine        = -r_in.Direction.Dot(rec.Normal) / r_in.Direction.Length;
            }

            Vec3   refracted;
            double reflect_probe;

            if (Vec3.Refract(r_in.Direction, outward_normal, ni_over_nt, out refracted))
            {
                reflect_probe = Function.Schlick(consine, _ref_idx);
            }
            else
            {
                reflect_probe = 1.0;
            }

            if (_sampler.NextDouble() < reflect_probe)
            {
                scattered = new Ray(rec.P, reflected, r_in.Time);
            }
            else
            {
                scattered = new Ray(rec.P, refracted, r_in.Time);
            }
            return(true);
        }
Пример #7
0
    private void HitSphere(SphereRecord sphere, Ray ray, float tMin, float tMax, out HitRecord hitRecord)
    {
        Vector3 oc           = ray.origin - sphere.Center;
        float   a            = Vector3.Dot(ray.direction, ray.direction);
        float   b            = Vector3.Dot(oc, ray.direction);
        float   c            = Vector3.Dot(oc, oc) - sphere.Radius * sphere.Radius;
        float   discriminant = b * b - a * c;

        if (discriminant < 0.0f)
        {
            hitRecord = null;
            return;
        }

        float temp = (-b - Mathf.Sqrt(discriminant)) / a;

        if (temp < tMax && temp > tMin)
        {
            Vector3 point = ray.GetPoint(temp);
            hitRecord = new HitRecord()
            {
                T        = temp,
                Point    = point,
                Normal   = (point - sphere.Center) / sphere.Radius,
                Material = sphere.Material,
            };
            return;
        }

        temp = (-b + Mathf.Sqrt(discriminant)) / a;
        if (temp < tMax && temp > tMin)
        {
            Vector3 point = ray.GetPoint(temp);
            hitRecord = new HitRecord()
            {
                T        = temp,
                Point    = point,
                Normal   = (point - sphere.Center) / sphere.Radius,
                Material = sphere.Material,
            };
            return;
        }

        hitRecord = null;
    }
Пример #8
0
        public bool Hit(Ray r, double tMin, double tMax, out HitRecord hitRec)
        {
            var oc    = r.Origin - Center;
            var a     = r.Dir.LengthSquared;
            var halfB = Vec3.Dot(oc, r.Dir);
            var c     = oc.LengthSquared - Radius * Radius;

            var disc = halfB * halfB - a * c;

            if (disc < 0)
            {
                hitRec = default(HitRecord);
                return(false);
            }

            var sqrtd = Math.Sqrt(disc);

            var root = (-halfB - sqrtd) / a;

            if (root < tMin || tMax < root)
            {
                root = (-halfB + sqrtd) / a;
                if (root < tMin || tMax < root)
                {
                    hitRec = default;
                    return(false);
                }
            }

            var t             = root;
            var point         = r.At(t);
            var outwardNormal = (point - Center) / Radius;

            GetSphereUV(outwardNormal, out var u, out var v);
            hitRec = new HitRecord
            {
                T        = t,
                Point    = point,
                Material = Material,
                U        = u,
                V        = v
            };
            hitRec.SetFaceNormal(r, outwardNormal);
            return(true);
        }
    public override bool scatter(Ray in_ray, ref HitRecord hr, out Color attenuation, out Ray scattered)
    {
        Vector3 outward_normal;
        Vector3 reflected = Vector3.Reflect(in_ray.direction, hr.raycastHit.normal);
        float   in_over_nt;

        attenuation = new Color(1f, 1f, 1f);
        Vector3 refracted;
        float   reflect_prob;
        float   cosine;

        if (Vector3.Dot(in_ray.direction, hr.raycastHit.normal) > 0)
        {
            outward_normal = -hr.raycastHit.normal;
            in_over_nt     = ref_idx;
            cosine         = ref_idx * Vector3.Dot(in_ray.direction, hr.raycastHit.normal) / in_ray.direction.magnitude;
        }
        else
        {
            outward_normal = hr.raycastHit.normal;
            in_over_nt     = 1f / ref_idx;
            cosine         = -Vector3.Dot(in_ray.direction, hr.raycastHit.normal) / in_ray.direction.magnitude;
        }

        if (Common.refract(in_ray.direction, outward_normal, in_over_nt, out refracted))
        {
            //scattered = new Ray(hr.raycastHit.point, refracted);
            reflect_prob = Common.schlick(cosine, ref_idx);
        }
        else
        {
            reflect_prob = 1.0f;
        }

        if (Common.random.NextDouble() < reflect_prob)
        {
            scattered = new Ray(hr.raycastHit.point, reflected);
        }
        else
        {
            scattered = new Ray(hr.raycastHit.point, refracted);
        }

        return(true);
    }
Пример #10
0
        public new HitRecord Intersect(Ray ray)
        {
            //Transform ray to object coordinate system
            Ray       transfRay = RayTransformer.TransformRayToObject(ray, InvTransformationMatrix);
            HitRecord hit       = Intersectable.Intersect(transfRay);


            if (hit != null)
            {
                if (Material != null)
                {
                    hit.Material = Material;
                }
                //Transform HitRecrod back to world coordinate system
                RayTransformer.TransformHitToWorld(hit, TransformationMatrix, TransposedTransformationMatrix);
            }
            return(hit);
        }
        public bool Hit(Ray r, double t_min, double t_max, out HitRecord rec)
        {
            rec = null;
            HitRecord temp_rec;
            bool      hit_anything   = false;
            double    closest_so_far = t_max;

            foreach (var hitable in _list)
            {
                if (hitable.Hit(r, t_min, closest_so_far, out temp_rec))
                {
                    hit_anything   = true;
                    closest_so_far = temp_rec.T;
                    rec            = temp_rec;
                }
            }
            return(hit_anything);
        }
Пример #12
0
        public bool Hit(Ray ray, double tMin, double tMax, out HitRecord hit)
        {
            hit = default;

            var hitAnything  = false;
            var closestSoFar = tMax;

            foreach (var @object in _objects)
            {
                if (@object.Hit(ray, tMin, closestSoFar, out hit))
                {
                    hitAnything  = true;
                    closestSoFar = hit.T;
                }
            }

            return(hitAnything);
        }
Пример #13
0
        public Color Integrate(Ray ray, IIntersectable objects, List <ILight> lights, ISampler sampler, List <List <Sample> > subPathSamples, LightSample lightSample)
        {
            Color returnColor = new Color(0, 0, 0);

            /*
             * Core Ray Tracing algorithm
             */
            HitRecord record = objects.Intersect(ray);

            if (record != null && record.Distance > 0 && record.Distance < float.PositiveInfinity)
            {
                foreach (ILight light in lights)
                {
                    returnColor.Append(record.Material.Shade(record, light.GetLightDirection(record.IntersectionPoint)).Mult(light.GetIncidentColor(record.IntersectionPoint)));
                }
            }
            return(returnColor);
        }
Пример #14
0
    public virtual bool Hit(Ray r, double tMin, double tMax, out HitRecord rec)
    {
        rec = new HitRecord();
        HitRecord tempRec      = new HitRecord();
        bool      hitAnything  = false;
        double    closestSoFar = tMax;    //没有物体遮挡的情况下我们可以看无限远

        for (int i = 0; i < list.Count; i++)
        {
            if (list[i].Hit(r, tMin, closestSoFar, out tempRec))
            {
                hitAnything  = true;
                closestSoFar = tempRec.t;   //当有物体遮挡视线之后视线可达到的最远处就是上一个击中点
                rec          = tempRec;
            }
        }
        return(hitAnything);
    }
Пример #15
0
    private void HitColliders(Ray ray, float tMin, float tMax, out HitRecord hitRecord)
    {
        RaycastHit hitInfo;

        ray.origin += ray.direction * tMin;
        if (!Physics.Raycast(ray, out hitInfo, tMax - tMin))
        {
            hitRecord = null;
            return;
        }

        hitRecord = new HitRecord()
        {
            Material = FindMaterial(hitInfo.transform),
            Normal   = hitInfo.normal,
            Point    = hitInfo.point,
        };
    }
Пример #16
0
    public override bool Hit(Ray ray, float t_min, float t_max, ref HitRecord hit)
    {
        HitRecord tempRecord = new HitRecord();
        bool      hitted     = false;
        float     closest    = t_max;

        for (int i = 0; i < this.hitLists.Count; i++)
        {
            if (this.hitLists[i].Hit(ray, t_min, closest, ref tempRecord))
            {
                hit     = tempRecord;
                closest = tempRecord.t;
                hitted  = true;
            }
        }

        return(hitted);
    }
Пример #17
0
        public override bool Scatter(Ray rIn, HitRecord rec, out Vec3 attenuation, out Ray scattered)
        {
            Vec3   outwardNormal = new Vec3();
            Vec3   reflected     = Vec3.Reflect(rIn.Direction(), rec.Normal);
            double niOverNt;

            attenuation = new Vec3(1.0, 1.0, 1.0);
            Vec3   refracted = new Vec3();
            double reflectProb;
            double cosine;

            if (Vec3.Dot(rIn.Direction(), rec.Normal) > 0)
            {
                outwardNormal = -rec.Normal;
                niOverNt      = _refIndex;
                cosine        = _refIndex * Vec3.Dot(rIn.Direction(), rec.Normal) / rIn.Direction().Length();
            }
            else
            {
                outwardNormal = rec.Normal;
                niOverNt      = 1.0 / _refIndex;
                cosine        = -Vec3.Dot(rIn.Direction(), rec.Normal) / rIn.Direction().Length();
            }

            if (Vec3.Refract(rIn.Direction(), outwardNormal, niOverNt, out refracted))
            {
                reflectProb = Schlick(cosine, _refIndex);
            }
            else
            {
                reflectProb = 1.0;
            }

            if (FastRandom.RandomDouble() < reflectProb)
            {
                scattered = new Ray(rec.P, reflected, rIn.Time());
            }
            else
            {
                scattered = new Ray(rec.P, refracted, rIn.Time());
            }

            return(true);
        }
Пример #18
0
        /// <summary>
        /// Event handler for the timeline control.MouseDownPicked event</summary>
        /// <param name="sender">Timeline control that we are attached to</param>
        /// <param name="e">Event args</param>
        protected virtual void Owner_MouseDownPicked(object sender, HitEventArgs e)
        {
            HitRecord    hitRecord = e.HitRecord;
            TimelinePath hitObject = hitRecord.HitPath;

            if (hitObject != null)
            {
                Keys modifiers = Control.ModifierKeys;

                if (e.MouseEvent.Button == MouseButtons.Left)
                {
                    if (modifiers == Keys.None && SelectionContext != null &&
                        SelectionContext.SelectionContains(hitObject))
                    {
                        // The hit object is already selected. Wait until the mouse up to see if there was
                        //  a drag or not. If no drag, then set the selection set to be this one object.
                        m_mouseDownHitRecord = hitRecord;
                        m_mouseDownPos       = e.MouseEvent.Location;
                    }
                    else if (modifiers == Keys.Control)
                    {
                        // Either this object is not already selected or Shift key is being held down.
                        //  to be consistent with the Windows interface.
                        m_mouseDownHitRecord = hitRecord;
                        m_mouseDownPos       = e.MouseEvent.Location;
                    }
                    else if ((modifiers & Keys.Alt) == 0)
                    {
                        // The 'Alt' key might mean something different. If no Alt key, we can update the
                        //  selection immediately.
                        UpdateSelection(hitRecord, modifiers);
                    }
                }
                else if (e.MouseEvent.Button == MouseButtons.Right)
                {
                    if (modifiers == Keys.None && SelectionContext != null &&
                        !SelectionContext.SelectionContains(hitObject))
                    {
                        // The hit object is not already selected and a right-click landed on it. Select it.
                        UpdateSelection(hitRecord, modifiers);
                    }
                }
            }
        }
Пример #19
0
        public bool Scatter(Ray ray, HitRecord record, ref Vector attenuation, ref Ray scattered)
        {
            attenuation = albedo.GetColor(record.U, record.V, record.P);
            var    refracted = Vector.Zero;
            Vector outwardNormal;
            float  newRefractivity;
            float  cosin;
            float  possible;
            var    reflected = Reflect(ray.Direction, record.Normal);

            if (ray.Direction.Dot(record.Normal) > 0f)
            {
                outwardNormal   = record.Normal.Negative();
                newRefractivity = refractivity;
                cosin           = ray.Direction.Normalize().Dot(record.Normal);
            }
            else
            {
                outwardNormal   = record.Normal;
                newRefractivity = 1f / refractivity;
                cosin           = -ray.Direction.Normalize().Dot(record.Normal);
            }

            if (Refract(ray.Direction, outwardNormal, newRefractivity, ref refracted))
            {
                possible = SchlickEquation(cosin, newRefractivity);
            }
            else
            {
                scattered = new Ray(record.P, reflected);
                possible  = 1f;
            }

            // reflection or refraction
            if (MathHelper.Randf() < possible)
            {
                scattered = new Ray(record.P, reflected);
            }
            else
            {
                scattered = new Ray(record.P, refracted);
            }
            return(true);
        }
Пример #20
0
        public override bool Hit(Ray ray, float t_min, float t_max, ref HitRecord rec)
        {
            void GetSphereUV(ref HitRecord record)
            {
                float phi   = Mathf.Atan2(record.p.z, record.p.x);
                float theta = Mathf.Asin(record.p.y);

                record.u = 1 - (phi + Mathf.PI) / (2 * Mathf.PI);
                record.v = (theta + Mathf.PI / 2) / Mathf.PI;
            }

            var oc           = ray.origin - center;
            var a            = Vector3.Dot(ray.direction, ray.direction);
            var b            = 2f * Vector3.Dot(oc, ray.direction);
            var c            = Vector3.Dot(oc, oc) - radius * radius;
            var discriminant = b * b - 4 * a * c;

            if (!(discriminant > 0))
            {
                return(false);
            }
            var temp = (-b - Mathf.Sqrt(discriminant)) / a * 0.5f;

            if (temp < t_max && temp > t_min)
            {
                rec.shader = shader;
                rec.t      = temp;
                rec.p      = ray.GetPoint(rec.t);
                rec.normal = (rec.p - center).Normalized();
                GetSphereUV(ref rec);
                return(true);
            }
            temp = (-b + Mathf.Sqrt(discriminant)) / a * 0.5f;
            if (!(temp < t_max) || !(temp > t_min))
            {
                return(false);
            }
            rec.shader = shader;
            rec.t      = temp;
            rec.p      = ray.GetPoint(rec.t);
            rec.normal = (rec.p - center).Normalized();
            GetSphereUV(ref rec);
            return(true);
        }
    public override void Kill(NTGBattleUnitController killer)
    {
        if (alive)
        {
            base.Kill(killer);

            unitAnimator.SetBool("dead", true);

            HitRecord lastPlayerHit = null;
            while (hitRecords.Count > 0)
            {
                var hitRecord = hitRecords.Dequeue() as HitRecord;
                var p         = hitRecord.shooter as NTGBattlePlayerController;
                if (p != null)
                {
                    lastPlayerHit = hitRecord;
                }
            }
            if (lastPlayerHit != null && Time.time - lastPlayerHit.time < mainController.configX)
            {
                var k = lastPlayerHit.shooter as NTGBattlePlayerController;
                k.statistic.towerKill++;
            }

            GetComponent <CapsuleCollider>().enabled = false;
            gun.gameObject.SetActive(false);

            if (warningHint != null)
            {
                warningHint.gameObject.SetActive(false);
                warningDeadHint.gameObject.SetActive(false);
            }

            foreach (var fx in transform.GetComponentsInChildren <ParticleSystem>())
            {
                fx.Stop();
            }
            PlayDeadFX();

            mainController.uiController.ShowUnitKillMessage(killer, this);

            StartCoroutine(doDead());
        }
    }
Пример #22
0
        private Color32 Diffusing(Ray ray, HitableList hitableList, int depth)
        {
            var record = new HitRecord();

            if (hitableList.Hit(ray, 0.0001f, float.MaxValue, ref record))
            {
                var r           = new Ray(Vector3.zero, Vector3.zero);
                var attenuation = Color32.black;
                if (depth >= MAX_SCATTER_TIME || !record.material.scatter(ray, record, ref attenuation, ref r))
                {
                    return(Color32.black);
                }
                var c = Diffusing(r, hitableList, depth + 1);
                return(new Color32(c.r * attenuation.r, c.g * attenuation.g, c.b * attenuation.b));
            }
            var t = 0.5f * ray.normalDirection.y + 1f;

            return((1 - t) * new Color32(1, 1, 1) + t * new Color32(0.5f, 0.7f, 1));
        }
Пример #23
0
        void CookerTree_DragDrop(object sender, DragEventArgs e)
        {
            Node data = e.Data.GetData(typeof(Node)) as Node;

            if (data == null)
            {
                return;
            }
            Point     p   = this.PointToClient(new Point(e.X, e.Y));
            HitRecord hit = Pick(p);

            if (hit.Node != null)
            {
                Node dest = hit.Node;
                if (!(dest.Tag is CookTask))
                {
                    return;
                }
                dest.Expanded = true;
                ICookBase cb      = Activator.CreateInstance((Type)data.Tag) as ICookBase;
                Node      newNode = dest.Add(cb);
                newNode.Label       = cb.GetName();
                cb.PropertyChanged += (src, args) => {
                    newNode.Label = cb.GetName();
                };

                {
                    ((CookTask)hit.Node.Tag).Targets.Add((CookTarget)cb);
                    newNode.IsLeaf = true;
                }
            }
            else
            {
                ICookBase cb      = Activator.CreateInstance((Type)data.Tag) as ICookBase;
                Node      newNode = Root.Add(cb);
                newNode.Label       = cb.GetName();
                cb.PropertyChanged += (src, args) =>
                {
                    newNode.Label = cb.GetName();
                };
                document.CookingItems.Add(cb);
            }
        }
Пример #24
0
    public override bool Scatter(RTRay ray, HitRecord hit, out Color attenuation, out RTRay scattered)
    {
        attenuation = new Color(1, 1, 1);

        Vector3 outwardN;
        float   ni_over_nt;
        Vector3 refracted;
        float   reflect_prob;
        float   cosine;

        if (Vector3.Dot(ray.direction, hit.n) > 0)
        {
            outwardN   = -hit.n;
            ni_over_nt = refractiveIndex;
            cosine     = Vector3.Dot(ray.direction, hit.n) / ray.direction.magnitude;
        }
        else
        {
            outwardN   = hit.n;
            ni_over_nt = 1.0f / refractiveIndex;
            cosine     = -Vector3.Dot(ray.direction, hit.n) / ray.direction.magnitude;
        }

        if (RTMath.Refract(ray.direction, outwardN, ni_over_nt, out refracted))
        {
            reflect_prob = RTMath.schlick(cosine, refractiveIndex);
        }
        else
        {
            reflect_prob = 1.0f;
        }

        if (RTMath.Rnd01() < reflect_prob)
        {
            scattered = new RTRay().Set(hit.p, RTMath.Reflect(ray.direction, hit.n));
        }
        else
        {
            scattered = new RTRay().Set(hit.p, refracted);
        }

        return(true);
    }
Пример #25
0
        private static HitRecord GetWorldHit(Ray r, dWorldBuffer world, float minT)
        {
            HitRecord rec    = GetSphereHit(r, world.spheres, minT);
            HitRecord vRec   = world.VoxelChunk.hit(r, minT, rec.t);
            HitRecord triRec = GetMeshHit(r, world, vRec.t);

            if (rec.t < vRec.t && rec.t < triRec.t)
            {
                return(rec);
            }
            else if (vRec.t < rec.t && vRec.t < triRec.t)
            {
                return(vRec);
            }
            else
            {
                return(triRec);
            }
        }
Пример #26
0
        public bool Hit(Ray r, float tMin, float tMax, out HitRecord rec)
        {
            rec = HitRecord.Empty;
            bool  hitAnything  = false;
            float closestSoFar = tMax;

            for (int i = 0; i < Spheres.Length; i++)
            {
                Sphere elem = Spheres[i];
                if (elem.Hit(r, tMin, closestSoFar, out HitRecord tempRec))
                {
                    hitAnything  = true;
                    closestSoFar = tempRec.T;
                    rec          = tempRec;
                }
            }

            return(hitAnything);
        }
Пример #27
0
        public bool Scatter(Ray rIn, HitRecord hitRecord, out Vector3 attenuation, out Ray scattered)
        {
            Vector3 outwardNormal;
            var     reflected = HelperFunctions.Reflect(rIn.Direction(), hitRecord.Normal);
            float   niOverNt;

            attenuation = new Vector3(1.0f, 1.0f, 1.0f);
            float cosine;

            if (Vector3.Dot(rIn.Direction(), hitRecord.Normal) > 0)
            {
                outwardNormal = -hitRecord.Normal;
                niOverNt      = RefIdx;
                cosine        = RefIdx * Vector3.Dot(rIn.Direction(), hitRecord.Normal) / rIn.Direction().Length();
            }
            else
            {
                outwardNormal = hitRecord.Normal;
                niOverNt      = 1.0f / RefIdx;
                cosine        = -Vector3.Dot(rIn.Direction(), hitRecord.Normal) / rIn.Direction().Length();
            }
            float reflectProb;

            if (HelperFunctions.Refract(rIn.Direction(), outwardNormal, niOverNt, out Vector3 refracted))
            {
                reflectProb = HelperFunctions.Schlick(cosine, RefIdx);
            }
            else
            {
                reflectProb = 1.0f;
            }
            var random = new Random();

            if (random.NextDouble() < reflectProb)
            {
                scattered = new Ray(hitRecord.P, reflected);
            }
            else
            {
                scattered = new Ray(hitRecord.P, refracted);
            }
            return(true);
        }
Пример #28
0
        /// <summary>
        /// Checks if the ray intersects with the sphere at a certain point
        /// </summary>
        /// <param name="ray"></param>
        /// <param name="minDist"></param>
        /// <param name="maxDist"></param>
        /// <param name="hitRecord"></param>
        /// <returns></returns>
        public bool Hit(Ray ray, double minDist, double maxDist, out HitRecord hitRecord)
        {
            hitRecord          = new HitRecord();
            hitRecord.Material = this.Material;

            Vector3 oc           = ray.Origin - (Vector3)this.Origin; // Ray Origin - Center of the Sphere = OC
            double  a            = ray.Direction.LengthSquared;
            double  half_b       = Vector3.Dot(oc, ray.Direction);
            double  c            = oc.LengthSquared - Radius * Radius;
            double  discriminant = half_b * half_b - a * c;

            if (discriminant > 0)
            {
                double root = Math.Sqrt(discriminant);
                double temp = (-half_b - root) / a;

                if (temp < maxDist && temp > minDist)
                {
                    hitRecord.Distance = temp;
                    hitRecord.Point    = ray.PointAtDistance(hitRecord.Distance);
                    Vector3 outwardNormal = ((Vector3)hitRecord.Point - this.Origin) / this.Radius;

                    // determine if ray faces normal
                    hitRecord.HitFront = Vector3.Dot(ray.Direction, outwardNormal) < 0;
                    hitRecord.Normal   = hitRecord.HitFront ? outwardNormal : -outwardNormal;

                    return(true);
                }
                temp = (-half_b + root) / a;
                if (temp < maxDist && temp > minDist)
                {
                    hitRecord.Distance = temp;
                    hitRecord.Point    = ray.PointAtDistance(hitRecord.Distance);
                    Vector3 outwardNormal = ((Vector3)hitRecord.Point - this.Origin) / this.Radius;

                    // determine if ray faces normal
                    hitRecord.HitFront = Vector3.Dot(ray.Direction, outwardNormal) < 0;
                    hitRecord.Normal   = hitRecord.HitFront ? outwardNormal : -outwardNormal;
                    return(true);
                }
            }
            return(false);
        }
Пример #29
0
        /// <summary>
        /// Updates the selection set, given the hit object and the modifier keys</summary>
        /// <param name="hitRecord">HitRecord</param>
        /// <param name="modifiers">Modifier keys</param>
        private void UpdateSelection(HitRecord hitRecord, Keys modifiers)
        {
            TimelinePath hitObject        = hitRecord.HitPath;
            bool         hitIsValidAnchor = true;

            switch (hitRecord.Type)
            {
            case HitType.GroupMove:
                SelectGroups(hitObject);
                break;

            case HitType.TrackMove:
                SelectTracks(hitObject);
                break;

            case HitType.Interval:
            case HitType.Key:
            case HitType.Marker:
                SelectEvents(hitObject);
                Owner.Constrain = (modifiers & Owner.ConstrainModifierKeys) != 0;
                break;

            default:
                Anchor           = null;
                hitIsValidAnchor = false;
                break;
            }

            if (hitIsValidAnchor)
            {
                // If the Shift key is not held down or the current Anchor is null, or the user
                //  has switched between track and group, or the user has picked an event, then
                //  update the Anchor. IEvents are always additive with the shift key.
                if ((modifiers & Keys.Shift) == 0 ||
                    Anchor == null ||
                    (Anchor.Last is IGroup && hitObject.Last is ITrack) ||
                    (Anchor.Last is ITrack && hitObject.Last is IGroup) ||
                    (Anchor.Last is IEvent && hitObject.Last is IEvent))
                {
                    Anchor = hitObject;
                }
            }
        }
Пример #30
0
        public override bool Hit(Ray ray, float t_min, float t_max, ref HitRecord rec)
        {
            HitRecord rec1 = new HitRecord(), rec2 = new HitRecord();

            if (boundary.Hit(ray, -float.MaxValue, float.MaxValue, ref rec1))
            {
                if (boundary.Hit(ray, rec1.t + 0.0001f, float.MaxValue, ref rec2))
                {
                    rec1.t = Mathf.Range(rec1.t, t_min, t_max);

                    if (rec1.t < t_min)
                    {
                        rec1.t = t_min;
                    }
                    if (rec2.t > t_max)
                    {
                        rec2.t = t_max;
                    }
                    if (rec1.t >= rec2.t)
                    {
                        return(false);
                    }
                    if (rec1.t < 0)
                    {
                        rec1.t = 0;
                    }
                    float distance_inside_boundary = (rec2.t - rec1.t) * ray.direction.length();

                    float hit_distance = -(1 / density) * Mathf.Log(Mathematics.Random.Get());
                    if (hit_distance < distance_inside_boundary)
                    {
                        rec.t      = rec1.t + hit_distance / ray.direction.length();
                        rec.p      = ray.GetPoint(rec.t);
                        rec.normal = new Vector3(1, 0, 0); // arbitrary
                        rec.shader = phase_function;
                        return(true);
                    }
                }
            }

            return(false);
        }
Пример #31
0
    public override bool scatter(Ray rin, HitRecord rec, ref Vec3 attenuation, ref Ray scattered)
    {
        Vec3  outwardNormal;
        Vec3  reflected = reflect(rin.direction(), rec.normal);
        float niOverNt;

        attenuation = new Vec3(1.0F, 1.0F, 1.0F);
        Vec3  refracted = new Vec3();
        float reflectProb;
        float cosine;

        if (Vec3.dot(rin.direction(), rec.normal) > 0)
        {
            outwardNormal = -rec.normal;
            niOverNt      = refIdx;
            cosine        = refIdx * Vec3.dot(rin.direction(), rec.normal) / rin.direction().Length();
        }
        else
        {
            outwardNormal = rec.normal;
            niOverNt      = 1 / refIdx;
            cosine        = -Vec3.dot(rin.direction(), rec.normal) / rin.direction().Length();
        }
        if (refract(rin.direction(), outwardNormal, niOverNt, ref refracted))
        {
            reflectProb = schlick(cosine, refIdx);
        }
        else
        {
            scattered   = new Ray(rec.p, reflected);
            reflectProb = 1.0F;
        }
        if (new Random().NextDouble() < reflectProb)
        {
            scattered = new Ray(rec.p, reflected);
        }
        else
        {
            scattered = new Ray(rec.p, refracted);
        }
        return(true);
    }
Пример #32
0
        void TestBoxesIntersectionBasic()
        {
            Box box = new Box();
            Ray ray1 = new Ray(new Point(-5f, 0f, 0f), Constant.VEC_X);
            HitRecord? intersection1 = box.rayIntersection(ray1);
            Assert.True(intersection1 != null, "TestBoxesIntersectionBasic failed - assert 1/10");
            // new Vec2D(0.375f, 0.8333334f) for other method UV mapping
            HitRecord hit1 = new HitRecord(
                                            new Point(-1.0f, 0.0f, 0.0f),
                                            new Normal(-1.0f, 0.0f, 0.0f),
                                            new Vec2D(0.125f, 0.5f),
                                            4.0f,
                                            ray1
                                        );
            Assert.True(hit1.isClose(intersection1), "TestBoxesIntersectionBasic failed - assert 2/10");
            Assert.True(box.quickRayIntersection(ray1), "TestBoxesIntersectionBasic failed - assert 3/10");

            Ray ray2 = new Ray(new Point(0f, 0f, 10f), -Constant.VEC_Z);
            HitRecord? intersection2 = box.rayIntersection(ray2);
            Assert.True(intersection2 != null, "TestBoxesIntersectionBasic failed - assert 4/10");
            // new Vec2D(0.625f, 0.5f) for other method UV mapping
            HitRecord hit2 = new HitRecord(
                                            new Point(0.0f, 0.0f, 1.0f),
                                            new Normal(0.0f, 0.0f, 1.0f),
                                            new Vec2D(0.875f, 0.5f),
                                            9.0f,
                                            ray2
                                        );
            Assert.True(hit2.isClose(intersection2), "TestBoxesIntersectionBasic failed - assert 5/10");
            Assert.True(box.quickRayIntersection(ray2), "TestBoxesIntersectionBasic failed - assert 6/10");

            Ray ray3 = new Ray(new Point(-5f, 0f, 10f), Constant.VEC_X);
            HitRecord? intersection3 = box.rayIntersection(ray3);
            Assert.True(intersection3 == null, "TestBoxesIntersectionBasic failed - assert 7/10");
            Assert.False(box.quickRayIntersection(ray3), "TestBoxesIntersectionBasic failed - assert 8/10");

            // Intersect for t<0
            Ray ray4 = new Ray(new Point(0f, 3f, 0f), Constant.VEC_Y);
            HitRecord? intersection4 = box.rayIntersection(ray4);
            Assert.True(intersection4 == null, "TestBoxesIntersectionBasic failed - assert 9/10");
            Assert.False(box.quickRayIntersection(ray4), "TestBoxesIntersectionBasic failed - assert 10/10");
        }
Пример #33
0
    // TODO: Merge with BunnyCrownState
    public override void HandleCollision(GameObject player, Collider2D collision, ref Vector3 velocity)
    {
        Bunny  bunny = collision.GetComponent <Bunny>();
        Player enemy = collision.GetComponent <Player>();

        Vector3 knockbackForce = velocity;

        if (bunny)
        {
            HitRecord hitRecord = new HitRecord();
            bunny.Hit(player, ref hitRecord, knockbackForce);
        }
        else if (enemy)
        {
            // Trying to hit the enemy player
            HitRecord hitRecord = new HitRecord();
            enemy.Hit(player, ref hitRecord, knockbackForce);

            // If an enemy is hit, the dash stops
            Player self = player.GetComponent <Player>();
            if (self.collisionInfo.below)
            {
                self.controller.SwitchState(PlayerController.States.IDLE);
            }
            else
            {
                self.controller.SwitchState(PlayerController.States.AIRBORNE);
            }

            // If the dash was reflected because of a collision with a dashing player, both players are repelled in the opposite facing direction
            if (hitRecord.reflected)
            {
                Player  hitPlayer        = hitRecord.hitObject as Player;
                Vector2 reflectDirection = hitPlayer.transform.position - player.transform.position;
                reflectDirection.Normalize();

                velocity = reflectDirection * 10.0f;

                Debug.Log("Reflected!");
            }
        }
    }
Пример #34
0
        public override bool Hit(Ray r, double tMin, double tMax, out HitRecord rec)
        {
            Vec3   oc = r.Origin() - Center(r.Time());
            double a  = Vec3.Dot(r.Direction(), r.Direction());
            double b  = Vec3.Dot(oc, r.Direction());
            double c  = Vec3.Dot(oc, oc) - _radius * _radius;

            double discriminant = b * b - a * c;

            if (discriminant > 0)
            {
                double temp = (-b - Math.Sqrt(b * b - a * c)) / a;
                if (temp < tMax && temp > tMin)
                {
                    rec.T        = temp;
                    rec.P        = r.PointAtParameter(rec.T);
                    rec.Normal   = (rec.P - Center(r.Time())) / _radius;
                    rec.Material = _material;
                    Sphere.GetSphereUV((rec.P - Center(r.Time())) / _radius, out rec.U, out rec.V);
                    return(true);
                }

                temp = (-b + Math.Sqrt(b * b - a * c)) / a;
                if (temp < tMax && temp > tMin)
                {
                    rec.T        = temp;
                    rec.P        = r.PointAtParameter(rec.T);
                    rec.Normal   = (rec.P - Center(r.Time())) / _radius;
                    rec.Material = _material;
                    Sphere.GetSphereUV((rec.P - Center(r.Time())) / _radius, out rec.U, out rec.V);
                    return(true);
                }
            }

            rec.T        = 0.0;
            rec.P        = null;
            rec.Normal   = null;
            rec.Material = null;
            rec.U        = 0.0;
            rec.V        = 0.0;
            return(false);
        }
Пример #35
0
        /// <summary>
        /// Intersects the specified client point with the scene, knowing that the given
        /// HitRecords were the result of having called Dispatch with these same client points</summary>
        /// <param name="x">Client x coordinate</param>
        /// <param name="y">Client y coordinate</param>
        /// <param name="hits">The hits</param>
        /// <param name="pt">The intersection point</param>
        /// <param name="surfaceNormal">The surface normal of the target object at the intersection
        /// point, or the zero vector if the surface normal could not be found. Check against
        /// Vec3F.ZeroVector before using.</param>
        /// <returns>True iff client point intersects scene</returns>
        protected bool Intersect(int x, int y, HitRecord[] hits, ref Vec3F pt, out Vec3F surfaceNormal)
        {
            surfaceNormal = new Vec3F(); 
            
            if (hits.Length == 0)
                return false;

            HitRecord hit = hits[0];
            
            if (hit.HasNormal)
                surfaceNormal = hit.Normal;

            if (hit.HasWorldIntersection)
            {
                pt = hit.WorldIntersection;
                return true;
            }

            return false;
        }
Пример #36
0
        /// <summary>
        /// Dispatches untyped items. Replaces DispatchNotTyped(). To get the same behavior as
        /// the old DispatchNotTyped(), set the TypeFilter property to null prior to calling.</summary>
        /// <param name="traverseList">The traverse list</param>
        /// <param name="camera">The camera</param>
        protected void DispatchTraverseList(ICollection<TraverseNode> traverseList, Camera camera)
        {
            // Prepare for geometric picking -- create the ray in world space and reset geometric hit-list.
            // First create the ray in viewing coordinates and transform to world coordinates.
            float nx = (m_x / (float)m_width) - 0.5f;//normalized x
            float ny = 0.5f - (m_y / (float)m_height);//normalized y
            Ray3F rayWorld = camera.CreateRay(nx, ny);
            Matrix4F worldToView = camera.ViewMatrix;
            Matrix4F viewToWorld = new Matrix4F();
            viewToWorld.Invert(worldToView);
            rayWorld.Transform(viewToWorld);
            ClearHitList();

            // for geometric picking. will be cleared for each HitRecord.
            List<uint> userData = new List<uint>(1);

            // Dispatch traverse list
            int index = 0;
            foreach (TraverseNode node in traverseList)
            {
                // First test for filtering. 
                IRenderObject renderObject = node.RenderObject;
                if (FilterByType(renderObject))
                {
                    IIntersectable intersectable = renderObject.GetIntersectable();
                    IGeometricPick geometricPick = intersectable as IGeometricPick;
                    if (geometricPick != null)
                    {
                        // Picking by geometry.
                        Matrix4F objToWorld = new Matrix4F(node.Transform);
                        Matrix4F worldToObj = new Matrix4F();
                        worldToObj.Invert(objToWorld);
                        Matrix4F viewToObj = Matrix4F.Multiply(viewToWorld, worldToObj);

                        if (m_frustumPick)
                        {
                            //The pick frustum is in view space. Transform to world space then object space.
                            Frustum frustumObj = new Frustum(m_viewFrust0);
                            frustumObj.Transform(viewToObj);

                            //Multi-pick. Get everything in the pick frustum (m_viewFrust0).
                            Vec3F eyeObj;
                            worldToObj.Transform(camera.Eye, out eyeObj);
                            userData.Clear();

                            if (geometricPick.IntersectFrustum(frustumObj, eyeObj, node.RenderState, userData))
                            {
                                // Prepare a multi-pick HitRecord, as if OpenGL had calculated this.
                                HitRecord hit = new HitRecord(
                                    node.GraphPath,
                                    renderObject,
                                    objToWorld,
                                    userData.ToArray());

                                m_geoHitList.Add(hit);
                            }
                        }
                        else
                        {   //Single pick. We care about distance from camera eye.
                            //Make a copy of the ray in world-space and tranform it to object space.
                            Ray3F rayObj = rayWorld; //remember, Ray3F is a value type, not a reference type.
                            rayObj.Transform(worldToObj);

                            // Do the intersection test in object space.
                            userData.Clear();
                            Vec3F intersectionPt, surfaceNormal;
                            Vec3F nearestVert;
                            bool intersected;
                            intersected = geometricPick.IntersectRay(
                                rayObj, camera, node.RenderState, objToWorld, this,
                                out intersectionPt, out nearestVert, out surfaceNormal, userData);

                            if (intersected)
                            {
                                // Transform to world space and then to screen space.
                                objToWorld.Transform(intersectionPt, out intersectionPt);
                                objToWorld.Transform(nearestVert, out nearestVert);
                                // Prepare a single-pick HitRecord, as if OpenGL had calculated this.
                                HitRecord hit = new HitRecord(
                                    node.GraphPath,
                                    renderObject,
                                    objToWorld,
                                    userData.ToArray());

                                // This is the one difference from OpenGL pick. We have the world pt already.
                                hit.WorldIntersection = intersectionPt;
                                hit.NearestVert = nearestVert;

                                // Another difference is that it's possible to get the surface normal.
                                if (surfaceNormal != Vec3F.ZeroVector)
                                {
                                    objToWorld.TransformNormal(surfaceNormal, out surfaceNormal);
                                    surfaceNormal.Normalize();
                                    hit.Normal = surfaceNormal;
                                }

                                m_geoHitList.Add(hit);
                            }
                        }
                    }
                    else
                    {
                        // Picking by "rendering", using OpenGL pick.
                        PushMatrix(node.Transform, false);
                        Gl.glPushName(index);
                        IRenderPick pickInterface = renderObject as IRenderPick;
                        if (pickInterface != null)
                        {
                            pickInterface.PickDispatch(node.GraphPath, node.RenderState, this, camera);
                        }
                        else
                        {
                            renderObject.Dispatch(node.GraphPath, node.RenderState, this, camera);
                        }
                        Gl.glPopName();
                        PopMatrix();
                    }
                }

                index++;
            }
        }
Пример #37
0
        /// <summary>
        /// Shoots a ray into the scene and returns the intersection point</summary>
        /// <param name="camera">The camera</param>
        /// <param name="x">Ray X coordinate in screen space</param>
        /// <param name="y">Ray y coordinate in screen space</param>
        /// <param name="scene">The given scene</param>
        /// <param name="point">The point of intersection</param>
        /// <param name="firstHit">The HitRecord giving possible nearest vertex and surface normal</param>
        /// <returns>True if the ray intersects the scene</returns>
        public bool Intersect(Camera camera, int x, int y, Scene scene, ref Vec3F point,
            out HitRecord firstHit)
        {
            firstHit = null;

            //Too small of a pick tolerance makes Design View tooltips and right-click context
            //menus not work on wireframe / linework.
            //m_pickTolerance = 0.001f;
            Init(camera, x, y, x, y, false, true);
            Dispatch(scene, camera);
            HitRecord[] hits = GetHits();
            //m_pickTolerance = 3.0f;

            if (hits.Length == 0)
                return false;

            firstHit = hits[0];
            if (firstHit.HasWorldIntersection)
            {
                point = firstHit.WorldIntersection;
                return true;
            }

            return false;
        }
Пример #38
0
        /// <summary>
        /// Gets the HitRecord array from a given traverse list</summary>
        /// <param name="traverseList">The traverse list</param>
        /// <param name="multiPick">True to return all available HitRecords. False to return just the closest</param>
        /// <returns>HitRecord array</returns>
        /// <remarks>Must be called after Init() and Dispatch(). There can potentially be duplicate
        /// HitRecords returned for two reasons: 1) Proxy objects, like the cube by default, render
        /// themselves twice, once with solid fill and once with the outline. Both renderings can
        /// yield a HitRecord, sometimes with slightly different z values. 2) Models are made up of
        /// multiple TransformNodes and each one can generate a HitRecord.</remarks>
        public HitRecord[] GetHits(ICollection<TraverseNode> traverseList, bool multiPick)
        {
            if (m_frustumPick == true && multiPick == false)
                throw new InvalidOperationException("results can't be sorted front-to-back with frustum picking");

            // First get the hits from OpenGL pick. Gl.glRenderMode resets this value when it is called,
            // so consecutive calls to GetHits() will fail. Thus, we need to cache glRenderMode(GL_RENDER).
            if (m_openGlHits == 0)
            {
                m_openGlHits = Gl.glRenderMode(Gl.GL_RENDER);
            }
            HitRecord[] renderSelect = null;

            if (m_openGlHits > 0 && traverseList.Count > 0)
            {
                renderSelect = PopulateOpenGlSelection(traverseList);
            }
            else
            {
                renderSelect = s_emptyHitRecordArray;
            }

            // now integrate the hits from geometrical picking.
            HitRecord[] select;
            if (m_geoHitList.Count == 0)
            {
                select = renderSelect;
            }
            else
            {
                int total = renderSelect.Length + m_geoHitList.Count;
                select = new HitRecord[total];
                renderSelect.CopyTo(select, 0);
                m_geoHitList.CopyTo(select, renderSelect.Length);
            }

            // sort the results by distance from camera eye, near-to-far
            if (m_frustumPick == false)
                HitRecord.Sort(select, m_eye);

            // if the caller only wants one result, just give them one.
            if (multiPick == false && select.Length > 1)
            {
                HitRecord[] singleHit = new HitRecord[1];
                singleHit[0] = select[0];
                select = singleHit;
            }

            // useful debug output
            //Console.WriteLine("multiPick:{0}, m_frustumPick:{1}", multiPick, m_frustumPick);
            //foreach (HitRecord hit in select)
            //{
            //    Console.WriteLine("  hit: {0} at z {1}", hit.RenderObject.InternalObject.Id, hit.ZMin);
            //}
            
            // return the results
            return select;
        }
Пример #39
0
 public override bool IsHit(Ray ray, HitRecord record, float near, float far)
 {
     throw new NotImplementedException();
 }
Пример #40
0
 private void SetManipulator(IManipulator manipulator, HitRecord[] hits)
 {
     s_isManipulating = true;
     m_manipulatorHitRecords = hits;
 }
Пример #41
0
 public abstract void intersect(ref HitRecord hit, RenderContext rc, Ray ray);
Пример #42
0
 /// <summary>
 /// Performs actions at the beginning of control drag</summary>
 /// <param name="hit">Hit record</param>
 /// <param name="x">Mouse x position</param>
 /// <param name="y">Mouse y position</param>
 /// <param name="action">Render action</param>
 /// <param name="camera">Camera</param>
 /// <param name="transform">Transform</param>
 /// <returns>Code for control element under mouse x, y</returns>
 public HitElement OnHit(HitRecord hit, float x, float y, IRenderAction action, Camera camera, Matrix4F transform)
 {
     // Store pick coords
     m_iX = x;
     m_iY = y;
     return (HitElement)hit.RenderObjectData[1];
 }
Пример #43
0
 public void traceRay(Ray ray, HitRecord hr, RenderContext rc)
 {
     this.obj.intersect(ref hr, rc, ray);
 }
Пример #44
0
        public override Color shade(RenderContext rc, Ray ray, HitRecord hrec, int depth)
        {
            Scene scene = rc.getScene();
              Point hp = ray.pointOn(hrec.getT());
              Vector normal = hrec.getPrimitive().normal(hp);
              Vector v = scene.getCamera().getEye() - hp;
              v.normalize();

              hp += 0.0001f * normal;

              int numlights = scene.numberOfLights();
              Color finalc = new Color(0,0,0);

              for(int i = 0; i < numlights; i++) {

              Vector ldir = new Vector();
              Color lcolor = new Color();
              float ldist = scene.getLight(i).getLight(ref lcolor, ref ldir, rc, hp);

             HitRecord shadowhr = new HitRecord();
             Ray shadowray = new Ray(hp, ldir);
             scene.getObject().intersect(ref shadowhr, rc, shadowray);
              if((shadowhr.getT() >= ldist || shadowhr.getT() < 0.01)) {
                float dp = Vector.dot(normal, ldir) * this.kd;
                if(!(dp > 0)) dp = 0;
                Vector r = 2*(Vector.dot(ldir, normal))*normal - ldir;
                r.normalize();
                float spec = Vector.dot(r, v);
                if(!(spec > 0)) spec = 0;
                else
                   spec = (float)System.Math.Pow(spec, this.n);

                finalc += (dp*kd+spec*ks)*lcolor;
             }
              }

              return color*(finalc + scene.getAmbient()*ka);
        }
Пример #45
0
 public abstract Color shade( RenderContext rc, Ray ray, HitRecord hrec, int depth );
Пример #46
0
        public override bool IsHit(Ray ray, HitRecord record, float near, float far)
        {
            bool isHit = false;
            foreach (SceneObject obj in components)
            {
                bool currentHit  =  obj.IsHit(ray, record, float.MinValue, float.MaxValue);

                isHit = isHit || currentHit;
            }
            if (RenderingParameters.showMouse && isHit)
            {
                Console.WriteLine("Hit by " + record.ObjectName);
                Console.WriteLine("t: " + record.T);
                Console.WriteLine("Distance: " + record.Distance);
            }
            return isHit;
        }
Пример #47
0
 /// <summary>
 /// Comparer for sorting HitRecords by their HitType enum. Lower-valued enums come first.</summary>
 private int CompareHits(HitRecord x, HitRecord y)
 {
     return x.Type.CompareTo(y.Type);
 }
Пример #48
0
        private HitRecord[] PopulateOpenGlSelection(ICollection<TraverseNode> traverseList)
        {
            // Ensure that OpenGL is in correct state.
            double[] viewMat = null;
            double[] projectionMat = null;
            int[] viewport = null;
            if (m_frustumPick == false)
            {
                Gl.glViewport(0, 0, m_width, m_height);
                Gl.glMatrixMode(Gl.GL_PROJECTION);
                Gl.glLoadIdentity();
                Util3D.glMultMatrixf(m_projectionMatrix);

                Gl.glMatrixMode(Gl.GL_MODELVIEW);
                Gl.glLoadIdentity();
                Util3D.glMultMatrixf(m_viewMatrix);

                viewMat = new double[16];
                Gl.glGetDoublev(Gl.GL_MODELVIEW_MATRIX, viewMat);

                projectionMat = new double[16];
                Gl.glGetDoublev(Gl.GL_PROJECTION_MATRIX, projectionMat);

                viewport = new int[4];
                viewport[0] = viewport[1] = 0;
                viewport[2] = m_width;
                viewport[3] = m_height;
            }

            // Construct traverse array
            HitRecord[] selection = null;
            List<HitRecord> selectionList = new List<HitRecord>();
            TraverseNode[] travArray = new TraverseNode[traverseList.Count];
            traverseList.CopyTo(travArray, 0);

            uint start = 0;
            for (int i = 0; i < m_openGlHits; ++i)
            {
                uint nameCount = (uint)m_selectionBuffer[start];

                if (nameCount > 0)
                {
                    uint travNodeIndex = (uint)m_selectionBuffer[start + 3];
                    TraverseNode travNode = travArray[travNodeIndex];
                    HitRecord hitRecord;
                    if (m_frustumPick)
                    {
                        hitRecord = new HitRecord(
                            travNode.GraphPath,
                            travNode.RenderObject,
                            new Matrix4F(travNode.Transform),
                            new uint[nameCount - 1]);
                    }
                    else
                    {
                        hitRecord = new HitRecord(
                            travNode.GraphPath,
                            travNode.RenderObject,
                            new Matrix4F(travNode.Transform),
                            new uint[nameCount - 1]);

                        // Transform screen to world and record world-space intersection point.
                        float zMin = ((float)((uint)m_selectionBuffer[start + 1])) / 0xFFFFFFFF;
                        Vec3F intersectionPt = GetWorldIntersectionFromScreen(
                            m_x, m_y, zMin,
                            viewMat, projectionMat, viewport);
                        hitRecord.WorldIntersection = intersectionPt;
                    }

                    // Populate object data
                    for (uint j = 0; j < nameCount - 1; j++)
                    {
                        hitRecord.RenderObjectData[j] = (uint)m_selectionBuffer[start + 4 + j];
                    }

                    selectionList.Add(hitRecord);

                    start += 3 + nameCount;
                }
            }
            selection = new HitRecord[selectionList.Count];
            selectionList.CopyTo(selection, 0);
            return selection;
        }
Пример #49
0
        /// <summary>
        /// Performs a picking test to see if any manipulator is visible on the screen at the given coordinates</summary>
        /// <param name="x">X-coordinate in screen coordinates (like from MouseEventArgs)</param>
        /// <param name="y">Y-coordinate in screen coordinates (like from MouseEventArgs)</param>
        /// <param name="hits">Resulting HitRecord(s) if there was a manipulator found</param>
        /// <returns>The found manipulator or null if none found</returns>
        protected IManipulator TestForManipulator(int x, int y, out HitRecord[] hits)
        {
            IManipulator manipulator = null;
            m_pickAction.TypeFilter = typeof(IManipulator);

            SetCurrentContext();
            m_pickAction.Set(m_renderAction);
            m_pickAction.Init(Camera, x, y, x, y, true, false);
            Render(m_pickAction, true, true);
            hits = m_pickAction.GetHits();
            m_pickAction.TypeFilter = null;

            // Analyze hits
            if (hits.Length > 0)
                manipulator = hits[0].RenderObject as IManipulator;

            m_pickAction.Clear();

            return manipulator;
        }
Пример #50
0
 /// <summary>
 /// Constructor</summary>
 /// <param name="hits">HitRecords for event</param>
 /// <param name="multiSelect">Whether user selecting multiple objects</param>
 public PickEventArgs(HitRecord[] hits, bool multiSelect)
 {
     HitArray = hits;
     MultiSelect = multiSelect;
 }
Пример #51
0
 public override void intersect(ref HitRecord hit, RenderContext rc, Ray ray)
 {
     for( int i = 0; i < this.objects.Count; i++ )
         this.objects[i].intersect( ref hit, rc, ray );
 }
        /// <summary>
        /// Updates the selection set, given the hit object and the modifier keys</summary>
        /// <param name="hitRecord">HitRecord</param>
        /// <param name="modifiers">Modifier keys</param>
        private void UpdateSelection(HitRecord hitRecord, Keys modifiers)
        {
            TimelinePath hitObject = hitRecord.HitPath;
            bool hitIsValidAnchor = true;

            switch (hitRecord.Type)
            {
                case HitType.GroupMove:
                    SelectGroups(hitObject);
                    break;

                case HitType.TrackMove:
                    SelectTracks(hitObject);
                    break;

                case HitType.Interval:
                case HitType.Key:
                case HitType.Marker:
                    SelectEvents(hitObject);
                    Owner.Constrain = (modifiers & Owner.ConstrainModifierKeys) != 0;
                    break;
                
                default:
                    Anchor = null;
                    hitIsValidAnchor = false;
                    break;
            }

            if (hitIsValidAnchor)
            {
                // If the Shift key is not held down or the current Anchor is null, or the user
                //  has switched between track and group, or the user has picked an event, then
                //  update the Anchor. IEvents are always additive with the shift key.
                if ((modifiers & Keys.Shift) == 0 ||
                    Anchor == null ||
                    (Anchor.Last is IGroup && hitObject.Last is ITrack) ||
                    (Anchor.Last is ITrack && hitObject.Last is IGroup) ||
                    (Anchor.Last is IEvent && hitObject.Last is IEvent))
                {
                    Anchor = hitObject;
                }
            }
        }
Пример #53
0
        /// <summary>
        /// Performs actions during control drag</summary>
        /// <param name="hit">Hit record</param>
        /// <param name="x">Mouse x position</param>
        /// <param name="y">Mouse y position</param>
        /// <param name="action">Render action</param>
        /// <param name="camera">Camera</param>
        /// <param name="transform">Transform</param>
        /// <returns>Translation, in world coordinates</returns>
        public Vec3F OnDrag(HitRecord hit, float x, float y, IRenderAction action, Camera camera, Matrix4F transform)
        {
            float a1, a2;
            Matrix4F W = new Matrix4F();
            W.Mul(transform, camera.ViewMatrix);

            // Setup rays, in view space. (-z goes into the screen.)
            Ray3F ray0 = camera.CreateRay(m_iX, m_iY);
            Ray3F ray = camera.CreateRay(x, y);

            // Build axis and origin in view space
            Vec3F xAxis = W.XAxis;
            Vec3F yAxis = W.YAxis;
            Vec3F zAxis = W.ZAxis;
            Vec3F origin = W.Translation;

            Vec3F trans = new Vec3F();

            // Choose the best projection plane according to the projection angle
            switch ((HitElement)hit.RenderObjectData[1])
            {
                case HitElement.X_ARROW:
                    {
                        a1 = Math.Abs(Vec3F.Dot(ray0.Direction, yAxis));
                        a2 = Math.Abs(Vec3F.Dot(ray0.Direction, zAxis));
                        Vec3F axis = (a1 > a2 ? yAxis : zAxis);
                        Vec3F p0 = ray0.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                        Vec3F p1 = ray.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                        float dragAmount = Vec3F.Dot(xAxis, p1 - p0);
                        Vec3F xLocal = transform.XAxis;
                        trans = dragAmount * xLocal;
                    }
                    break;

                case HitElement.Y_ARROW:
                    {
                        a1 = Math.Abs(Vec3F.Dot(ray0.Direction, zAxis));
                        a2 = Math.Abs(Vec3F.Dot(ray0.Direction, xAxis));
                        Vec3F axis = (a1 > a2 ? zAxis : xAxis);
                        Vec3F p0 = ray0.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                        Vec3F p1 = ray.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                        float dragAmount = Vec3F.Dot(yAxis, p1 - p0);
                        Vec3F yLocal = transform.YAxis;
                        trans = dragAmount * yLocal;
                    }
                    break;

                case HitElement.Z_ARROW:
                    {
                        a1 = Math.Abs(Vec3F.Dot(ray0.Direction, xAxis));
                        a2 = Math.Abs(Vec3F.Dot(ray0.Direction, yAxis));
                        Vec3F axis = (a1 > a2 ? xAxis : yAxis);
                        Vec3F p0 = ray0.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                        Vec3F p1 = ray.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                        float dragAmount = Vec3F.Dot(zAxis, p1 - p0);
                        Vec3F zLocal = transform.ZAxis;
                        trans = dragAmount * zLocal;
                    }
                    break;
                
                case HitElement.XY_SQUARE:
                    {
                        Vec3F p0 = ray0.IntersectPlane(zAxis, -Vec3F.Dot(zAxis, origin));
                        Vec3F p1 = ray.IntersectPlane(zAxis, -Vec3F.Dot(zAxis, origin));
                        Vec3F deltaLocal = p1 - p0;
                        float dragX = Vec3F.Dot(xAxis, deltaLocal);
                        float dragY = Vec3F.Dot(yAxis, deltaLocal);
                        Vec3F xLocal = transform.XAxis;
                        Vec3F yLocal = transform.YAxis;
                        trans = dragX * xLocal + dragY * yLocal;
                    }
                    break;

                case HitElement.YZ_SQUARE:
                    {
                        Vec3F p0 = ray0.IntersectPlane(xAxis, -Vec3F.Dot(xAxis, origin));
                        Vec3F p1 = ray.IntersectPlane(xAxis, -Vec3F.Dot(xAxis, origin));
                        Vec3F deltaLocal = p1 - p0;
                        float dragY = Vec3F.Dot(yAxis, deltaLocal);
                        float dragZ = Vec3F.Dot(zAxis, deltaLocal);
                        Vec3F yLocal = transform.YAxis;
                        Vec3F zLocal = transform.ZAxis;
                        trans = dragY * yLocal + dragZ * zLocal;
                    }
                    break;

                case HitElement.XZ_SQUARE:
                    {
                        Vec3F p0 = ray0.IntersectPlane(yAxis, -Vec3F.Dot(yAxis, origin));
                        Vec3F p1 = ray.IntersectPlane(yAxis, -Vec3F.Dot(yAxis, origin));
                        Vec3F deltaLocal = p1 - p0;
                        float dragX = Vec3F.Dot(xAxis, deltaLocal);
                        float dragZ = Vec3F.Dot(zAxis, deltaLocal);
                        Vec3F xLocal = transform.XAxis;
                        Vec3F zLocal = transform.ZAxis;
                        trans = dragX * xLocal + dragZ * zLocal;
                    }
                    break;
            }
            return trans;
        }
Пример #54
0
        private HitRecord Pick(Point pt)
        {
            HitRecord result = new HitRecord();

            int left = -m_hScroll;
            int xPadding = Margin.Left;

            foreach (Property p in Properties)
            {
                if (p.FirstInCategory)
                {
                    if (pt.Y < HeaderHeight &&
                        pt.X >= left &&
                        pt.X <= left + ExpanderSize + 2 * xPadding)
                    {
                        result.Type = HitType.CategoryExpander;
                        result.Property = p;
                        result.Category = p.Category;
                        result.Row = -1;
                        result.Offset = new Point(pt.X - left, pt.Y);
                        return result;
                    }

                    if (!GetVisible(p))
                        left += RowHeight;
                }

                if (GetVisible(p))
                {
                    int width = GetColumnInfo(p).Width;
                    if (pt.X >= left && pt.X <= left + width)
                    {
                        result.Property = p;
                        if ((pt.Y >= 0) && (pt.Y < HeaderHeight))
                        {
                            if (Math.Abs(left + width - pt.X) < SystemDragSize.Width)
                            {
                                result.Type = HitType.ColumnHeaderRightEdge;
                                result.Offset = new Point(pt.X - left, pt.Y);
                                return result;
                            }
                            else
                            {
                                result.Type = HitType.ColumnHeader;
                                result.Offset = new Point(pt.X - left, pt.Y);
                                return result;
                            }
                        }

                        // check if after the property editing row
                        int row = GetRowAtY(pt.Y);
                        if (row < SelectedObjects.Length)
                        {
                            result.Offset = new Point(pt.X - left, pt.Y % RowHeight);
                            result.Type = HitType.Cell;
                            result.Row = row;
                        }
                        return result;
                    }

                    left += width;
                }
            }

            return result;
        }
Пример #55
0
 /// <summary>
 /// Returns whether the control was hit during a picking operation</summary>
 /// <param name="hit">Hit record</param>
 /// <returns>True if the control was hit during a picking operation</returns>
 public bool IsHit(HitRecord hit)
 {
     return (hit.RenderObjectData[0] == m_nameBase);
 }