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); } }