public TriangeIntersectable(Triangle triangle)
            : base(triangle)
        {
            Vector3 a = Vector3.Transform(triangle.A, triangle.Transform);
            Vector3 b = Vector3.Transform(triangle.B, triangle.Transform);
            Vector3 c = Vector3.Transform(triangle.C, triangle.Transform);

            Center = (a + b + c)/3;
            BoundingBox = BoundingBox.CreateFromPoints(new[] {a, b, c});
        }
        public void BuildMesh(int[] vertexCounts, int[] poligonIndexes, float[] vertices, float[] normals, float[] texcoord, Material material)
        {
            //Only tiangles supported for now
            if (!vertexCounts.All(c => c == 3))
                throw new Exception("Only tiangles supported for now");

            int poligonCount = vertexCounts.Count();
            Triangles = new List<Triangle>(poligonCount);

            int poligonComponentsCount = texcoord != null ? 3 : 2;

            for (int i = 0; i < poligonCount; i++)
            {
                Triangle triangle = new Triangle();
                triangle.Material = material;

                int polygonOffset = i*vertexCounts[i]*poligonComponentsCount;

                int vertexBOffset = 1*poligonComponentsCount;
                int vertexCOffset = 2*poligonComponentsCount;

                triangle.A = vertices.ToVec3(poligonIndexes[polygonOffset]);
                triangle.B = vertices.ToVec3(poligonIndexes[polygonOffset + vertexBOffset]);
                triangle.C = vertices.ToVec3(poligonIndexes[polygonOffset + vertexCOffset]);

                int normalOffset = polygonOffset + 1;

                triangle.Na = normals.ToVec3(poligonIndexes[normalOffset]);
                triangle.Nb = normals.ToVec3(poligonIndexes[normalOffset + vertexBOffset]);
                triangle.Nc = normals.ToVec3(poligonIndexes[normalOffset + vertexCOffset]);

                if (texcoord != null)
                {
                    int texcoordOffset = polygonOffset + 2;

                    triangle.Ta = texcoord.ToVec2(poligonIndexes[texcoordOffset]);
                    triangle.Tb = texcoord.ToVec2(poligonIndexes[texcoordOffset + vertexBOffset]);
                    triangle.Tc = texcoord.ToVec2(poligonIndexes[texcoordOffset + vertexCOffset]);
                }

                Triangles.Add(triangle);
            }
        }
        private void ProcessLine(string[] tokens)
        {
            string command = tokens[0];

            TargetedCamera camera = (TargetedCamera) _scene.Camera;
            switch (command)
            {
                case "size":
                    {
                        camera.Width = tokens.ToInt(1);
                        camera.Height = tokens.ToInt(2);
                        break;
                    }
                case "maxdepth ":
                    {
                        _scene.MaxDepth = tokens.ToInt(1);
                        break;
                    }
                case "output":
                    {
                        _scene.OutputFileName = tokens[1];
                        break;
                    }
                case "camera":
                    {
                        camera.Translation = Matrix.CreateTranslation(tokens.ToVec3(1));
                        camera.Target = tokens.ToVec3(4);
                        camera.Up = tokens.ToVec3(7);

                        float yFov = tokens.ToFloat(10);
                        camera.Fov = yFov;
                        camera.UseXFov = false;
                        break;
                    }
                case "sphere":
                    {
                        Sphere sphere = new Sphere(tokens.ToVec3(1), tokens.ToFloat(4))
                                            {
                                                Material = (Material) _material.Clone(),
                                                Transform = _transforms.Peek()
                                            };

                        _scene.Geomertries.Add(sphere);
                        break;
                    }
                case "maxverts":
                    {
                        _vertices = new List<Vector3>(tokens.ToInt(1));
                        break;
                    }
                case "maxvertnorms":
                    {
                        _vertices = new List<Vector3>(tokens.ToInt(1));
                        _verticesNormals = new List<Vector3>(tokens.ToInt(1));
                        break;
                    }
                case "vertex":
                    {
                        _vertices.Add(tokens.ToVec3(1));
                        break;
                    }
                case "vertexnormal":
                    {
                        _vertices.Add(tokens.ToVec3(1));
                        _verticesNormals.Add(tokens.ToVec3(4));
                        break;
                    }
                case "tri":
                    {
            //						Triangle triangle = new Triangle(_vertices[tokens.ToInt(1)], _vertices[tokens.ToInt(2)], _vertices[tokens.ToInt(3)])
            //						                    	{
            //						                    		Material = (Material) _material.Clone(),
            //						                    		Transform = _transforms.Peek()
            //						                    	};
                        CalculatedTriangle triangle = new CalculatedTriangle(_vertices[tokens.ToInt(1)], _vertices[tokens.ToInt(2)], _vertices[tokens.ToInt(3)],_transforms.Peek())
                                                {
                                                    Material = (Material) _material.Clone()
                                                };

                        _scene.Geomertries.Add(triangle);
                        break;
                    }
                case "trinormal":
                    {
                        Triangle triangle = new Triangle(_vertices[tokens.ToInt(1)], _vertices[tokens.ToInt(2)], _vertices[tokens.ToInt(3)])
                                                {
                                                    Na = _verticesNormals[tokens.ToInt(1)],
                                                    Nb = _verticesNormals[tokens.ToInt(2)],
                                                    Nc = _verticesNormals[tokens.ToInt(3)],
                                                    Material = (Material) _material.Clone(),
                                                    Transform = _transforms.Peek()
                                                };

                        _scene.Geomertries.Add(triangle);
                        break;
                    }
                case "translate":
                    {
                        Matrix matrix = Matrix.CreateTranslation(tokens.ToVec3(1));
                        RightMultiply(matrix);
                        break;
                    }
                case "rotate":
                    {
                        Matrix matrix = Transform.Rotate(tokens.ToFloat(4), tokens.ToVec3(1));
                        RightMultiply(matrix);
                        break;
                    }
                case "scale":
                    {
                        Matrix matrix = Matrix.CreateScale(tokens.ToVec3(1));
                        RightMultiply(matrix);
                        break;
                    }
                case "pushTransform":
                    {
                        Matrix matrix = _transforms.Peek();
                        _transforms.Push(matrix);
                        break;
                    }
                case "popTransform":
                    {
                        _transforms.Pop();
                        break;
                    }
                case "directional":
                    {
                        DirectionalLight light = new DirectionalLight
                                                 	{
                                                 		Color = tokens.ToVec3(4)
                                                 	};

                        Matrix rotation = Matrix.Identity;
                        rotation.Backward = tokens.ToVec3(1);
                        light.Rotation = rotation;

                        _scene.Lights.Add(light);
                        break;
                    }
                case "point":
                    {
                        PointLight light = new PointLight
                                           	{
                                           		Color = tokens.ToVec3(4),
                                           		Translation = Matrix.CreateTranslation(tokens.ToVec3(1)),
                                           		AttenuationConst = _attenuationConst,
                                           		AttenuationLinear = _attenuationLinear,
                                           		AttenuationQuadratic = _attenuationQuadratic
                                           	};

                        _scene.Lights.Add(light);
                        break;
                    }
                case "attenuation":
                    {
                        _attenuationConst = tokens.ToFloat(1);
                        _attenuationLinear = tokens.ToFloat(2);
                        _attenuationQuadratic = tokens.ToFloat(3);
                        break;
                    }
                case "ambient":
                    {
                        _material.AmbientColor = tokens.ToVec3(1);
                        break;
                    }
                case "diffuse":
                    {
                        _material.DiffuseColor = new PlaneColorSampler(tokens.ToVec3(1));
                        break;
                    }
                case "specular":
                    {
                        _material.SpecularColor = tokens.ToVec3(1);
                        _material.ReflectiveColor = tokens.ToVec3(1);
                        _material.Reflectivity = 1.0f;
                        break;
                    }
                case "shininess":
                    {
                        _material.Shininess = tokens.ToFloat(1);
                        break;
                    }
                case "emission":
                    {
                        _material.EmissionColor = tokens.ToVec3(1);
                        break;
                    }
            }
        }