private void buildHierarchy(HierarchyNode nodeParent, TreeViewItem treeItem, 
            List<HierarchyMesh> meshes, List<HierarchyLight> lights)
        {
            foreach (TreeViewItem tvi in treeItem.Items)
            {
                if (tvi.HasItems)
                {
                    HierarchyNode hn = new HierarchyNode(tvi.Header.ToString());
                    //Console.WriteLine("nazwa nodea " + tvi.Header.ToString());
                    buildHierarchy(hn, tvi, meshes, lights);
                    //Console.WriteLine("budujemy hierarchie - node :" + hn.name.ToString());
                    nodeParent.hObjects.Add(hn);
                }
                else //mesh || light
                {
                    char[] delimiterChars = { '_' };
                    string[] words = tvi.Name.Split(delimiterChars);
                    if (words[0].Equals("mesh"))  //mesh
                    {
                        HierarchyMesh hm = new HierarchyMesh(tvi.Header.ToString());
                        foreach (HierarchyMesh hmesh in meshes)
                        {
                            if (Convert.ToInt32(words[1]) == (int)hmesh.triangles.ElementAt(0))
                            {
                                hm = hmesh;
                                hm.name = tvi.Header.ToString();
                                break;
                            }
                        }
                        //Console.WriteLine("budujemy hierarchie - mesh :" + hm.name.ToString());
                        nodeParent.hObjects.Add(hm);
                    }
                    else //if(words[0].Equals("light"));
                    {

                        HierarchyLight hl = new HierarchyLight(tvi.Name.ToString(), (Convert.ToInt32(words[1])));
                        hl.name = tvi.Header.ToString();
                        nodeParent.hObjects.Add(hl);
                    }
                }
            }
        }
        //po modyfikacjach w panelu hierarchii "odświeżamy" hierarchię sceny
        private void refreshHierarchy()
        {
            Hierarchy hierarchy = new Hierarchy();

            if (((TreeViewItem)treeView1.Items.GetItemAt(0)).HasItems)
            {
                List<HierarchyMesh> meshes = currScene.hierarchy.GetAllMeshes();
                List<HierarchyLight> lights = currScene.hierarchy.GetAllLights();
                foreach (TreeViewItem tvi in ((TreeViewItem)treeView1.Items.GetItemAt(0)).Items)
                {
                    if (tvi.HasItems)
                    {
                        HierarchyNode hn = new HierarchyNode(tvi.Header.ToString());
                        buildHierarchy(hn, tvi, meshes, lights);
                        hierarchy.objects.Add(hn);
                        //Console.WriteLine("budujemy hierarchie - node :" + hn.name.ToString());
                    }
                    else
                    {
                        char[] delimiterChars = { '_' };
                        string[] words = tvi.Name.Split(delimiterChars);
                        if (words[0].Equals("mesh"))
                        {
                            HierarchyMesh hm = new HierarchyMesh(tvi.Header.ToString());
                            foreach (HierarchyMesh hmesh in meshes)
                            {
                                if (Convert.ToInt32(words[1]) == (int)hmesh.triangles.ElementAt(0))
                                {
                                    hm = hmesh;
                                    hm.name = tvi.Header.ToString();
                                    break;
                                }
                            }
                            //Console.WriteLine("budujemy hierarchie - mesh :" + hm.name.ToString());
                            hierarchy.objects.Add(hm);
                        }
                        else //if(words[0].Equals("light"));
                        {
                            HierarchyLight hl = new HierarchyLight(tvi.Header.ToString(), Convert.ToInt32(words[1]));
                            hl.name = tvi.Header.ToString();
                            hierarchy.objects.Add(hl);
                        }
                    }
                }
            }
            currScene.hierarchy = hierarchy;
        }
        private void addTreeViewNode(HierarchyNode hobj, TreeViewItem parent)
        {
            TreeViewItem node = new TreeViewItem();
            node.Header = hobj.ToString();
            node.IsSelected = false;
            List<HierarchyObject> treeList = new List<HierarchyObject>();
            foreach (HierarchyObject ho in hobj.hObjects)
            {
                if (ho is HierarchyMesh)
                    addTreeViewMesh((HierarchyMesh)ho, node);
                else if (ho is HierarchyLight)
                    addTreeViewLight((HierarchyLight)ho, node);
                else //hierarchyNode
                {
                    HierarchyNode hn = (HierarchyNode)ho;
                    if (hn.hObjects.Count == 0) //jeśli w między czasie zostały przeniesione/usunięte niższe warstwy
                    {
                        //hobj.hObjects.Remove(ho);
                        treeList.Add(ho);
                    }
                    else
                    {
                        addTreeViewNode((HierarchyNode)ho, node);
                    }
                }
            }
            foreach (HierarchyObject ho in treeList)
            {
                hobj.hObjects.Remove(ho);
            }

            parent.Items.Add(node);
        }
        private void SaveHierarchy(HierarchyNode node, List<string> text, uint level)
        {
            text.Add(InsertTabs(level) + "node_count " + node.hObjects.Count.ToString());

            foreach(HierarchyObject obj in node.hObjects)
            {
                text.Add(InsertTabs(level) + "");

                string type = "";
                if(obj is HierarchyNode)
                {
                    type = "Node";
                }
                else if(obj is HierarchyMesh)
                {
                    type = "Mesh";
                }
                else if(obj is HierarchyLight)
                {
                    type = "Light";
                }

                text.Add(InsertTabs(level) + "hier_type " + type);
                text.Add(InsertTabs(level) + "hier_name " + obj.name);

                if(obj is HierarchyMesh)
                {
                    text.Add(InsertTabs(level) + "triangle_count " + ((HierarchyMesh)obj).triangles.Count.ToString());

                    StringBuilder line = new StringBuilder();
                    foreach(uint triangle in ((HierarchyMesh)obj).triangles)
                    {
                        line.Append(triangle.ToString() + " ");
                    }
                    text.Add(InsertTabs(level) + line.ToString());
                }
                else if(obj is HierarchyLight)
                {
                    text.Add(InsertTabs(level) + "light_index " + ((HierarchyLight)obj).lightIndex);
                }
                else if(obj is HierarchyNode)
                {
                    SaveHierarchy((HierarchyNode)obj, text, level + 1);
                }
            }
        }
        //pozmienia hierarchię a później stworzy widok od nowa
        private void GrupujB_Click(object sender, RoutedEventArgs e)
        {
            if (currScene.selTriangles.Count > 1 && currScene.selLights.Count ==0)  //zaznaczone same meshe
            {
                HierarchyNode node = new HierarchyNode("Węzeł");
                Modeler.DialogBoxes.NameDialog newName = new NameDialog();
                string nodeName = "Węzeł";
                bool res = (bool)newName.Show("Podaj nazwę obiektu", nodeName);
                if (!res)
                    return;
                node.name = newName.Result;

                foreach (HierarchyMesh mesh in currScene.selTriangles)
                {
                    node.hObjects.Add(mesh);
                    deleteMesh((int)mesh.triangles.ElementAt(0), currScene.hierarchy.objects);
                }
                currScene.hierarchy.objects.Add(node);
                currScene.hierarchyChange = false;
                initializeTreeView();

                //sceneChange = true;
            }
            else if (currScene.selTriangles.Count == 0 && currScene.selLights.Count > 0) //zaznaczone same światła
            {
                HierarchyNode node = new HierarchyNode("Węzeł");
                List<HierarchyLight> lights = currScene.hierarchy.GetAllLights();

                foreach (int lightIndex in currScene.selLights)
                {
                    node.hObjects.Add(lights.ElementAt(lightIndex));
                    deleteLight(lightIndex, currScene.hierarchy.objects);
                }
                currScene.hierarchy.objects.Add(node);
                currScene.hierarchyChange = false;
                initializeTreeView();

                //sceneChange = true;
            }
            else //zaznaczone światła i meshe
            {
                HierarchyNode node = new HierarchyNode("Węzeł");
                List<HierarchyLight> lights = currScene.hierarchy.GetAllLights();

                foreach (HierarchyMesh mesh in currScene.selTriangles)
                {
                    node.hObjects.Add(mesh);
                    deleteMesh((int)mesh.triangles.ElementAt(0), currScene.hierarchy.objects);
                }
                foreach (int lightIndex in currScene.selLights)
                {
                    node.hObjects.Add(lights.ElementAt(lightIndex));
                    deleteLight(lightIndex, currScene.hierarchy.objects);
                }
                currScene.hierarchy.objects.Add(node);
                currScene.hierarchyChange = false;
                initializeTreeView();

                //sceneChange = true;
            }
            currScene.selectedHierObj = null;
        }
        public void SaveSceneFile(string file)
        {
            filePath = file;
            modified = false;

            List<string> text = new List<string>();

            text.Add("");
            text.Add("// punkty");
            text.Add("points_count " + points.Count.ToString());
            foreach(Vector3D point in points)
            {
                text.Add(point.x.ToString(CultureInfo.InvariantCulture) + " " + point.y.ToString(CultureInfo.InvariantCulture) + " " + point.z.ToString(CultureInfo.InvariantCulture));
            }
            text.Add("");
            text.Add("");

            text.Add("// trójkąty");
            text.Add("triangles_count " + triangles.Count.ToString());
            foreach(Triangle triangle in triangles)
            {
                text.Add(triangle.p1.ToString() + " " + triangle.p2.ToString() + " " + triangle.p3.ToString());
            }
            text.Add("");
            text.Add("");

            text.Add("// części");
            text.Add("parts_count " + parts.Count.ToString());

            int[] trParts = new int[triangles.Count];
            for(int i = 0; i < parts.Count; ++i)
            {
                foreach(int triangle in parts[i].triangles)
                {
                    trParts[triangle] = i;
                }
            }

            StringBuilder partsStr = new StringBuilder();
            foreach(int trPart in trParts)
            {
                partsStr.Append(trPart.ToString() + " ");
            }
            text.Add(partsStr.ToString());
            text.Add("");
            text.Add("");

            text.Add("// materiały");
            text.Add("materials_count " + materials.Count.ToString());

            foreach(Material_ mat in materials)
            {
                text.Add("");

                text.Add("mat_name " + mat.name);
                text.Add("rgb " + mat.colorR.ToString(CultureInfo.InvariantCulture) + " " + mat.colorG.ToString(CultureInfo.InvariantCulture) + " " + mat.colorB.ToString(CultureInfo.InvariantCulture));
                text.Add("kdCr " + mat.kdcR.ToString(CultureInfo.InvariantCulture));
                text.Add("kdCg " + mat.kdcG.ToString(CultureInfo.InvariantCulture));
                text.Add("kdCb " + mat.kdcB.ToString(CultureInfo.InvariantCulture));
                text.Add("ksCr " + mat.kscR.ToString(CultureInfo.InvariantCulture));
                text.Add("ksCg " + mat.kscG.ToString(CultureInfo.InvariantCulture));
                text.Add("ksCb " + mat.kscB.ToString(CultureInfo.InvariantCulture));
                text.Add("krCr " + mat.krcR.ToString(CultureInfo.InvariantCulture));
                text.Add("krCg " + mat.krcG.ToString(CultureInfo.InvariantCulture));
                text.Add("krCb " + mat.krcB.ToString(CultureInfo.InvariantCulture));
                text.Add("kaCr " + mat.kacR.ToString(CultureInfo.InvariantCulture));
                text.Add("kaCg " + mat.kacG.ToString(CultureInfo.InvariantCulture));
                text.Add("kaCb " + mat.kacB.ToString(CultureInfo.InvariantCulture));
                text.Add("g " + mat.g.ToString(CultureInfo.InvariantCulture));
                text.Add("n " + mat.n.ToString(CultureInfo.InvariantCulture));
            }
            text.Add("");
            text.Add("");

            text.Add("// przypisanie materiałów");
            for(int i = 0; i < materialAssign.Count; ++i)
            {
                text.Add(i.ToString() + " " + materialAssign[i]);
            }
            text.Add("");
            text.Add("");

            text.Add("// światła");
            text.Add("lights_count " + lights.Count.ToString());

            foreach(Light_ light in lights)
            {
                text.Add("");

                text.Add("light_name " + light.name);
                text.Add("enabled " + (light.enabled == true ? "1" : "0"));
                text.Add("light_type " + light.type.ToString().ToLowerInvariant());
                text.Add("rgb " + light.colorR.ToString(CultureInfo.InvariantCulture) + " " + light.colorG.ToString(CultureInfo.InvariantCulture) + " " + light.colorB.ToString(CultureInfo.InvariantCulture));
                text.Add("power " + light.power);
                text.Add("pos " + light.position.X.ToString(CultureInfo.InvariantCulture) + " " + light.position.Y.ToString(CultureInfo.InvariantCulture) + " " + light.position.Z.ToString(CultureInfo.InvariantCulture));
                text.Add("dir " + light.direction.X.ToString(CultureInfo.InvariantCulture) + " " + light.direction.Y.ToString(CultureInfo.InvariantCulture) + " " + light.direction.Z.ToString(CultureInfo.InvariantCulture));
                text.Add("inner_angle " + light.innerAngle);
                text.Add("outer_angle " + light.outerAngle);
                text.Add("gonio_count " + light.goniometric.Count.ToString());

                for(int i = 0; i < light.goniometric.Count; ++i)
                {
                    text.Add(light.goniometric.Keys[i].ToString(CultureInfo.InvariantCulture) + " " + light.goniometric.Values[i].ToString(CultureInfo.InvariantCulture));
                }
            }
            text.Add("");
            text.Add("");

            text.Add("// kamery");
            text.Add("cams_count " + cams.Count.ToString());
            text.Add("active " + activeCamera.ToString());

            foreach(Camera cam in cams)
            {
                text.Add("");

                text.Add("cam_name " + cam.name);
                text.Add("resolution " + cam.resolutionX.ToString(CultureInfo.InvariantCulture) + " " + cam.resolutionY.ToString(CultureInfo.InvariantCulture));
                text.Add("pos " + cam.position.X.ToString(CultureInfo.InvariantCulture) + " " + cam.position.Y.ToString(CultureInfo.InvariantCulture) + " " + cam.position.Z.ToString(CultureInfo.InvariantCulture));
                text.Add("lookAt " + cam.lookAt.X.ToString(CultureInfo.InvariantCulture) + " " + cam.lookAt.Y.ToString(CultureInfo.InvariantCulture) + " " + cam.lookAt.Z.ToString(CultureInfo.InvariantCulture));
                text.Add("fov " + cam.fovAngle.ToString(CultureInfo.InvariantCulture));
                text.Add("rotation " + cam.rotateAngle.ToString(CultureInfo.InvariantCulture));
            }
            text.Add("");
            text.Add("");

            text.Add("// hierarchia");
            HierarchyNode node = new HierarchyNode("Hierarchy");
            node.hObjects = hierarchy.objects;

            SaveHierarchy(node, text, 0);

            File.SaveFileLines(file, text);
        }
        private static void ReadHierarchy(HierarchyNode node, List<Light_> lights, List<string> text, ref int pointer)
        {
            string objNumLabel = File.GetAttribute(text[pointer], 0);
            if(objNumLabel != "node_count")
            {
                throw new Exception();
            }
            uint objNum = uint.Parse(File.GetAttribute(text[pointer++], 1));

            for(int i = 0; i < objNum; ++i)
            {
                HierarchyObject newObject = null;
                string objStrLabel = File.GetAttribute(text[pointer], 0);
                if(objStrLabel != "hier_type")
                {
                    throw new Exception();
                }
                string objStr = File.GetAttribute(text[pointer++], 1);

                string[] objNameAtts = File.GetAttributes(text[pointer]);
                if(objNameAtts[0] != "hier_name")
                {
                    throw new Exception();
                }
                string objName = objName = File.CutFirstString(text[pointer]);
                ++pointer;

                switch(objStr)
                {
                    case "Mesh":
                        newObject = new HierarchyMesh(objName);
                        node.hObjects.Add(newObject);

                        string triangleNumLabel = File.GetAttribute(text[pointer], 0);
                        if(triangleNumLabel != "triangle_count")
                        {
                            new Exception();
                        }
                        uint triangleNum = uint.Parse(File.GetAttribute(text[pointer++], 1));
                        List<uint> triangles = new List<uint>();

                        string[] triangs = File.GetAttributes(text[pointer]);
                        for(int j = 0; j < triangleNum; ++j)
                        {
                            triangles.Add(uint.Parse(triangs[j]));
                        }
                        ++pointer;

                        ((HierarchyMesh)newObject).triangles = triangles;
                        break;

                    case "Light":
                        string lightIdxLabel = File.GetAttribute(text[pointer], 0);
                        if (lightIdxLabel != "light_index")
                        {
                            new Exception();
                        }
                        int lightIdx = int.Parse(File.GetAttribute(text[pointer++], 1));
                        newObject = new HierarchyLight(objName, lightIdx);
                        node.hObjects.Add(newObject);
                        break;

                    case "Node":
                        newObject = new HierarchyNode(objName);
                        node.hObjects.Add(newObject);

                        ReadHierarchy((HierarchyNode)newObject, lights, text, ref pointer);
                        break;
                }
            }
        }
        private static void ReadHierarchy(HierarchyNode node, List<Light_> lights, List<string> text, int pointer)
        {
            string objNumLabel = File.GetAttribute(text[pointer], 0);
            if(objNumLabel != "node_count")
            {
                node = null;
            }
            uint objNum = uint.Parse(File.GetAttribute(text[pointer++], 1));

            for(int i = 0; i < objNum; ++i)
            {
                HierarchyObject newObject = null;
                string objStrLabel = File.GetAttribute(text[pointer], 0);
                if(objStrLabel != "hier_type")
                {
                    node = null;
                }
                string objStr = File.GetAttribute(text[pointer++], 1);
                string objNameLabel = File.GetAttribute(text[pointer], 0);
                if(objNameLabel != "hier_name")
                {
                    node = null;
                }
                string objName = File.GetAttribute(text[pointer++], 1);

                switch(objStr)
                {
                    case "Mesh":
                        newObject = new HierarchyMesh(objName);
                        node.hObjects.Add(newObject);

                        string triangleNumLabel = File.GetAttribute(text[pointer], 0);
                        if(triangleNumLabel != "triangle_count")
                        {
                            node = null;
                        }
                        uint triangleNum = uint.Parse(File.GetAttribute(text[pointer++], 1));
                        List<uint> triangles = new List<uint>();

                        string[] triangs = File.GetAttributes(text[pointer]);
                        for(int j = 0; j < triangleNum; ++j)
                        {
                            triangles.Add(uint.Parse(triangs[j]));
                        }
                        ++pointer;

                        ((HierarchyMesh)newObject).triangles = triangles;
                        break;

                    case "Light":
                        newObject = new HierarchyLight(GetLightByName(lights, objName));
                        node.hObjects.Add(newObject);
                        break;

                    case "Node":
                        newObject = new HierarchyNode(objName);
                        node.hObjects.Add(newObject);

                        ReadHierarchy((HierarchyNode)newObject, lights, text, pointer);
                        break;
                }
            }
        }
        public static Scene ReadSceneFromFile(string file)
        {
            Scene scene = new Scene();

            try
            {
                scene.filePath = file;
                scene.modified = false;

                List<string> text = File.ReadFileLines(file);
                int pointer = 0;

                string pointsNumLabel = File.GetAttribute(text[pointer], 0);
                if(pointsNumLabel != "points_count")
                {
                    return null;
                }
                uint pointsNum = uint.Parse(File.GetAttribute(text[pointer++], 1));

                List<Vector3D> points = new List<Vector3D>();

                for(int i = 0; i < pointsNum; ++i)
                {
                    string[] attsPoint = File.GetAttributes(text[pointer++]);
                    points.Add(new Vector3D(float.Parse(attsPoint[0], CultureInfo.InvariantCulture),
                                            float.Parse(attsPoint[1], CultureInfo.InvariantCulture),
                                            float.Parse(attsPoint[2], CultureInfo.InvariantCulture)));
                }

                string triangleNumLabel = File.GetAttribute(text[pointer], 0);
                if(triangleNumLabel != "triangles_count")
                {
                    return null;
                }
                uint triangleNum = uint.Parse(File.GetAttribute(text[pointer++], 1));

                List<Triangle> triangles = new List<Triangle>();

                for(int i = 0; i < triangleNum; ++i)
                {
                    string[] attsTriangle = File.GetAttributes(text[pointer++]);
                    triangles.Add(new Triangle(uint.Parse(attsTriangle[0]), uint.Parse(attsTriangle[1]), uint.Parse(attsTriangle[2])));
                }

                string partsNumLabel = File.GetAttribute(text[pointer], 0);
                if(partsNumLabel != "parts_count")
                {
                    return null;
                }
                uint partsNum = uint.Parse(File.GetAttribute(text[pointer++], 1));

                List<uint> trPart = new List<uint>();

                string[] atts = File.GetAttributes(text[pointer]);
                for(int i = 0; i < triangleNum; ++i)
                {
                    trPart.Add(uint.Parse(atts[i]));
                }
                ++pointer;

                List<Part> parts = new List<Part>();

                for(int i = 0; i < partsNum; ++i)
                {
                    List<int> partTriangles = new List<int>();

                    for(int j = 0; j < trPart.Count; ++j)
                    {
                        if(trPart[j] == i)
                        {
                            partTriangles.Add(j);
                        }
                    }

                    parts.Add(new Part(partTriangles));
                }

                string matNumLabel = File.GetAttribute(text[pointer], 0);
                if(matNumLabel != "materials_count")
                {
                    return null;
                }
                uint matNum = uint.Parse(File.GetAttribute(text[pointer++], 1));

                List<Material_> materials = new List<Material_>();

                for(int i = 0; i < matNum; ++i)
                {
                    string[] matName = File.GetAttributes(text[pointer]);
                    if(matName[0] != "mat_name")
                    {
                        return null;
                    }
                    string name = File.CutFirstString(text[pointer]);
                    ++pointer;

                    string rgbLabel = File.GetAttribute(text[pointer], 0);
                    if(rgbLabel != "rgb")
                    {
                        return null;
                    }
                    float colorR = float.Parse(File.GetAttribute(text[pointer], 1), CultureInfo.InvariantCulture);
                    float colorG = float.Parse(File.GetAttribute(text[pointer], 2), CultureInfo.InvariantCulture);
                    float colorB = float.Parse(File.GetAttribute(text[pointer++], 3), CultureInfo.InvariantCulture);

                    string kdCrLabel = File.GetAttribute(text[pointer], 0);
                    float kdCr = float.Parse(File.GetAttribute(text[pointer++], 1), CultureInfo.InvariantCulture);
                    if(kdCrLabel != "kdCr")
                    {
                        return null;
                    }
                    string kdCgLabel = File.GetAttribute(text[pointer], 0);
                    float kdCg = float.Parse(File.GetAttribute(text[pointer++], 1), CultureInfo.InvariantCulture);
                    if(kdCgLabel != "kdCg")
                    {
                        return null;
                    }
                    string kdCbLabel = File.GetAttribute(text[pointer], 0);
                    float kdCb = float.Parse(File.GetAttribute(text[pointer++], 1), CultureInfo.InvariantCulture);
                    if(kdCbLabel != "kdCb")
                    {
                        return null;
                    }

                    string ksCrLabel = File.GetAttribute(text[pointer], 0);
                    float ksCr = float.Parse(File.GetAttribute(text[pointer++], 1), CultureInfo.InvariantCulture);
                    if(ksCrLabel != "ksCr")
                    {
                        return null;
                    }
                    string ksCgLabel = File.GetAttribute(text[pointer], 0);
                    float ksCg = float.Parse(File.GetAttribute(text[pointer++], 1), CultureInfo.InvariantCulture);
                    if(ksCgLabel != "ksCg")
                    {
                        return null;
                    }
                    string ksCbLabel = File.GetAttribute(text[pointer], 0);
                    float ksCb = float.Parse(File.GetAttribute(text[pointer++], 1), CultureInfo.InvariantCulture);
                    if(ksCbLabel != "ksCb")
                    {
                        return null;
                    }

                    string krCrLabel = File.GetAttribute(text[pointer], 0);
                    float krCr = float.Parse(File.GetAttribute(text[pointer++], 1), CultureInfo.InvariantCulture);
                    if(krCrLabel != "krCr")
                    {
                        return null;
                    }
                    string krCgLabel = File.GetAttribute(text[pointer], 0);
                    float krCg = float.Parse(File.GetAttribute(text[pointer++], 1), CultureInfo.InvariantCulture);
                    if(krCgLabel != "krCg")
                    {
                        return null;
                    }
                    string krCbLabel = File.GetAttribute(text[pointer], 0);
                    float krCb = float.Parse(File.GetAttribute(text[pointer++], 1), CultureInfo.InvariantCulture);
                    if(krCbLabel != "krCb")
                    {
                        return null;
                    }

                    string kaCrLabel = File.GetAttribute(text[pointer], 0);
                    float kaCr = float.Parse(File.GetAttribute(text[pointer++], 1), CultureInfo.InvariantCulture);
                    if(kaCrLabel != "kaCr")
                    {
                        return null;
                    }
                    string kaCgLabel = File.GetAttribute(text[pointer], 0);
                    float kaCg = float.Parse(File.GetAttribute(text[pointer++], 1), CultureInfo.InvariantCulture);
                    if(kaCgLabel != "kaCg")
                    {
                        return null;
                    }
                    string kaCbLabel = File.GetAttribute(text[pointer], 0);
                    float kaCb = float.Parse(File.GetAttribute(text[pointer++], 1), CultureInfo.InvariantCulture);
                    if(kaCbLabel != "kaCb")
                    {
                        return null;
                    }

                    string gLabel = File.GetAttribute(text[pointer], 0);
                    float g = float.Parse(File.GetAttribute(text[pointer++], 1), CultureInfo.InvariantCulture);
                    if(gLabel != "g")
                    {
                        return null;
                    }
                    string nLabel = File.GetAttribute(text[pointer], 0);
                    float n = float.Parse(File.GetAttribute(text[pointer++], 1), CultureInfo.InvariantCulture);
                    if(nLabel != "n")
                    {
                        return null;
                    }

                    materials.Add(new Material_(name, colorR, colorG, colorB, kdCr, kdCg, kdCb, ksCr, ksCg, ksCb, krCr, krCg, krCb, kaCr, kaCg, kaCb, g, n));
                }

                List<string> matAssign = new List<string>();

                for(int i = 0; i < partsNum; ++i)
                {
                    string mat = File.CutFirstString(text[pointer++]);
                    matAssign.Add(mat);
                }

                string lightsLabel = File.GetAttribute(text[pointer], 0);
                if(lightsLabel != "lights_count")
                {
                    return null;
                }
                uint lightsNum = uint.Parse(File.GetAttribute(text[pointer++], 1));

                List<Light_> lights = new List<Light_>();

                for(int i = 0; i < lightsNum; ++i)
                {
                    string[] lightName = File.GetAttributes(text[pointer]);
                    if(lightName[0] != "light_name")
                    {
                        return null;
                    }
                    string name = File.CutFirstString(text[pointer]);
                    ++pointer;

                    string enabledLabel = File.GetAttribute(text[pointer], 0);
                    if(enabledLabel != "enabled")
                    {
                        return null;
                    }
                    bool enabled = int.Parse(File.GetAttribute(text[pointer++], 1)) == 1 ? true : false;

                    string typeLabel = File.GetAttribute(text[pointer], 0);
                    if(typeLabel != "light_type")
                    {
                        return null;
                    }
                    Light_Type type = Light_Type.Point;
                    switch(File.GetAttribute(text[pointer++], 1))
                    {
                        case "point":
                            type = Light_Type.Point;
                            break;

                        case "spot":
                            type = Light_Type.Spot;
                            break;

                        case "goniometric":
                            type = Light_Type.Goniometric;
                            break;
                    }

                    string colorLabel = File.GetAttribute(text[pointer], 0);
                    if(colorLabel != "rgb")
                    {
                        return null;
                    }
                    float colorR = float.Parse(File.GetAttribute(text[pointer], 1), CultureInfo.InvariantCulture);
                    float colorG = float.Parse(File.GetAttribute(text[pointer], 2), CultureInfo.InvariantCulture);
                    float colorB = float.Parse(File.GetAttribute(text[pointer++], 3), CultureInfo.InvariantCulture);

                    string powerLabel = File.GetAttribute(text[pointer], 0);
                    if(powerLabel != "power")
                    {
                        return null;
                    }
                    float power = float.Parse(File.GetAttribute(text[pointer++], 1), CultureInfo.InvariantCulture);

                    string posLabel = File.GetAttribute(text[pointer], 0);
                    if(posLabel != "pos")
                    {
                        return null;
                    }
                    Vector3 pos = new Vector3(float.Parse(File.GetAttribute(text[pointer], 1), CultureInfo.InvariantCulture),
                        float.Parse(File.GetAttribute(text[pointer], 2), CultureInfo.InvariantCulture),
                        float.Parse(File.GetAttribute(text[pointer++], 3), CultureInfo.InvariantCulture));

                    string dirLabel = File.GetAttribute(text[pointer], 0);
                    if(dirLabel != "dir")
                    {
                        return null;
                    }
                    Vector3 dir = new Vector3(float.Parse(File.GetAttribute(text[pointer], 1), CultureInfo.InvariantCulture),
                        float.Parse(File.GetAttribute(text[pointer], 2), CultureInfo.InvariantCulture),
                        float.Parse(File.GetAttribute(text[pointer++], 3), CultureInfo.InvariantCulture));

                    string innerAngleLabel = File.GetAttribute(text[pointer], 0);
                    if(innerAngleLabel != "inner_angle")
                    {
                        return null;
                    }
                    float innerAngle = float.Parse(File.GetAttribute(text[pointer++], 1), CultureInfo.InvariantCulture);
                    string outerAngleLabel = File.GetAttribute(text[pointer], 0);
                    if(outerAngleLabel != "outer_angle")
                    {
                        return null;
                    }
                    float outerAngle = float.Parse(File.GetAttribute(text[pointer++], 1), CultureInfo.InvariantCulture);

                    SortedList<float, float> goniometric = new SortedList<float, float>();

                    string gonioNumLabel = File.GetAttribute(text[pointer], 0);
                    if(gonioNumLabel != "gonio_count")
                    {
                        return null;
                    }
                    uint gonioNum = uint.Parse(File.GetAttribute(text[pointer++], 1));

                    for(int j = 0; j < gonioNum; ++j)
                    {
                        float gonioIndex = float.Parse(File.GetAttribute(text[pointer], 0), CultureInfo.InvariantCulture);
                        float gonioValue = float.Parse(File.GetAttribute(text[pointer++], 1), CultureInfo.InvariantCulture);

                        goniometric.Add(gonioIndex, gonioValue);
                    }

                    lights.Add(new Light_(name, type, enabled, colorR, colorG, colorB, power, pos));

                    lights[lights.Count - 1].direction = new Vector3(dir.X, dir.Y, dir.Z);
                    lights[lights.Count - 1].innerAngle = innerAngle;
                    lights[lights.Count - 1].outerAngle = outerAngle;
                    lights[lights.Count - 1].goniometric = goniometric;
                }

                string camsNumLabel = File.GetAttribute(text[pointer], 0);
                if(camsNumLabel != "cams_count")
                {
                    return null;
                }
                uint camsNum = uint.Parse(File.GetAttribute(text[pointer++], 1));

                List<Camera> cams = new List<Camera>();

                string activeCamLabel = File.GetAttribute(text[pointer], 0);
                if(activeCamLabel != "active")
                {
                    return null;
                }
                uint activeCam = uint.Parse(File.GetAttribute(text[pointer++], 1));

                for(int i = 0; i < camsNum; ++i)
                {
                    string nameLabel = File.GetAttribute(text[pointer], 0);
                    if(nameLabel != "cam_name")
                    {
                        return null;
                    }
                    string name = File.CutFirstString(text[pointer]);
                    ++pointer;

                    string resLabel = File.GetAttribute(text[pointer], 0);
                    if(resLabel != "resolution")
                    {
                        return null;
                    }
                    Pair<int, int> res = new Pair<int, int>(int.Parse(File.GetAttribute(text[pointer], 1)), int.Parse(File.GetAttribute(text[pointer++], 2)));

                    string posLabel = File.GetAttribute(text[pointer], 0);
                    if(posLabel != "pos")
                    {
                        return null;
                    }
                    Vector3 pos = new Vector3(float.Parse(File.GetAttribute(text[pointer], 1), CultureInfo.InvariantCulture),
                        float.Parse(File.GetAttribute(text[pointer], 2), CultureInfo.InvariantCulture),
                        float.Parse(File.GetAttribute(text[pointer++], 3), CultureInfo.InvariantCulture));

                    string lookAtLabel = File.GetAttribute(text[pointer], 0);
                    if(lookAtLabel != "lookAt")
                    {
                        return null;
                    }
                    Vector3 lookAt = new Vector3(float.Parse(File.GetAttribute(text[pointer], 1), CultureInfo.InvariantCulture),
                        float.Parse(File.GetAttribute(text[pointer], 2), CultureInfo.InvariantCulture),
                        float.Parse(File.GetAttribute(text[pointer++], 3), CultureInfo.InvariantCulture));

                    string fovAngleLabel = File.GetAttribute(text[pointer], 0);
                    if(fovAngleLabel != "fov")
                    {
                        return null;
                    }
                    float fovAngle = float.Parse(File.GetAttribute(text[pointer++], 1), CultureInfo.InvariantCulture);
                    string rotateAngleLabel = File.GetAttribute(text[pointer], 0);
                    if(rotateAngleLabel != "rotation")
                    {
                        return null;
                    }
                    float rotateAngle = float.Parse(File.GetAttribute(text[pointer++], 1), CultureInfo.InvariantCulture);

                    cams.Add(new Camera(name, res.First, res.Second, pos, lookAt, fovAngle, rotateAngle));
                }

                HierarchyNode root = new HierarchyNode("Hierarchy");

                ReadHierarchy(root, lights, text, ref pointer);
                if(root == null)
                {
                    return null;
                }

                Hierarchy hierarchy = new Hierarchy();
                hierarchy.objects = root.hObjects;

                scene.points = points;
                scene.triangles = triangles;
                scene.parts = parts;
                scene.materials = materials;
                scene.materialAssign = matAssign;
                scene.lights = lights;
                scene.cams = cams;
                scene.activeCamera = (int)activeCam;
                scene.hierarchy = hierarchy;
            }
            catch(Exception)
            {
                return null;
            }

            return scene;
        }
        public void SaveSceneFile(string file)
        {
            List <string> text = new List <string>();

            text.Add("");
            text.Add("// punkty");
            text.Add("points_count " + points.Count.ToString());
            foreach (Vector3D point in points)
            {
                text.Add(point.x.ToString(CultureInfo.InvariantCulture) + " " + point.y.ToString(CultureInfo.InvariantCulture) + " " + point.z.ToString(CultureInfo.InvariantCulture));
            }
            text.Add("");
            text.Add("");

            text.Add("// trójkąty");
            text.Add("triangles_count " + triangles.Count.ToString());
            foreach (Triangle triangle in triangles)
            {
                text.Add(triangle.p1.ToString() + " " + triangle.p2.ToString() + " " + triangle.p3.ToString());
            }
            text.Add("");
            text.Add("");

            text.Add("// części");
            text.Add("parts_count " + parts.Count.ToString());

            int[] trParts = new int[triangles.Count];
            for (int i = 0; i < parts.Count; ++i)
            {
                foreach (int triangle in parts[i].triangles)
                {
                    trParts[triangle] = i;
                }
            }

            StringBuilder partsStr = new StringBuilder();

            foreach (int trPart in trParts)
            {
                partsStr.Append(trPart.ToString() + " ");
            }
            text.Add(partsStr.ToString());
            text.Add("");
            text.Add("");

            text.Add("// materiały");
            text.Add("materials_count " + materials.Count.ToString());

            foreach (Material_ mat in materials)
            {
                text.Add("");

                text.Add("mat_name " + mat.name);
                text.Add("rgb " + mat.colorR.ToString(CultureInfo.InvariantCulture) + " " + mat.colorG.ToString(CultureInfo.InvariantCulture) + " " + mat.colorB.ToString(CultureInfo.InvariantCulture));
                text.Add("kdCr " + mat.kdcR.ToString(CultureInfo.InvariantCulture));
                text.Add("kdCg " + mat.kdcG.ToString(CultureInfo.InvariantCulture));
                text.Add("kdCb " + mat.kdcB.ToString(CultureInfo.InvariantCulture));
                text.Add("ksCr " + mat.kscR.ToString(CultureInfo.InvariantCulture));
                text.Add("ksCg " + mat.kscG.ToString(CultureInfo.InvariantCulture));
                text.Add("ksCb " + mat.kscB.ToString(CultureInfo.InvariantCulture));
                text.Add("krCr " + mat.krcR.ToString(CultureInfo.InvariantCulture));
                text.Add("krCg " + mat.krcG.ToString(CultureInfo.InvariantCulture));
                text.Add("krCb " + mat.krcB.ToString(CultureInfo.InvariantCulture));
                text.Add("kaCr " + mat.kacR.ToString(CultureInfo.InvariantCulture));
                text.Add("kaCg " + mat.kacG.ToString(CultureInfo.InvariantCulture));
                text.Add("kaCb " + mat.kacB.ToString(CultureInfo.InvariantCulture));
                text.Add("g " + mat.g.ToString(CultureInfo.InvariantCulture));
                text.Add("n " + mat.n.ToString(CultureInfo.InvariantCulture));
            }
            text.Add("");
            text.Add("");

            text.Add("// przypisanie materiałów");
            for (int i = 0; i < materialAssign.Count; ++i)
            {
                text.Add(i.ToString() + " " + materialAssign[i]);
            }
            text.Add("");
            text.Add("");

            text.Add("// światła");
            text.Add("lights_count " + lights.Count.ToString());

            foreach (Light_ light in lights)
            {
                text.Add("");

                text.Add("light_name " + light.name);
                text.Add("enabled " + (light.enabled == true ? "1" : "0"));
                text.Add("light_type " + light.type.ToString().ToLowerInvariant());
                text.Add("rgb " + light.colorR.ToString(CultureInfo.InvariantCulture) + " " + light.colorG.ToString(CultureInfo.InvariantCulture) + " " + light.colorB.ToString(CultureInfo.InvariantCulture));
                text.Add("power " + light.power);
                text.Add("pos " + light.position.X.ToString(CultureInfo.InvariantCulture) + " " + light.position.Y.ToString(CultureInfo.InvariantCulture) + " " + light.position.Z.ToString(CultureInfo.InvariantCulture));
                text.Add("dir " + light.direction.X.ToString(CultureInfo.InvariantCulture) + " " + light.direction.Y.ToString(CultureInfo.InvariantCulture) + " " + light.direction.Z.ToString(CultureInfo.InvariantCulture));
                text.Add("inner_angle " + light.innerAngle);
                text.Add("outer_angle " + light.outerAngle);
                text.Add("gonio_count " + light.goniometric.Count.ToString());

                for (int i = 0; i < light.goniometric.Count; ++i)
                {
                    text.Add(light.goniometric.Keys[i].ToString(CultureInfo.InvariantCulture) + " " + light.goniometric.Values[i].ToString(CultureInfo.InvariantCulture));
                }
            }
            text.Add("");
            text.Add("");

            text.Add("// kamery");
            text.Add("cams_count " + cams.Count.ToString());
            text.Add("active " + activeCamera.ToString());

            foreach (Camera cam in cams)
            {
                text.Add("");

                text.Add("cam_name " + cam.name);
                text.Add("resolution " + cam.resolutionX.ToString(CultureInfo.InvariantCulture) + " " + cam.resolutionY.ToString(CultureInfo.InvariantCulture));
                text.Add("pos " + cam.position.X.ToString(CultureInfo.InvariantCulture) + " " + cam.position.Y.ToString(CultureInfo.InvariantCulture) + " " + cam.position.Z.ToString(CultureInfo.InvariantCulture));
                text.Add("lookAt " + cam.lookAt.X.ToString(CultureInfo.InvariantCulture) + " " + cam.lookAt.Y.ToString(CultureInfo.InvariantCulture) + " " + cam.lookAt.Z.ToString(CultureInfo.InvariantCulture));
                text.Add("fov " + cam.fovAngle.ToString(CultureInfo.InvariantCulture));
                text.Add("rotation " + cam.rotateAngle.ToString(CultureInfo.InvariantCulture));
            }
            text.Add("");
            text.Add("");

            text.Add("// hierarchia");
            HierarchyNode node = new HierarchyNode("Hierarchy");

            node.hObjects = hierarchy.objects;

            SaveHierarchy(node, text, 0);

            File.SaveFileLines(file, text);
        }
        private static void ReadHierarchy(HierarchyNode node, List <Light_> lights, List <string> text, int pointer)
        {
            string objNumLabel = File.GetAttribute(text[pointer], 0);

            if (objNumLabel != "node_count")
            {
                node = null;
            }
            uint objNum = uint.Parse(File.GetAttribute(text[pointer++], 1));

            for (int i = 0; i < objNum; ++i)
            {
                HierarchyObject newObject   = null;
                string          objStrLabel = File.GetAttribute(text[pointer], 0);
                if (objStrLabel != "hier_type")
                {
                    node = null;
                }
                string objStr       = File.GetAttribute(text[pointer++], 1);
                string objNameLabel = File.GetAttribute(text[pointer], 0);
                if (objNameLabel != "hier_name")
                {
                    node = null;
                }
                string objName = File.GetAttribute(text[pointer++], 1);

                switch (objStr)
                {
                case "Mesh":
                    newObject = new HierarchyMesh(objName);
                    node.hObjects.Add(newObject);

                    string triangleNumLabel = File.GetAttribute(text[pointer], 0);
                    if (triangleNumLabel != "triangle_count")
                    {
                        node = null;
                    }
                    uint        triangleNum = uint.Parse(File.GetAttribute(text[pointer++], 1));
                    List <uint> triangles   = new List <uint>();

                    string[] triangs = File.GetAttributes(text[pointer]);
                    for (int j = 0; j < triangleNum; ++j)
                    {
                        triangles.Add(uint.Parse(triangs[j]));
                    }
                    ++pointer;

                    ((HierarchyMesh)newObject).triangles = triangles;
                    break;

                case "Light":
                    newObject = new HierarchyLight(GetLightByName(lights, objName));
                    node.hObjects.Add(newObject);
                    break;

                case "Node":
                    newObject = new HierarchyNode(objName);
                    node.hObjects.Add(newObject);

                    ReadHierarchy((HierarchyNode)newObject, lights, text, pointer);
                    break;
                }
            }
        }
        public static Scene ReadSceneFromFile(string file)
        {
            Scene scene = new Scene();

            try
            {
                List <string> text    = File.ReadFileLines(file);
                int           pointer = 0;

                string pointsNumLabel = File.GetAttribute(text[pointer], 0);
                if (pointsNumLabel != "points_count")
                {
                    return(null);
                }
                uint pointsNum = uint.Parse(File.GetAttribute(text[pointer++], 1));

                List <Vector3D> points = new List <Vector3D>();

                for (int i = 0; i < pointsNum; ++i)
                {
                    points.Add(new Vector3D(float.Parse(File.GetAttribute(text[pointer], 0), CultureInfo.InvariantCulture),
                                            float.Parse(File.GetAttribute(text[pointer], 1), CultureInfo.InvariantCulture),
                                            float.Parse(File.GetAttribute(text[pointer++], 2), CultureInfo.InvariantCulture)));
                }

                string triangleNumLabel = File.GetAttribute(text[pointer], 0);
                if (triangleNumLabel != "triangles_count")
                {
                    return(null);
                }
                uint triangleNum = uint.Parse(File.GetAttribute(text[pointer++], 1));

                List <Triangle> triangles = new List <Triangle>();

                for (int i = 0; i < triangleNum; ++i)
                {
                    triangles.Add(new Triangle(uint.Parse(File.GetAttribute(text[pointer], 0)), uint.Parse(File.GetAttribute(text[pointer], 1)),
                                               uint.Parse(File.GetAttribute(text[pointer++], 2))));
                }

                string partsNumLabel = File.GetAttribute(text[pointer], 0);
                if (partsNumLabel != "parts_count")
                {
                    return(null);
                }
                uint partsNum = uint.Parse(File.GetAttribute(text[pointer++], 1));

                List <uint> trPart = new List <uint>();

                string[] atts = File.GetAttributes(text[pointer]);
                for (int i = 0; i < triangleNum; ++i)
                {
                    trPart.Add(uint.Parse(atts[i]));
                }
                ++pointer;

                List <Part> parts = new List <Part>();

                for (int i = 0; i < partsNum; ++i)
                {
                    List <int> partTriangles = new List <int>();

                    for (int j = 0; j < trPart.Count; ++j)
                    {
                        if (trPart[j] == i)
                        {
                            partTriangles.Add(j);
                        }
                    }

                    parts.Add(new Part(partTriangles));
                }


                string matNumLabel = File.GetAttribute(text[pointer], 0);
                if (matNumLabel != "materials_count")
                {
                    return(null);
                }
                uint matNum = uint.Parse(File.GetAttribute(text[pointer++], 1));

                List <Material_> materials = new List <Material_>();

                for (int i = 0; i < matNum; ++i)
                {
                    string matNameLabel = File.GetAttribute(text[pointer], 0);
                    if (matNameLabel != "mat_name")
                    {
                        return(null);
                    }
                    string name = File.GetAttribute(text[pointer++], 1);

                    string rgbLabel = File.GetAttribute(text[pointer], 0);
                    if (rgbLabel != "rgb")
                    {
                        return(null);
                    }
                    float colorR = float.Parse(File.GetAttribute(text[pointer], 1), CultureInfo.InvariantCulture);
                    float colorG = float.Parse(File.GetAttribute(text[pointer], 2), CultureInfo.InvariantCulture);
                    float colorB = float.Parse(File.GetAttribute(text[pointer++], 3), CultureInfo.InvariantCulture);

                    string kdCrLabel = File.GetAttribute(text[pointer], 0);
                    float  kdCr      = float.Parse(File.GetAttribute(text[pointer++], 1), CultureInfo.InvariantCulture);
                    if (kdCrLabel != "kdCr")
                    {
                        return(null);
                    }
                    string kdCgLabel = File.GetAttribute(text[pointer], 0);
                    float  kdCg      = float.Parse(File.GetAttribute(text[pointer++], 1), CultureInfo.InvariantCulture);
                    if (kdCgLabel != "kdCg")
                    {
                        return(null);
                    }
                    string kdCbLabel = File.GetAttribute(text[pointer], 0);
                    float  kdCb      = float.Parse(File.GetAttribute(text[pointer++], 1), CultureInfo.InvariantCulture);
                    if (kdCbLabel != "kdCb")
                    {
                        return(null);
                    }

                    string ksCrLabel = File.GetAttribute(text[pointer], 0);
                    float  ksCr      = float.Parse(File.GetAttribute(text[pointer++], 1), CultureInfo.InvariantCulture);
                    if (ksCrLabel != "ksCr")
                    {
                        return(null);
                    }
                    string ksCgLabel = File.GetAttribute(text[pointer], 0);
                    float  ksCg      = float.Parse(File.GetAttribute(text[pointer++], 1), CultureInfo.InvariantCulture);
                    if (ksCgLabel != "ksCg")
                    {
                        return(null);
                    }
                    string ksCbLabel = File.GetAttribute(text[pointer], 0);
                    float  ksCb      = float.Parse(File.GetAttribute(text[pointer++], 1), CultureInfo.InvariantCulture);
                    if (ksCbLabel != "ksCb")
                    {
                        return(null);
                    }

                    string krCrLabel = File.GetAttribute(text[pointer], 0);
                    float  krCr      = float.Parse(File.GetAttribute(text[pointer++], 1), CultureInfo.InvariantCulture);
                    if (krCrLabel != "krCr")
                    {
                        return(null);
                    }
                    string krCgLabel = File.GetAttribute(text[pointer], 0);
                    float  krCg      = float.Parse(File.GetAttribute(text[pointer++], 1), CultureInfo.InvariantCulture);
                    if (krCgLabel != "krCg")
                    {
                        return(null);
                    }
                    string krCbLabel = File.GetAttribute(text[pointer], 0);
                    float  krCb      = float.Parse(File.GetAttribute(text[pointer++], 1), CultureInfo.InvariantCulture);
                    if (krCbLabel != "krCb")
                    {
                        return(null);
                    }

                    string kaCrLabel = File.GetAttribute(text[pointer], 0);
                    float  kaCr      = float.Parse(File.GetAttribute(text[pointer++], 1), CultureInfo.InvariantCulture);
                    if (kaCrLabel != "kaCr")
                    {
                        return(null);
                    }
                    string kaCgLabel = File.GetAttribute(text[pointer], 0);
                    float  kaCg      = float.Parse(File.GetAttribute(text[pointer++], 1), CultureInfo.InvariantCulture);
                    if (kaCgLabel != "kaCg")
                    {
                        return(null);
                    }
                    string kaCbLabel = File.GetAttribute(text[pointer], 0);
                    float  kaCb      = float.Parse(File.GetAttribute(text[pointer++], 1), CultureInfo.InvariantCulture);
                    if (kaCbLabel != "kaCb")
                    {
                        return(null);
                    }

                    string gLabel = File.GetAttribute(text[pointer], 0);
                    float  g      = float.Parse(File.GetAttribute(text[pointer++], 1), CultureInfo.InvariantCulture);
                    if (gLabel != "g")
                    {
                        return(null);
                    }
                    string nLabel = File.GetAttribute(text[pointer], 0);
                    float  n      = float.Parse(File.GetAttribute(text[pointer++], 1), CultureInfo.InvariantCulture);
                    if (nLabel != "n")
                    {
                        return(null);
                    }

                    materials.Add(new Material_(name, colorR, colorG, colorB, kdCr, kdCg, kdCb, ksCr, ksCg, ksCb, krCr, krCg, krCb, kaCr, kaCg, kaCb, g, n));
                }

                List <string> matAssign = new List <string>();

                for (int i = 0; i < partsNum; ++i)
                {
                    matAssign.Add(File.GetAttribute(text[pointer++], 1));
                }

                string lightsLabel = File.GetAttribute(text[pointer], 0);
                if (lightsLabel != "lights_count")
                {
                    return(null);
                }
                uint lightsNum = uint.Parse(File.GetAttribute(text[pointer++], 1));

                List <Light_> lights = new List <Light_>();

                for (int i = 0; i < lightsNum; ++i)
                {
                    string nameLabel = File.GetAttribute(text[pointer], 0);
                    if (nameLabel != "light_name")
                    {
                        return(null);
                    }
                    string name = File.GetAttribute(text[pointer++], 1);

                    string enabledLabel = File.GetAttribute(text[pointer], 0);
                    if (enabledLabel != "enabled")
                    {
                        return(null);
                    }
                    bool enabled = int.Parse(File.GetAttribute(text[pointer++], 1)) == 1 ? true : false;

                    string typeLabel = File.GetAttribute(text[pointer], 0);
                    if (typeLabel != "light_type")
                    {
                        return(null);
                    }
                    Light_Type type = Light_Type.Point;
                    switch (File.GetAttribute(text[pointer++], 1))
                    {
                    case "point":
                        type = Light_Type.Point;
                        break;

                    case "spot":
                        type = Light_Type.Spot;
                        break;

                    case "goniometric":
                        type = Light_Type.Goniometric;
                        break;
                    }

                    string colorLabel = File.GetAttribute(text[pointer], 0);
                    if (colorLabel != "rgb")
                    {
                        return(null);
                    }
                    float colorR = float.Parse(File.GetAttribute(text[pointer], 1), CultureInfo.InvariantCulture);
                    float colorG = float.Parse(File.GetAttribute(text[pointer], 2), CultureInfo.InvariantCulture);
                    float colorB = float.Parse(File.GetAttribute(text[pointer++], 3), CultureInfo.InvariantCulture);

                    string powerLabel = File.GetAttribute(text[pointer], 0);
                    if (powerLabel != "power")
                    {
                        return(null);
                    }
                    float power = float.Parse(File.GetAttribute(text[pointer++], 1), CultureInfo.InvariantCulture);

                    string posLabel = File.GetAttribute(text[pointer], 0);
                    if (posLabel != "pos")
                    {
                        return(null);
                    }
                    Vector3 pos = new Vector3(float.Parse(File.GetAttribute(text[pointer], 1), CultureInfo.InvariantCulture),
                                              float.Parse(File.GetAttribute(text[pointer], 2), CultureInfo.InvariantCulture),
                                              float.Parse(File.GetAttribute(text[pointer++], 3), CultureInfo.InvariantCulture));

                    string dirLabel = File.GetAttribute(text[pointer], 0);
                    if (dirLabel != "dir")
                    {
                        return(null);
                    }
                    Vector3 dir = new Vector3(float.Parse(File.GetAttribute(text[pointer], 1), CultureInfo.InvariantCulture),
                                              float.Parse(File.GetAttribute(text[pointer], 2), CultureInfo.InvariantCulture),
                                              float.Parse(File.GetAttribute(text[pointer++], 3), CultureInfo.InvariantCulture));

                    string innerAngleLabel = File.GetAttribute(text[pointer], 0);
                    if (innerAngleLabel != "inner_angle")
                    {
                        return(null);
                    }
                    float  innerAngle      = float.Parse(File.GetAttribute(text[pointer++], 1), CultureInfo.InvariantCulture);
                    string outerAngleLabel = File.GetAttribute(text[pointer], 0);
                    if (outerAngleLabel != "outer_angle")
                    {
                        return(null);
                    }
                    float outerAngle = float.Parse(File.GetAttribute(text[pointer++], 1), CultureInfo.InvariantCulture);

                    SortedList <float, float> goniometric = new SortedList <float, float>();

                    string gonioNumLabel = File.GetAttribute(text[pointer], 0);
                    if (gonioNumLabel != "gonio_count")
                    {
                        return(null);
                    }
                    uint gonioNum = uint.Parse(File.GetAttribute(text[pointer++], 1));

                    for (int j = 0; j < gonioNum; ++j)
                    {
                        float gonioIndex = float.Parse(File.GetAttribute(text[pointer], 0), CultureInfo.InvariantCulture);
                        float gonioValue = float.Parse(File.GetAttribute(text[pointer++], 1), CultureInfo.InvariantCulture);

                        goniometric.Add(gonioIndex, gonioValue);
                    }

                    lights.Add(new Light_(name, type, enabled, colorR, colorG, colorB, power, pos.X, pos.Y, pos.Z));

                    lights[lights.Count - 1].direction   = new Vector3(dir.X, dir.Y, dir.Z);
                    lights[lights.Count - 1].innerAngle  = innerAngle;
                    lights[lights.Count - 1].outerAngle  = outerAngle;
                    lights[lights.Count - 1].goniometric = goniometric;
                }

                string camsNumLabel = File.GetAttribute(text[pointer], 0);
                if (camsNumLabel != "cams_count")
                {
                    return(null);
                }
                uint camsNum = uint.Parse(File.GetAttribute(text[pointer++], 1));

                List <Camera> cams = new List <Camera>();

                string activeCamLabel = File.GetAttribute(text[pointer], 0);
                if (activeCamLabel != "active")
                {
                    return(null);
                }
                uint activeCam = uint.Parse(File.GetAttribute(text[pointer++], 1));

                for (int i = 0; i < camsNum; ++i)
                {
                    string nameLabel = File.GetAttribute(text[pointer], 0);
                    if (nameLabel != "cam_name")
                    {
                        return(null);
                    }
                    string name = File.GetAttribute(text[pointer++], 1);

                    string resLabel = File.GetAttribute(text[pointer], 0);
                    if (resLabel != "resolution")
                    {
                        return(null);
                    }
                    Pair <int, int> res = new Pair <int, int>(int.Parse(File.GetAttribute(text[pointer], 1)), int.Parse(File.GetAttribute(text[pointer++], 2)));

                    string posLabel = File.GetAttribute(text[pointer], 0);
                    if (posLabel != "pos")
                    {
                        return(null);
                    }
                    Vector3 pos = new Vector3(float.Parse(File.GetAttribute(text[pointer], 1), CultureInfo.InvariantCulture),
                                              float.Parse(File.GetAttribute(text[pointer], 2), CultureInfo.InvariantCulture),
                                              float.Parse(File.GetAttribute(text[pointer++], 3), CultureInfo.InvariantCulture));

                    string lookAtLabel = File.GetAttribute(text[pointer], 0);
                    if (lookAtLabel != "lookAt")
                    {
                        return(null);
                    }
                    Vector3 lookAt = new Vector3(float.Parse(File.GetAttribute(text[pointer], 1), CultureInfo.InvariantCulture),
                                                 float.Parse(File.GetAttribute(text[pointer], 2), CultureInfo.InvariantCulture),
                                                 float.Parse(File.GetAttribute(text[pointer++], 3), CultureInfo.InvariantCulture));

                    string fovAngleLabel = File.GetAttribute(text[pointer], 0);
                    if (fovAngleLabel != "fov")
                    {
                        return(null);
                    }
                    float  fovAngle         = float.Parse(File.GetAttribute(text[pointer++], 1), CultureInfo.InvariantCulture);
                    string rotateAngleLabel = File.GetAttribute(text[pointer], 0);
                    if (rotateAngleLabel != "rotation")
                    {
                        return(null);
                    }
                    float rotateAngle = float.Parse(File.GetAttribute(text[pointer++], 1), CultureInfo.InvariantCulture);

                    cams.Add(new Camera(name, res.First, res.Second, pos, lookAt, fovAngle, rotateAngle));
                }

                HierarchyNode root = new HierarchyNode("Hierarchy");

                ReadHierarchy(root, lights, text, pointer);
                if (root == null)
                {
                    return(null);
                }

                Hierarchy hierarchy = new Hierarchy();
                hierarchy.objects = root.hObjects;

                scene.points         = points;
                scene.triangles      = triangles;
                scene.parts          = parts;
                scene.materials      = materials;
                scene.materialAssign = matAssign;
                scene.lights         = lights;
                scene.cams           = cams;
                scene.activeCamera   = (int)activeCam;
                scene.hierarchy      = hierarchy;
            }
            catch (Exception)
            {
                return(null);
            }

            return(scene);
        }
        public Scene SceneFromSelection(out Vector3D center)
        {
            Scene retScene = new Scene();

            HashSet<uint> selectedTriangIdx = new HashSet<uint>();
            HashSet<uint> selectedPointsIdx = new HashSet<uint>();
            List<Triangle> newTriangles = new List<Triangle>();
            List<Vector3D> newPoints = new List<Vector3D>();
            List<uint> newTriangleIdx = new List<uint>();
            List<int> newLightIdx = new List<int>();
            uint idx = 0;
            for (int i = 0; i < triangles.Count; ++i)
                newTriangleIdx.Add(0);
            //List<HierarchyMesh> selectedMeshes = new List<HierarchyMesh>();
            bool[] selectedPoints = new bool[points.Count];
            bool[] selectedTriangs = new bool[triangles.Count];
            for (int i = 0; i < selectedPoints.Length; i++)
            {
                selectedPoints[i] = false;
            }
            for (int i = 0; i < selectedTriangs.Length; i++)
            {
                selectedTriangs[i] = false;
            }

            foreach (HierarchyMesh mesh in selTriangles)
            //for (int i = 0; i < selTriangles.Count; i++)
            {
                //selectedMeshes.Add(Hierarchy.GetSelectedMesh(hierarchy.objects, (int)mesh.triangles[0]));
                for (int j = 0; j < mesh.triangles.Count; j++)
                {
                    int oldIdx = (int)mesh.triangles[j];
                    newTriangleIdx[oldIdx] = idx++;
                    selectedTriangIdx.Add(mesh.triangles[j]);
                    int triang = (int)mesh.triangles[j];
                    selectedTriangs[mesh.triangles[j]] = true;

                    newTriangles.Add(new Triangle(triangles[triang].p1, triangles[triang].p2, triangles[triang].p3));

                    selectedPointsIdx.Add(triangles[(int)mesh.triangles[j]].p1);
                    selectedPointsIdx.Add(triangles[(int)mesh.triangles[j]].p2);
                    selectedPointsIdx.Add(triangles[(int)mesh.triangles[j]].p3);

                    selectedPoints[triangles[(int)mesh.triangles[j]].p1] = true;
                    selectedPoints[triangles[(int)mesh.triangles[j]].p2] = true;
                    selectedPoints[triangles[(int)mesh.triangles[j]].p3] = true;
                }
            }

            idx = 0;
            for (int i = 0; i < lights.Count; i++)
            {
                newLightIdx.Add(-1);
            }
            for (int i = 0; i < selLights.Count; i++)
            {
                newLightIdx[selLights[i]] = (int)idx++;
            }

            for (int i=0; i<points.Count; i++)
            {
                if (selectedPoints[i])
                {
                    newPoints.Add(new Vector3D(points[i]));
                }
            }

            // Lista zawiera indeksy poczatka i konca usuwanych punktow (beda
            // one wystepowaly sekcjami)
            List<int> pointStartEnd = new List<int>();
            bool flag = true;
            for (int i = 0; i < selectedPoints.Length; i++)
            {
                if (!selectedPoints[i] && flag)
                {
                    pointStartEnd.Add(i);
                    flag = false;
                }
                if (selectedPoints[i] && !flag)
                {
                    pointStartEnd.Add(i - 1);
                    flag = true;
                }
            }
            if (!flag)
                pointStartEnd.Add(selectedPoints.Length - 1);

            // Lista zawiera indeksy poczatka i konca usuwanych trojkatow
            List<int> triangStartEnd = new List<int>();
            flag = true;
            for (int i = 0; i < selectedTriangs.Length; i++)
            {
                if (!selectedTriangs[i] && flag)
                {
                    triangStartEnd.Add(i);
                    flag = false;
                }
                if (selectedTriangs[i] && !flag)
                {
                    triangStartEnd.Add(i - 1);
                    flag = true;
                }
            }
            if (!flag)
                triangStartEnd.Add(selectedTriangs.Length - 1);

            int offset = 0;
            for (int i = 0; i < pointStartEnd.Count; i += 2)
            {
                int diffP = pointStartEnd[i + 1] - pointStartEnd[i] + 1;
                foreach (Triangle triangle in newTriangles)
                {
                    if (triangle.p1 > pointStartEnd[i + 1] - offset)
                        triangle.p1 -= (uint)diffP;
                    if (triangle.p2 > pointStartEnd[i + 1] - offset)
                        triangle.p2 -= (uint)diffP;
                    if (triangle.p3 > pointStartEnd[i + 1] - offset)
                        triangle.p3 -= (uint)diffP;
                }
                offset += diffP;
            }
            List<HierarchyObject> newHierarchy = new List<HierarchyObject>();
            if (selectedHierObj != null)
            {
                HierarchyNode newNode = new HierarchyNode(selectedHierObj);
                newHierarchy.Add(newNode);
                RebuildHierarchy(newHierarchy, newTriangleIdx, newLightIdx);
            }
            else
            {
                foreach (HierarchyMesh mesh in selTriangles)
                {
                    HierarchyMesh newMesh = (new HierarchyMesh(mesh.name));
                    for (int i = 0; i < mesh.triangles.Count; i++)
                    {
                        newMesh.triangles.Add(newTriangleIdx[(int) mesh.triangles[i]]);
                    }
                    newHierarchy.Add(newMesh);
                }
            }

            List<Part> newParts = new List<Part>();
            List<String> newMaterialAssign = new List<string>();
            for (int i = 0; i < parts.Count; i++)
            {
                Part newPart = (new Part(new List<int>()));
                bool used = false;
                for (int j = 0; j < parts[i].triangles.Count; j++)
                {
                    newPart.triangles.Add((int)newTriangleIdx[parts[i].triangles[j]]);
                    if ((int)newTriangleIdx[parts[i].triangles[j]] > 0) used = true;
                }
                if (used)
                {
                    newParts.Add(newPart);
                    newMaterialAssign.Add(materialAssign[i]);
                }
            }

            foreach (Material_ material in materials) retScene.materials.Add(new Material_(material));
            center = new Data.Scene.Vector3D(0, 0, 0);
            int count = newPoints.Count + selCams.Count + selLights.Count;

            foreach (Data.Scene.Vector3D v in newPoints)
            {
                center.x = center.x + v.x / count;
                center.y = center.y + v.y / count;
                center.z = center.z + v.z / count;
            }
            //foreach (int c in selCams)
            //{
            //    Camera cam = cams[c];
            //    center.x = center.x + cam.position.X / count;
            //    center.y = center.y + cam.position.Y / count;
            //    center.z = center.z + cam.position.Z / count;
            //}
            foreach (int l in selLights)
            {
                Light_ light = lights[l];
                center.x = center.x + light.position.X / count;
                center.y = center.y + light.position.Y / count;
                center.z = center.z + light.position.Z / count;
            }
            foreach (Data.Scene.Vector3D v in newPoints)
            {
                v.x -= center.x;
                v.y -= center.y;
                v.z -= center.z;
            }

            List<Light_> newwLights1 = new List<Light_>();

            foreach (int lightIndex in selLights)
            {
                Light_ light = new Light_(lights[lightIndex]);
                newwLights1.Add(light);
                newwLights1[newwLights1.Count - 1].position -= center;
                int tmp = newwLights1.Count - 1;

                //dodawanie światel do hierarchii
                if (selectedHierObj == null)
                {
                    HierarchyLight newLight = new HierarchyLight(light.name.ToString(), tmp);
                    newHierarchy.Add(newLight);
                }
                //newLight.name = light.name;
                Console.WriteLine( "dodawanie do hierarchiii");
            }

            //List<Camera> newCams = new List<Camera>();
            //foreach (int camIndex in selCams)
            //{
            //    newCams.Add(new Camera(cams[camIndex]));
            //    newCams[newCams.Count - 1].position -= center;
            //}

            retScene.points = newPoints;
            retScene.triangles = newTriangles;
            retScene.hierarchy.objects = newHierarchy;
            retScene.parts = newParts;
            retScene.materialAssign = newMaterialAssign;
            retScene.lights = newwLights1;
            //retScene.cams = newCams;

            hierarchyChange = true;
            return retScene;
        }
Exemple #14
0
        private static void ReadHierarchy(HierarchyNode node, List <Light_> lights, List <string> text, ref int pointer)
        {
            string objNumLabel = File.GetAttribute(text[pointer], 0);

            if (objNumLabel != "node_count")
            {
                throw new Exception();
            }
            uint objNum = uint.Parse(File.GetAttribute(text[pointer++], 1));

            for (int i = 0; i < objNum; ++i)
            {
                HierarchyObject newObject   = null;
                string          objStrLabel = File.GetAttribute(text[pointer], 0);
                if (objStrLabel != "hier_type")
                {
                    throw new Exception();
                }
                string objStr = File.GetAttribute(text[pointer++], 1);

                string[] objNameAtts = File.GetAttributes(text[pointer]);
                if (objNameAtts[0] != "hier_name")
                {
                    throw new Exception();
                }
                string objName = objName = File.CutFirstString(text[pointer]);
                ++pointer;

                switch (objStr)
                {
                case "Mesh":
                    newObject = new HierarchyMesh(objName);
                    node.hObjects.Add(newObject);

                    string triangleNumLabel = File.GetAttribute(text[pointer], 0);
                    if (triangleNumLabel != "triangle_count")
                    {
                        new Exception();
                    }
                    uint        triangleNum = uint.Parse(File.GetAttribute(text[pointer++], 1));
                    List <uint> triangles   = new List <uint>();

                    string[] triangs = File.GetAttributes(text[pointer]);
                    for (int j = 0; j < triangleNum; ++j)
                    {
                        triangles.Add(uint.Parse(triangs[j]));
                    }
                    ++pointer;

                    ((HierarchyMesh)newObject).triangles = triangles;
                    break;

                case "Light":
                    string lightIdxLabel = File.GetAttribute(text[pointer], 0);
                    if (lightIdxLabel != "light_index")
                    {
                        new Exception();
                    }
                    int lightIdx = int.Parse(File.GetAttribute(text[pointer++], 1));
                    newObject = new HierarchyLight(objName, lightIdx);
                    node.hObjects.Add(newObject);
                    break;

                case "Node":
                    newObject = new HierarchyNode(objName);
                    node.hObjects.Add(newObject);

                    ReadHierarchy((HierarchyNode)newObject, lights, text, ref pointer);
                    break;
                }
            }
        }