private SphereObject findHittedSphere(List <SphereObject> sphereLst, Ray ray, out double closest,
                                              double min = 0,
                                              double max = double.PositiveInfinity)
        {
            closest = Double.PositiveInfinity;
            SphereObject closestSphere = null;

            foreach (var sphere in sphereLst)
            {
                if (hit_sphere(sphere.transform.Position, sphere.radius, ray, out float t1, out float t2))
                {
                    if (t1 >= min && t1 <= max && t1 <= closest)
                    {
                        closest       = t1;
                        closestSphere = sphere;
                    }
                    if (t2 >= min && t2 <= max && t2 <= closest)
                    {
                        closest       = t2;
                        closestSphere = sphere;
                    }
                }
            }
            return(closestSphere);
        }
        private List <IProgramSceneObject> getSceneObjects(Google.Protobuf.Collections.RepeatedField <SceneObject> sceneObjects)
        {
            List <IProgramSceneObject> objects = new List <IProgramSceneObject>();

            foreach (var obj in sceneObjects)
            {
                Transform transform = new Transform();
                if (obj.Transform.ToString().Length != 0)
                {
                    transform.Position = new Vector3((float)obj.Transform.Position.X, (float)obj.Transform.Position.Y, (float)obj.Transform.Position.Z);
                    transform.Rotation = new Vector3((float)obj.Transform.Rotation.X, (float)obj.Transform.Rotation.Y, (float)obj.Transform.Rotation.Z);
                    transform.Scale    = new Vector3((float)obj.Transform.Scale.X, (float)obj.Transform.Scale.Y, (float)obj.Transform.Scale.Z);
                }


                IMaterial material = null;
                if (obj.Material.LambertReflection != null)
                {
                    Vector3 color = new Vector3((float)obj.Material.LambertReflection.Color.R,
                                                (float)obj.Material.LambertReflection.Color.G,
                                                (float)obj.Material.LambertReflection.Color.B);
                    material = new LambertMaterial(color);
                }
                else if (obj.Material.SpecularReflection.ToString().Length != 0)
                {
                    material = new SpecReflMaterial((float)obj.Material.SpecularReflection.Eta);
                }

                if (obj.MeshedObject != null)
                {
                    MeshObject newSceneObj = new MeshObject();
                    newSceneObj.material  = material;
                    newSceneObj.transform = transform;

                    newSceneObj.filePath = obj.MeshedObject.Reference;
                    objects.Add(newSceneObj);
                }
                else if (obj.Sphere.ToString().Length != 0)
                {
                    SphereObject newSceneObj = new SphereObject();
                    newSceneObj.material  = material;
                    newSceneObj.transform = transform;

                    newSceneObj.radius = (float)obj.Sphere.Radius;
                    objects.Add(newSceneObj);
                }
            }
            return(objects);
        }