//Helper function to draw OBB using Gizmos class
    static public void Draw_OBB(Octree.OBB obb)
    {
        Vector3[] Positions = new Vector3[8];
        Vector3   v         = new Vector3(obb.e.x * obb.s.x, obb.e.y * obb.s.y, obb.e.z * obb.s.z);

        Positions[0] = obb.c + (((obb.x - obb.c) * v.x) + ((obb.y - obb.c) * v.y) + ((obb.z - obb.c) * v.z));
        Positions[1] = obb.c + (((obb.c - obb.x) * v.x) + ((obb.y - obb.c) * v.y) + ((obb.z - obb.c) * v.z));
        Positions[2] = obb.c + (((obb.x - obb.c) * v.x) + ((obb.c - obb.y) * v.y) + ((obb.z - obb.c) * v.z));
        Positions[3] = obb.c + (((obb.c - obb.x) * v.x) + ((obb.c - obb.y) * v.y) + ((obb.z - obb.c) * v.z));

        Positions[4] = obb.c + (((obb.x - obb.c) * v.x) + ((obb.y - obb.c) * v.y) + ((obb.c - obb.z) * v.z));
        Positions[5] = obb.c + (((obb.c - obb.x) * v.x) + ((obb.y - obb.c) * v.y) + ((obb.c - obb.z) * v.z));
        Positions[6] = obb.c + (((obb.x - obb.c) * v.x) + ((obb.c - obb.y) * v.y) + ((obb.c - obb.z) * v.z));
        Positions[7] = obb.c + (((obb.c - obb.x) * v.x) + ((obb.c - obb.y) * v.y) + ((obb.c - obb.z) * v.z));

        Gizmos.color = Color.green;
        Gizmos.DrawLine(Positions[0], Positions[1]);
        Gizmos.DrawLine(Positions[1], Positions[3]);
        Gizmos.DrawLine(Positions[3], Positions[2]);
        Gizmos.DrawLine(Positions[2], Positions[0]);

        Gizmos.DrawLine(Positions[4], Positions[5]);
        Gizmos.DrawLine(Positions[5], Positions[7]);
        Gizmos.DrawLine(Positions[7], Positions[6]);
        Gizmos.DrawLine(Positions[6], Positions[4]);
        //Connectors
        Gizmos.DrawLine(Positions[0], Positions[4]);
        Gizmos.DrawLine(Positions[1], Positions[5]);
        Gizmos.DrawLine(Positions[3], Positions[7]);
        Gizmos.DrawLine(Positions[2], Positions[6]);
    }
    //=====================================================================================================================
    // Helper functions to Generate the Octree and then Pack it
    //=====================================================================================================================

    //send all scene Geometry(OBBs) to the Octree class
    void StreamGeometry()
    {
        MeshRenderer[] allMesh = FindObjectsOfType(typeof(MeshRenderer)) as MeshRenderer[];

        Octree.AABB volume = new Octree.AABB(); //this is the volume of the Octree Root node
        Vector3     p      = transform.position;

        volume.Max.x = p.x + VoxelSize;
        volume.Max.y = p.y + VoxelSize;
        volume.Max.z = p.z + VoxelSize;
        volume.Min.x = p.x - VoxelSize;
        volume.Min.y = p.y - VoxelSize;
        volume.Min.z = p.z - VoxelSize;

        //All the AABBs
        for (int i = 0; i < allMesh.Length; ++i)
        {
            if (allMesh[i].enabled == false)
            {
                continue;
            }

            //world position bounds
            Octree.AABB meshAABB = new Octree.AABB();
            meshAABB.Max = allMesh[i].bounds.max;
            meshAABB.Min = allMesh[i].bounds.min;

            if (IsInOctree(meshAABB, volume))
            {
                //Now Because Unity uses AABBs for all its bounds we first have to construct our own OBBs
                Octree.OBB obb = new Octree.OBB();

                Vector3 c = allMesh[i].bounds.center;
                Mesh    m = allMesh[i].gameObject.GetComponent <MeshFilter>().sharedMesh;

                obb.c = c;
                obb.e = m.bounds.extents;
                obb.s = allMesh[i].transform.localScale;

                //if it's a sphere use AABB instead
                if (m == SphereExample)
                {
                    obb.x = c + Vector3.right;
                    obb.y = c + Vector3.up;
                    obb.z = c + Vector3.forward;
                }
                else
                {
                    obb.x = c + allMesh[i].transform.right;
                    obb.y = c + allMesh[i].transform.up;
                    obb.z = c + allMesh[i].transform.forward;
                }

                Octree.All_OBBs.Add(obb);
            }
        }
    }
    // Use this for initialization
    void Awake()
    {
        meshRenderer = GetComponent <MeshRenderer>();
        meshFilter   = GetComponent <MeshFilter>();

        obb = new Octree.OBB();

        if (aabb == null)
        {
            aabb     = new Octree.AABB();
            aabb.Min = new Vector3(-size, -size, -size);
            aabb.Max = new Vector3(size, size, size);
        }
    }