public MeshingResult CreateMeshFromPrimMesher(string primName, PrimitiveBaseShape primShape, OpenMetaverse.Vector3 size, float lod, ShapeType desiredShape, bool preScale) { Vector3 szvec = new Vector3(size.X, size.Y, size.Z); ulong meshKey = primShape.GetMeshKey(szvec, lod); try { if (primShape.SculptEntry && ((primShape.SculptData == null) || (primShape.SculptData.Length == 0))) { //preload the sculpt/mesh data AssetBase asset = _assetCache.GetAsset(primShape.SculptTexture, AssetRequestInfo.InternalRequest()); if (asset == null) { return(null); } primShape.SculptData = asset.Data; } if (primShape.SculptEntry == false || (primShape.SculptEntry == true && (SculptType)primShape.SculptType != SculptType.Mesh)) { return(ExtractTrimeshFromPrimOrSculpt(primName, primShape, ref size, lod, preScale, meshKey)); } else //mesh { return(ExtractMeshingResultFromMesh(primName, primShape, ref size, lod, preScale, desiredShape, meshKey)); } } finally { //we dont need the sculpt data around anymore primShape.SculptData = null; } }
/// <summary> /// Load an asset /// </summary> /// <param name="assetFilename"></param> /// <param name="data"></param> /// <returns>true if asset was successfully loaded, false otherwise</returns> private bool LoadAsset(string assetPath, byte[] data) { // Right now we're nastily obtaining the UUID from the filename string filename = assetPath.Remove(0, ArchiveConstants.ASSETS_PATH.Length); int i = filename.LastIndexOf(ArchiveConstants.ASSET_EXTENSION_SEPARATOR); if (i == -1) { m_log.ErrorFormat( "[ARCHIVER]: Could not find extension information in asset path {0} since it's missing the separator {1}. Skipping", assetPath, ArchiveConstants.ASSET_EXTENSION_SEPARATOR); return(false); } string extension = filename.Substring(i); string uuid = filename.Remove(filename.Length - extension.Length); if (ArchiveConstants.EXTENSION_TO_ASSET_TYPE.ContainsKey(extension)) { sbyte assetType = ArchiveConstants.EXTENSION_TO_ASSET_TYPE[extension]; //m_log.DebugFormat("[ARCHIVER]: Importing asset {0}, type {1}", uuid, assetType); AssetBase asset = new AssetBase(new UUID(uuid), String.Empty); asset.Type = assetType; asset.Data = data; try { m_scene.CommsManager.AssetCache.AddAsset(asset, AssetRequestInfo.InternalRequest()); } catch (AssetServerException e) { m_log.ErrorFormat("[ARCHIVER] Uploading asset {0} failed: {1}", uuid, e); } /** * Create layers on decode for image assets. This is likely to significantly increase the time to load archives so * it might be best done when dearchive takes place on a separate thread * if (asset.Type=AssetType.Texture) * { * IJ2KDecoder cacheLayerDecode = scene.RequestModuleInterface<IJ2KDecoder>(); * if (cacheLayerDecode != null) * cacheLayerDecode.syncdecode(asset.FullID, asset.Data); * } */ return(true); } else { m_log.ErrorFormat( "[ARCHIVER]: Tried to dearchive data with path {0} with an unknown type extension {1}", assetPath, extension); return(false); } }
public void run(object o) { for (int i = 0; i < arrassets.Length; i++) { AssetBase ab = sn.CommsManager.AssetCache.GetAsset(arrassets[i], AssetRequestInfo.InternalRequest()); if (ab != null && ab.Data != null) { j2kdecode.Decode(arrassets[i], ab.Data); } } ThreadTracker.Remove(thisthread); }
/// <summary> /// Load an asset /// </summary> /// <param name="assetFilename"></param> /// <param name="data"></param> /// <returns>true if asset was successfully loaded, false otherwise</returns> private bool LoadAsset(string assetPath, byte[] data) { //IRegionSerializer serializer = scene.RequestModuleInterface<IRegionSerializer>(); // Right now we're nastily obtaining the UUID from the filename string filename = assetPath.Remove(0, ArchiveConstants.ASSETS_PATH.Length); int i = filename.LastIndexOf(ArchiveConstants.ASSET_EXTENSION_SEPARATOR); if (i == -1) { m_log.ErrorFormat( "[INVENTORY ARCHIVER]: Could not find extension information in asset path {0} since it's missing the separator {1}. Skipping", assetPath, ArchiveConstants.ASSET_EXTENSION_SEPARATOR); return(false); } string extension = filename.Substring(i); string uuid = filename.Remove(filename.Length - extension.Length); if (ArchiveConstants.EXTENSION_TO_ASSET_TYPE.ContainsKey(extension)) { sbyte assetType = ArchiveConstants.EXTENSION_TO_ASSET_TYPE[extension]; //m_log.DebugFormat("[INVENTORY ARCHIVER]: Importing asset {0}, type {1}", uuid, assetType); AssetBase asset = new AssetBase(new UUID(uuid), "RandomName"); asset.Type = assetType; asset.Data = data; try { m_commsManager.AssetCache.AddAsset(asset, AssetRequestInfo.InternalRequest()); } catch (AssetServerException) { } return(true); } else { m_log.ErrorFormat( "[INVENTORY ARCHIVER]: Tried to dearchive data with path {0} with an unknown type extension {1}", assetPath, extension); return(false); } }
protected internal void Execute() { m_log.DebugFormat("[ARCHIVER]: AssetsRequest executed looking for {0} assets", m_repliesRequired); // We can stop here if there are no assets to fetch if (m_repliesRequired == 0) { m_assetsRequestCallback(m_foundAssetUuids, m_notFoundAssetUuids); } foreach (UUID uuid in m_uuids) { m_assetCache.GetAsset(uuid, AssetRequestCallback, AssetRequestInfo.InternalRequest()); } }
/// <summary> /// Get an asset synchronously, potentially using an asynchronous callback. If the /// asynchronous callback is used, we will wait for it to complete. /// </summary> /// <param name="uuid"></param> /// <returns></returns> protected AssetBase GetAsset(UUID uuid) { m_waitingForObjectAsset = true; m_assetCache.GetAsset(uuid, AssetRequestCallback, AssetRequestInfo.InternalRequest()); // The asset cache callback can either // // 1. Complete on the same thread (if the asset is already in the cache) or // 2. Come in via a different thread (if we need to go fetch it). // // The code below handles both these alternatives. lock (this) { if (m_waitingForObjectAsset) { Monitor.Wait(this); m_waitingForObjectAsset = false; } } return(m_requestedObjectAsset); }
// This fetches the texture from the asset server synchroneously. That should be ok, as we // call map-creation only in those places: // - on start: We can wait here until the asset server returns the texture // TODO (- on "map" command: We are in the command-line thread, we will wait for completion anyway) // TODO (- on "automatic" update after some change: We are called from the mapUpdateTimer here and // will wait anyway) private Bitmap fetchTexture(UUID id) { AssetBase asset = m_scene.CommsManager.AssetCache.GetAsset(id, AssetRequestInfo.InternalRequest()); m_log.DebugFormat("Fetched texture {0}, found: {1}", id, asset != null); if (asset == null) { return(null); } ManagedImage managedImage; Image image; try { if (OpenJPEG.DecodeToImage(asset.Data, out managedImage, out image)) { return(new Bitmap(image)); } else { return(null); } } catch (DllNotFoundException) { m_log.ErrorFormat("[TexturedMapTileRenderer]: OpenJpeg is not installed correctly on this system. Asset Data is empty for {0}", id); } catch (IndexOutOfRangeException) { m_log.ErrorFormat("[TexturedMapTileRenderer]: OpenJpeg was unable to encode this. Asset Data is empty for {0}", id); } catch (Exception) { m_log.ErrorFormat("[TexturedMapTileRenderer]: OpenJpeg was unable to encode this. Asset Data is empty for {0}", id); } return(null); }
/// <summary> /// Resolve a new piece of asset data against stored metadata /// </summary> /// <param name="assetFilename"></param> /// <param name="data"></param> protected void ResolveAssetData(string assetPath, byte[] data) { // Right now we're nastily obtaining the UUID from the filename string filename = assetPath.Remove(0, ArchiveConstants.ASSETS_PATH.Length); if (m_metadata.ContainsKey(filename)) { AssetMetadata metadata = m_metadata[filename]; if (ArchiveConstants.ASSET_TYPE_TO_EXTENSION.ContainsKey(metadata.AssetType)) { string extension = ArchiveConstants.ASSET_TYPE_TO_EXTENSION[metadata.AssetType]; filename = filename.Remove(filename.Length - extension.Length); } m_log.DebugFormat("[ARCHIVER]: Importing asset {0}", filename); AssetBase asset = new AssetBase(new UUID(filename), metadata.Name); asset.Description = metadata.Description; asset.Type = metadata.AssetType; asset.Data = data; try { m_cache.AddAsset(asset, AssetRequestInfo.InternalRequest()); } catch (AssetServerException e) { m_log.ErrorFormat("[ARCHIVER] Uploading asset {0} failed: {1}", filename, e); } } else { m_log.ErrorFormat( "[DEARCHIVER]: Tried to dearchive data with filename {0} without any corresponding metadata", assetPath); } }
private bool SubmitAssetLoadRequest(LoadUnloadRequest lrq) { UUID scriptAssetId = this.FindAssetId(lrq); if (scriptAssetId != UUID.Zero) { if (AddAssetWait(scriptAssetId, lrq)) { _assetCache.GetAsset(scriptAssetId, delegate(UUID i, AssetBase a) { this.AssetReceived(lrq.Prim.LocalId, lrq.ItemId, i, a); }, AssetRequestInfo.InternalRequest()); } return(true); } return(false); }
/// <summary> /// Called once new texture data has been received for this updater. /// </summary> public void DataReceived(byte[] data, Scene scene) { SceneObjectPart part = scene.GetSceneObjectPart(PrimID); if (data == null) { string msg = String.Format("DynamicTextureModule: Error preparing image using URL {0}", Url); scene.SimChat(Utils.StringToBytes(msg), ChatTypeEnum.Say, 0, part.ParentGroup.RootPart.AbsolutePosition, part.Name, part.UUID, false); return; } byte[] assetData; AssetBase oldAsset = null; if (BlendWithOldTexture) { UUID lastTextureID = part.Shape.Textures.DefaultTexture.TextureID; oldAsset = scene.CommsManager.AssetCache.GetAsset(lastTextureID, AssetRequestInfo.InternalRequest()); if (oldAsset != null) { assetData = BlendTextures(data, oldAsset.Data, SetNewFrontAlpha, FrontAlpha); } else { assetData = new byte[data.Length]; Array.Copy(data, assetData, data.Length); } } else { assetData = new byte[data.Length]; Array.Copy(data, assetData, data.Length); } // Create a new asset for user AssetBase asset = new AssetBase(); asset.FullID = UUID.Random(); asset.Data = assetData; asset.Name = "DynamicImage" + Util.RandomClass.Next(1, 10000); asset.Type = 0; asset.Description = "dynamic image"; asset.Local = false; asset.Temporary = true; scene.CommsManager.AssetCache.AddAsset(asset, AssetRequestInfo.InternalRequest()); LastAssetID = asset.FullID; IJ2KDecoder cacheLayerDecode = scene.RequestModuleInterface <IJ2KDecoder>(); if (cacheLayerDecode != null) { cacheLayerDecode.Decode(asset.FullID, asset.Data); } cacheLayerDecode = null; // mostly keep the values from before Primitive.TextureEntry tmptex = part.Shape.Textures; // remove the old asset from the cache UUID oldID = tmptex.DefaultTexture.TextureID; tmptex.DefaultTexture.TextureID = asset.FullID; // I'm pretty sure we always want to force this to true // I'm pretty sure noone whats to set fullbright true if it wasn't true before. // tmptex.DefaultTexture.Fullbright = true; part.Shape.Textures = tmptex; part.ScheduleFullUpdate(); }
/// <summary> /// Export the world map /// </summary> /// <param name="fileName"></param> public void HandleExportWorldMapConsoleCommand(string module, string[] cmdparams) { if (m_scene.ConsoleScene() == null) { // FIXME: If console region is root then this will be printed by every module. Currently, there is no // way to prevent this, short of making the entire module shared (which is complete overkill). // One possibility is to return a bool to signal whether the module has completely handled the command m_log.InfoFormat("[WORLD MAP]: Please change to a specific region in order to export its world map"); return; } if (m_scene.ConsoleScene() != m_scene) { return; } string exportPath; if (cmdparams.Length > 1) { exportPath = cmdparams[1]; } else { exportPath = DEFAULT_WORLD_MAP_EXPORT_PATH; } m_log.InfoFormat( "[WORLD MAP]: Exporting world map for {0} to {1}", m_scene.RegionInfo.RegionName, exportPath); List <MapBlockData> mapBlocks = m_scene.CommsManager.GridService.RequestNeighbourMapBlocks( (int)(m_scene.RegionInfo.RegionLocX - 9), (int)(m_scene.RegionInfo.RegionLocY - 9), (int)(m_scene.RegionInfo.RegionLocX + 9), (int)(m_scene.RegionInfo.RegionLocY + 9)); List <AssetBase> textures = new List <AssetBase>(); List <Image> bitImages = new List <Image>(); foreach (MapBlockData mapBlock in mapBlocks) { AssetBase texAsset = m_scene.CommsManager.AssetCache.GetAsset(mapBlock.MapImageId, AssetRequestInfo.InternalRequest()); if (texAsset != null) { textures.Add(texAsset); } else { texAsset = m_scene.CommsManager.AssetCache.GetAsset(mapBlock.MapImageId, AssetRequestInfo.InternalRequest()); if (texAsset != null) { textures.Add(texAsset); } } } foreach (AssetBase asset in textures) { ManagedImage managedImage; Image image; if (OpenJPEG.DecodeToImage(asset.Data, out managedImage, out image)) { bitImages.Add(image); } } Bitmap mapTexture = new Bitmap(2560, 2560); Graphics g = Graphics.FromImage(mapTexture); SolidBrush sea = new SolidBrush(Color.DarkBlue); g.FillRectangle(sea, 0, 0, 2560, 2560); for (int i = 0; i < mapBlocks.Count; i++) { ushort x = (ushort)((mapBlocks[i].X - m_scene.RegionInfo.RegionLocX) + 10); ushort y = (ushort)((mapBlocks[i].Y - m_scene.RegionInfo.RegionLocY) + 10); g.DrawImage(bitImages[i], (x * 128), (y * 128), 128, 128); } mapTexture.Save(exportPath, ImageFormat.Jpeg); m_log.InfoFormat( "[WORLD MAP]: Successfully exported world map for {0} to {1}", m_scene.RegionInfo.RegionName, exportPath); }
public Hashtable OnHTTPGetMapImage(Hashtable keysvals) { bool forceRefresh = false; if (keysvals.ContainsKey("requestvars")) { Hashtable rvars = (Hashtable)keysvals["requestvars"]; if (rvars.ContainsKey("forcerefresh")) { forceRefresh = true; } } if (forceRefresh) { m_log.Debug("[WORLD MAP]: Forcing refresh of map tile"); //regenerate terrain m_scene.CreateTerrainTexture(false); } m_log.Debug("[WORLD MAP]: Sending map image jpeg"); Hashtable reply = new Hashtable(); int statuscode = 200; byte[] jpeg = new byte[0]; if (myMapImageJPEG.Length == 0 || (DateTime.Now - _lastImageGenerationTime).TotalDays > MAPIMAGE_CACHE_TIME || forceRefresh) { MemoryStream imgstream = new MemoryStream(); Bitmap mapTexture = new Bitmap(1, 1); ManagedImage managedImage; Image image = (Image)mapTexture; try { // Taking our jpeg2000 data, decoding it, then saving it to a byte array with regular jpeg data imgstream = new MemoryStream(); // non-async because we know we have the asset immediately. AssetBase mapasset = m_scene.CommsManager.AssetCache.GetAsset(m_scene.RegionInfo.lastMapUUID, AssetRequestInfo.InternalRequest()); // Decode image to System.Drawing.Image if (OpenJPEG.DecodeToImage(mapasset.Data, out managedImage, out image)) { // Save to bitmap mapTexture = new Bitmap(image); EncoderParameters myEncoderParameters = new EncoderParameters(); myEncoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, 95L); // Save bitmap to stream mapTexture.Save(imgstream, GetEncoderInfo("image/jpeg"), myEncoderParameters); // Write the stream to a byte array for output jpeg = imgstream.ToArray(); myMapImageJPEG = jpeg; _lastImageGenerationTime = DateTime.Now; } } catch (Exception) { // Dummy! m_log.Warn("[WORLD MAP]: Unable to generate Map image"); } finally { // Reclaim memory, these are unmanaged resources mapTexture.Dispose(); image.Dispose(); imgstream.Close(); imgstream.Dispose(); } } else { // Use cached version so we don't have to loose our mind jpeg = myMapImageJPEG; } reply["str_response_string"] = Convert.ToBase64String(jpeg); reply["int_response_code"] = statuscode; reply["content_type"] = "image/jpeg"; return(reply); }
public void LazySaveGeneratedMaptile(byte[] data, bool temporary) { // Overwrites the local Asset cache with new maptile data // Assets are single write, this causes the asset server to ignore this update, // but the local asset cache does not // this is on purpose! The net result of this is the region always has the most up to date // map tile while protecting the (grid) asset database from bloat caused by a new asset each // time a mapimage is generated! UUID lastMapRegionUUID = m_scene.RegionInfo.lastMapUUID; int lastMapRefresh = 0; int twoDays = 172800; int RefreshSeconds = twoDays; try { lastMapRefresh = Convert.ToInt32(m_scene.RegionInfo.lastMapRefresh); } catch (ArgumentException) { } catch (FormatException) { } catch (OverflowException) { } UUID TerrainImageUUID = UUID.Random(); if (lastMapRegionUUID == UUID.Zero || (lastMapRefresh + RefreshSeconds) < Util.UnixTimeSinceEpoch()) { m_scene.RegionInfo.SaveLastMapUUID(TerrainImageUUID); m_log.Debug("[MAPTILE]: STORING MAPTILE IMAGE"); } else { TerrainImageUUID = lastMapRegionUUID; m_log.Debug("[MAPTILE]: REUSING OLD MAPTILE IMAGE ID"); } m_scene.RegionInfo.RegionSettings.TerrainImageID = TerrainImageUUID; AssetBase asset = new AssetBase(); asset.FullID = m_scene.RegionInfo.RegionSettings.TerrainImageID; asset.Data = data; asset.Name = "terrainImage_" + m_scene.RegionInfo.RegionID.ToString() + "_" + lastMapRefresh.ToString(); asset.Description = m_scene.RegionInfo.RegionName; asset.Type = 0; asset.Temporary = temporary; try { m_scene.CommsManager.AssetCache.AddAsset(asset, AssetRequestInfo.InternalRequest()); } catch (AssetServerException) { } }