Inheritance: MonoBehaviour
Example #1
0
 public void RemoveHitable(Hitable hitable)
 {
     if (hitable is HitableCube)
     {
         HitableCubes.Remove(hitable);
     }
 }
Example #2
0
    /**
     *
     */
    public void OnCharacterControllerHit(object _hitInfo)
    {
        // Local variables
        ControllerColliderHit hitInfo = _hitInfo as ControllerColliderHit;
        Hitable hitable = null;

        // Useless message?
        if (hitInfo == null)
        {
            return;
        }

        // Hitable?
        hitable = hitInfo.controller.gameObject.GetComponent <Hitable>();
        if (hitable == null)
        {
            return;
        }

        // Hit from above?
        if (Vector3.Dot(hitInfo.normal, Vector3.up) >= GameConfig.ENEMY_PLAYER_ABOVE_FACTOR)
        {
            // Player?
            if (hitable is Player)
            {
                (hitable as Player).jumpingFromAnEnemy();
            }
            onHit(hitable);
            return;
        }

        // Notify
        hitable.onHit(this);
    }
Example #3
0
        public override HitRecord Hit(Ray ray, float tMin, float tMax)
        {
            var origin = ray.Origin.ToSingleArray();
            var dir    = ray.Direction.ToSingleArray();

            origin[0] = (CosTheta * ray.Origin.X) - (SinTheta * ray.Origin.Z);
            origin[2] = (SinTheta * ray.Origin.X) + (CosTheta * ray.Origin.Z);
            dir[0]    = (CosTheta * ray.Direction.X) - (SinTheta * ray.Direction.Z);
            dir[2]    = (SinTheta * ray.Direction.X) + (CosTheta * ray.Direction.Z);
            var rotatedRay = new Ray(new Vector3(origin[0], origin[1], origin[2]), new Vector3(dir[0], dir[1], dir[2]));
            var hitRecord  = Hitable.Hit(rotatedRay, tMin, tMax);

            if (hitRecord == null)
            {
                return(null);
            }

            var p      = hitRecord.P.ToSingleArray();
            var normal = hitRecord.Normal.ToSingleArray();

            p[0]      = (CosTheta * hitRecord.P.X) + (SinTheta * hitRecord.P.Z);
            p[2]      = (-SinTheta * hitRecord.P.X) + (CosTheta * hitRecord.P.Z);
            normal[0] = (CosTheta * hitRecord.Normal.X) + (SinTheta * hitRecord.Normal.Z);
            normal[2] = (-SinTheta * hitRecord.Normal.X) + (CosTheta * hitRecord.Normal.Z);
            return(new HitRecord(hitRecord.T, new Vector3(p[0], p[1], p[2]), new Vector3(normal[0], normal[1], normal[2]), hitRecord.UvCoords, hitRecord.Material));
        }
Example #4
0
 public Transform(Hitable obj, Vector3 p, Vector3 r, Vector3 s)
 {
     position = p;
     Object   = obj;
     rotation = r;
     scale    = s;
 }
Example #5
0
    protected virtual List <Hitable> pickAttackTargets(int hitmask)
    {
        List <Hitable> output = new List <Hitable>();

        Collider2D[] colliders;
        if (isLookinkRight)
        {
            colliders = Physics2D.OverlapAreaAll(transform.position + attackAreaRightMin, transform.position + attackAreaRightMax, hitmask);
        }
        else
        {
            colliders = Physics2D.OverlapAreaAll(transform.position + attackAreaLeftMin, transform.position + attackAreaLeftMax, hitmask);
        }
        foreach (Collider2D c in colliders)
        {
            if (c.gameObject != gameObject)
            {
                Hitable h = null;
                h = c.GetComponent <Entity>();
                if (h != null)
                {
                    output.Add(h);
                    continue;
                }
                h = c.GetComponent <Dice>();
                if (h != null)
                {
                    output.Add(h);
                    continue;
                }
            }
        }
        return(output);
    }
Example #6
0
        /// <summary>
        /// Scene with rectangle and three spheres.
        /// </summary>
        private void CreateScene2()
        {
            // Set up camera
            this.hFovDeg = 90;
            var   lookFrom  = new Vec3(0, 1, 1);
            var   lookAt    = new Vec3(0, 0.5f, 0);
            var   lookUp    = new Vec3(0, 1, 0);
            float focusDist = (lookAt - lookFrom).Length;
            float aperture  = 0.00f;

            this.camera = new CartesianCamera(this.rows, this.columns, this.hFovDeg, lookFrom, lookAt, lookUp,
                                              aperture, focusDist);

            var hitables  = new List <Hitable>();
            var recOrigin = new Vec3(2f, -2, -2);
            var u         = new Vec3(0, 4, 0);
            var v         = new Vec3(-4, 0, 0);
            var material  = new Metal(new Vec3(0.1f, 0.1f, 0.3f), 0.0f);

            hitables.Add(new Rectangle(recOrigin, u, v, material));

            var sphere = new Sphere(new Vec3(0, 0, -1), 0.5f, new Metal(new Vec3(0.7f, 0.25f, 0), 0.1f));

            hitables.Add(sphere);
            sphere = new Sphere(new Vec3(1.3f, 0, -1), 0.5f, new Metal(new Vec3(0, 0.25f, 0.7f), 0.025f));
            hitables.Add(sphere);
            sphere = new Sphere(new Vec3(-1.3f, 0, -1), 0.5f, new Metal(new Vec3(0.1f, 0.8f, 0.3f), 0.05f));
            hitables.Add(sphere);
            this.world = new HitableList(hitables);
        }
Example #7
0
    void OnTriggerEnter2D(Collider2D other)
    {
        TankMovementScript tankScript = other.gameObject.GetComponent <TankMovementScript>();

        if (other.gameObject.tag == "Tank")
        {
            tankScript.HitByProjectile();
        }


        // resolve hit
        Hitable HitableComp  = other.gameObject.GetComponent <Hitable>();
        float   damageRemain = Ballisitcs.damage;

        if (HitableComp != null)
        {
            if (HitableComp.shield > damageRemain * Ballisitcs.shieldmod)
            {
                HitableComp.shield -= damageRemain * Ballisitcs.shieldmod;
            }
            else
            {
                float absorb = HitableComp.shield / Ballisitcs.shieldmod;
                HitableComp.shield = 0.0f;
                damageRemain      -= absorb;
            }


            if (HitableComp.armor > damageRemain * Ballisitcs.armormod)
            {
                HitableComp.armor -= damageRemain * Ballisitcs.armormod;
            }
            else
            {
                float absorb = HitableComp.armor / Ballisitcs.armormod;
                HitableComp.armor = 0.0f;
                damageRemain     -= absorb;
            }

            if (HitableComp.health > damageRemain * Ballisitcs.healthmod)
            {
                HitableComp.health -= damageRemain * Ballisitcs.healthmod;
            }
            else
            {
                if (other.gameObject.tag == "Tank")
                {
                    // Destroy tanks
                    tankScript.Destruction();
                }
                else
                {
                    Destroy(HitableComp.ObjToRemove);
                }
            }

            // Destroy Projectile
            Destroy(transform.root.gameObject);
        }
    }
Example #8
0
    // Override: Monobehaviour::OnControllerColliderHit()
    public void OnControllerColliderHit(ControllerColliderHit _hit)
    {
        // Local variables
        Hitable hitable = _hit.gameObject.GetComponent <Hitable>();

        // Hitable?
        if (hitable == null)
        {
            return;
        }

        // Hit from above?
        if (Vector3.Dot(_hit.normal, Vector3.down) >= GameConfig.ENEMY_PLAYER_ABOVE_FACTOR)
        {
            // Player?
            if (hitable is Player)
            {
                (hitable as Player).jumpingFromAnEnemy();
            }
            onHit(hitable);
            return;
        }

        // Notify
        hitable.onHit(this);
    }
    Color color(zRay r, Hitable world, int depth)
    {
        hit_record rec = new hit_record();

        if (world.hit(r, 0.0f, float.MaxValue, ref rec))
        {
            zRay    scattered   = new zRay();
            Vector3 attenuation = Vector3.zero;
            Color   emitted     = rec.mat.emitted();
            if (depth < maxDepth && rec.mat.scatter(r, rec, ref attenuation, ref scattered))
            {
                return(emitted + new Color(attenuation.x, attenuation.y, attenuation.z) * color(scattered, world, depth + 1));
            }
            else
            {
                return(emitted);
            }
        }
        else
        {
            //float t = 0.5f * (r.direction.normalized.y + 1f);
            //return (1f - t) * Color.white + t * new Color(0.5f, 0.7f, 1.0f);
            return(env_Color);
        }
    }
Example #10
0
        public BvhNode(List <Hitable> list, double time0, double time1)
        {
            int axis = (int)(FastRandom.RandomDouble() * 3);

            list.Sort(compareHitable(axis));

            if (list.Count == 1)
            {
                left = right = list[0];
            }
            else if (list.Count == 2)
            {
                left  = list[0];
                right = list[1];
            }
            else
            {
                left  = new BvhNode(list.GetRange(0, list.Count / 2), time0, time1);
                right = new BvhNode(list.GetRange(list.Count / 2, list.Count - list.Count / 2), time0, time1);
            }

            AxisAlignedBoundingBox boxLeft, boxRight;

            if (!left.BoundingBox(time0, time1, out boxLeft) || !right.BoundingBox(time0, time1, out boxRight))
            {
                throw new Exception("No Bounding Box in BvhNode Constructor.");
            }

            box = AxisAlignedBoundingBox.SurroundingBox(boxLeft, boxRight);
        }
Example #11
0
    private void OnTriggerEnter(Collider other)
    {
        if (!m_Active)
        {
            return;
        }

        Hitable h_other = other.GetComponent <Hitable>();

        if (h_other)
        {
            if (m_TagTarget != null || m_TagTarget != "")
            {
                if (h_other.m_ObjectOwner != m_ObjectOwner && h_other.m_ObjectOwner.tag == m_TagTarget)
                {
                    print("hit " + other.name + "!");
                    h_other.takeHit(m_power, this);
                    m_Active = false;
                }
            }
            else
            if (h_other.m_ObjectOwner != m_ObjectOwner)
            {
                print("hit " + other.name + "!");
                h_other.takeHit(m_power, this);
                m_Active = false;
            }
        }
    }
Example #12
0
        public static void DoRaycastInThread(Hitable world, MotionBlurRayCamera camera,
                                             int i, int j, int nx, float ny, int ns, Vector3[,] img, ManualResetEvent mre, System.Random seed)
        {
            Vector3 color = Vector3.zero;

            for (int k = 0; k < ns; ++k)
            {
                float u = (float)(i + RandomFloat01(seed)) / (float)(nx);
                float v = (float)(j + RandomFloat01(seed)) / (float)(ny);
                Ray   r = camera.GetRay(u, v, seed);
                color += RayCast(r, world, seed, 0);
            }
            color   = color / (float)(ns);
            color.x = Mathf.Sqrt(color.x);
            color.y = Mathf.Sqrt(color.y);
            color.z = Mathf.Sqrt(color.z);

            //lock (img)
            {
                img[i, j] = color;
            }

            if (Interlocked.Decrement(ref myThreadCount) == 0)
            {
                mre.Set();
            }
        }
Example #13
0
 public void AddHitable(Hitable hitable)
 {
     if (!this.hitLists.Contains(hitable))
     {
         this.hitLists.Add(hitable);
     }
 }
Example #14
0
        static Hitable CornellBox()
        {
            var      red      = new Lambertian(new vec3(0.65f, 0.05f, 0.05f));
            var      white    = new Lambertian(new vec3(0.73f, 0.73f, 0.73f));
            var      green    = new Lambertian(new vec3(0.12f, 0.45f, 0.15f));
            Material aluminum = new Metal(new vec3(0.8f, 0.85f, 0.88f), 0.3f);

            var light = new DiffuseLight(new SolidTexture(new vec3(15, 15, 15)));
            int i     = 0;

            Hitable[] hitables = new Hitable[8];
            hitables[i++] = new YZRect(555, 0, 555, 0, 555, green, true);
            hitables[i++] = new YZRect(0, 0, 555, 0, 555, red);
            var lightRect = new XZRect(554, 213, 343, 227, 332, light, true);

            hitables[i++] = lightRect;
            hitables[i++] = new XZRect(0, 0, 555, 0, 555, aluminum);
            hitables[i++] = new XZRect(555, 0, 555, 0, 555, white, true);
            hitables[i++] = new XYRect(555, 0, 555, 0, 555, white, true);

            //Hitable box = new Box(new vec3(0, 0, 0), new vec3(165, 165, 165), white);
            //box = new Tranlate(new RotateY(box, -18), new vec3(130, 0, 65));
            //hitables[i++] = box;
            Sphere sp = new Sphere(new vec3(190, 90.5f, 190), 90f, new Dieletric(1.6f));

            hitables[i++] = sp;
            Hitable box2 = new Box(new vec3(0, 0, 0), new vec3(165, 330, 165), white);

            box2          = new Tranlate(new RotateY(box2, 15), new vec3(265, 0, 295));
            hitables[i++] = box2;
            _lightPDf     = new LightPDF(lightRect);
            _spherePDF    = new SpherePDF(sp);
            return(new HitList(hitables.Where(p => p != null).ToArray()));
        }
Example #15
0
        public BVHNode(Hitable[] list, int low, int high, float t0, float t1)
        {
            if (low < 0 || high > list.Length)
            {
                throw new Exception("BVHNode Contruction error low <0 || high >list.Length");
            }
            int length = high - low;

            if (length <= 0)
            {
                throw new Exception("BVHNode Contruction error low >= high");
            }

            if (length == 1)
            {
                _left = _right = list[low];
                _box  = _left.BoundVolume(t0, t1);
            }
            else if (length == 2)
            {
                _left  = list[low];
                _right = list[low + 1];
                _box   = AABB.SurroundingBox(_left.BoundVolume(t0, t1), _right.BoundVolume(t0, t1));
            }
            else
            {
                Array.Sort(list, low, high - low, new BVHComparer((int)(3 * Exten.rand01())));
                int mid = (low + high) / 2;
                _left  = new BVHNode(list, low, mid, t0, t1);
                _right = new BVHNode(list, mid, high, t0, t1);
                _box   = AABB.SurroundingBox(_left.BoundVolume(t0, t1), _right.BoundVolume(t0, t1));
            }
        }
Example #16
0
    // Override: Monobehaviour::OnControllerColliderHit()
    public void OnControllerColliderHit(ControllerColliderHit _hit)
    {
        // Local variables
        Hitable hitable = _hit.gameObject.GetComponent <Hitable>();

        // Collided sidewards?
        if ((m_controller.collisionFlags & CollisionFlags.CollidedSides) != 0 && hitable is Projectile == false)
        {
            m_needTurnAround = true;
            //m_controller.Move(Vector3.right * -m_direction * m_worldScale.x * 0.05f);
            //turnAround();
        }

        // Hitable?
        if (hitable == null)
        {
            return;
        }

        // Hit from above?
        if (Vector3.Dot(_hit.normal, Vector3.down) >= GameConfig.ENEMY_PLAYER_ABOVE_FACTOR)
        {
            // Player?
            if (hitable is Player)
            {
                (hitable as Player).jumpingFromAnEnemy();
            }
            onHit(hitable);
            return;
        }

        // Notify
        hitable.onHit(this);
    }
Example #17
0
            static int CmpBVH(Hitable left, Hitable right, int idx)
            {
                var ab1 = left.BoundVolume(0, 1);
                var ab2 = right.BoundVolume(0, 1);

                return((int)(ab1._max[idx] - ab2._min[idx]));
            }
        public static Vector3 RayCast(Ray ray, Hitable world, int depth)
        {
            Hit_record rec;
            float      min = 0;
            float      max = float.MaxValue;

            if (world.Hit(ray, ref min, ref max, out rec))
            {
                Ray     scattered   = new Ray();
                Vector3 attenuation = Vector3.one;

                if (depth < MaxDepth && rec.mat.Scatter(ref ray, ref rec, ref attenuation, ref scattered))
                {
                    var color = RayCast(scattered, world, depth + 1);
                    attenuation.x *= color.x;
                    attenuation.y *= color.y;
                    attenuation.z *= color.z;
                    return(attenuation);
                }
                else
                {
                    return(Vector3.zero);
                }
            }
            else
            {
                Vector3 unit_direction = ray.direction.normalized;
                float   t = 0.5f * (unit_direction.y + 1.0f);
                return(Vector3.Lerp(topColor, bottomColor, t));
            }
        }
Example #19
0
    private void OnTriggerEnter(Collider other)
    {
        Hitable hit       = other.GetComponent <Hitable>();
        bool    canDamage = true;

        if (hit)
        {
            if (cantDamage.Count > 0)
            {
                foreach (Hitable alreadyHit in cantDamage)
                {
                    if (hit == alreadyHit)
                    {
                        canDamage = false;
                    }
                }
            }

            if (canDamage)
            {
                hit.HitMe(dmg, teamNo, true);
                cantDamage.Add(hit);
            }
        }
    }
    Color color(Ray r, Hitable world, int depth)
    {
        //RaycastHit rh = new RaycastHit();
        HitRecord hr = new HitRecord();

        if (world.Hit(r, t_min, t_max, ref hr))
        {
            Ray   scattered;
            Color attenuation;
            if (depth < 50 && hr.material.scatter(r, ref hr, out attenuation, out scattered))
            {
                return(attenuation * color(scattered, world, depth + 1));
            }
            else
            {
                return(Color.black);
            }
        }
        else
        {
            Vector3 unit_direction = r.direction.normalized;
            float   t = 0.5f * (unit_direction.y + 1f);
            return(Color.Lerp(c1, c2, t));
        }
    }
Example #21
0
        public RotateY(Hitable hitable, float angle)
        {
            _inner = hitable;
            float radians = (MathF.PI / 180.0f) * angle;

            sin_theta = MathF.Sin(radians);
            cos_theta = MathF.Cos(radians);
        }
Example #22
0
        public void Run()
        {
            Stopwatch sw = new Stopwatch();

            sw.Start();
            int nx = 200;
            int ny = 100;
            // link to ppm viewer
            // http://www.cs.rhodes.edu/welshc/COMP141_F16/ppmReader.html

            Vector3 lowerLeftCorner = new Vector3(-2.0f, -1.0f, -1.0f);
            Vector3 horizontal      = new Vector3(4.0f, 0.0f, 0.0f);
            Vector3 vertical        = new Vector3(0.0f, 2.0f, 0.0f);
            Vector3 origin          = new Vector3(0.0f, 0.0f, 0.0f);

            Hitable[] objList = new Hitable[2];
            objList[0] = new Sphere(new Vector3(0, 0, -1), 0.5f);
            objList[1] = new Sphere(new Vector3(0, -100.5f, -1), 100);

            HitableList world = new HitableList(objList);

            string filePath = @"d:\DEV_stuff\DEV\Sanbox\RayTracingSanbox\RayTracingInWeek\Output";

            if (File.Exists(Path.Combine(filePath, "texture.ppm")))
            {
                File.Delete(Path.Combine(filePath, "texture.ppm"));
                Console.WriteLine("Deleted file: " + Path.Combine(filePath, "texture.ppm"));
            }

            using (StreamWriter outputFile = new StreamWriter(Path.Combine(filePath, "texture.ppm"), true))
            {
                outputFile.Write("P3\n" + nx + " " + ny + "\n255\n");
                //Console.Write("P3\n" + nx + " " + ny + "\n255\n");
                for (int j = ny - 1; j >= 0; j--)
                {
                    for (int i = 0; i < nx; i++)
                    {
                        float   u   = (float)i / (float)nx;
                        float   v   = (float)j / (float)ny;
                        Ray     r   = new Ray(origin, lowerLeftCorner + u * horizontal + v * vertical);
                        Vector3 p   = r.PointAtParameter(2);
                        Vector3 col = Color(r, world);

                        int ir = (int)(255.99 * col.X);
                        int ig = (int)(255.99 * col.Y);
                        int ib = (int)(255.99 * col.Z);
                        outputFile.Write(ir + " " + ig + " " + ib + "\n");
                        //Console.Write(ir + " " + ig + " " + ib + "\n");
                    }
                }
            }

            sw.Stop();

            Console.WriteLine("Time to output image with StreamWriter : " + sw.ElapsedMilliseconds.ToString() + " ms");
            Console.WriteLine("Press enter to close...");
            Console.ReadLine();
        }
Example #23
0
    protected new void Awake()
    {
        base.Awake();
        damagePerLevel = new int[] { 10, 15, 30 };

        hit        = GetComponent <Hitable>();
        hit.hits   = new System.Type[] { typeof(PlayerCanon), typeof(MineralMiner) };
        hit.damage = damagePerLevel[level];
    }
Example #24
0
    protected new void Awake()
    {
        base.Awake();
        damagePerLevel = new int[]{10,15,30};

        hit = GetComponent<Hitable>();
        hit.hits = new System.Type[]{ typeof(PlayerCanon), typeof(MineralMiner) };
        hit.damage = damagePerLevel[level];
    }
Example #25
0
        //class Scene : Hitable
        //{
        //    AABB _box;
        //    Hitable _inner;
        //    public Scene(HitList l,float t0,float t1)
        //    {
        //        _box = l.BoundVolume(t0,t1);
        //        _inner = l;
        //    }
        //    public AABB BoundVolume(float t0, float t1)
        //    {
        //        return _box;
        //    }

        //    public bool Hit(Ray ray, float min, float max, out HitRecord r)
        //    {
        //        r = null;
        //        if(!_box.Hit(ray,min,max))
        //        {
        //            return false;
        //        }
        //        return _inner.Hit(ray, min, max, out r);
        //    }
        //}

        static Hitable random_scene(bool bvh)
        {
            int n = 500;

            Hitable[] list  = new Hitable[n + 1];
            vec3      black = new vec3(0.1f, 0.1f, 0.2f);
            vec3      white = new vec3(1f, 1f, 1f);
            var       check = new CheckTexture(black, white);
            var       noise = new NoiseTexture(new Noise());

            list[0] = new Sphere(new vec3(0, -1000, 0), 1000, new Lambertian(noise));
            int i = 1;

            //for (int a = -11; a < 11; a++)
            //{
            //    for (int b = -11; b < 11; b++)
            //    {
            //        float choose_mat = Exten.rand01();
            //        var center = new vec3(a + 0.9f * Exten.rand01(), 0.2f, b + 0.9f * Exten.rand01());
            //        if ((center - new vec3(4f, 0.2f, 0f)).length() > 0.9f)
            //        {
            //            if (choose_mat < 0.8)
            //            {  // diffuse
            //                var color = new vec3(Exten.rand01() * Exten.rand01(), Exten.rand01() * Exten.rand01(), Exten.rand01() * Exten.rand01());

            //                var mat = new Lambertian(new SolidTexture(color));
            //                list[i++] = new Sphere(center, 0.2f,mat);
            //            }
            //            else if (choose_mat < 0.95f)
            //            { // metal
            //                list[i++] = new Sphere(center, 0.2f,
            //                        new Metal(new vec3(0.5f * (1 + drand48()), 0.5f * (1 + drand48()), 0.5f * (1 + drand48())), 0.5f * drand48()));
            //            }
            //            else
            //            {  // glass
            //                list[i++] = new Sphere(center, 0.2f, new Dieletric(1.5f));
            //            }
            //        }
            //    }
            //}

            //list[i++] = new Sphere(new vec3(2, 1, 0), 1.0f, new Dieletric(1.3f));
            //list[i++] = new Sphere(new vec3(-3, 1, 2), 1.0f, new Metal(new vec3(0.4f, 0.2f, 0.1f),0.2f));
            list[i++] = new Sphere(new vec3(4, 1, 0), 1.0f, new Lambertian(noise));
            //list[i++] = new Sphere(new vec3(4, 1, -0.5f), 1.0f, new Metal(new vec3(0.7f, 0.6f, 0.5f), 0.0f));
            var finalList = list.Where(p => p != null).ToArray();

            if (!bvh)
            {
                return(new HitList(finalList));
            }
            else
            {
                //Array.Sort(finalList, new BVHNode.BVHComparer(0));
                return(new BVHNode(finalList, 0, finalList.Length, 0, 1));
            }
        }
Example #26
0
    protected override bool DamagePickup(Hitable objHit)
    {
        bool dead = hp.decreaseHp((int)objHit.customValue);

        if (dead)
        {
            Global.instance.FailLevel();
        }
        return(true);
    }
Example #27
0
    protected override bool DamagePickup(Hitable objHit)
    {
        bool dead = hp.decreaseHp((int)objHit.customValue);

        if (dead)
        {
            //todo
        }
        return(true);
    }
Example #28
0
        public BVHNode(List <Hitable> scene, int n = -1)
        {
            if (n == -1)
            {
                n = scene.Count;
            }

            var axis = (int)(Random.Value * 3.0f);

            if (axis == 0)
            {
                scene.Sort(BoxXCompare);
            }
            else if (axis == 1)
            {
                scene.Sort(BoxYCompare);
            }
            else
            {
                scene.Sort(BoxZCompare);
            }

            if (n == 1)
            {
                m_Left = m_Right = scene[0];
            }
            else if (n == 2)
            {
                m_Left  = scene[0];
                m_Right = scene[1];
            }
            else
            {
                m_Left = new BVHNode(scene, n / 2);

                var list = new List <Hitable>();
                for (var i = n / 2; i < scene.Count; i++)
                {
                    list.Add(scene[i]);
                }

                m_Right = new BVHNode(list, n - n / 2);
            }

            var left  = new AABB();
            var right = new AABB();

            if (!m_Left.BoundingBox(ref left) || !m_Right.BoundingBox(ref right))
            {
                throw new System.Exception("No bounding box in bvh_node constructor");
            }

            m_BoundingBox = AABB.SurroundingBox(ref left, ref right);
        }
Example #29
0
    private Vector3D GetColor(Ray r, HitableList world, Hitable lightShape, int depth)
    {
        HitRecord hRec;

        /*这里的0.001不能改为0,当tmin设0的时候会导致,遍历hitlist时候,ray的t求解出来是0,
         * hit的时候全走了else,导致递归到50层的时候,最后return的是0,* attenuation结果还是0。
         * 距离越远,散射用到random_in_unit_sphere生成的ray误差越大
         */
        if (world.Hit(r, 0.001f, float.MaxValue, out hRec))
        {
            ScatterRecord sRec;
            Vector3D      emitted = hRec.matPtr.Emitted(r, hRec, hRec.u, hRec.v, hRec.p);
            if (depth < 50 && hRec.matPtr.Scatter(r, hRec, out sRec))
            {
                if (sRec.isSpecular)
                {
                    Vector3D c = GetColor(sRec.specularRay, world, lightShape, depth + 1);
                    return(new Vector3D(sRec.attenuation.X * c.X, sRec.attenuation.Y * c.Y, sRec.attenuation.Z * c.Z));
                }
                PDF p;
                if (lightShape != null)
                {
                    HitablePDF p0 = new HitablePDF(lightShape, hRec.p);
                    p = new MixturePDF(p0, sRec.pdfPtr);
                    ((MixturePDF)p).MixRatio = scene.MixRatio;
                }
                else
                {
                    p = sRec.pdfPtr;
                }
                //CosinePDF p = new CosinePDF(hRec.normal);
                Ray      scattered = new Ray(hRec.p, p.Generate(), r.Time);
                float    pdfVal    = p.Value(scattered.Direction);
                Vector3D color     = GetColor(scattered, world, lightShape, depth + 1);  //每次光线衰减之后深度加一
                return(emitted + hRec.matPtr.ScatteringPDF(r, hRec, scattered)
                       * new Vector3D(sRec.attenuation.X * color.X, sRec.attenuation.Y
                                      * color.Y, sRec.attenuation.Z * color.Z) / pdfVal);
            }
            else
            {
                return(emitted);
            }
        }
        else
        {
            if (isSky)
            {
                Vector3D unitDirection = r.Direction.UnitVector();
                float    t             = 0.5f * (unitDirection.Y + 1f);
                return((1 - t) * new Vector3D(1, 1, 1) + t * new Vector3D(0.5f, 0.7f, 1));
            }
            return(new Vector3D(0, 0, 0));
        }
    }
Example #30
0
        private int BoxZCompare(Hitable a, Hitable b)
        {
            BoundingBox aBox = null;
            BoundingBox bBox = null;

            if (!a.GetBoundingBox(0, 0, ref aBox) || !b.GetBoundingBox(0, 0, ref bBox))
            {
                throw new ArgumentException("No bounding box in BVHNode comparer z");
            }
            return(aBox.Min.Z < bBox.Min.Z ? -1 : 1);
        }
    public BVHNode(List <Hitable> l, int n, float time0, float time1)
    {
        int Compare(Hitable a, Hitable b, int i)
        {
            AABB boxL = new AABB();
            AABB boxR = new AABB();

            if (!a.BoundingBox(0, 0, out boxL) || !b.BoundingBox(0, 0, out boxR))
            {
                throw new Exception();
            }
            return(boxL.Min[i] - boxR.Min[i] < 0 ? -1 : 1);
        }

        List <Hitable> SplitList(List <Hitable> source, int startIndex, int endIndex)
        {
            List <Hitable> result = new List <Hitable>();

            for (int i = 0; i <= endIndex - startIndex; i++)
            {
                result.Add(source[i + startIndex]);
            }
            return(result);
        }

        int method = (int)(3 * Mathf.Randomfloat());

        l.Sort((a, b) => Compare(a, b, method));
        switch (n)
        {
        case 1:
            left = right = l[0];
            break;

        case 2:
            left  = l[0];
            right = l[1];
            break;

        default:
            left  = new BVHNode(SplitList(l, 0, n / 2 - 1), n / 2, time0, time1);
            right = new BVHNode(SplitList(l, n / 2, n - 1), n - n / 2, time0, time1);
            break;
        }
        AABB boxLeft  = new AABB();
        AABB boxRight = new AABB();

        if (!left.BoundingBox(time0, time1, out boxLeft) ||
            !right.BoundingBox(time0, time1, out boxRight))
        {
            throw new Exception();
        }
        box = SurroundingBox(boxLeft, boxRight);
    }
Example #32
0
 void attack()
 {
     if (target != null ) {
         if (null==hit){
             hit = GetComponentInChildren<Hitable>();
             hit.keepAlive = true;
             hit.hits = new System.Type[]{ typeof(PlayerCanon), typeof(MineralMiner), typeof(AutoCanon) };
             hit.damage = damagePerLevel[level];
         }
         hit.enabled = true;
         animator.SetTrigger("attack");
     } else {
         attacking = false;
         CancelInvoke("attack");
         hit.enabled = false;
     }
 }