public Vector3 CalculateNormal(Model model)
 {
     //var vertices = Indices.Select(i => model.Positions[i]).ToArray();
     var u = model.Positions[Indices[1]] - model.Positions[Indices[0]];
     var v = model.Positions[Indices[2]] - model.Positions[Indices[0]];
     Normal = Vector3.Normalize(Vector3.Cross(u, v));
     return Normal;
 }
        //public void Draw(DeviceContext context, ShaderEnvironment environment)
        //{
        //    var modelBuffer = Buffer;
        //    if (modelBuffer == null)
        //        return;

        //    environment.World = Matrix;
        //    environment.UpdateBuffer(context);
            
        //    context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(modelBuffer, Vertex.Size, 0));
        //    context.Draw(Vertices.Count, 0);
        //}


        public static Model Join(string name, IEnumerable<Model> models)
        {
            var newModel = new Model
            {
                Name = name,
            };
            foreach (var model in models)
            {
                newModel.Faces.AddRange(model
                    .Faces
                    .Select(face => new Face(face
                        .Indices
                        .Select(i => i + newModel.Positions.Count)
                        .ToArray())
                        {
                            Color = face.Color
                        }));
                newModel.Positions.AddRange(model.Positions.Select(v => Vector3.TransformCoordinate(v, model.Matrix)));
                newModel.Normals.AddRange(model.Normals.Select(n => Vector3.TransformNormal(n, model.Matrix)));
                newModel.Colors.AddRange(model.Colors);
                newModel.TexCoord0.AddRange(model.TexCoord0);
                newModel.Normals = model.Normals;
            }
            return newModel;
        }
        public void Draw(Model model, ICamera camera)
        {
            if (model.Buffer == null)
                throw new NullReferenceException();
                //return;

            // TODO refactor
            //RenderContext.Apply(DeviceContext);

            var env = RenderContext.ShaderEnvironment;
            env.Resolution = new Vector2(RenderContext.RenderTarget.Width, RenderContext.RenderTarget.Height);
            //env.LerpTime = TimeFrame.Lerp;
            //env.AbsoluteTime = (float)TimeFrame.Absolute;
            env.LerpTime = (float)SyncManager.Data.LerpTime;
            env.AbsoluteTime = (float)Timer.Time;
            env.BeatTime = (float)(Timer.Time / 60 * Timer.Bpm);
            env.UpdateBuffer(DeviceContext, model.Matrix, camera);
            env.Lead = (float)SyncManager.Data.Lead;
            env.Nisse0 = (float)SyncManager.Data.Nisse0;
            env.Nisse1 = (float)SyncManager.Data.Nisse1;
            env.Nisse2 = (float)SyncManager.Data.Nisse2;
            env.Nisse3 = (float)SyncManager.Data.Nisse3;

            DeviceContext.VertexShader.SetConstantBuffer(0, env.Buffer);
            DeviceContext.PixelShader.SetConstantBuffer(0, env.Buffer);
            DeviceContext.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(model.Buffer, Vertex.Size, 0));
            DeviceContext.Draw(model.Positions.Count, 0);
        }