public override void Initialize()
        {
            // load all models
            lock (_syncRoot)
            {
                if (_initialized)
                {
                    return;
                }

                foreach (var voxelModel in VoxelModelStorage.Enumerate())
                {
                    var vmodel = new VisualVoxelModel(voxelModel, VoxelMeshFactory);
                    vmodel.BuildMesh(); //Build the mesh of all local models
                    _models.Add(voxelModel.Name, vmodel);
                }

                _initialized = true;
            }

            // if we have some requested models, remove those that was loaded
            List <string> loadedModels;

            lock (_syncRoot)
            {
                loadedModels = _pendingModels.Where(Contains).ToList();
                loadedModels.ForEach(m => _pendingModels.Remove(m));
            }

            // fire events
            foreach (var loadedModel in loadedModels)
            {
                var model = GetModel(loadedModel, false);
                OnVoxelModelAvailable(new VoxelModelReceivedEventArgs {
                    Model = model.VoxelModel
                });
            }

            HashSet <string> requestSet;

            lock (_syncRoot)
            {
                _pendingModels.ExceptWith(loadedModels);
                requestSet     = _pendingModels;
                _pendingModels = new HashSet <string>();
            }

            // request the rest models
            foreach (var absentModel in requestSet)
            {
                RequestModelAsync(absentModel);
            }
        }
 void ManagerVoxelModelReceived(object sender, VoxelModelReceivedEventArgs e)
 {
     // our model just downloaded, set it
     if (e.Model.Name == _voxelEntity.ModelName)
     {
         _visualVoxelModel             = _manager.GetModel(e.Model.Name);
         _manager.VoxelModelAvailable -= ManagerVoxelModelReceived;
         if (_voxelEntity.DefaultSize == Vector3.Zero && _visualVoxelModel.VoxelModel.States[0].BoundingBox != null)
         {
             SetEntityVoxelBB(_visualVoxelModel.VoxelModel.States[0].BoundingBox);
         }
     }
 }
        /// <summary>
        /// Creates a VisualVoxelEntity ready to render
        /// </summary>
        /// <param name="manager"></param>
        /// <param name="wrapped">wrapped VoxelEntity from server</param>
        public VisualVoxelEntity(IVoxelEntity wrapped, VoxelModelManager manager)
            : base(wrapped.DefaultSize, wrapped)
        {
            _voxelEntity = wrapped;
            _manager     = manager;

            //Create the world position of the Voxel Entity, based on its initial position

            if (wrapped.ModelInstance == null)
            {
                return;
            }

            var model = manager.GetModel(wrapped.ModelName);

            // set the model or wait for it
            if (model == null)
            {
                _manager.VoxelModelAvailable += ManagerVoxelModelReceived;
            }
            else
            {
                _visualVoxelModel = model;

                BoundingBox voxelModelBB;
                if (Entity is IOrientedSlope)
                {
                    //Use a forced boundingbox for the slope to work properly, this will be a 16*16*16 BB
                    voxelModelBB = new BoundingBox(new Vector3(-8, 0, -8), new Vector3(8, 16, 8));
                }
                else
                {
                    //Use the computed Bounding box from the model
                    voxelModelBB = _voxelEntity.ModelInstance.State.BoundingBox;
                }

                var scaleFactor = GetModelScale(wrapped);

                LocalBBox = new BoundingBox(voxelModelBB.Minimum * scaleFactor, voxelModelBB.Maximum * scaleFactor);

                //Add instance rotation, if existing
                if (Entity is IStaticEntity)
                {
                    LocalBBox = LocalBBox.Transform(Matrix.RotationQuaternion(((IStaticEntity)Entity).Rotation));
                }

                ComputeWorldBoundingBox(Entity.Position, out WorldBBox);
            }
        }
        /// <summary>
        /// Adds a new voxel model or updates it
        /// </summary>
        /// <param name="model"></param>
        public void SaveModel(VisualVoxelModel model)
        {
            model.VoxelModel.UpdateHash();

            lock (_syncRoot)
            {
                if (_models.ContainsKey(model.VoxelModel.Name))
                {
                    _models.Remove(model.VoxelModel.Name);
                    VoxelModelStorage.Delete(model.VoxelModel.Name);
                }
                _models.Add(model.VoxelModel.Name, model);
                VoxelModelStorage.Save(model.VoxelModel);
            }
        }
        /// <summary>
        /// Request a missing model from the server
        /// </summary>
        /// <param name="name"></param>
        public void DownloadModel(string name)
        {
            logger.Info("Downloading model: {0}", name);

            try
            {
                var req      = WebRequest.Create(string.Format("http://utopiarealms.com/models/{0}/download", Uri.EscapeDataString(name)));
                var response = req.GetResponse();

                using (var stream = response.GetResponseStream())
                {
                    var voxelModel = VoxelModel.LoadFromStream(stream);

                    lock (_syncRoot)
                    {
                        if (_models.ContainsKey(voxelModel.Name))
                        {
                            _models.Remove(voxelModel.Name);
                        }

                        var model = new VisualVoxelModel(voxelModel, VoxelMeshFactory);
                        model.BuildMesh();
                        _models.Add(voxelModel.Name, model);
                        _pendingModels.Remove(voxelModel.Name);
                    }

                    _receivedModels.Enqueue(voxelModel);
                    VoxelModelStorage.Save(voxelModel);
                }

                response.Close();
            }
            catch (Exception x)
            {
                logger.Error("Unable to download the model: {0}", x.Message);
            }
        }