private void IterInitMirror(Transform right, Transform left_Parent)
    {
        GameObject right_obj = right.gameObject;
        Transform  left      = null;
        string     left_name = MirrorBehavior.SwitchName(right_obj.name);

        if (!left_Parent)
        {
            GameObject left_obj = GameObject.Find(left_name);
            left = left_obj ? left_obj.transform : null;
        }
        else
        {
            left = left_Parent.Find(left_name);
        }
        if (!left)
        {
            GameObject left_obj = GameObject.Instantiate(right_obj);
            left        = left_obj.transform;
            left.parent = left_Parent;

            left_obj.name = left_name;
            ResetMirrorData(left_obj, right_obj, false);
        }
        else
        {
            ResetMirrorData(left.gameObject, right_obj, false);
        }

        for (int idx = 0; idx < right_obj.transform.childCount; ++idx)
        {
            IterInitMirror(right_obj.transform.GetChild(idx), left);
        }
    }
	// Update is called once per frame
	void Update () 
	{
		// figure out current location and angle
		Vector3 beamDir = !useReflection ? (Quaternion.Euler(angleOffset) * lightSource.transform.up).normalized : reflectionAngle;
		Vector3 firstPoint = lightSource.transform.position; //might get rid of this Vector3, just get it from lineRenderer
		Vector3 lastPoint = lightSource.transform.position + beamDir * beamLength;

		// check collisions with all obstacles
		List<GameObject> collisionList = new List<GameObject>();
		List<float> distList = new List<float> ();
		for (int i = 0; i < obstacles.Count; i++) 
		{
			Vector3 obsVec = obstacles [i].transform.position - firstPoint;
			float dotProduct = Vector3.Dot (obsVec, beamDir);
			if (dotProduct > 0) 
			{
				Vector3 lineProj = firstPoint + dotProduct * beamDir;
				float distFromBeam = (lineProj - obstacles [i].transform.position).magnitude;
				if (distFromBeam <= beamWidth && obsVec.magnitude <= beamLength) //later, add in obstacle radius as well
				{
					// it's a hit! add it to the list
					collisionList.Add (obstacles [i]);
					distList.Add (obsVec.magnitude);
				}
			}
		}

		GameObject closestCollision = null;
		float closestDist = beamLength;
		for (int i = 0; i < collisionList.Count; i++) 
		{
			if (distList [i] < closestDist) 
			{
				closestCollision = collisionList [i];
				closestDist = distList [i];
			}
		}

		if (closestCollision) 
		{
			// perform hit calcs
			lastPoint = lightSource.transform.position + beamDir * closestDist;
			MirrorBehavior closestMirror = closestCollision.GetComponent<MirrorBehavior> ();
			if (closestMirror) 
			{
				closestMirror.HitByLight (firstPoint);
			}
		}

		lightBeam.SetPosition (0, firstPoint);
		lightBeam.SetPosition (1, lastPoint);
	}
    private void InitAllMirror()
    {
        GameObject right = GameObject.Find("root_right");

        right.GetComponent <MirrorBehavior>().SetMirror(true);
        foreach (Transform g in right.transform)
        {
            MirrorBehavior m = g.GetComponent <MirrorBehavior>();
            if (m)
            {
                m.SetMirror(true);
            }
        }

        IterInitMirror(right.transform, null);
    }
    public void RegisterMirror(MirrorBehavior m)
    {
        foreach (MirrorBehavior mb in m_mirrors)
        {
            if (mb == m)
            {
                return;
            }
        }

        if (m_count == m_capacity)
        {
            m_capacity <<= 2;
            MirrorBehavior[] new_mirrors = new MirrorBehavior[m_capacity];
            m_mirrors.CopyTo(new_mirrors, 0);
            m_mirrors = new_mirrors;
        }
        m_mirrors[m_count] = m;
        m_count++;
    }
 public void UnRegisterMirror(MirrorBehavior m)
 {
     for (int i = 0; i < m_count; i++)
     {
         if (m_mirrors[i] == m)
         {
             if (i == m_count - 1)
             {
                 m_mirrors[i] = null;
             }
             else
             {
                 m_mirrors[i]           = m_mirrors[m_count - 1];
                 m_mirrors[m_count - 1] = null;
             }
             m_count--;
             return;
         }
     }
 }
    private void ResetMirrorData(GameObject left, GameObject right, bool is_right)
    {
        Vector3 mirror_map = new Vector3(-1, 1, 1);

        Vector3 pos = right.transform.position;

        pos.Scale(mirror_map);
        left.transform.position = pos;

        Vector3 scale = right.transform.localScale;

        scale.Scale(mirror_map);
        left.transform.localScale = scale;

        left.GetComponent <MirrorBehavior>().SetMirror(is_right);
        foreach (Transform g in left.transform)
        {
            MirrorBehavior m = g.GetComponent <MirrorBehavior>();
            if (m)
            {
                m.SetMirror(is_right);
            }
        }
    }