Ejemplo n.º 1
0
        void AssetUploadRequestHandler(Packet packet, Agent agent)
        {
            AssetUploadRequestPacket request = (AssetUploadRequestPacket)packet;
            UUID assetID = UUID.Combine(request.AssetBlock.TransactionID, agent.SecureSessionID);

            // Check if the asset is small enough to fit in a single packet
            if (request.AssetBlock.AssetData.Length != 0)
            {
                // Create a new asset from the completed upload
                Asset asset = CreateAsset((AssetType)request.AssetBlock.Type, assetID, request.AssetBlock.AssetData);
                if (asset == null)
                {
                    Logger.Log("Failed to create asset from uploaded data", Helpers.LogLevel.Warning);
                    return;
                }

                Logger.DebugLog(String.Format("Storing uploaded asset {0} ({1})", assetID, asset.AssetType));

                asset.Temporary = (request.AssetBlock.Tempfile | request.AssetBlock.StoreLocal);

                // Store the asset
                StoreAsset(asset);

                // Send a success response
                AssetUploadCompletePacket complete = new AssetUploadCompletePacket();
                complete.AssetBlock.Success = true;
                complete.AssetBlock.Type    = request.AssetBlock.Type;
                complete.AssetBlock.UUID    = assetID;
                server.UDP.SendPacket(agent.AgentID, complete, PacketCategory.Inventory);
            }
            else
            {
                // Create a new (empty) asset for the upload
                Asset asset = CreateAsset((AssetType)request.AssetBlock.Type, assetID, null);
                if (asset == null)
                {
                    Logger.Log("Failed to create asset from uploaded data", Helpers.LogLevel.Warning);
                    return;
                }

                Logger.DebugLog(String.Format("Starting upload for {0} ({1})", assetID, asset.AssetType));

                asset.Temporary = (request.AssetBlock.Tempfile | request.AssetBlock.StoreLocal);

                RequestXferPacket xfer = new RequestXferPacket();
                xfer.XferID.DeleteOnCompletion = request.AssetBlock.Tempfile;
                xfer.XferID.FilePath           = 0;
                xfer.XferID.Filename           = new byte[0];
                xfer.XferID.ID            = request.AssetBlock.TransactionID.GetULong();
                xfer.XferID.UseBigPackets = false;
                xfer.XferID.VFileID       = asset.AssetID;
                xfer.XferID.VFileType     = request.AssetBlock.Type;

                // Add this asset to the current upload list
                lock (CurrentUploads)
                    CurrentUploads[xfer.XferID.ID] = asset;

                server.UDP.SendPacket(agent.AgentID, xfer, PacketCategory.Inventory);
            }
        }
Ejemplo n.º 2
0
        private void SendPresenceAnimationsHandler(object sender, PhysicalPresenceArgs e)
        {
            IPhysicalPresence presence = e.Presence;

            presence.Scene.CreateInterestListEvent(new InterestListEvent(UUID.Combine(presence.ID, ANIMATION_EVENT_ID),
                                                                         AVATAR_ANIMATION, presence.ScenePosition, presence.Scale, presence));
        }
        public void RequestUpdateInventoryItem(IClientAPI remoteClient, UUID transactionID,
                                               InventoryItemBase item)
        {
            if (XferUploaders.ContainsKey(transactionID))
            {
                UUID assetID = UUID.Combine(transactionID, remoteClient.SecureSessionId);

                AssetBase asset = Manager.MyScene.AssetService.Get(assetID.ToString());

                if (asset == null)
                {
                    asset = GetTransactionAsset(transactionID);
                }

                if (asset != null && asset.FullID == assetID)
                {
                    // Assets never get updated, new ones get created
                    asset.FullID      = UUID.Random();
                    asset.Name        = item.Name;
                    asset.Description = item.Description;
                    asset.Type        = (sbyte)item.AssetType;
                    item.AssetID      = asset.FullID;

                    Manager.MyScene.AssetService.Store(asset);
                }

                IInventoryService invService = Manager.MyScene.InventoryService;
                invService.UpdateItem(item);
            }
        }
Ejemplo n.º 4
0
 public void PreloadSound(ISceneEntity source, UUID soundID, float radius)
 {
     m_scene.CreateInterestListEvent(new InterestListEvent(
                                         UUID.Combine(soundID, PRELOAD_EVENT_ID),
                                         PRELOAD_SOUND,
                                         source.ScenePosition,
                                         new Vector3(radius),
                                         new object[] { source, soundID })
                                     );
 }
Ejemplo n.º 5
0
        /*private Packet UpdateInventory(Packet packet, IPEndPoint sim)
         * {
         *  /*
         *  UpdateInventoryItemPacket uip = (UpdateInventoryItemPacket)packet;
         *  foreach (UpdateInventoryItemPacket.InventoryDataBlock block in uip.InventoryData)
         *  {
         *      if (block.Type == 10)
         *      {
         *          if(trans2Item.ContainsKey(block.TransactionID))
         *          {
         *              trans2Item[block.TransactionID]=block.ItemID;
         *          }else
         *          trans2Item.Add(block.TransactionID, block.ItemID);
         *      }
         *  }
         *  foreach (CurrentUploadType cu in name2SaveBuffer)
         *  {
         *      if (trans2Item.ContainsKey(cu.uploadID))
         *      {
         *          string filename = trans2Item[curentUpload.uploadID].ToString();
         *
         *          File.WriteAllBytes("Scripts Cache\\" + filename, curentUpload.oldscriptdata);
         *      }
         *  }
         *  name2SaveBuffer.Clear();
         *  return packet;
         * }*/
        private Packet TryToSendAsset(Packet packet, IPEndPoint sim)
        {
            if (Enabled)
            {
                AssetUploadRequestPacket ass = (AssetUploadRequestPacket)packet;
                if (ass.AssetBlock.Type == (sbyte)AssetType.LSLText)
                {
                    Console.WriteLine("Atempting to save to inv with asset type " + ass.AssetBlock.Type.ToString());

                    CurrentUploadType curentUpload = new CurrentUploadType();
                    curentUpload.proxySending  = false;
                    curentUpload.local         = ass.AssetBlock.StoreLocal;
                    curentUpload.temp          = ass.AssetBlock.Tempfile;
                    curentUpload.uploadID      = ass.AssetBlock.TransactionID;
                    curentUpload.type          = ass.AssetBlock.Type;
                    curentUpload.data          = new byte[] { };
                    curentUpload.paid          = false;
                    curentUpload.oldscriptdata = new byte[300000];

                    /*uint newperms = 0;
                     * newperms |= (uint)PermissionMask.Modify;
                     * newperms |= (uint)PermissionMask.Copy;
                     * newperms |= (uint)PermissionMask.Transfer;
                     *
                     * curentUpload.ownerMask = newperms;*/


                    curentUpload.curentdatalenght = 0;
                    curentUpload.oldmaxsize       = 90000;
                    //Buffer.BlockCopy(ass.AssetBlock.AssetData, 0, curentUpload.oldscriptdata, 0, curentUpload.curentdatalenght);


                    AssetUploadRequestPacket asetUp = new AssetUploadRequestPacket();
                    asetUp.AssetBlock.StoreLocal    = curentUpload.local;
                    asetUp.AssetBlock.Tempfile      = false;
                    asetUp.AssetBlock.TransactionID = curentUpload.uploadID;
                    asetUp.AssetBlock.Type          = (sbyte)AssetType.LSLText;
                    asetUp.AssetBlock.AssetData     = new byte[] { };
                    //proxy.InjectPacket(asetUp, Direction.Outgoing);
                    //proxy
                    curentUpload.VFileAssetID = UUID.Combine(curentUpload.uploadID, frame.SecureSessionID);

                    form.log("We are expecintg a vfile id of " + curentUpload.VFileAssetID.ToString(), System.Drawing.Color.Black, System.Drawing.Color.Magenta);
                    if (this.uploadsLookingForXferId.ContainsKey(curentUpload.VFileAssetID))
                    {
                        this.uploadsLookingForXferId[curentUpload.VFileAssetID] = curentUpload;
                    }
                    else
                    {
                        this.uploadsLookingForXferId.Add(curentUpload.VFileAssetID, curentUpload);
                    }
                }
            }
            return(packet);
        }
Ejemplo n.º 6
0
        private void ChatFromViewerHandler(Packet packet, LLAgent agent)
        {
            ChatFromViewerPacket chat     = (ChatFromViewerPacket)packet;
            ChatType             chatType = (ChatType)chat.ChatData.Type;
            string message = Utils.BytesToString(chat.ChatData.Message);
            int    channel = chat.ChatData.Channel;

            // Don't allow clients to chat on negative channels
            if (channel < 0)
            {
                channel = 0;
            }

            // Start/stop typing messages are specific to the LLUDP protocol, so we create events
            // directly that will be processed by this same class. Chat messages are a generic
            // event that can be supported by multiple protocols, so we call IScene.EntityChat and
            // hook IScene.OnChat to do the actual processing

            // Event IDs for start/stop typing are generated with UUID.Combine(agent.ID, TYPING_EVENT_ID)
            // to create an ID that is unique to each agent in the context of typing. Newer typing
            // events will overwrite older ones

            switch (chatType)
            {
            case ChatType.StartTyping:
                m_scene.CreateInterestListEvent(new InterestListEvent(UUID.Combine(agent.ID, TYPING_EVENT_ID),
                                                                      VIEWER_TYPING, agent.ScenePosition, new Vector3(NORMAL_DIST),
                                                                      new TypingData {
                    Source = agent, StartTyping = true
                }));
                break;

            case ChatType.StopTyping:
                m_scene.CreateInterestListEvent(new InterestListEvent(UUID.Combine(agent.ID, TYPING_EVENT_ID),
                                                                      VIEWER_TYPING, agent.ScenePosition, new Vector3(NORMAL_DIST),
                                                                      new TypingData {
                    Source = agent, StartTyping = false
                }));
                break;

            case ChatType.Whisper:
                m_scene.EntityChat(this, agent, WHISPER_DIST, message, channel, EntityChatType.Normal);
                break;

            case ChatType.Shout:
                m_scene.EntityChat(this, agent, SHOUT_DIST, message, channel, EntityChatType.Normal);
                break;

            case ChatType.Normal:
            default:
                m_scene.EntityChat(this, agent, NORMAL_DIST, message, channel, EntityChatType.Normal);
                break;
            }
        }
Ejemplo n.º 7
0
        public void SaveToSLInventory(byte[] uploaddata, String nname, sbyte type, bool copy, bool mod, bool trans, bool pay, bool local, bool temp)
        {
            Console.WriteLine("Atempting to save to inv");
            uploadID = UUID.Random();
            AssetUploadRequestPacket asetUp = new AssetUploadRequestPacket();

            asetUp.AssetBlock.StoreLocal = local;

            asetUp.AssetBlock.Tempfile      = temp;
            asetUp.AssetBlock.TransactionID = uploadID;
            specialID = UUID.Combine(uploadID, frame.SessionID);
            asetUp.AssetBlock.Type = (sbyte)type;

            asetUp.AssetBlock.AssetData = new byte[] { };
            proxy.InjectPacket(asetUp, Direction.Outgoing);

            this.curentUpload  = new CurrentUploadType();
            curentUpload.name  = nname;
            curentUpload.data  = uploaddata;
            curentUpload.temp  = temp;
            curentUpload.type  = (sbyte)type;
            curentUpload.local = local;
            curentUpload.paid  = pay;

            grabbed = 0;
            if (pay)
            {
                payMoney(10);
            }
            uint newperms = 0;

            if (mod)
            {
                newperms |= (uint)PermissionMask.Modify;
            }
            if (copy)
            {
                newperms |= (uint)PermissionMask.Copy;
            }
            if (trans)
            {
                newperms |= (uint)PermissionMask.Transfer;
            }

            curentUpload.ownerMask = newperms;

            //generate owner mask
        }
Ejemplo n.º 8
0
        private void SaveScriptState(LSLScriptInstance instance)
        {
            // Create a state file for this script
            byte[] scriptState = instance.GetSerializedState();

            m_assetClient.StoreAsset(new Asset
            {
                ContentType  = "application/vnd.ll.lslstate",
                CreatorID    = instance.Host.OwnerID,
                Data         = scriptState,
                ID           = UUID.Combine(instance.ID, SCRIPT_STATE_MAGIC_ID),
                Local        = true,
                Temporary    = true,
                CreationDate = DateTime.UtcNow
            });
        }
Ejemplo n.º 9
0
        private void PresenceAddHandler(object sender, PresenceArgs e)
        {
            m_scene.ForEachPresence(
                delegate(IScenePresence presence)
            {
                InterestListEvent eventData = new InterestListEvent
                                              (
                    UUID.Combine(presence.ID, APPEARANCE_EVENT_ID),
                    AVATAR_APPEARANCE,
                    presence.ScenePosition,
                    presence.Scale,
                    presence
                                              );

                m_scene.CreateInterestListEventFor(e.Presence, eventData);
            }
                );
        }
Ejemplo n.º 10
0
        public void RequestUpdateInventoryItem(IClientAPI remoteClient, UUID transactionID,
                                               InventoryItemBase item)
        {
            if (XferUploaders.ContainsKey(transactionID))
            {
                UUID assetID = UUID.Combine(transactionID, remoteClient.SecureSessionId);

                AssetXferUploader uploader = XferUploaders[transactionID];
                if (!uploader.Finished)
                {
                    uploader.FinishedEvent = () =>
                                             UpdateInventoryItemWithAsset(item, assetID, transactionID);
                    return;
                }

                UpdateInventoryItemWithAsset(item, assetID, transactionID);
            }
        }
Ejemplo n.º 11
0
        public void llInstantMessage(IScriptInstance script, string user, string message)
        {
            if (m_messaging != null)
            {
                UUID toID;
                UUID.TryParse(user, out toID);

                // Keep a persistent messageID for all IMs from the host object to the target agent
                UUID messageID = UUID.Combine(script.Host.ID, toID);

                m_messaging.SendInstantMessage(messageID, toID, script.Host.Name,
                                               script.Host.ScenePosition, script.Host.Scene.ID, false,
                                               InstantMessageDialog.MessageFromObject, message, false, DateTime.UtcNow,
                                               Utils.EmptyBytes);
            }

            script.AddSleepMS(2000);
        }
Ejemplo n.º 12
0
        public void RequestUpdateInventoryItem(IClientAPI remoteClient, UUID transactionID,
                                               InventoryItemBase item)
        {
            if (XferUploaders.ContainsKey(transactionID))
            {
                CachedUserInfo userInfo = Manager.MyScene.CommsManager.UserProfileCacheService.GetUserDetails(
                    remoteClient.AgentId);

                if (userInfo != null)
                {
                    UUID assetID = UUID.Combine(transactionID, remoteClient.SecureSessionId);

                    AssetBase asset
                        = Manager.MyScene.CommsManager.AssetCache.GetAsset(
                              assetID, (item.AssetType == (int)AssetType.Texture ? true : false));

                    if (asset == null)
                    {
                        asset = GetTransactionAsset(transactionID);
                    }

                    if (asset != null && asset.FullID == assetID)
                    {
                        // Assets never get updated, new ones get created
                        asset.FullID      = UUID.Random();
                        asset.Name        = item.Name;
                        asset.Description = item.Description;
                        asset.Type        = (sbyte)item.AssetType;
                        item.AssetID      = asset.FullID;

                        Manager.MyScene.CommsManager.AssetCache.AddAsset(asset);
                    }

                    userInfo.UpdateItem(item);
                }
                else
                {
                    m_log.ErrorFormat(
                        "[ASSET TRANSACTIONS]: Could not find user {0} for inventory item update",
                        remoteClient.AgentId);
                }
            }
        }
Ejemplo n.º 13
0
        private void ViewerEffectHandler(Packet packet, LLAgent agent)
        {
            ViewerEffectPacket effect = (ViewerEffectPacket)packet;

            // Broadcast this viewer effect to everyone
            for (int i = 0; i < effect.Effect.Length; i++)
            {
                ViewerEffectPacket.EffectBlock block = effect.Effect[i];

                if (block.AgentID == agent.ID)
                {
                    m_scene.CreateInterestListEvent(new InterestListEvent(UUID.Combine(block.ID, EFFECT_EVENT_ID), VIEWER_EFFECT, agent.ScenePosition, Vector3.One, block));
                }
                else
                {
                    m_log.Warn("Skipping ViewerEffect block for " + block.AgentID + " from " + agent.ID + " (" + agent.Name + ")");
                }
            }
        }
Ejemplo n.º 14
0
        public void RequestUpdateInventoryItem(IClientAPI remoteClient, UUID transactionID,
                                               InventoryItemBase item)
        {
            if (XferUploaders.ContainsKey(transactionID))
            {
                UUID assetID = UUID.Combine(transactionID, remoteClient.SecureSessionId);

                AssetBase asset = Manager.MyScene.AssetService.Get(assetID.ToString());

                if (asset == null)
                {
                    asset = GetTransactionAsset(transactionID);
                }

                if (asset != null && asset.ID == assetID)
                {
                    // Assets never get updated, new ones get created
                    asset.ID          = UUID.Random();
                    asset.Name        = item.Name;
                    asset.Description = item.Description;
                    asset.Type        = (sbyte)item.AssetType;
                    item.AssetID      = asset.ID;

                    asset.ID     = Manager.MyScene.AssetService.Store(asset);
                    item.AssetID = asset.ID;
                }

                IMonitorModule monitorModule = Manager.MyScene.RequestModuleInterface <IMonitorModule>();
                if (monitorModule != null)
                {
                    INetworkMonitor networkMonitor =
                        (INetworkMonitor)
                        monitorModule.GetMonitor(Manager.MyScene.RegionInfo.RegionID.ToString(),
                                                 MonitorModuleHelper.NetworkMonitor);
                    networkMonitor.AddPendingUploads(-1);
                }

                IInventoryService invService = Manager.MyScene.InventoryService;
                invService.UpdateItem(item);
            }
        }
Ejemplo n.º 15
0
        private void AssetUploadRequestHandler(Packet packet, LLAgent agent)
        {
            AssetUploadRequestPacket request = (AssetUploadRequestPacket)packet;
            UUID      assetID = UUID.Combine(request.AssetBlock.TransactionID, agent.SecureSessionID);
            AssetType type    = (AssetType)request.AssetBlock.Type;

            // Check if the agent is allowed to upload an asset
            string uploadError;

            if (m_permissions != null && !m_permissions.TryUploadOneAsset(agent, out uploadError))
            {
                m_scene.PresenceAlert(this, agent, uploadError);
                return;
            }

            bool local = request.AssetBlock.StoreLocal | type == AssetType.LSLBytecode;
            bool temp  = request.AssetBlock.Tempfile;

            // Check if the asset is small enough to fit in a single packet
            if (request.AssetBlock.AssetData.Length != 0)
            {
                // Create a new asset from the completed upload

                Asset asset = CreateAsset(type, assetID, DateTime.UtcNow, agent.ID, local, temp, request.AssetBlock.AssetData);

                if (asset == null)
                {
                    m_log.Warn("Failed to create asset from uploaded data");
                    return;
                }

                if (type != AssetType.LSLBytecode)
                {
                    // Store the asset
                    m_log.DebugFormat("Storing uploaded asset {0} ({1})", assetID, asset.ContentType);
                    if (!m_assets.StoreAsset(asset))
                    {
                        m_log.ErrorFormat("Failed to store uploaded asset {0} ({1})", assetID, asset.ContentType);
                    }
                }
                else
                {
                    m_log.Debug("Ignoring LSL bytecode upload " + assetID);
                }

                // Send a success response
                AssetUploadCompletePacket complete = new AssetUploadCompletePacket();
                complete.AssetBlock.Success = true;
                complete.AssetBlock.Type    = request.AssetBlock.Type;
                complete.AssetBlock.UUID    = assetID;
                m_udp.SendPacket(agent, complete, ThrottleCategory.Task, false);
            }
            else
            {
                // Create a new (empty) asset for the upload
                Asset asset = CreateAsset(type, assetID, DateTime.UtcNow, agent.ID, local, temp, null);

                if (asset == null)
                {
                    m_log.Warn("Failed to create asset from uploaded data");
                    return;
                }

                asset.Temporary = (request.AssetBlock.Tempfile | request.AssetBlock.StoreLocal);
                ulong transferID = request.AssetBlock.TransactionID.GetULong();

                // Prevent LSL bytecode transfers from colliding with LSL source transfers, which
                // use a colliding UUID
                if (type == AssetType.LSLBytecode)
                {
                    ++transferID;
                }

                RequestXferPacket xfer = new RequestXferPacket();
                xfer.XferID.DeleteOnCompletion = request.AssetBlock.Tempfile;
                xfer.XferID.FilePath           = 0;
                xfer.XferID.Filename           = Utils.EmptyBytes;
                xfer.XferID.ID            = transferID;
                xfer.XferID.UseBigPackets = false;
                xfer.XferID.VFileID       = asset.ID;
                xfer.XferID.VFileType     = request.AssetBlock.Type;

                m_log.DebugFormat("Starting upload for {0} / {1} ({2})", assetID, transferID, asset.ContentType);

                // Add this asset to the current upload list
                lock (currentUploads)
                    currentUploads[transferID] = asset;

                m_udp.SendPacket(agent, xfer, ThrottleCategory.Task, false);
            }
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Builds a composited terrain texture given the region texture
        /// and heightmap settings
        /// </summary>
        /// <param name="terrain">Terrain heightmap</param>
        /// <param name="regionInfo">Region information including terrain texture parameters</param>
        /// <returns>A 256x256 square RGB texture ready for rendering</returns>
        /// <remarks>Based on the algorithm described at http://opensimulator.org/wiki/Terrain_Splatting
        /// Note we create a 256x256 dimension texture even if the actual terrain is larger.
        /// </remarks>
        public static Bitmap Splat(ITerrainChannel terrain,
                                   UUID[] textureIDs, float[] startHeights, float[] heightRanges,
                                   Vector3d regionPosition, IAssetService assetService, bool textureTerrain)
        {
            Debug.Assert(textureIDs.Length == 4);
            Debug.Assert(startHeights.Length == 4);
            Debug.Assert(heightRanges.Length == 4);

            Bitmap[] detailTexture = new Bitmap[4];

            if (textureTerrain)
            {
                // Swap empty terrain textureIDs with default IDs
                for (int i = 0; i < textureIDs.Length; i++)
                {
                    if (textureIDs[i] == UUID.Zero)
                    {
                        textureIDs[i] = DEFAULT_TERRAIN_DETAIL[i];
                    }
                }

                #region Texture Fetching

                if (assetService != null)
                {
                    for (int i = 0; i < 4; i++)
                    {
                        AssetBase asset;
                        UUID      cacheID = UUID.Combine(TERRAIN_CACHE_MAGIC, textureIDs[i]);

                        // Try to fetch a cached copy of the decoded/resized version of this texture
                        asset = assetService.GetCached(cacheID.ToString());
                        if (asset != null)
                        {
                            try
                            {
                                using (System.IO.MemoryStream stream = new System.IO.MemoryStream(asset.Data))
                                    detailTexture[i] = (Bitmap)Image.FromStream(stream);
                            }
                            catch (Exception ex)
                            {
                                m_log.Warn("Failed to decode cached terrain texture " + cacheID +
                                           " (textureID: " + textureIDs[i] + "): " + ex.Message);
                            }
                        }

                        if (detailTexture[i] == null)
                        {
                            // Try to fetch the original JPEG2000 texture, resize if needed, and cache as PNG
                            asset = assetService.Get(textureIDs[i].ToString());
                            if (asset != null)
                            {
                                //                                    m_log.DebugFormat(
                                //                                        "[TERRAIN SPLAT]: Got cached original JPEG2000 terrain texture {0} {1}", i, asset.ID);

                                try { detailTexture[i] = (Bitmap)CSJ2K.J2kImage.FromBytes(asset.Data); }
                                catch (Exception ex)
                                {
                                    m_log.Warn("Failed to decode terrain texture " + asset.ID + ": " + ex.Message);
                                }
                            }

                            if (detailTexture[i] != null)
                            {
                                // Make sure this texture is the correct size, otherwise resize
                                if (detailTexture[i].Width != 256 || detailTexture[i].Height != 256)
                                {
                                    using (Bitmap origBitmap = detailTexture[i])
                                    {
                                        detailTexture[i] = ImageUtils.ResizeImage(origBitmap, 256, 256);
                                    }
                                }

                                // Save the decoded and resized texture to the cache
                                byte[] data;
                                using (System.IO.MemoryStream stream = new System.IO.MemoryStream())
                                {
                                    detailTexture[i].Save(stream, ImageFormat.Png);
                                    data = stream.ToArray();
                                }

                                // Cache a PNG copy of this terrain texture
                                AssetBase newAsset = new AssetBase
                                {
                                    Data        = data,
                                    Description = "PNG",
                                    Flags       = AssetFlags.Collectable,
                                    FullID      = cacheID,
                                    ID          = cacheID.ToString(),
                                    Local       = true,
                                    Name        = String.Empty,
                                    Temporary   = true,
                                    Type        = (sbyte)AssetType.Unknown
                                };
                                newAsset.Metadata.ContentType = "image/png";
                                assetService.Store(newAsset);
                            }
                        }
                    }
                }

                #endregion Texture Fetching
            }

            // Fill in any missing textures with a solid color
            for (int i = 0; i < 4; i++)
            {
                if (detailTexture[i] == null)
                {
                    m_log.DebugFormat("{0} Missing terrain texture for layer {1}. Filling with solid default color",
                                      LogHeader, i);
                    // Create a solid color texture for this layer
                    detailTexture[i] = new Bitmap(256, 256, PixelFormat.Format24bppRgb);
                    using (Graphics gfx = Graphics.FromImage(detailTexture[i]))
                    {
                        using (SolidBrush brush = new SolidBrush(DEFAULT_TERRAIN_COLOR[i]))
                            gfx.FillRectangle(brush, 0, 0, 256, 256);
                    }
                }
                else
                {
                    if (detailTexture[i].Width != 256 || detailTexture[i].Height != 256)
                    {
                        detailTexture[i] = ResizeBitmap(detailTexture[i], 256, 256);
                    }
                }
            }

            #region Layer Map

            float[,] layermap = new float[256, 256];

            // Scale difference between actual region size and the 256 texture being created
            int xFactor = terrain.Width / 256;
            int yFactor = terrain.Height / 256;

            // Create 'layermap' where each value is the fractional layer number to place
            //    at that point. For instance, a value of 1.345 gives the blending of
            //    layer 1 and layer 2 for that point.
            for (int y = 0; y < 256; y++)
            {
                for (int x = 0; x < 256; x++)
                {
                    float height = (float)terrain[x * xFactor, y *yFactor];

                    float pctX = (float)x / 255f;
                    float pctY = (float)y / 255f;

                    // Use bilinear interpolation between the four corners of start height and
                    // height range to select the current values at this position
                    float startHeight = ImageUtils.Bilinear(
                        startHeights[0],
                        startHeights[2],
                        startHeights[1],
                        startHeights[3],
                        pctX, pctY);
                    startHeight = Utils.Clamp(startHeight, 0f, 255f);

                    float heightRange = ImageUtils.Bilinear(
                        heightRanges[0],
                        heightRanges[2],
                        heightRanges[1],
                        heightRanges[3],
                        pctX, pctY);
                    heightRange = Utils.Clamp(heightRange, 0f, 255f);

                    // Generate two frequencies of perlin noise based on our global position
                    // The magic values were taken from http://opensimulator.org/wiki/Terrain_Splatting
                    Vector3 vec = new Vector3
                                  (
                        ((float)regionPosition.X + (x * xFactor)) * 0.20319f,
                        ((float)regionPosition.Y + (y * yFactor)) * 0.20319f,
                        height * 0.25f
                                  );

                    float lowFreq  = Perlin.noise2(vec.X * 0.222222f, vec.Y * 0.222222f) * 6.5f;
                    float highFreq = Perlin.turbulence2(vec.X, vec.Y, 2f) * 2.25f;
                    float noise    = (lowFreq + highFreq) * 2f;

                    // Combine the current height, generated noise, start height, and height range parameters, then scale all of it
                    float layer = ((height + noise - startHeight) / heightRange) * 4f;
                    if (Single.IsNaN(layer))
                    {
                        layer = 0f;
                    }
                    layermap[x, y] = Utils.Clamp(layer, 0f, 3f);
                }
            }

            #endregion Layer Map

            #region Texture Compositing

            Bitmap     output     = new Bitmap(256, 256, PixelFormat.Format24bppRgb);
            BitmapData outputData = output.LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);

            // Unsafe work as we lock down the source textures for quicker access and access the
            //    pixel data directly
            unsafe
            {
                // Get handles to all of the texture data arrays
                BitmapData[] datas = new BitmapData[]
                {
                    detailTexture[0].LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.ReadOnly, detailTexture[0].PixelFormat),
                    detailTexture[1].LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.ReadOnly, detailTexture[1].PixelFormat),
                    detailTexture[2].LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.ReadOnly, detailTexture[2].PixelFormat),
                    detailTexture[3].LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.ReadOnly, detailTexture[3].PixelFormat)
                };

                // Compute size of each pixel data (used to address into the pixel data array)
                int[] comps = new int[]
                {
                    (datas[0].PixelFormat == PixelFormat.Format32bppArgb) ? 4 : 3,
                    (datas[1].PixelFormat == PixelFormat.Format32bppArgb) ? 4 : 3,
                    (datas[2].PixelFormat == PixelFormat.Format32bppArgb) ? 4 : 3,
                    (datas[3].PixelFormat == PixelFormat.Format32bppArgb) ? 4 : 3
                };

                for (int y = 0; y < 256; y++)
                {
                    for (int x = 0; x < 256; x++)
                    {
                        float layer = layermap[x, y];

                        // Select two textures
                        int l0 = (int)Math.Floor(layer);
                        int l1 = Math.Min(l0 + 1, 3);

                        byte *ptrA = (byte *)datas[l0].Scan0 + y * datas[l0].Stride + x * comps[l0];
                        byte *ptrB = (byte *)datas[l1].Scan0 + y * datas[l1].Stride + x * comps[l1];
                        byte *ptrO = (byte *)outputData.Scan0 + y * outputData.Stride + x * 3;

                        float aB = *(ptrA + 0);
                        float aG = *(ptrA + 1);
                        float aR = *(ptrA + 2);

                        float bB = *(ptrB + 0);
                        float bG = *(ptrB + 1);
                        float bR = *(ptrB + 2);

                        float layerDiff = layer - l0;

                        // Interpolate between the two selected textures
                        *(ptrO + 0) = (byte)Math.Floor(aB + layerDiff * (bB - aB));
                        *(ptrO + 1) = (byte)Math.Floor(aG + layerDiff * (bG - aG));
                        *(ptrO + 2) = (byte)Math.Floor(aR + layerDiff * (bR - aR));
                    }
                }

                for (int i = 0; i < detailTexture.Length; i++)
                {
                    detailTexture[i].UnlockBits(datas[i]);
                }
            }

            for (int i = 0; i < detailTexture.Length; i++)
            {
                if (detailTexture[i] != null)
                {
                    detailTexture[i].Dispose();
                }
            }

            output.UnlockBits(outputData);

            // We generated the texture upside down, so flip it
            output.RotateFlip(RotateFlipType.RotateNoneFlipY);

            #endregion Texture Compositing

            return(output);
        }
        public bool RequestUpdateInventoryItem(IClientAPI remoteClient, UUID transactionID, InventoryItemBase item)
        {
            AssetXferUploader uploader = GetTransactionUploader(transactionID);

            if (uploader == null)
            {
                m_log.WarnFormat("[ASSET TRANSACTIONS]: Transaction {0} NOT FOUND (duplicate removed?) for inventory item update {1}", transactionID, item.Name);
                return(false);
            }

            CachedUserInfo userInfo = Manager.MyScene.CommsManager.UserService.GetUserDetails(remoteClient.AgentId);

            if (userInfo == null)
            {
                m_log.WarnFormat("[ASSET TRANSACTIONS]: Could not find user {0} for transaction {1} for inventory update {2}",
                                 remoteClient.AgentId, transactionID, item.Name);
                return(false);
            }

            // This may complete now if upload complete, or later when the upload completes.
            uploader.TriggerWhenUploadComplete(delegate(AssetBase asset)
            {
                // This upload transaction is complete.
                XferUploaders.Remove(transactionID);

                UUID assetID = UUID.Combine(transactionID, remoteClient.SecureSessionId);
                if (asset == null || asset.FullID != assetID)
                {
                    m_log.ErrorFormat("[ASSETS]: RequestUpdateInventoryItem wrong asset ID or not found {0}", asset == null ? "null" : asset.FullID.ToString());
                    return;
                }

                // Assets never get updated, new ones get created
                UUID oldID        = asset.FullID;
                asset.FullID      = UUID.Random();
                asset.Name        = item.Name;
                asset.Description = item.Description;
                asset.Type        = (sbyte)item.AssetType;

                try
                {
                    m_log.DebugFormat("[ASSETS]: RequestUpdateInventoryItem for transaction {0}, new asset {1} -> {2}", transactionID, oldID, asset.FullID);
                    Manager.MyScene.CommsManager.AssetCache.AddAsset(asset, AssetRequestInfo.GenericNetRequest());
                }
                catch (AssetServerException e)
                {
                    remoteClient.SendAgentAlertMessage("Unable to upload asset. Please try again later.", false);
                    m_log.ErrorFormat("[ASSET TRANSACTIONS] Creation of asset failed {0}", e);
                    return;
                }

                item.AssetID = asset.FullID;

                //wait for completion of the write to avoid reversion
                ManualResetEventSlim waitEvent = new ManualResetEventSlim();

                remoteClient.HandleWithInventoryWriteThread(() =>
                {
                    // Update the asset ID
                    userInfo.UpdateItem(item);
                    waitEvent.Set();
                });

                waitEvent.Wait();
                waitEvent.Dispose();
            });

            return(true);    // userInfo item was updated
        }
 public bool UploadAssetData(bool storeLocal)
 {
     if (IsLocalScene)
     {
         ReplaceAll();
         RezRequested = true;
         NewID        = OldID;
         _NewItem     = OldItem;
         return(true);
     }
     if (CogbotHelpers.IsNullOrZero(NewID))
     {
         if (UseUploadKnown)
         {
             AssetUploaded.Reset();
             if (assetType == AssetType.Notecard)
             {
                 Inventory.RequestCreateItem(GetAssetUploadsFolder(), "" + OldID,
                                             Description, assetType, UUID.Zero,
                                             OpenMetaverse.InventoryType.Notecard,
                                             PermissionMask.All, UpdateInvItem);
             }
             else if (assetType == AssetType.Gesture)
             {
                 Inventory.RequestCreateItem(GetAssetUploadsFolder(), "" + OldID,
                                             Description, assetType, UUID.Zero,
                                             OpenMetaverse.InventoryType.Gesture,
                                             PermissionMask.All, UpdateInvItem);
                 // (gesture.Sequence)
             }
             else if (assetType == AssetType.LSLText)
             {
                 Inventory.RequestCreateItem(GetAssetUploadsFolder(), "" + OldID,
                                             Description, assetType, UUID.Zero,
                                             OpenMetaverse.InventoryType.LSL,
                                             PermissionMask.All, UpdateInvItem);
             }
             else if (assetType == AssetType.Landmark)
             {
                 var decodeME = new AssetLandmark(UUID.Zero, AssetData);
                 decodeME.Decode();
                 byte[] bytes = AssetData;
                 Inventory.RequestCreateItem(GetAssetUploadsFolder(), "" + OldID,
                                             "RegionID:" + decodeME.RegionID + ",Postion" + decodeME.Position +
                                             "," + DateTime.Now, assetType, UUID.Zero,
                                             OpenMetaverse.InventoryType.Landmark,
                                             PermissionMask.All, UpdateInvItem);
             }
             else if (assetType == AssetType.CallingCard)
             {
                 var decodeME = new AssetCallingCard(UUID.Zero, AssetData);
                 decodeME.Decode();
                 byte[] bytes = AssetData;
                 Inventory.RequestCreateItem(GetAssetUploadsFolder(), "" + OldID,
                                             "AvatarID:" + decodeME.AvatarID + "," + DateTime.Now,
                                             assetType, UUID.Zero,
                                             OpenMetaverse.InventoryType.CallingCard,
                                             PermissionMask.All, UpdateInvItem);
             }
             else
             {
                 Inventory.RequestCreateItemFromAsset(AssetData, "" + OldID, Description,
                                                      assetType, inventoryType,
                                                      GetAssetUploadsFolder(),
                                                      Permissions.FullPermissions,
                                                      InvItemCreated);
             }
             if (!AssetUploaded.WaitOne(10000))
             {
                 return(false);
             }
             return(true);
         }
         NewID = UUID.Combine(OldID, Importing.Client.Self.SecureSessionID);
         NewUUID2OBJECT[NewID] = this;
         Importing.Client.Assets.RequestUploadKnown(NewID, assetType, AssetData, storeLocal, OldID);
         RezRequested = true;
     }
     return(true);
 }
Ejemplo n.º 19
0
        private void AgentSetAppearanceHandler(Packet packet, LLAgent agent)
        {
            AgentSetAppearancePacket set = (AgentSetAppearancePacket)packet;
            UpdateFlags   updateFlags    = 0;
            LLUpdateFlags llUpdateFlags  = 0;

            m_log.Debug("Updating avatar appearance with " + set.VisualParam.Length + " visual params, texture=" +
                        (set.ObjectData.TextureEntry.Length > 1 ? "yes" : "no"));

            //TODO: Store this for cached bake responses
            for (int i = 0; i < set.WearableData.Length; i++)
            {
                //AvatarTextureIndex index = (AvatarTextureIndex)set.WearableData[i].TextureIndex;
                //UUID cacheID = set.WearableData[i].CacheID;

                //m_log.DebugFormat("WearableData: {0} is now {1}", index, cacheID);
            }

            // Create a TextureEntry
            if (set.ObjectData.TextureEntry.Length > 1)
            {
                agent.TextureEntry = new Primitive.TextureEntry(set.ObjectData.TextureEntry, 0,
                                                                set.ObjectData.TextureEntry.Length);

                llUpdateFlags |= LLUpdateFlags.Textures;

                #region Bake Cache Check

                for (int i = 0; i < BAKE_INDICES.Length; i++)
                {
                    int j = BAKE_INDICES[i];
                    Primitive.TextureEntryFace face = agent.TextureEntry.FaceTextures[j];

                    if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE)
                    {
                        m_log.Debug("Baked texture " + (AvatarTextureIndex)j + " set to " + face.TextureID);
                    }
                }

                #endregion Bake Cache Check
            }

            if (agent.Scale != set.AgentData.Size)
            {
                // This will be modified in UpdateHeight() if VisualParams are also sent
                agent.Scale  = set.AgentData.Size;
                updateFlags |= UpdateFlags.Scale;
            }

            // Create a block of VisualParams
            if (set.VisualParam.Length > 1)
            {
                byte[] visualParams = new byte[set.VisualParam.Length];
                for (int i = 0; i < set.VisualParam.Length; i++)
                {
                    visualParams[i] = set.VisualParam[i].ParamValue;
                }

                agent.VisualParams = visualParams;
                agent.UpdateHeight();

                // Create the event that generates an AvatarAppearance packet for this agent
                m_scene.CreateInterestListEvent(new InterestListEvent
                                                (
                                                    UUID.Combine(agent.ID, APPEARANCE_EVENT_ID),
                                                    AVATAR_APPEARANCE,
                                                    agent.ScenePosition,
                                                    agent.Scale,
                                                    agent
                                                ));
            }

            if (updateFlags != 0 || llUpdateFlags != 0)
            {
                m_scene.EntityAddOrUpdate(this, agent, updateFlags, (uint)llUpdateFlags);
            }
        }
Ejemplo n.º 20
0
 private void PresenceAddHandler(object sender, PresenceArgs e)
 {
     // When an LLUDP agent logs in, send them current animation data for every presence in the sim
     if (e.Presence is LLAgent)
     {
         m_scene.ForEachPresence(
             delegate(IScenePresence presence)
         {
             m_scene.CreateInterestListEventFor(e.Presence, new InterestListEvent(UUID.Combine(presence.ID, ANIMATION_EVENT_ID), AVATAR_ANIMATION,
                                                                                  presence.ScenePosition, presence.Scale, presence));
         }
             );
     }
 }
Ejemplo n.º 21
0
        private Color4 GetFaceColor(Primitive.TextureEntryFace face)
        {
            Color4 color;

            if (face.TextureID == UUID.Zero)
            {
                return(face.RGBA);
            }

            if (!m_colors.TryGetValue(face.TextureID, out color))
            {
                bool fetched = false;

                // Attempt to fetch the texture metadata
                UUID      metadataID = UUID.Combine(face.TextureID, TEXTURE_METADATA_MAGIC);
                AssetBase metadata   = m_scene.AssetService.GetCached(metadataID.ToString());
                if (metadata != null)
                {
                    OSDMap map = null;
                    try
                    {
                        map = OSDParser.Deserialize(metadata.Data) as OSDMap;
                    }
                    catch
                    {
                    }

                    if (map != null)
                    {
                        color = map["X-JPEG2000-RGBA"].AsColor4();
                        if (!(color.R == 0.5f && color.G == 0.5f && color.B == 0.5f && color.A == 1.0f))
                        {
                            //If we failed, don't save it
                            fetched = true;
                        }
                    }
                    map      = null;
                    metadata = null;
                }

                if (!fetched)
                {
                    // Fetch the texture, decode and get the average color,
                    // then save it to a temporary metadata asset
                    AssetBase textureAsset = m_scene.AssetService.Get(face.TextureID.ToString());
                    if (textureAsset != null)
                    {
                        int width, height;
                        color = GetAverageColor(textureAsset.ID, textureAsset.Data, m_scene, out width, out height);
                        if (!(color.R == 0.5f && color.G == 0.5f && color.B == 0.5f && color.A == 1.0f))
                        //If we failed, don't save it
                        {
                            OSDMap data = new OSDMap {
                                { "X-JPEG2000-RGBA", OSD.FromColor4(color) }
                            };
                            metadata = new AssetBase
                            {
                                Data        = Encoding.UTF8.GetBytes(OSDParser.SerializeJsonString(data)),
                                Description = "Avg Color-JPEG2000 texture " + face.TextureID.ToString(),
                                Flags       = AssetFlags.Collectable | AssetFlags.Temperary | AssetFlags.Local,
                                ID          = metadataID,
                                Name        = String.Empty,
                                TypeAsset   = AssetType.Simstate
                                              // Make something up to get around OpenSim's myopic treatment of assets
                            };
                            metadata.ID = m_scene.AssetService.Store(metadata);
                        }
                        textureAsset = null;
                    }
                    else
                    {
                        color = new Color4(0.5f, 0.5f, 0.5f, 1.0f);
                    }
                }

                m_colors[face.TextureID] = color;
            }

            return(color * face.RGBA);
        }
Ejemplo n.º 22
0
 private UUID CreateTerrainEventID(int x, int y)
 {
     return(UUID.Combine(TERRAIN_EVENT_ID, new UUID(Utils.UIntsToLong((uint)x, (uint)y))));
 }
Ejemplo n.º 23
0
        private void UpdateTaskInventoryHandler(Packet packet, LLAgent agent)
        {
            UpdateTaskInventoryPacket update = (UpdateTaskInventoryPacket)packet;

            LLInventoryTaskItem item;
            ISceneEntity        targetObj;

            if (update.UpdateData.Key != 0)
            {
                m_log.Warn("Got an UpdateTaskInventory packet with a Key of " + update.UpdateData.Key);
                return;
            }

            if (m_scene.TryGetEntity(update.UpdateData.LocalID, out targetObj) && targetObj is LLPrimitive)
            {
                LLPrimitive targetPrim = (LLPrimitive)targetObj;

                // Updating an existing item in the task inventory
                if (targetPrim.Inventory.TryGetItem(update.InventoryData.ItemID, out item))
                {
                    if (update.InventoryData.TransactionID != UUID.Zero)
                    {
                        item.AssetID = UUID.Combine(update.InventoryData.TransactionID, agent.SecureSessionID);
                    }

                    item.Description = Utils.BytesToString(update.InventoryData.Description);
                    item.Flags       = update.InventoryData.Flags;
                    item.GroupID     = update.InventoryData.GroupID;
                    item.GroupOwned  = update.InventoryData.GroupOwned;
                    item.Name        = Utils.BytesToString(update.InventoryData.Name);
                    item.Permissions = new Permissions(update.InventoryData.BaseMask, update.InventoryData.EveryoneMask,
                                                       update.InventoryData.GroupMask, update.InventoryData.NextOwnerMask, update.InventoryData.OwnerMask);
                    item.SalePrice = update.InventoryData.SalePrice;
                    item.SaleType  = (SaleType)update.InventoryData.SaleType;

                    targetPrim.Inventory.AddOrUpdateItem(item, true);
                    m_log.Debug(agent.Name + " updated task inventory item: " + item.Name);

                    SignalTaskInventoryChange(agent, targetPrim);
                }
                else if (m_inventory != null)
                {
                    // Copying from agent inventory to task inventory
                    InventoryBase obj;
                    if (m_inventory.TryGetInventory(agent.ID, update.InventoryData.ItemID, out obj))
                    {
                        if (obj is InventoryItem)
                        {
                            // Create a new item in the task inventory
                            LLInventoryItem fromItem = new LLInventoryItem((InventoryItem)obj);

                            item = new LLInventoryTaskItem();
                            //item.ID will be assigned in AddOrUpdateItem
                            item.AssetID            = fromItem.AssetID;
                            item.ContentType        = fromItem.ContentType;
                            item.CreationDate       = fromItem.CreationDate;
                            item.CreatorID          = fromItem.CreatorID;
                            item.Description        = fromItem.Description;
                            item.Flags              = fromItem.ExtraData["Flags"].AsUInteger();
                            item.GrantedPermissions = 0;
                            item.GroupID            = fromItem.ExtraData["group_id"].AsUUID();
                            item.GroupOwned         = fromItem.ExtraData["group_owned"].AsBoolean();
                            item.Name              = fromItem.Name;
                            item.OwnerID           = agent.ID;
                            item.ParentID          = update.InventoryData.FolderID;
                            item.ParentObjectID    = targetPrim.ID;
                            item.PermissionGranter = UUID.Zero;
                            item.Permissions       = fromItem.Permissions;
                            item.SalePrice         = fromItem.ExtraData["sale_price"].AsInteger();
                            item.SaleType          = (SaleType)fromItem.ExtraData["sale_type"].AsInteger();

                            targetPrim.Inventory.AddOrUpdateItem(item, false);
                            m_log.Debug(agent.Name + " created new task inventory item: " + item.Name);

                            SignalTaskInventoryChange(agent, targetPrim);
                        }
                        else
                        {
                            m_log.Error("[TODO] Handle dropping folders in task inventory");
                        }
                    }
                    else
                    {
                        m_log.Warn(agent.Name + " sent an UpdateTaskInventory packet requesting unknown " +
                                   "(or failed to fetch) inventory item " + update.InventoryData.ItemID);
                    }
                }
                else
                {
                    m_log.Warn(agent.Name + "attempted to copy inventory item " + update.InventoryData.ItemID +
                               " to task inventory, but we have no IInventoryClient");
                }
            }
            else
            {
                m_log.Warn(agent.Name + " attempted to update task inventory for prim " + update.UpdateData.LocalID +
                           " that does not exist in this scene");
            }
        }
Ejemplo n.º 24
0
        /// <summary>
        ///   Builds a composited terrain texture given the region texture
        ///   and heightmap settings
        /// </summary>
        /// <param name = "heightmap">Terrain heightmap</param>
        /// <param name = "regionInfo">Region information including terrain texture parameters</param>
        /// <returns>A composited 256x256 RGB texture ready for rendering</returns>
        /// <remarks>
        ///   Based on the algorithm described at http://opensimulator.org/wiki/Terrain_Splatting
        /// </remarks>
        public static Bitmap Splat(ITerrainChannel heightmap, UUID[] textureIDs, float[] startHeights,
                                   float[] heightRanges, Vector3d regionPosition, IAssetService assetService,
                                   bool textureTerrain)
        {
            Debug.Assert(textureIDs.Length == 4);
            Debug.Assert(startHeights.Length == 4);
            Debug.Assert(heightRanges.Length == 4);

            Bitmap[] detailTexture = new Bitmap[4];

            if (textureTerrain)
            {
                // Swap empty terrain textureIDs with default IDs
                for (int i = 0; i < textureIDs.Length; i++)
                {
                    if (textureIDs[i] == UUID.Zero)
                    {
                        textureIDs[i] = DEFAULT_TERRAIN_DETAIL[i];
                    }
                }

                #region Texture Fetching

                if (assetService != null)
                {
                    for (int i = 0; i < 4; i++)
                    {
                        UUID      cacheID = UUID.Combine(TERRAIN_CACHE_MAGIC, textureIDs[i]);
                        AssetBase asset   = assetService.GetCached(cacheID.ToString());
                        if ((asset != null) && (asset.Data != null) && (asset.Data.Length != 0))
                        {
                            try
                            {
                                using (MemoryStream stream = new MemoryStream(asset.Data))
                                    detailTexture[i] = (Bitmap)Image.FromStream(stream);
                            }
                            catch (Exception ex)
                            {
                                MainConsole.Instance.Warn("Failed to decode cached terrain texture " + cacheID +
                                                          " (textureID: " + textureIDs[i] + "): " + ex.Message);
                            }
                        }

                        if (detailTexture[i] == null)
                        {
                            // Try to fetch the original JPEG2000 texture, resize if needed, and cache as PNG
                            asset = assetService.Get(textureIDs[i].ToString());
                            if (asset != null)
                            {
                                try
                                {
                                    detailTexture[i] = (Bitmap)J2kImage.FromBytes(asset.Data);
                                }
                                catch (Exception ex)
                                {
                                    MainConsole.Instance.Warn("Failed to decode terrain texture " + asset.ID + ": " + ex.Message);
                                }
                            }

                            if (detailTexture[i] != null)
                            {
                                Bitmap bitmap = detailTexture[i];

                                // Make sure this texture is the correct size, otherwise resize
                                if (bitmap.Width != 256 || bitmap.Height != 256)
                                {
                                    bitmap = ImageUtils.ResizeImage(bitmap, 256, 256);
                                }

                                // Save the decoded and resized texture to the cache
                                byte[] data;
                                using (MemoryStream stream = new MemoryStream())
                                {
                                    bitmap.Save(stream, ImageFormat.Png);
                                    data = stream.ToArray();
                                }

                                // Cache a PNG copy of this terrain texture
                                AssetBase newAsset = new AssetBase
                                {
                                    Data        = data,
                                    Description = "PNG",
                                    Flags       =
                                        AssetFlags.Collectable | AssetFlags.Temporary |
                                        AssetFlags.Local,
                                    ID         = cacheID,
                                    Name       = String.Empty,
                                    TypeString = "image/png"
                                };
                                newAsset.FillHash();
                                newAsset.ID = assetService.Store(newAsset);
                            }
                        }
                    }
                }

                #endregion Texture Fetching
            }

            // Fill in any missing textures with a solid color
            for (int i = 0; i < 4; i++)
            {
                if (detailTexture[i] == null)
                {
                    // Create a solid color texture for this layer
                    detailTexture[i] = new Bitmap(256, 256, PixelFormat.Format24bppRgb);
                    using (Graphics gfx = Graphics.FromImage(detailTexture[i]))
                    {
                        using (SolidBrush brush = new SolidBrush(DEFAULT_TERRAIN_COLOR[i]))
                            gfx.FillRectangle(brush, 0, 0, 256, 256);
                    }
                }
                else if (detailTexture[i].Width != 256 || detailTexture[i].Height != 256)
                {
                    detailTexture[i] = ResizeBitmap(detailTexture[i], 256, 256);
                }
            }

            #region Layer Map

            float   diff     = (float)heightmap.Height / (float)Constants.RegionSize;
            float[] layermap = new float[Constants.RegionSize * Constants.RegionSize];

            for (float y = 0; y < heightmap.Height; y += diff)
            {
                for (float x = 0; x < heightmap.Height; x += diff)
                {
                    float newX   = x / diff;
                    float newY   = y / diff;
                    float height = heightmap[(int)newX, (int)newY];

                    float pctX = newX / 255f;
                    float pctY = newY / 255f;

                    // Use bilinear interpolation between the four corners of start height and
                    // height range to select the current values at this position
                    float startHeight = ImageUtils.Bilinear(
                        startHeights[0],
                        startHeights[2],
                        startHeights[1],
                        startHeights[3],
                        pctX, pctY);
                    startHeight = Utils.Clamp(startHeight, 0f, 255f);

                    float heightRange = ImageUtils.Bilinear(
                        heightRanges[0],
                        heightRanges[2],
                        heightRanges[1],
                        heightRanges[3],
                        pctX, pctY);
                    heightRange = Utils.Clamp(heightRange, 0f, 255f);

                    // Generate two frequencies of perlin noise based on our global position
                    // The magic values were taken from http://opensimulator.org/wiki/Terrain_Splatting
                    Vector3 vec = new Vector3
                                  (
                        ((float)regionPosition.X + newX) * 0.20319f,
                        ((float)regionPosition.Y + newY) * 0.20319f,
                        height * 0.25f
                                  );

                    float lowFreq  = Perlin.noise2(vec.X * 0.222222f, vec.Y * 0.222222f) * 6.5f;
                    float highFreq = Perlin.turbulence2(vec.X, vec.Y, 2f) * 2.25f;
                    float noise    = (lowFreq + highFreq) * 2f;

                    // Combine the current height, generated noise, start height, and height range parameters, then scale all of it
                    float layer = ((height + noise - startHeight) / heightRange) * 4f;
                    if (Single.IsNaN(layer))
                    {
                        layer = 0f;
                    }
                    layermap[(int)(newY * Constants.RegionSize + newX)] = Utils.Clamp(layer, 0f, 3f);
                }
            }

            #endregion Layer Map

            #region Texture Compositing

            Bitmap     output     = new Bitmap(256, 256, PixelFormat.Format24bppRgb);
            BitmapData outputData = output.LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.WriteOnly,
                                                    PixelFormat.Format24bppRgb);

            unsafe
            {
                // Get handles to all of the texture data arrays
                BitmapData[] datas = new[]
                {
                    detailTexture[0].LockBits(new Rectangle(0, 0, 256, 256),
                                              ImageLockMode.ReadOnly,
                                              detailTexture[0].PixelFormat),
                    detailTexture[1].LockBits(new Rectangle(0, 0, 256, 256),
                                              ImageLockMode.ReadOnly,
                                              detailTexture[1].PixelFormat),
                    detailTexture[2].LockBits(new Rectangle(0, 0, 256, 256),
                                              ImageLockMode.ReadOnly,
                                              detailTexture[2].PixelFormat),
                    detailTexture[3].LockBits(new Rectangle(0, 0, 256, 256),
                                              ImageLockMode.ReadOnly,
                                              detailTexture[3].PixelFormat)
                };

                int[] comps = new[]
                {
                    (datas[0].PixelFormat == PixelFormat.Format32bppArgb) ? 4 : 3,
                    (datas[1].PixelFormat == PixelFormat.Format32bppArgb) ? 4 : 3,
                    (datas[2].PixelFormat == PixelFormat.Format32bppArgb) ? 4 : 3,
                    (datas[3].PixelFormat == PixelFormat.Format32bppArgb) ? 4 : 3
                };

                for (int y = 0; y < Constants.RegionSize; y++)
                {
                    for (int x = 0; x < Constants.RegionSize; x++)
                    {
                        float layer = layermap[y * Constants.RegionSize + x];

                        // Select two textures
                        int l0 = (int)Math.Floor(layer);
                        int l1 = Math.Min(l0 + 1, 3);

                        byte *ptrA = (byte *)datas[l0].Scan0 + y * datas[l0].Stride + x * comps[l0];
                        byte *ptrB = (byte *)datas[l1].Scan0 + y * datas[l1].Stride + x * comps[l1];
                        byte *ptrO = (byte *)outputData.Scan0 + y * outputData.Stride + x * 3;

                        float aB = *(ptrA + 0);
                        float aG = *(ptrA + 1);
                        float aR = *(ptrA + 2);

                        float bB = *(ptrB + 0);
                        float bG = *(ptrB + 1);
                        float bR = *(ptrB + 2);

                        float layerDiff = layer - l0;

                        // Interpolate between the two selected textures
                        *(ptrO + 0) = (byte)Math.Floor(aB + layerDiff * (bB - aB));
                        *(ptrO + 1) = (byte)Math.Floor(aG + layerDiff * (bG - aG));
                        *(ptrO + 2) = (byte)Math.Floor(aR + layerDiff * (bR - aR));
                    }
                }

                for (int i = 0; i < 4; i++)
                {
                    detailTexture[i].UnlockBits(datas[i]);
                    detailTexture[i].Dispose();
                }
            }

            layermap = null;
            output.UnlockBits(outputData);

            // We generated the texture upside down, so flip it
            output.RotateFlip(RotateFlipType.RotateNoneFlipY);

            #endregion Texture Compositing

            return(output);
        }
Ejemplo n.º 25
0
        private void RezScriptHandler(Packet packet, LLAgent agent)
        {
            RezScriptPacket rez = (RezScriptPacket)packet;

            LLInventoryTaskItem scriptItem;
            ISceneEntity        targetObj;

            if (m_scene.TryGetEntity(rez.UpdateBlock.ObjectLocalID, out targetObj) && targetObj is LLPrimitive)
            {
                LLPrimitive targetPrim = (LLPrimitive)targetObj;

                if (rez.InventoryBlock.ItemID != UUID.Zero)
                {
                    if (targetPrim.Inventory.TryGetItem(rez.InventoryBlock.ItemID, out scriptItem))
                    {
                        // Rezzing a script from task inventory
                        UUID assetID = UUID.Combine(rez.InventoryBlock.TransactionID, agent.SecureSessionID);

                        // Update task inventory with the new script source assetID
                        scriptItem.AssetID = assetID;
                        targetPrim.Inventory.AddOrUpdateItem(scriptItem, true);

                        // Run the script
                        if (m_scriptEngine != null)
                        {
                            m_scriptEngine.RezScript(scriptItem.ID, assetID, targetObj, 0);
                        }
                        else
                        {
                            m_log.Warn("Can't rez script in prim " + targetObj.ID + " without an ILSLScriptEngine");
                        }

                        SignalTaskInventoryChange(agent, targetPrim);
                    }
                    else if (m_inventory != null)
                    {
                        InventoryBase obj;
                        if (m_inventory.TryGetInventory(agent.ID, rez.InventoryBlock.ItemID, out obj) &&
                            obj is InventoryItem && ((InventoryItem)obj).ContentType == "application/vnd.ll.lsltext")
                        {
                            LLInventoryItem sourceItem = new LLInventoryItem((InventoryItem)obj);

                            // Rezzing a script from agent inventory
                            scriptItem                = new LLInventoryTaskItem();
                            scriptItem.AssetID        = sourceItem.AssetID;
                            scriptItem.ContentType    = "application/vnd.ll.lsltext";
                            scriptItem.CreationDate   = DateTime.UtcNow;
                            scriptItem.CreatorID      = agent.ID;
                            scriptItem.Description    = sourceItem.Description;
                            scriptItem.ID             = UUID.Random();
                            scriptItem.Name           = sourceItem.Name;
                            scriptItem.OwnerID        = sourceItem.OwnerID;
                            scriptItem.ParentID       = sourceItem.ParentID;
                            scriptItem.ParentObjectID = targetPrim.ID;

                            scriptItem.Flags       = sourceItem.Flags;
                            scriptItem.GroupID     = sourceItem.GroupID;
                            scriptItem.GroupOwned  = sourceItem.GroupOwned;
                            scriptItem.Permissions = sourceItem.Permissions;
                            scriptItem.SalePrice   = sourceItem.SalePrice;
                            scriptItem.SaleType    = sourceItem.SaleType;

                            targetPrim.Inventory.AddOrUpdateItem(scriptItem, false);
                            m_log.Info(agent.Name + " copied agent inventory script to task inventory: " + scriptItem.Name);

                            // Run the script
                            if (m_scriptEngine != null)
                            {
                                m_scriptEngine.RezScript(scriptItem.ID, scriptItem.AssetID, targetObj, 0);
                            }
                            else
                            {
                                m_log.Warn("Can't rez script in prim " + targetObj.ID + " without an ILSLScriptEngine");
                            }

                            SignalTaskInventoryChange(agent, targetPrim);
                        }
                        else
                        {
                            m_log.Warn(agent.Name + " called RezScript for unknown inventory script " + rez.InventoryBlock.ItemID);
                        }
                    }
                    else
                    {
                        m_log.Warn(agent.Name + "attempted to copy (and rez) script " + rez.InventoryBlock.ItemID +
                                   " to task inventory, but we have no IInventoryClient");
                    }
                }
                else
                {
                    // Rezzing a new script
                    scriptItem                = new LLInventoryTaskItem();
                    scriptItem.AssetID        = DEFAULT_SCRIPT;
                    scriptItem.ContentType    = "application/vnd.ll.lsltext";
                    scriptItem.CreationDate   = DateTime.UtcNow;
                    scriptItem.CreatorID      = agent.ID;
                    scriptItem.Description    = String.Empty;
                    scriptItem.ID             = UUID.Random();
                    scriptItem.Name           = "New script";
                    scriptItem.OwnerID        = agent.ID;
                    scriptItem.ParentID       = rez.InventoryBlock.FolderID;
                    scriptItem.ParentObjectID = targetPrim.ID;
                    scriptItem.Permissions    = GetDefaultPermissions();
                    scriptItem.SalePrice      = 10;
                    scriptItem.SaleType       = SaleType.Not;

                    targetPrim.Inventory.AddOrUpdateItem(scriptItem, false);
                    m_log.Info(agent.Name + " created new task inventory script: " + scriptItem.Name);

                    // Run the script
                    if (m_scriptEngine != null)
                    {
                        m_scriptEngine.RezScript(scriptItem.ID, scriptItem.AssetID, targetObj, 0);
                    }
                    else
                    {
                        m_log.Warn("Can't rez script in prim " + targetObj.ID + " without an ILSLScriptEngine");
                    }

                    SignalTaskInventoryChange(agent, targetPrim);
                }
            }
            else
            {
                m_log.Warn(agent.Name + "sent a RezScript packet referencing unknown object " + rez.UpdateBlock.ObjectLocalID);
            }
        }
Ejemplo n.º 26
0
        private Color4 GetFaceColor(Primitive.TextureEntryFace face)
        {
            Color4 color;

            if (face.TextureID == UUID.Zero)
            {
                return(face.RGBA);
            }

            if (!m_colors.TryGetValue(face.TextureID, out color))
            {
                bool fetched = false;

                // Attempt to fetch the texture metadata
                UUID      metadataID = UUID.Combine(face.TextureID, TEXTURE_METADATA_MAGIC);
                AssetBase metadata   = m_scene.AssetService.GetCached(metadataID.ToString());
                if (metadata != null)
                {
                    OSDMap map = null;
                    try { map = OSDParser.Deserialize(metadata.Data) as OSDMap; } catch { }

                    if (map != null)
                    {
                        color   = map["X-JPEG2000-RGBA"].AsColor4();
                        fetched = true;
                    }
                }

                if (!fetched)
                {
                    // Fetch the texture, decode and get the average color,
                    // then save it to a temporary metadata asset
                    AssetBase textureAsset = m_scene.AssetService.Get(face.TextureID.ToString());
                    if (textureAsset != null)
                    {
                        int width, height;
                        color = GetAverageColor(textureAsset.FullID, textureAsset.Data, out width, out height);

                        OSDMap data = new OSDMap {
                            { "X-JPEG2000-RGBA", OSD.FromColor4(color) }
                        };
                        metadata = new AssetBase
                        {
                            Data        = System.Text.Encoding.UTF8.GetBytes(OSDParser.SerializeJsonString(data)),
                            Description = "Metadata for JPEG2000 texture " + face.TextureID.ToString(),
                            Flags       = AssetFlags.Collectable,
                            FullID      = metadataID,
                            ID          = metadataID.ToString(),
                            Local       = true,
                            Temporary   = true,
                            Name        = String.Empty,
                            Type        = (sbyte)AssetType.Unknown
                        };
                        m_scene.AssetService.Store(metadata);
                    }
                    else
                    {
                        color = new Color4(0.5f, 0.5f, 0.5f, 1.0f);
                    }
                }

                m_colors[face.TextureID] = color;
            }

            return(color * face.RGBA);
        }
Ejemplo n.º 27
0
        /// <summary>
        /// Builds a composited terrain texture given the region texture
        /// and heightmap settings
        /// </summary>
        /// <param name="heightmap">Terrain heightmap</param>
        /// <param name="regionInfo">Region information including terrain texture parameters</param>
        /// <returns>A composited 256x256 RGB texture ready for rendering</returns>
        /// <remarks>Based on the algorithm described at http://opensimulator.org/wiki/Terrain_Splatting
        /// </remarks>
        public static Bitmap Splat(float[] heightmap, UUID[] textureIDs, float[] startHeights, float[] heightRanges, Vector3d regionPosition, IAssetClient assetClient)
        {
            Debug.Assert(heightmap.Length == 256 * 256);
            Debug.Assert(textureIDs.Length == 4);
            Debug.Assert(startHeights.Length == 4);
            Debug.Assert(heightRanges.Length == 4);

            // Swap empty terrain textureIDs with default IDs
            for (int i = 0; i < textureIDs.Length; i++)
            {
                if (textureIDs[i] == UUID.Zero)
                {
                    textureIDs[i] = DEFAULT_TERRAIN_DETAIL[i];
                }
            }

            #region Texture Fetching

            Bitmap[] detailTexture = new Bitmap[4];

            if (assetClient != null)
            {
                for (int i = 0; i < 4; i++)
                {
                    Asset asset;
                    UUID  cacheID = UUID.Combine(TEXTURE_CACHE_MAGIC, textureIDs[i]);

                    // Try to fetch a cached copy of the decoded/resized version of this texture
                    if (assetClient.TryGetCachedAsset(cacheID, "image/png", out asset))
                    {
                        try
                        {
                            using (System.IO.MemoryStream stream = new System.IO.MemoryStream(asset.Data))
                                detailTexture[i] = (Bitmap)Image.FromStream(stream);
                        }
                        catch (Exception ex)
                        {
                            m_log.Warn("Failed to decode cached terrain texture " + cacheID +
                                       " (textureID: " + textureIDs[i] + "): " + ex.Message);
                        }
                    }

                    if (detailTexture[i] == null)
                    {
                        // Try to fetch the original JPEG2000 texture, resize if needed, and cache as PNG
                        if (assetClient.TryGetAsset(textureIDs[i], "image/x-j2c", out asset))
                        {
                            try { detailTexture[i] = (Bitmap)CSJ2K.J2kImage.FromBytes(asset.Data); }
                            catch (Exception ex)
                            {
                                m_log.Warn("Failed to decode terrain texture " + asset.ID + ": " + ex.Message);
                            }
                        }

                        if (detailTexture[i] != null)
                        {
                            Bitmap bitmap = detailTexture[i];

                            // Make sure this texture is the correct size, otherwise resize
                            if (bitmap.Width != 256 || bitmap.Height != 256)
                            {
                                bitmap = Util.ResizeImage(bitmap, 256, 256);
                            }

                            // Save the decoded and resized texture to the cache
                            byte[] data;
                            using (System.IO.MemoryStream stream = new System.IO.MemoryStream())
                            {
                                bitmap.Save(stream, ImageFormat.Png);
                                data = stream.ToArray();
                            }

                            assetClient.StoreAsset(
                                new Asset
                            {
                                ContentType  = "image/png",
                                CreationDate = DateTime.UtcNow,
                                CreatorID    = UUID.Zero,
                                Data         = data,
                                ID           = cacheID,
                                Local        = true,
                                Temporary    = true
                            }
                                );
                        }
                    }
                }
            }

            // Fill in any missing textures with a solid color
            for (int i = 0; i < 4; i++)
            {
                if (detailTexture[i] == null)
                {
                    // Create a solid color texture for this layer
                    detailTexture[i] = new Bitmap(256, 256, PixelFormat.Format24bppRgb);
                    using (Graphics gfx = Graphics.FromImage(detailTexture[i]))
                    {
                        using (SolidBrush brush = new SolidBrush(DEFAULT_TERRAIN_COLOR[i]))
                            gfx.FillRectangle(brush, 0, 0, 256, 256);
                    }
                }
            }

            #endregion Texture Fetching

            #region Layer Map

            float[] layermap = new float[256 * 256];

            for (int y = 0; y < 256; y++)
            {
                for (int x = 0; x < 256; x++)
                {
                    float height = heightmap[y * 256 + x];

                    float pctX = (float)x / 255f;
                    float pctY = (float)y / 255f;

                    // Use bilinear interpolation between the four corners of start height and
                    // height range to select the current values at this position
                    float startHeight = Util.Bilinear(
                        startHeights[0],
                        startHeights[2],
                        startHeights[1],
                        startHeights[3],
                        pctX, pctY);
                    startHeight = Utils.Clamp(startHeight, 0f, 255f);

                    float heightRange = Util.Bilinear(
                        heightRanges[0],
                        heightRanges[2],
                        heightRanges[1],
                        heightRanges[3],
                        pctX, pctY);
                    heightRange = Utils.Clamp(heightRange, 0f, 255f);

                    // Generate two frequencies of perlin noise based on our global position
                    // The magic values were taken from http://opensimulator.org/wiki/Terrain_Splatting
                    Vector3 vec = new Vector3
                                  (
                        ((float)regionPosition.X + x) * 0.20319f,
                        ((float)regionPosition.Y + y) * 0.20319f,
                        height * 0.25f
                                  );

                    float lowFreq  = Perlin.noise2(vec.X * 0.222222f, vec.Y * 0.222222f) * 6.5f;
                    float highFreq = Perlin.turbulence2(vec.X, vec.Y, 2f) * 2.25f;
                    float noise    = (lowFreq + highFreq) * 2f;

                    // Combine the current height, generated noise, start height, and height range parameters, then scale all of it
                    float layer = ((height + noise - startHeight) / heightRange) * 4f;
                    if (Single.IsNaN(layer))
                    {
                        layer = 0f;
                    }
                    layermap[y * 256 + x] = Utils.Clamp(layer, 0f, 3f);
                }
            }

            #endregion Layer Map

            #region Texture Compositing

            Bitmap     output     = new Bitmap(256, 256, PixelFormat.Format24bppRgb);
            BitmapData outputData = output.LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);

            unsafe
            {
                // Get handles to all of the texture data arrays
                BitmapData[] datas = new BitmapData[]
                {
                    detailTexture[0].LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.ReadOnly, detailTexture[0].PixelFormat),
                    detailTexture[1].LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.ReadOnly, detailTexture[1].PixelFormat),
                    detailTexture[2].LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.ReadOnly, detailTexture[2].PixelFormat),
                    detailTexture[3].LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.ReadOnly, detailTexture[3].PixelFormat)
                };

                int[] comps = new int[]
                {
                    (datas[0].PixelFormat == PixelFormat.Format32bppArgb) ? 4 : 3,
                    (datas[1].PixelFormat == PixelFormat.Format32bppArgb) ? 4 : 3,
                    (datas[2].PixelFormat == PixelFormat.Format32bppArgb) ? 4 : 3,
                    (datas[3].PixelFormat == PixelFormat.Format32bppArgb) ? 4 : 3
                };

                for (int y = 0; y < 256; y++)
                {
                    for (int x = 0; x < 256; x++)
                    {
                        float layer = layermap[y * 256 + x];

                        // Select two textures
                        int l0 = (int)Math.Floor(layer);
                        int l1 = Math.Min(l0 + 1, 3);

                        byte *ptrA = (byte *)datas[l0].Scan0 + y * datas[l0].Stride + x * comps[l0];
                        byte *ptrB = (byte *)datas[l1].Scan0 + y * datas[l1].Stride + x * comps[l1];
                        byte *ptrO = (byte *)outputData.Scan0 + y * outputData.Stride + x * 3;

                        float aB = *(ptrA + 0);
                        float aG = *(ptrA + 1);
                        float aR = *(ptrA + 2);

                        float bB = *(ptrB + 0);
                        float bG = *(ptrB + 1);
                        float bR = *(ptrB + 2);

                        float layerDiff = layer - l0;

                        // Interpolate between the two selected textures
                        *(ptrO + 0) = (byte)Math.Floor(aB + layerDiff * (bB - aB));
                        *(ptrO + 1) = (byte)Math.Floor(aG + layerDiff * (bG - aG));
                        *(ptrO + 2) = (byte)Math.Floor(aR + layerDiff * (bR - aR));
                    }
                }

                for (int i = 0; i < 4; i++)
                {
                    detailTexture[i].UnlockBits(datas[i]);
                }
            }

            output.UnlockBits(outputData);

            // We generated the texture upside down, so flip it
            output.RotateFlip(RotateFlipType.RotateNoneFlipY);

            #endregion Texture Compositing

            return(output);
        }