private warp_Texture GetTexture(UUID id)
        {
            warp_Texture ret = null;

            byte[] asset = m_scene.AssetService.GetData(id.ToString());

            if (asset != null)
            {
                IJ2KDecoder imgDecoder = m_scene.RequestModuleInterface <IJ2KDecoder>();

                try
                {
                    using (Bitmap img = (Bitmap)imgDecoder.DecodeToImage(asset))
                    {
                        ret = new warp_Texture(img);
                        img.Dispose();
                    }
                }
                catch (Exception e)
                {
                    m_log.Warn(string.Format("[WARP 3D IMAGE MODULE]: Failed to decode asset {0}, exception  ", id), e);
                }
            }

            return(ret);
        }
        warp_Texture GetTexture(UUID id)
        {
            warp_Texture ret = null;

            if (id == UUID.Zero)
            {
                id = (UUID)Constants.MISSING_TEXTURE_ID;
            }

            byte [] assetData = m_scene.AssetService.GetData(id.ToString(), false);         // suppress warnings here
            if (assetData == null || assetData.Length == 0)
            {
                assetData = m_scene.AssetService.GetData(Constants.MISSING_TEXTURE_ID);     // not found, replace with something identifable
            }
            if (assetData != null && assetData.Length > 0)
            {
                IJ2KDecoder imgDecoder = m_scene.RequestModuleInterface <IJ2KDecoder> ();
                Bitmap      img        = (Bitmap)imgDecoder.DecodeToImage(assetData);

                if (img != null)
                {
                    ret = new warp_Texture(img);
                    img.Dispose();
                    return(ret);
                }
            }
            MainConsole.Instance.Debug("[WarpTile generator]: Gettexture returning null, asset id: " + id);
            return(ret);
        }
예제 #3
0
        private byte[] ConvertTextureData(AssetBase texture, string format)
        {
            MainConsole.Instance.DebugFormat("[GETTEXTURE]: Converting texture {0} to {1}", texture.ID, format);
            byte[] data = new byte[0];

            MemoryStream imgstream = new MemoryStream();
            Image        image     = null;

            try
            {
                // Taking our jpeg2000 data, decoding it, then saving it to a byte array with regular data
                image = m_j2kDecoder.DecodeToImage(texture.Data);
                if (image == null)
                {
                    return(data);
                }
                // Save to bitmap
                image = new Bitmap(image);

                EncoderParameters myEncoderParameters = new EncoderParameters();
                myEncoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, 95L);

                // Save bitmap to stream
                ImageCodecInfo codec = GetEncoderInfo("image/" + format);
                if (codec != null)
                {
                    image.Save(imgstream, codec, myEncoderParameters);
                    // Write the stream to a byte array for output
                    data = imgstream.ToArray();
                }
                else
                {
                    MainConsole.Instance.WarnFormat("[GETTEXTURE]: No such codec {0}", format);
                }
            }
            catch (Exception e)
            {
                MainConsole.Instance.WarnFormat("[GETTEXTURE]: Unable to convert texture {0} to {1}: {2}", texture.ID,
                                                format, e.Message);
            }
            finally
            {
                // Reclaim memory, these are unmanaged resources
                // If we encountered an exception, one or more of these will be null

                if (image != null)
                {
                    image.Dispose();
                }
                image = null;

                imgstream.Close();
                imgstream = null;
            }

            return(data);
        }
예제 #4
0
        private warp_Texture GetTexture(UUID id)
        {
            warp_Texture ret = null;

            byte[] asset = m_scene.AssetService.GetData(id.ToString());
            if (asset != null)
            {
                IJ2KDecoder imgDecoder = m_scene.RequestModuleInterface <IJ2KDecoder>();
                Bitmap      img        = (Bitmap)imgDecoder.DecodeToImage(asset);
                if (img != null)
                {
                    return(new warp_Texture(img));
                }
            }
            return(ret);
        }
        private warp_Texture GetTexture(UUID id)
        {
            warp_Texture ret   = null;
            AssetBase    asset = m_scene.AssetService.Get(id.ToString());

            if (asset != null)
            {
                IJ2KDecoder imgDecoder = m_scene.RequestModuleInterface <IJ2KDecoder>();
                Bitmap      img        = (Bitmap)imgDecoder.DecodeToImage(asset.Data);
                if (img != null)
                {
                    ret = new warp_Texture(img);
                    img.Dispose();
                }
                asset.Dispose();
            }
            return(ret);
        }
예제 #6
0
        public Image GetTexture(UUID TextureID)
        {
            if (TextureID == UUID.Zero) //Send white instead of null
            {
                TextureID = Util.BLANK_TEXTURE_UUID;
            }

            byte[] asset = m_assetService.GetData(TextureID.ToString());
            if (asset == null || m_decoder == null)
            {
                return(new Bitmap(1, 1));
            }
            Image image = m_decoder.DecodeToImage(asset);

            if (image != null)
            {
                return(image);
            }
            else
            {
                return(new Bitmap(1, 1));
            }
        }
예제 #7
0
        /// <summary>
        /// Generate a mesh from the sculpt data the accompanies a prim.
        /// </summary>
        /// <param name="primName"></param>
        /// <param name="primShape"></param>
        /// <param name="size"></param>
        /// <param name="lod"></param>
        /// <param name="key"></param>
        /// <returns>created mesh or null if invalid</returns>
        Mesh GenerateFromPrimSculptData(string primName, PrimitiveBaseShape primShape, Vector3 size, float lod, ulong key)
        {
            SculptMesh sculptMesh;
            Image      idata = null;
            string     decodedSculptFileName = "";


            if (cacheSculptMaps && primShape.SculptTexture != UUID.Zero)
            {
                decodedSculptFileName = System.IO.Path.Combine(decodedSculptMapPath,
                                                               "smap_" + primShape.SculptTexture);
                try
                {
                    if (File.Exists(decodedSculptFileName))
                    {
                        idata = Image.FromFile(decodedSculptFileName);
                    }
                } catch (Exception e)
                {
                    MainConsole.Instance.Error("[Sculpt]: unable to load cached sculpt map " +
                                               decodedSculptFileName + " " + e);
                }
                //if (idata != null)
                //    MainConsole.Instance.Debug("[SCULPT]: loaded cached map asset for map ID: " + primShape.SculptTexture.ToString());
            }

            if (idata == null)
            {
                if (primShape.SculptData == null || primShape.SculptData.Length == 0)
                {
                    return(null);
                }

                try
                {
                    idata = m_j2kDecoder.DecodeToImage(primShape.SculptData);

                    if (idata != null && cacheSculptMaps &&
                        (cacheSculptAlphaMaps || (((ImageFlags)(idata.Flags) & ImageFlags.HasAlpha) == 0)))
                    {
                        try
                        {
                            idata.Save(decodedSculptFileName, ImageFormat.MemoryBmp);
                        } catch (Exception e)
                        {
                            MainConsole.Instance.Error("[Sculpt]: unable to cache sculpt map " +
                                                       decodedSculptFileName + " " +
                                                       e);
                        }
                    }
                } catch (DllNotFoundException)
                {
                    MainConsole.Instance.Error(
                        "[Physics]: OpenJpeg is not installed correctly on this system. Physics Proxy generation failed.\n" +
                        "Often times this is because of an old version of GLIBC.  You must have version 2.4 or above!");
                    return(null);
                } catch (IndexOutOfRangeException)
                {
                    MainConsole.Instance.Error(
                        "[Physics]: OpenJpeg was unable to decode this. Physics Proxy generation failed");
                    return(null);
                } catch (Exception ex)
                {
                    MainConsole.Instance.Error(
                        "[Physics]: Unable to generate a Sculpty physics proxy. Sculpty texture decode failed: " +
                        ex);
                    return(null);
                }
            }

            SculptMesh.SculptType sculptType;
            switch ((SculptType)primShape.SculptType)
            {
            case SculptType.Cylinder:
                sculptType = SculptMesh.SculptType.cylinder;
                break;

            case SculptType.Plane:
                sculptType = SculptMesh.SculptType.plane;
                break;

            case SculptType.Torus:
                sculptType = SculptMesh.SculptType.torus;
                break;

            case SculptType.Sphere:
                sculptType = SculptMesh.SculptType.sphere;
                break;

            default:
                sculptType = SculptMesh.SculptType.plane;
                break;
            }

            bool mirror = ((primShape.SculptType & 128) != 0);
            bool invert = ((primShape.SculptType & 64) != 0);

            if (idata == null)
            {
                return(null);
            }

            sculptMesh = new SculptMesh((Bitmap)idata, sculptType, (int)lod, false, mirror, invert);

            idata.Dispose();
            #if SPAM
            sculptMesh.DumpRaw(baseDir, primName, "primMesh");
            #endif

            sculptMesh.Scale(size.X, size.Y, size.Z);

            var coords = sculptMesh.coords;
            var faces  = sculptMesh.faces;

            Mesh mesh = new Mesh(key);
            mesh.Set(coords, faces);
            coords.Clear();
            faces.Clear();

            // debug info only
            //Console.Write ("S");

            return(mesh);
        }
예제 #8
0
        byte [] ProcessGetTexture(string path, Stream request, OSHttpRequest httpRequest,
                                  OSHttpResponse httpResponse)
        {
            // MainConsole.Instance.DebugFormat("[GETTEXTURE]: called in {0}", m_scene.RegionInfo.RegionName);

            // Try to parse the texture ID from the request URL
            NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
            string textureStr         = query.GetOne("texture_id");
            string format             = query.GetOne("format");

            if (m_assetService == null)
            {
                httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
                return(MainServer.BlankResponse);
            }

            UUID textureID;

            if (!string.IsNullOrEmpty(textureStr) && UUID.TryParse(textureStr, out textureID))
            {
                string [] formats;
                if (!string.IsNullOrEmpty(format))
                {
                    formats = new [] { format.ToLower() }
                }
                ;
                else
                {
                    formats = WebUtils.GetPreferredImageTypes(httpRequest.Headers.Get("Accept"));
                    if (formats.Length == 0)
                    {
                        formats = new [] { DefaultFormat }
                    }
                    ;                                           // default
                }

                // OK, we have an array with preferred formats, possibly with only one entry
                byte [] response;
                foreach (string f in formats)
                {
                    if (FetchTexture(httpRequest, httpResponse, textureID, f, out response))
                    {
                        return(response);
                    }
                }
            }

            // null or invalid UUID
            MainConsole.Instance.Warn("[AssetCAPS]: Failed to parse a texture_id from GetTexture request: " +
                                      httpRequest.Url);
            httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
            return(MainServer.BlankResponse);
        }

        /// <summary>
        /// </summary>
        /// <param name="httpRequest"></param>
        /// <param name="httpResponse"></param>
        /// <param name="textureID"></param>
        /// <param name="format"></param>
        /// <param name="response"></param>
        /// <returns>False for "caller try another codec"; true otherwise</returns>
        bool FetchTexture(OSHttpRequest httpRequest, OSHttpResponse httpResponse, UUID textureID, string format,
                          out byte [] response)
        {
            // MainConsole.Instance.DebugFormat("[GETTEXTURE]: {0} with requested format {1}", textureID, format);
            AssetBase texture;

            string fullID = textureID.ToString();

            if (format != DefaultFormat)
            {
                fullID = fullID + "-" + format;
            }

            if (!string.IsNullOrEmpty(redirect_URL))
            {
                // Only try to fetch locally cached textures. Misses are redirected
                texture = m_assetService.GetCached(fullID);

                if (texture != null)
                {
                    if (texture.Type != (sbyte)AssetType.Texture &&        // not actually a texture
                        texture.Type != (sbyte)AssetType.Unknown &&        // .. but valid
                        texture.Type != (sbyte)AssetType.Simstate)
                    {
                        httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
                        response = MainServer.BlankResponse;
                        return(true);
                    }

                    response = WriteTextureData(httpRequest, httpResponse, texture, format);
                    return(true);
                }

                string textureUrl = redirect_URL + textureID;
                MainConsole.Instance.Debug("[AssetCAPS]: Redirecting texture request to " + textureUrl);
                httpResponse.RedirectLocation = textureUrl;
                response = MainServer.BlankResponse;

                return(true);
            }

            // no redirect
            // try the cache
            texture = m_assetService.GetCached(fullID);

            if (texture == null)
            {
                // MainConsole.Instance.DebugFormat("[Get texture]: texture was not in the cache");

                // Fetch locally or remotely. Misses return a 404
                texture = m_assetService.Get(textureID.ToString());

                if (texture != null)
                {
                    if (texture.Type != (sbyte)AssetType.Texture &&
                        texture.Type != (sbyte)AssetType.Unknown &&
                        texture.Type != (sbyte)AssetType.Simstate)
                    {
                        httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
                        response = MainServer.BlankResponse;
                        texture.Dispose();
                        return(true);
                    }

                    if (format == DefaultFormat)
                    {
                        try {
                            response = WriteTextureData(httpRequest, httpResponse, texture, format);
                        } catch {
                            response = MainServer.BlankResponse;
                        }
                        texture.Dispose();
                        return(true);
                    }

                    AssetBase newTexture = new AssetBase(texture.ID + "-" + format, texture.Name,
                                                         AssetType.Texture,
                                                         texture.CreatorID)
                    {
                        Data = ConvertTextureData(texture, format)
                    };

                    if (newTexture.Data.Length == 0)            // unable to convert
                    {
                        response = MainServer.BlankResponse;
                        texture.Dispose();
                        newTexture.Dispose();
                        return(false);           // !!! Caller try another codec, please!
                    }

                    newTexture.Flags = AssetFlags.Collectable | AssetFlags.Temporary;
                    newTexture.ID    = m_assetService.Store(newTexture);
                    try {
                        response = WriteTextureData(httpRequest, httpResponse, newTexture, format);
                    } catch {
                        response = MainServer.BlankResponse;
                    }
                    newTexture.Dispose();
                    texture.Dispose();

                    return(true);
                }

                // nothing found... replace with the 'missing_texture" texture
                // try the cache first
                texture = m_assetService.GetCached(Constants.MISSING_TEXTURE_ID);

                if (texture == null)
                {
                    texture = m_assetService.Get(Constants.MISSING_TEXTURE_ID);                 // not in local cache...
                }
                if (texture != null)
                {
                    if (format == DefaultFormat)
                    {
                        MainConsole.Instance.Debug("[AssetCAPS]: Texture " + textureID + " replaced with default 'missing' texture");
                        response = WriteTextureData(httpRequest, httpResponse, texture, format);
                        texture.Dispose();
                        return(true);
                    }
                }

                // texture not found and we have no 'missing texture'??
                // ... or if all else fails...
                MainConsole.Instance.Warn("[AssetCAPS]: Texture " + textureID + " not found (no default)");
                httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
                response = MainServer.BlankResponse;
                return(true);
            }

            // found the texture in the cache
            if (texture.Type != (sbyte)AssetType.Texture &&
                texture.Type != (sbyte)AssetType.Unknown &&
                texture.Type != (sbyte)AssetType.Simstate)
            {
                httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
                response = MainServer.BlankResponse;
                return(true);
            }

            // the best result...
            // MainConsole.Instance.DebugFormat("[GETTEXTURE]: texture was in the cache");
            response = WriteTextureData(httpRequest, httpResponse, texture, format);
            return(true);
        }

        byte [] WriteTextureData(OSHttpRequest request, OSHttpResponse response, AssetBase texture, string format)
        {
            string range = request.Headers.GetOne("Range");

            // MainConsole.Instance.DebugFormat("[GETTEXTURE]: Range {0}", range);
            if (!string.IsNullOrEmpty(range))  // JP2's only
            {
                // Range request
                int start, end;
                if (TryParseRange(range, out start, out end))
                {
                    // Before clamping start make sure we can satisfy it in order to avoid
                    // sending back the last byte instead of an error status
                    if (start >= texture.Data.Length)
                    {
                        response.StatusCode = (int)System.Net.HttpStatusCode.RequestedRangeNotSatisfiable;
                        return(MainServer.BlankResponse);
                    }

                    // Handle the case where portions of the range are missing.
                    if (start == -1)
                    {
                        start = 0;
                    }
                    if (end == -1)
                    {
                        end = int.MaxValue;
                    }

                    end   = Utils.Clamp(end, 0, texture.Data.Length - 1);
                    start = Utils.Clamp(start, 0, end);
                    int len = end - start + 1;

                    // MainConsole.Instance.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID);

                    if (len < texture.Data.Length)
                    {
                        response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent;
                    }
                    else
                    {
                        response.StatusCode = (int)System.Net.HttpStatusCode.OK;
                    }

                    response.ContentType = texture.TypeString;
                    response.AddHeader("Content-Range",
                                       string.Format("bytes {0}-{1}/{2}", start, end, texture.Data.Length));
                    byte [] array = new byte [len];
                    Array.Copy(texture.Data, start, array, 0, len);

                    return(array);
                }

                MainConsole.Instance.Warn("[AssetCAPS]: Malformed Range header: " + range);
                response.StatusCode = (int)System.Net.HttpStatusCode.BadRequest;
                return(MainServer.BlankResponse);
            }

            // Full content request
            response.StatusCode  = (int)System.Net.HttpStatusCode.OK;
            response.ContentType = texture.TypeString;
            if (format == DefaultFormat)
            {
                response.ContentType = texture.TypeString;
            }
            else
            {
                response.ContentType = "image/" + format;
            }
            return(texture.Data);
        }

        /*
         * <summary>
         * Parse a range header.
         * </summary>
         * <remarks>
         * As per http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html,
         * this obeys range headers with two values (e.g. 533-4165) and no second value (e.g. 533-).
         * Where there is no value, -1 is returned. Also handles a range like (-4165) where -1 is
         * returned for the starting value.</remarks>
         * <returns></returns>
         * <param name='header'></param>
         * <param name='start'>Undefined if the parse fails.</param>
         * <param name='end'>Undefined if the parse fails.</param>
         */
        bool TryParseRange(string header, out int start, out int end)
        {
            start = end = -1;
            if (!header.StartsWith("bytes=", StringComparison.Ordinal))
            {
                return(false);
            }

            string [] rangeValues = header.Substring(6).Split('-');
            if (rangeValues.Length != 2)
            {
                return(false);
            }

            if (rangeValues [0] != "")
            {
                if (!int.TryParse(rangeValues [0], out start))
                {
                    return(false);
                }
            }

            if (rangeValues [1] != "")
            {
                if (!int.TryParse(rangeValues [1], out end))
                {
                    return(false);
                }
            }

            return(true);
        }

        byte [] ConvertTextureData(AssetBase texture, string format)
        {
            MainConsole.Instance.DebugFormat("[AssetCAPS]: Converting texture {0} to {1}", texture.ID, format);
            byte [] data = new byte [0];

            MemoryStream imgstream = new MemoryStream();
            Image        image     = null;

            try {
                // Taking our jpeg2000 data, decoding it, then saving it to a byte array with regular data
                image = m_j2kDecoder.DecodeToImage(texture.Data);
                if (image == null)
                {
                    return(data);
                }

                // Save to bitmap
                image = new Bitmap(image);

                EncoderParameters myEncoderParameters = new EncoderParameters();
                myEncoderParameters.Param [0] = new EncoderParameter(Encoder.Quality, 95L);

                // Save bitmap to stream
                try {
                    ImageCodecInfo codec = GetEncoderInfo("image/" + format);

                    if (codec != null)
                    {
                        image.Save(imgstream, codec, myEncoderParameters);
                        // Write the stream to a byte array for output
                        data = imgstream.ToArray();
                    }
                    else
                    {
                        MainConsole.Instance.WarnFormat("[AssetCAPS]: No such codec {0}", format);
                    }
                } catch {
                    MainConsole.Instance.ErrorFormat("[AssetCAPS]: Unable to retrieve codec {0}", format);
                }
                myEncoderParameters.Dispose();
            } catch (Exception e) {
                MainConsole.Instance.WarnFormat("[AssetCAPS]: Unable to convert texture {0} to {1}: {2}", texture.ID,
                                                format, e.Message);
            } finally {
                // Reclaim memory, these are unmanaged resources
                // If we encountered an exception, one or more of these will be null

                if (image != null)
                {
                    image.Dispose();
                }

                imgstream.Close();
            }

            return(data);
        }
예제 #9
0
        Bitmap BuildMapTile(int regionX, int regionY, List <GridRegion> regions)
        {
            if (regions == null)
            {
                int maxRegionSize = m_gridService.GetMaxRegionSize();
                if (maxRegionSize == 0)
                {
                    maxRegionSize = Constants.MaxRegionSize;
                }
                regions = m_gridService.GetRegionRange(
                    null,
                    (regionX * Constants.RegionSize) - maxRegionSize,
                    (regionX * Constants.RegionSize) + maxRegionSize,
                    (regionY * Constants.RegionSize) - maxRegionSize,
                    (regionY * Constants.RegionSize) + maxRegionSize);
            }

            List <Image>      bitImages  = new List <Image>();
            List <GridRegion> badRegions = new List <GridRegion>();
            Rectangle         mapRect    = new Rectangle(regionX * Constants.RegionSize, regionY * Constants.RegionSize, Constants.RegionSize, Constants.RegionSize);

            foreach (GridRegion r in regions)
            {
                Rectangle regionRect = new Rectangle(r.RegionLocX, r.RegionLocY, r.RegionSizeX, r.RegionSizeY);
                if (!mapRect.IntersectsWith(regionRect))
                {
                    badRegions.Add(r);
                }
            }
            foreach (GridRegion r in badRegions)
            {
                regions.Remove(r);
            }
            badRegions.Clear();
            IJ2KDecoder decoder = m_registry.RequestModuleInterface <IJ2KDecoder>();

            foreach (GridRegion r in regions)
            {
                byte[] texAsset = null;
                if (m_assetService.GetExists(r.TerrainMapImage.ToString()))
                {
                    texAsset = m_assetService.GetData(r.TerrainMapImage.ToString());
                }

                if (texAsset != null)
                {
                    Image image = decoder.DecodeToImage(texAsset);
                    if (image != null)
                    {
                        bitImages.Add(image);
                    }
                    else
                    {
                        badRegions.Add(r);
                    }
                }
                else
                {
                    badRegions.Add(r);
                }
            }
            foreach (GridRegion r in badRegions)
            {
                regions.Remove(r);
            }

            if (regions.Count == 0)
            {
                lock (m_blankTiles.BlankTiles)
                    m_blankTiles.BlankTiles.Add(Util.IntsToUlong(regionX, regionY));
                return(m_blankRegionTile);
            }

            const int SizeOfImage = Constants.RegionSize;           // 256

            Bitmap mapTexture = new Bitmap(SizeOfImage, SizeOfImage);

            using (Graphics g = Graphics.FromImage(mapTexture))
            {
                SolidBrush sea = new SolidBrush(Color.FromArgb(29, 71, 95));
                g.FillRectangle(sea, 0, 0, SizeOfImage, SizeOfImage);

                for (int i = 0; i < regions.Count; i++)
                {
                    //Find the offsets first
                    float x = (regions[i].RegionLocX - (regionX * (float)Constants.RegionSize)) /
                              Constants.RegionSize;
                    float y = (regions[i].RegionLocY - (regionY * (float)Constants.RegionSize)) /
                              Constants.RegionSize;
                    y += (regions[i].RegionSizeY - Constants.RegionSize) / Constants.RegionSize;
                    float xx = (x * (SizeOfImage));
                    float yy = SizeOfImage - (y * (SizeOfImage) + (SizeOfImage));
                    g.DrawImage(bitImages[i], xx, yy,
                                (int)(SizeOfImage * ((float)regions[i].RegionSizeX / Constants.RegionSize)),
                                (int)(SizeOfImage * (regions[i].RegionSizeY / (float)Constants.RegionSize))); // y origin is top
                }
            }

            foreach (var bmp in bitImages)
            {
                bmp.Dispose();
            }

            CacheMapTexture(1, regionX, regionY, mapTexture);
            //mapTexture = ResizeBitmap(mapTexture, 128, 128);
            return(mapTexture);
        }
예제 #10
0
        public byte[] MapRequest(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
        {
            //Remove the /MapService/
            string uri = httpRequest.RawUrl.Remove(0, 12);

            if (!uri.StartsWith("map", StringComparison.Ordinal))
            {
                if (uri == "")
                {
                    string resp = "<ListBucketResult xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\">" +
                                  "<Name>map.secondlife.com</Name>" +
                                  "<Prefix/>" +
                                  "<Marker/>" +
                                  "<MaxKeys>1000</MaxKeys>" +
                                  "<IsTruncated>true</IsTruncated>";

                    // TODO:  Why specific (was 1000)? Assumes the center of the map is here.
                    //  Should this be relative to the view?? i.e a passed map center location
                    var txSize = m_mapcenter_x * Constants.RegionSize;
                    var tySize = m_mapcenter_x * Constants.RegionSize;
                    var etSize = 8 * Constants.RegionSize;
                    List <GridRegion> regions = m_gridService.GetRegionRange(
                        null, (txSize - etSize), (txSize + etSize), (tySize - etSize), (tySize + etSize));
                    foreach (var region in regions)
                    {
                        resp += "<Contents><Key>map-1-" + region.RegionLocX / Constants.RegionSize +
                                "-" + region.RegionLocY / Constants.RegionSize +
                                "-objects.jpg</Key>" +
                                "<LastModified>2012-07-09T21:26:32.000Z</LastModified></Contents>";
                    }
                    resp += "</ListBucketResult>";
                    httpResponse.ContentType = "application/xml";
                    return(System.Text.Encoding.UTF8.GetBytes(resp));
                }
                using (MemoryStream imgstream = new MemoryStream())
                {
                    GridRegion region = m_gridService.GetRegionByName(null, uri.Remove(4));
                    if (region == null)
                    {
                        region = m_gridService.GetRegionByUUID(null, OpenMetaverse.UUID.Parse(uri.Remove(uri.Length - 4)));
                    }

                    // non-async because we know we have the asset immediately.
                    byte[] mapasset = null;
                    if (m_assetService.GetExists(region.TerrainMapImage.ToString()))
                    {
                        mapasset = m_assetService.GetData(region.TerrainMapImage.ToString());
                    }
                    if (mapasset != null)
                    {
                        try
                        {
                            Image image = m_j2kDecoder.DecodeToImage(mapasset);
                            if (image == null)
                            {
                                return(new byte[0]);
                            }
                            // Decode image to System.Drawing.Image

                            EncoderParameters myEncoderParameters = new EncoderParameters();
                            myEncoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, 95L);
                            var encInfo = GetEncoderInfo("image/jpeg");
                            if (encInfo != null)
                            {
                                // Save bitmap to stream
                                image.Save(imgstream, encInfo, myEncoderParameters);
                            }
                            image.Dispose();
                            myEncoderParameters.Dispose();

                            // Write the stream to a byte array for output
                            return(imgstream.ToArray());
                        }
                        catch { }
                    }
                }
                return(new byte[0]);
            }
            string[] splitUri = uri.Split('-');
            byte[]   jpeg     = FindCachedImage(uri);
            if (jpeg.Length != 0)
            {
                httpResponse.ContentType = "image/jpeg";
                return(jpeg);
            }
            try
            {
                int mapLayer      = int.Parse(uri.Substring(4, 1));
                int regionX       = int.Parse(splitUri[2]);
                int regionY       = int.Parse(splitUri[3]);
                int distance      = (int)Math.Pow(2, mapLayer);
                int maxRegionSize = m_gridService.GetMaxRegionSize();
                if (maxRegionSize == 0)
                {
                    maxRegionSize = Constants.MaxRegionSize;
                }
                List <GridRegion> regions = m_gridService.GetRegionRange(
                    null,
                    ((regionX) * Constants.RegionSize) - maxRegionSize,
                    ((regionX + distance) * Constants.RegionSize) + maxRegionSize,
                    ((regionY) * Constants.RegionSize) - maxRegionSize,
                    ((regionY + distance) * Constants.RegionSize) + maxRegionSize);

                Bitmap mapTexture = BuildMapTile(mapLayer, regionX, regionY, regions);
                jpeg = CacheMapTexture(mapLayer, regionX, regionY, mapTexture);
                DisposeTexture(mapTexture);
            }
            catch
            {
            }
            httpResponse.ContentType = "image/jpeg";
            return(jpeg);
        }
예제 #11
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,
                                   uint regionPositionX, uint regionPositionY,
                                   IAssetService assetService, IJ2KDecoder decoder,
                                   bool textureTerrain, bool averagetextureTerrain,
                                   int twidth, int theight)
        {
            Debug.Assert(textureIDs.Length == 4);
            Debug.Assert(startHeights.Length == 4);
            Debug.Assert(heightRanges.Length == 4);

            Bitmap[] detailTexture = new Bitmap[4];

            byte[] mapColorsRed   = new byte[4];
            byte[] mapColorsGreen = new byte[4];
            byte[] mapColorsBlue  = new byte[4];

            bool usecolors = false;

            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 = null;

                        // asset cache indexes are strings
                        string cacheName = "MAP" + textureIDs[i].ToString();

                        // Try to fetch a cached copy of the decoded/resized version of this texture
                        asset = assetService.GetCached(cacheName);
                        if (asset != null)
                        {
                            try
                            {
                                using (System.IO.MemoryStream stream = new System.IO.MemoryStream(asset.Data))
                                    detailTexture[i] = (Bitmap)Image.FromStream(stream);

                                if (detailTexture[i].PixelFormat != PixelFormat.Format24bppRgb ||
                                    detailTexture[i].Width != 16 || detailTexture[i].Height != 16)
                                {
                                    detailTexture[i].Dispose();
                                    detailTexture[i] = null;
                                }
                            }
                            catch (Exception ex)
                            {
                                m_log.Warn("Failed to decode cached terrain patch texture" + 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)decoder.DecodeToImage(asset.Data);
                                }
                                catch (Exception ex)
                                {
                                    m_log.Warn("Failed to decode terrain texture " + asset.ID + ": " + ex.Message);
                                }
                            }

                            if (detailTexture[i] != null)
                            {
                                if (detailTexture[i].PixelFormat != PixelFormat.Format24bppRgb ||
                                    detailTexture[i].Width != 16 || detailTexture[i].Height != 16)
                                {
                                    using (Bitmap origBitmap = detailTexture[i])
                                        detailTexture[i] = Util.ResizeImageSolid(origBitmap, 16, 16);
                                }

                                // 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      = UUID.Zero,
                                    ID          = cacheName,
                                    Local       = true,
                                    Name        = String.Empty,
                                    Temporary   = true,
                                    Type        = (sbyte)AssetType.Unknown
                                };
                                newAsset.Metadata.ContentType = "image/png";
                                assetService.Store(newAsset);
                            }
                        }
                    }
                }

                #endregion Texture Fetching
                if (averagetextureTerrain)
                {
                    for (int t = 0; t < 4; t++)
                    {
                        usecolors = true;
                        if (detailTexture[t] == null)
                        {
                            mapColorsRed[t]   = DEFAULT_TERRAIN_COLOR[t].R;
                            mapColorsGreen[t] = DEFAULT_TERRAIN_COLOR[t].G;
                            mapColorsBlue[t]  = DEFAULT_TERRAIN_COLOR[t].B;
                            continue;
                        }

                        int npixeis = 0;
                        int cR      = 0;
                        int cG      = 0;
                        int cB      = 0;

                        BitmapData bmdata = detailTexture[t].LockBits(new Rectangle(0, 0, 16, 16),
                                                                      ImageLockMode.ReadOnly, detailTexture[t].PixelFormat);

                        npixeis = bmdata.Height * bmdata.Width;
                        int ylen = bmdata.Height * bmdata.Stride;

                        unsafe
                        {
                            for (int y = 0; y < ylen; y += bmdata.Stride)
                            {
                                byte *ptrc = (byte *)bmdata.Scan0 + y;
                                for (int x = 0; x < bmdata.Width; ++x)
                                {
                                    cR += *(ptrc++);
                                    cG += *(ptrc++);
                                    cB += *(ptrc++);
                                }
                            }
                        }
                        detailTexture[t].UnlockBits(bmdata);
                        detailTexture[t].Dispose();

                        mapColorsRed[t]   = (byte)Util.Clamp(cR / npixeis, 0, 255);
                        mapColorsGreen[t] = (byte)Util.Clamp(cG / npixeis, 0, 255);
                        mapColorsBlue[t]  = (byte)Util.Clamp(cB / npixeis, 0, 255);
                    }
                }
                else
                {
                    // 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(16, 16, PixelFormat.Format24bppRgb);
                            using (Graphics gfx = Graphics.FromImage(detailTexture[i]))
                            {
                                using (SolidBrush brush = new SolidBrush(DEFAULT_TERRAIN_COLOR[i]))
                                    gfx.FillRectangle(brush, 0, 0, 16, 16);
                            }
                        }
                        else
                        {
                            if (detailTexture[i].Width != 16 || detailTexture[i].Height != 16)
                            {
                                using (Bitmap origBitmap = detailTexture[i])
                                    detailTexture[i] = Util.ResizeImageSolid(origBitmap, 16, 16);
                            }
                        }
                    }
                }
            }
            else
            {
                usecolors = true;
                for (int t = 0; t < 4; t++)
                {
                    mapColorsRed[t]   = DEFAULT_TERRAIN_COLOR[t].R;
                    mapColorsGreen[t] = DEFAULT_TERRAIN_COLOR[t].G;
                    mapColorsBlue[t]  = DEFAULT_TERRAIN_COLOR[t].B;
                }
            }

            #region Layer Map

            float xFactor = terrain.Width / twidth;
            float yFactor = terrain.Height / theight;

            #endregion Layer Map

            #region Texture Compositing

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

            // Unsafe work as we lock down the source textures for quicker access and access the
            //    pixel data directly
            float invtwitdthMinus1 = 1.0f / (twidth - 1);
            float invtheightMinus1 = 1.0f / (theight - 1);
            int   ty;
            int   tx;
            float pctx;
            float pcty;
            float height;
            float layer;
            float layerDiff;
            int   l0;
            int   l1;
            uint  yglobalpos;

            if (usecolors)
            {
                float a;
                float b;
                unsafe
                {
                    byte *ptrO;
                    for (int y = 0; y < theight; ++y)
                    {
                        pcty       = y * invtheightMinus1;
                        ptrO       = (byte *)outputData.Scan0 + y * outputData.Stride;
                        ty         = (int)(y * yFactor);
                        yglobalpos = (uint)ty + regionPositionY;

                        for (int x = 0; x < twidth; ++x)
                        {
                            tx     = (int)(x * xFactor);
                            pctx   = x * invtwitdthMinus1;
                            height = (float)terrain[tx, ty];
                            layer  = getLayerTex(height, pctx, pcty,
                                                 (uint)tx + regionPositionX, yglobalpos,
                                                 startHeights, heightRanges);

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

                            layerDiff = layer - l0;

                            a         = mapColorsRed[l0];
                            b         = mapColorsRed[l1];
                            *(ptrO++) = (byte)(a + layerDiff * (b - a));

                            a         = mapColorsGreen[l0];
                            b         = mapColorsGreen[l1];
                            *(ptrO++) = (byte)(a + layerDiff * (b - a));

                            a         = mapColorsBlue[l0];
                            b         = mapColorsBlue[l1];
                            *(ptrO++) = (byte)(a + layerDiff * (b - a));
                        }
                    }
                }
            }
            else
            {
                float aB;
                float aG;
                float aR;
                float bB;
                float bG;
                float bR;

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

                    byte *ptr;
                    byte *ptrO;
                    for (int y = 0; y < theight; y++)
                    {
                        pcty = y * invtheightMinus1;
                        int ypatch = ((int)(y * yFactor) & 0x0f) * datas[0].Stride;
                        ptrO       = (byte *)outputData.Scan0 + y * outputData.Stride;
                        ty         = (int)(y * yFactor);
                        yglobalpos = (uint)ty + regionPositionY;

                        for (int x = 0; x < twidth; x++)
                        {
                            tx     = (int)(x * xFactor);
                            pctx   = x * invtwitdthMinus1;
                            height = (float)terrain[tx, ty];
                            layer  = getLayerTex(height, pctx, pcty,
                                                 (uint)tx + regionPositionX, yglobalpos,
                                                 startHeights, heightRanges);

                            // Select two textures
                            l0        = (int)layer;
                            layerDiff = layer - l0;

                            int patchOffset = (tx & 0x0f) * 3 + ypatch;

                            ptr = (byte *)datas[l0].Scan0 + patchOffset;
                            aB  = *(ptr++);
                            aG  = *(ptr++);
                            aR  = *(ptr);

                            l1  = Math.Min(l0 + 1, 3);
                            ptr = (byte *)datas[l1].Scan0 + patchOffset;
                            bB  = *(ptr++);
                            bG  = *(ptr++);
                            bR  = *(ptr);


                            // Interpolate between the two selected textures
                            *(ptrO++) = (byte)(aB + layerDiff * (bB - aB));
                            *(ptrO++) = (byte)(aG + layerDiff * (bG - aG));
                            *(ptrO++) = (byte)(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);

//output.Save("terr.png",ImageFormat.Png);

            #endregion Texture Compositing

            return(output);
        }
        void CreatePrim(WarpRenderer renderer, ISceneChildEntity prim, bool texturePrims)
        {
            try {
                if ((PCode)prim.Shape.PCode != PCode.Prim)
                {
                    return;
                }
                if (prim.Scale.LengthSquared() < MIN_PRIM_SIZE * MIN_PRIM_SIZE)
                {
                    return;
                }

                Primitive   omvPrim    = prim.Shape.ToOmvPrimitive(prim.OffsetPosition, prim.GetRotationOffset());
                FacetedMesh renderMesh = null;

                // Are we dealing with a sculptie or mesh?
                if (omvPrim.Sculpt != null && omvPrim.Sculpt.SculptTexture != UUID.Zero)
                {
                    // Try fetching the asset
                    byte [] sculptAsset = m_scene.AssetService.GetData(omvPrim.Sculpt.SculptTexture.ToString());
                    if (sculptAsset != null)
                    {
                        // Is it a mesh?
                        if (omvPrim.Sculpt.Type == SculptType.Mesh)
                        {
                            AssetMesh meshAsset = new AssetMesh(omvPrim.Sculpt.SculptTexture, sculptAsset);
                            FacetedMesh.TryDecodeFromAsset(omvPrim, meshAsset, DetailLevel.Highest, out renderMesh);
                            meshAsset = null;
                        }
                        else   // It's sculptie
                        {
                            Image sculpt = m_imgDecoder.DecodeToImage(sculptAsset);
                            if (sculpt != null)
                            {
                                renderMesh = m_primMesher.GenerateFacetedSculptMesh(omvPrim, (Bitmap)sculpt,
                                                                                    DetailLevel.Medium);
                                sculpt.Dispose();
                            }
                        }
                        sculptAsset = null;
                    }
                    else
                    {
                        // missing sculpt data... replace with something
                        renderMesh = m_primMesher.GenerateFacetedMesh(omvPrim, DetailLevel.Medium);
                    }
                }
                else   // Prim
                {
                    renderMesh = m_primMesher.GenerateFacetedMesh(omvPrim, DetailLevel.Medium);
                }

                if (renderMesh == null)
                {
                    return;
                }

                warp_Vector     primPos = ConvertVector(prim.GetWorldPosition());
                warp_Quaternion primRot = ConvertQuaternion(prim.GetRotationOffset());

                warp_Matrix m = warp_Matrix.quaternionMatrix(primRot);

                if (prim.ParentID != 0)
                {
                    ISceneEntity group = m_scene.GetGroupByPrim(prim.LocalId);
                    if (group != null)
                    {
                        m.transform(warp_Matrix.quaternionMatrix(ConvertQuaternion(group.RootChild.GetRotationOffset())));
                    }
                }

                warp_Vector primScale = ConvertVector(prim.Scale);

                string primID = prim.UUID.ToString();

                // Create the prim faces
                for (int i = 0; i < renderMesh.Faces.Count; i++)
                {
                    Face   renderFace = renderMesh.Faces [i];
                    string meshName   = primID + "-Face-" + i;

                    warp_Object faceObj = new warp_Object(renderFace.Vertices.Count, renderFace.Indices.Count / 3);

                    foreach (Vertex v in renderFace.Vertices)
                    {
                        warp_Vector pos  = ConvertVector(v.Position);
                        warp_Vector norm = ConvertVector(v.Normal);

                        if (prim.Shape.SculptTexture == UUID.Zero)
                        {
                            norm = norm.reverse();
                        }
                        warp_Vertex vert = new warp_Vertex(pos, norm, v.TexCoord.X, v.TexCoord.Y);

                        faceObj.addVertex(vert);
                    }

                    for (int j = 0; j < renderFace.Indices.Count;)
                    {
                        faceObj.addTriangle(
                            renderFace.Indices [j++],
                            renderFace.Indices [j++],
                            renderFace.Indices [j++]);
                    }

                    Primitive.TextureEntryFace teFace = prim.Shape.Textures.GetFace((uint)i);
                    string materialName;
                    Color4 faceColor = GetFaceColor(teFace);

                    if (texturePrims && (prim.Scale.LengthSquared() > m_texturePrimSize))
                    {
                        materialName = GetOrCreateMaterial(renderer, faceColor, teFace.TextureID);
                    }
                    else
                    {
                        materialName = GetOrCreateMaterial(renderer, faceColor);
                    }

                    faceObj.transform(m);
                    faceObj.setPos(primPos);
                    faceObj.scaleSelf(primScale.x, primScale.y, primScale.z);

                    renderer.Scene.addObject(meshName, faceObj);

                    renderer.SetObjectMaterial(meshName, materialName);

                    faceObj = null;
                }
                renderMesh.Faces.Clear();
                renderMesh = null;
            } catch (Exception ex) {
                MainConsole.Instance.Warn("[WarpTile generator]: Exception creating prim, " + ex);
            }
        }
예제 #13
0
        private Mesh CreateMeshFromPrimMesher(string primName, PrimitiveBaseShape primShape, Vector3 size, float lod,
                                              ulong key)
        {
            PrimMesh   primMesh;
            SculptMesh sculptMesh;

            List <Coord> coords = new List <Coord>();
            List <Face>  faces  = new List <Face>();

            Image  idata = null;
            string decodedSculptFileName = "";

            if (primShape.SculptEntry)
            {
                if (((SculptType)primShape.SculptType & SculptType.Mesh) == SculptType.Mesh)
                {
                    if (!UseMeshesPhysicsMesh)
                    {
                        return(null);
                    }

                    MainConsole.Instance.Debug("[MESH]: experimental mesh proxy generation");

                    OSD meshOsd = null;

                    if (primShape.SculptData == null || primShape.SculptData.Length <= 0)
                    {
                        //MainConsole.Instance.Error("[MESH]: asset data is zero length");
                        return(null);
                    }

                    long start = 0;
                    using (MemoryStream data = new MemoryStream(primShape.SculptData))
                    {
                        try
                        {
                            meshOsd = OSDParser.DeserializeLLSDBinary(data);
                        }
                        catch (Exception e)
                        {
                            MainConsole.Instance.Error("[MESH]: Exception deserializing mesh asset header:" + e);
                        }
                        start = data.Position;
                    }

                    if (meshOsd is OSDMap)
                    {
                        OSDMap map          = (OSDMap)meshOsd;
                        OSDMap physicsParms = new OSDMap();

                        if (map.ContainsKey("physics_cached"))
                        {
                            OSD  cachedMeshMap = map["physics_cached"]; // cached data from Aurora
                            Mesh cachedMesh    = new Mesh(key);
                            cachedMesh.Deserialize(cachedMeshMap);
                            cachedMesh.WasCached = true;
                            return(cachedMesh); //Return here, we found all of the info right here
                        }
                        if (map.ContainsKey("physics_shape"))
                        {
                            physicsParms = (OSDMap)map["physics_shape"];  // old asset format
                        }
                        if (physicsParms.Count == 0 && map.ContainsKey("physics_mesh"))
                        {
                            physicsParms = (OSDMap)map["physics_mesh"];  // new asset format
                        }
                        if (physicsParms.Count == 0 && map.ContainsKey("physics_convex"))
                        {
                            // convex hull format, which we can't read, so instead
                            // read the highest lod that exists, and use it instead
                            physicsParms = (OSDMap)map["high_lod"];
                        }

                        int physOffset = physicsParms["offset"].AsInteger() + (int)start;
                        int physSize   = physicsParms["size"].AsInteger();

                        if (physOffset < 0 || physSize == 0)
                        {
                            return(null); // no mesh data in asset
                        }
                        OSD    decodedMeshOsd = new OSD();
                        byte[] meshBytes      = new byte[physSize];
                        Buffer.BlockCopy(primShape.SculptData, physOffset, meshBytes, 0, physSize);
                        try
                        {
                            using (MemoryStream inMs = new MemoryStream(meshBytes))
                            {
                                using (MemoryStream outMs = new MemoryStream())
                                {
                                    using (ZOutputStream zOut = new ZOutputStream(outMs))
                                    {
                                        byte[] readBuffer = new byte[2048];
                                        int    readLen    = 0;
                                        while ((readLen = inMs.Read(readBuffer, 0, readBuffer.Length)) > 0)
                                        {
                                            zOut.Write(readBuffer, 0, readLen);
                                        }
                                        zOut.Flush();
                                        outMs.Seek(0, SeekOrigin.Begin);

                                        byte[] decompressedBuf = outMs.GetBuffer();

                                        decodedMeshOsd = OSDParser.DeserializeLLSDBinary(decompressedBuf);
                                    }
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            MainConsole.Instance.Error("[MESH]: exception decoding physical mesh: " + e);
                            return(null);
                        }

                        OSDArray decodedMeshOsdArray = null;

                        // physics_shape is an array of OSDMaps, one for each submesh
                        if (decodedMeshOsd is OSDArray)
                        {
                            decodedMeshOsdArray = (OSDArray)decodedMeshOsd;
                            foreach (OSD subMeshOsd in decodedMeshOsdArray)
                            {
                                if (subMeshOsd is OSDMap)
                                {
                                    OSDMap subMeshMap = (OSDMap)subMeshOsd;

                                    // As per http://wiki.secondlife.com/wiki/Mesh/Mesh_Asset_Format, some Mesh Level
                                    // of Detail Blocks (maps) contain just a NoGeometry key to signal there is no
                                    // geometry for this submesh.
                                    if (subMeshMap.ContainsKey("NoGeometry") && (subMeshMap["NoGeometry"]))
                                    {
                                        continue;
                                    }

                                    Vector3 posMax = new Vector3(0.5f, 0.5f, 0.5f);
                                    Vector3 posMin = new Vector3(-0.5f, -0.5f, -0.5f);
                                    if (subMeshMap.ContainsKey("PositionDomain"))
                                    //Optional, so leave the max and min values otherwise
                                    {
                                        posMax = ((OSDMap)subMeshMap["PositionDomain"])["Max"].AsVector3();
                                        posMin = ((OSDMap)subMeshMap["PositionDomain"])["Min"].AsVector3();
                                    }
                                    ushort faceIndexOffset = (ushort)coords.Count;

                                    byte[] posBytes = subMeshMap["Position"].AsBinary();
                                    for (int i = 0; i < posBytes.Length; i += 6)
                                    {
                                        ushort uX = Utils.BytesToUInt16(posBytes, i);
                                        ushort uY = Utils.BytesToUInt16(posBytes, i + 2);
                                        ushort uZ = Utils.BytesToUInt16(posBytes, i + 4);

                                        Coord c = new Coord(
                                            Utils.UInt16ToFloat(uX, posMin.X, posMax.X) * size.X,
                                            Utils.UInt16ToFloat(uY, posMin.Y, posMax.Y) * size.Y,
                                            Utils.UInt16ToFloat(uZ, posMin.Z, posMax.Z) * size.Z);

                                        coords.Add(c);
                                    }

                                    byte[] triangleBytes = subMeshMap["TriangleList"].AsBinary();
                                    for (int i = 0; i < triangleBytes.Length; i += 6)
                                    {
                                        ushort v1 = (ushort)(Utils.BytesToUInt16(triangleBytes, i) + faceIndexOffset);
                                        ushort v2 =
                                            (ushort)(Utils.BytesToUInt16(triangleBytes, i + 2) + faceIndexOffset);
                                        ushort v3 =
                                            (ushort)(Utils.BytesToUInt16(triangleBytes, i + 4) + faceIndexOffset);
                                        Face f = new Face(v1, v2, v3);
                                        faces.Add(f);
                                    }
                                }
                            }
                        }
                    }
                }
                else
                {
                    if (cacheSculptMaps && primShape.SculptTexture != UUID.Zero)
                    {
                        decodedSculptFileName = System.IO.Path.Combine(decodedSculptMapPath,
                                                                       "smap_" + primShape.SculptTexture.ToString());
                        try
                        {
                            if (File.Exists(decodedSculptFileName))
                            {
                                idata = Image.FromFile(decodedSculptFileName);
                            }
                        }
                        catch (Exception e)
                        {
                            MainConsole.Instance.Error("[SCULPT]: unable to load cached sculpt map " +
                                                       decodedSculptFileName + " " + e);
                        }
                        //if (idata != null)
                        //    MainConsole.Instance.Debug("[SCULPT]: loaded cached map asset for map ID: " + primShape.SculptTexture.ToString());
                    }

                    if (idata == null)
                    {
                        if (primShape.SculptData == null || primShape.SculptData.Length == 0)
                        {
                            return(null);
                        }

                        try
                        {
                            idata = m_j2kDecoder.DecodeToImage(primShape.SculptData);

                            if (idata != null && cacheSculptMaps &&
                                (cacheSculptAlphaMaps || (((ImageFlags)(idata.Flags) & ImageFlags.HasAlpha) == 0)))
                            {
                                try
                                {
                                    idata.Save(decodedSculptFileName, ImageFormat.MemoryBmp);
                                }
                                catch (Exception e)
                                {
                                    MainConsole.Instance.Error("[SCULPT]: unable to cache sculpt map " +
                                                               decodedSculptFileName + " " +
                                                               e);
                                }
                            }
                        }
                        catch (DllNotFoundException)
                        {
                            MainConsole.Instance.Error(
                                "[PHYSICS]: OpenJpeg is not installed correctly on this system. Physics Proxy generation failed.  Often times this is because of an old version of GLIBC.  You must have version 2.4 or above!");
                            return(null);
                        }
                        catch (IndexOutOfRangeException)
                        {
                            MainConsole.Instance.Error(
                                "[PHYSICS]: OpenJpeg was unable to decode this. Physics Proxy generation failed");
                            return(null);
                        }
                        catch (Exception ex)
                        {
                            MainConsole.Instance.Error(
                                "[PHYSICS]: Unable to generate a Sculpty physics proxy. Sculpty texture decode failed: " +
                                ex);
                            return(null);
                        }
                    }

                    SculptMesh.SculptType sculptType;
                    switch ((SculptType)primShape.SculptType)
                    {
                    case SculptType.Cylinder:
                        sculptType = SculptMesh.SculptType.cylinder;
                        break;

                    case SculptType.Plane:
                        sculptType = SculptMesh.SculptType.plane;
                        break;

                    case SculptType.Torus:
                        sculptType = SculptMesh.SculptType.torus;
                        break;

                    case SculptType.Sphere:
                        sculptType = SculptMesh.SculptType.sphere;
                        break;

                    default:
                        sculptType = SculptMesh.SculptType.plane;
                        break;
                    }

                    bool mirror = ((primShape.SculptType & 128) != 0);
                    bool invert = ((primShape.SculptType & 64) != 0);

                    if (idata == null)
                    {
                        return(null);
                    }

                    sculptMesh = new SculptMesh((Bitmap)idata, sculptType, (int)lod, false, mirror, invert);

                    idata.Dispose();
                    idata = null;

                    sculptMesh.DumpRaw(baseDir, primName, "primMesh");

                    sculptMesh.Scale(size.X, size.Y, size.Z);

                    coords = sculptMesh.coords;
                    faces  = sculptMesh.faces;
                }
            }
            else
            {
                float pathShearX = primShape.PathShearX < 128
                                       ? primShape.PathShearX * 0.01f
                                       : (primShape.PathShearX - 256) * 0.01f;
                float pathShearY = primShape.PathShearY < 128
                                       ? primShape.PathShearY * 0.01f
                                       : (primShape.PathShearY - 256) * 0.01f;
                float pathBegin  = primShape.PathBegin * 2.0e-5f;
                float pathEnd    = 1.0f - primShape.PathEnd * 2.0e-5f;
                float pathScaleX = (primShape.PathScaleX - 100) * 0.01f;
                float pathScaleY = (primShape.PathScaleY - 100) * 0.01f;

                float profileBegin  = primShape.ProfileBegin * 2.0e-5f;
                float profileEnd    = 1.0f - primShape.ProfileEnd * 2.0e-5f;
                float profileHollow = primShape.ProfileHollow * 2.0e-5f;
                if (profileHollow > 0.95f)
                {
                    if (profileHollow > 0.99f)
                    {
                        profileHollow = 0.99f;
                    }
                    float sizeX = primShape.Scale.X - (primShape.Scale.X * profileHollow);
                    if (sizeX < 0.1f)                        //If its > 0.1, its fine to mesh at the small hollow
                    {
                        profileHollow = 0.95f + (sizeX / 2); //Scale the rest by how large the size of the prim is
                    }
                }

                int sides = 4;
                switch ((primShape.ProfileCurve & 0x07))
                {
                case (byte)ProfileShape.EquilateralTriangle:
                    sides = 3;
                    break;

                case (byte)ProfileShape.Circle:
                    sides = 24;
                    break;

                case (byte)ProfileShape.HalfCircle:
                    sides        = 24;
                    profileBegin = 0.5f * profileBegin + 0.5f;
                    profileEnd   = 0.5f * profileEnd + 0.5f;
                    break;
                }

                int hollowSides = sides;
                switch (primShape.HollowShape)
                {
                case HollowShape.Circle:
                    hollowSides = 24;
                    break;

                case HollowShape.Square:
                    hollowSides = 4;
                    break;

                case HollowShape.Triangle:
                    hollowSides = 3;
                    break;
                }

                primMesh = new PrimMesh(sides, profileBegin, profileEnd, profileHollow, hollowSides);

                if (primMesh.errorMessage != null)
                {
                    if (primMesh.errorMessage.Length > 0)
                    {
                        MainConsole.Instance.Error("[ERROR] " + primMesh.errorMessage);
                    }
                }

                primMesh.topShearX    = pathShearX;
                primMesh.topShearY    = pathShearY;
                primMesh.pathCutBegin = pathBegin;
                primMesh.pathCutEnd   = pathEnd;

                if (primShape.PathCurve == (byte)Extrusion.Straight || primShape.PathCurve == (byte)Extrusion.Flexible)
                {
                    primMesh.twistBegin = primShape.PathTwistBegin * 18 / 10;
                    primMesh.twistEnd   = primShape.PathTwist * 18 / 10;
                    primMesh.taperX     = pathScaleX;
                    primMesh.taperY     = pathScaleY;

                    if (profileBegin < 0.0f || profileBegin >= profileEnd || profileEnd > 1.0f)
                    {
                        ReportPrimError("*** CORRUPT PRIM!! ***", primName, primMesh);
                        if (profileBegin < 0.0f)
                        {
                            profileBegin = 0.0f;
                        }
                        if (profileEnd > 1.0f)
                        {
                            profileEnd = 1.0f;
                        }
                    }
#if SPAM
                    MainConsole.Instance.Debug("****** PrimMesh Parameters (Linear) ******\n" + primMesh.ParamsToDisplayString());
#endif
                    try
                    {
                        primMesh.Extrude(primShape.PathCurve == (byte)Extrusion.Straight
                                             ? PathType.Linear
                                             : PathType.Flexible);
                    }
                    catch (Exception ex)
                    {
                        ReportPrimError("Extrusion failure: exception: " + ex, primName, primMesh);
                        return(null);
                    }
                }
                else
                {
                    primMesh.holeSizeX   = (200 - primShape.PathScaleX) * 0.01f;
                    primMesh.holeSizeY   = (200 - primShape.PathScaleY) * 0.01f;
                    primMesh.radius      = 0.01f * primShape.PathRadiusOffset;
                    primMesh.revolutions = 1.0f + 0.015f * primShape.PathRevolutions;
                    primMesh.skew        = 0.01f * primShape.PathSkew;
                    primMesh.twistBegin  = primShape.PathTwistBegin * 36 / 10;
                    primMesh.twistEnd    = primShape.PathTwist * 36 / 10;
                    primMesh.taperX      = primShape.PathTaperX * 0.01f;
                    primMesh.taperY      = primShape.PathTaperY * 0.01f;

                    if (profileBegin < 0.0f || profileBegin >= profileEnd || profileEnd > 1.0f)
                    {
                        ReportPrimError("*** CORRUPT PRIM!! ***", primName, primMesh);
                        if (profileBegin < 0.0f)
                        {
                            profileBegin = 0.0f;
                        }
                        if (profileEnd > 1.0f)
                        {
                            profileEnd = 1.0f;
                        }
                    }
#if SPAM
                    MainConsole.Instance.Debug("****** PrimMesh Parameters (Circular) ******\n" + primMesh.ParamsToDisplayString());
#endif
                    try
                    {
                        primMesh.Extrude(PathType.Circular);
                    }
                    catch (Exception ex)
                    {
                        ReportPrimError("Extrusion failure: exception: " + ex, primName, primMesh);
                        return(null);
                    }
                }

                primMesh.DumpRaw(baseDir, primName, "primMesh");

                primMesh.Scale(size.X, size.Y, size.Z);

                coords   = primMesh.coords;
                faces    = primMesh.faces;
                primMesh = null;
            }

            Mesh mesh = new Mesh(key);
            //mesh.m_triangles = faces;
            //mesh.m_vertices = coords;
            // Add the corresponding triangles to the mesh
            mesh.Set(coords, faces);
            coords.Clear();
            faces.Clear();
            coords = null;
            faces  = null;
            return(mesh);
        }
예제 #14
0
        public Hashtable MapRequest(Hashtable request)
        {
            Hashtable reply = new Hashtable();
            string    uri   = request["uri"].ToString();

            //Remove the /MapService/
            uri = uri.Remove(0, 12);
            if (!uri.StartsWith("map"))
            {
                if (uri == "")
                {
                    string resp = "<ListBucketResult xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\">" +
                                  "<Name>map.secondlife.com</Name>" +
                                  "<Prefix/>" +
                                  "<Marker/>" +
                                  "<MaxKeys>1000</MaxKeys>" +
                                  "<IsTruncated>true</IsTruncated>";
                    List <GridRegion> regions = m_gridService.GetRegionRange(null,
                                                                             (1000 * Constants.RegionSize) - (8 * Constants.RegionSize),
                                                                             (1000 * Constants.RegionSize) + (8 * Constants.RegionSize),
                                                                             (1000 * Constants.RegionSize) - (8 * Constants.RegionSize),
                                                                             (1000 * Constants.RegionSize) + (8 * Constants.RegionSize));
                    foreach (var region in regions)
                    {
                        resp += "<Contents><Key>map-1-" + region.RegionLocX / 256 + "-" + region.RegionLocY / 256 + "-objects.jpg</Key>" +
                                "<LastModified>2012-07-09T21:26:32.000Z</LastModified></Contents>";
                    }
                    resp += "</ListBucketResult>";
                    reply["str_response_string"] = resp;
                    reply["int_response_code"]   = 200;
                    reply["content_type"]        = "application/xml";
                    return(reply);
                }
                return(null);
            }
            string[] splitUri = uri.Split('-');
            byte[]   jpeg     = FindCachedImage(uri);
            if (jpeg.Length != 0)
            {
                reply["str_response_string"] = Convert.ToBase64String(jpeg);
                reply["int_response_code"]   = 200;
                reply["content_type"]        = "image/jpeg";

                return(reply);
            }
            try
            {
                int mapLayer      = int.Parse(uri.Substring(4, 1));
                int mapView       = (int)Math.Pow(2, (mapLayer - 1));
                int regionX       = int.Parse(splitUri[2]);
                int regionY       = int.Parse(splitUri[3]);
                int maxRegionSize = m_gridService.GetMaxRegionSize();
                if (maxRegionSize == 0)
                {
                    maxRegionSize = 8192;
                }
                List <GridRegion> regions = m_gridService.GetRegionRange(null,
                                                                         (regionX * Constants.RegionSize) - maxRegionSize,
                                                                         (regionX * Constants.RegionSize) + maxRegionSize,
                                                                         (regionY * Constants.RegionSize) - maxRegionSize,
                                                                         (regionY * Constants.RegionSize) + maxRegionSize);
                List <Image>      bitImages  = new List <Image>();
                List <GridRegion> badRegions = new List <GridRegion>();
                IJ2KDecoder       decoder    = m_registry.RequestModuleInterface <IJ2KDecoder>();
                foreach (GridRegion r in regions)
                {
                    AssetBase texAsset = m_assetService.Get(r.TerrainMapImage.ToString());

                    if (texAsset != null)
                    {
                        Image image = decoder.DecodeToImage(texAsset.Data);
                        if (image != null)
                        {
                            bitImages.Add(image);
                        }
                        else
                        {
                            badRegions.Add(r);
                        }
                    }
                    else
                    {
                        badRegions.Add(r);
                    }
                }
                foreach (GridRegion r in badRegions)
                {
                    regions.Remove(r);
                }

                const int SizeOfImage = 256;

                using (Bitmap mapTexture = new Bitmap(SizeOfImage, SizeOfImage))
                {
                    using (Graphics g = Graphics.FromImage(mapTexture))
                    {
                        SolidBrush sea = new SolidBrush(Color.FromArgb(29, 71, 95));
                        g.FillRectangle(sea, 0, 0, SizeOfImage, SizeOfImage);

                        for (int i = 0; i < regions.Count; i++)
                        {
                            //Find the offsets first
                            float x = (regions[i].RegionLocX - (regionX * (float)Constants.RegionSize)) / Constants.RegionSize;
                            float y = (regions[i].RegionLocY - (regionY * (float)Constants.RegionSize)) / Constants.RegionSize;
                            y += (regions[i].RegionSizeX - Constants.RegionSize) / Constants.RegionSize;
                            float xx = (float)(x * (SizeOfImage / mapView));
                            float yy = SizeOfImage - (y * (SizeOfImage / mapView) + (SizeOfImage / (mapView)));
                            g.DrawImage(bitImages[i], xx, yy,
                                        (int)(SizeOfImage / (float)mapView * ((float)regions[i].RegionSizeX / Constants.RegionSize)), (int)(SizeOfImage / (float)mapView * (regions[i].RegionSizeY / (float)Constants.RegionSize))); // y origin is top
                        }
                    }

                    foreach (var bmp in bitImages)
                    {
                        bmp.Dispose();
                    }

                    EncoderParameters myEncoderParameters = new EncoderParameters();
                    myEncoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, 95L);

                    using (MemoryStream imgstream = new MemoryStream())
                    {
                        // Save bitmap to stream
                        mapTexture.Save(imgstream, GetEncoderInfo("image/jpeg"), myEncoderParameters);

                        // Write the stream to a byte array for output
                        jpeg = imgstream.ToArray();
                    }
                    SaveCachedImage(uri, jpeg);
                }
            }
            catch
            {
            }
            if (jpeg.Length == 0 && splitUri.Length > 1 && splitUri[1].Length > 1)
            {
                using (MemoryStream imgstream = new MemoryStream())
                {
                    GridRegion region = m_registry.RequestModuleInterface <IGridService>().GetRegionByName(null,
                                                                                                           splitUri[1].Remove
                                                                                                               (4));
                    if (region == null)
                    {
                        return(null);
                    }
                    // non-async because we know we have the asset immediately.
                    AssetBase mapasset = m_assetService.Get(region.TerrainMapImage.ToString());
                    if (mapasset != null)
                    {
                        Image        image;
                        ManagedImage mImage;
                        if (!OpenJPEG.DecodeToImage(mapasset.Data, out mImage, out image) || image == null)
                        {
                            return(null);
                        }
                        // Decode image to System.Drawing.Image

                        EncoderParameters myEncoderParameters = new EncoderParameters();
                        myEncoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, 95L);

                        // Save bitmap to stream
                        image.Save(imgstream, GetEncoderInfo("image/jpeg"), myEncoderParameters);

                        // Write the stream to a byte array for output
                        jpeg = imgstream.ToArray();
                        SaveCachedImage(uri, jpeg);

                        mapasset.Dispose();
                        image.Dispose();
                    }
                }
            }
            reply["str_response_string"] = Convert.ToBase64String(jpeg);
            reply["int_response_code"]   = 200;
            reply["content_type"]        = "image/jpeg";

            return(reply);
        }
예제 #15
0
        private void CreatePrim(WarpRenderer renderer, SceneObjectPart prim,
                                bool useTextures)
        {
            const float MIN_SIZE_SQUARE = 4f;

            if ((PCode)prim.Shape.PCode != PCode.Prim)
            {
                return;
            }
            float primScaleLenSquared = prim.Scale.LengthSquared();

            if (primScaleLenSquared < MIN_SIZE_SQUARE)
            {
                return;
            }

            FacetedMesh renderMesh = null;
            Primitive   omvPrim    = prim.Shape.ToOmvPrimitive(prim.OffsetPosition, prim.RotationOffset);

            if (m_renderMeshes)
            {
                if (omvPrim.Sculpt != null && omvPrim.Sculpt.SculptTexture != UUID.Zero)
                {
                    // Try fetchinng the asset
                    byte[] sculptAsset = m_scene.AssetService.GetData(omvPrim.Sculpt.SculptTexture.ToString());
                    if (sculptAsset != null)
                    {
                        // Is it a mesh?
                        if (omvPrim.Sculpt.Type == SculptType.Mesh)
                        {
                            AssetMesh meshAsset = new AssetMesh(omvPrim.Sculpt.SculptTexture, sculptAsset);
                            FacetedMesh.TryDecodeFromAsset(omvPrim, meshAsset, DetailLevel.Highest, out renderMesh);
                            meshAsset = null;
                        }
                        else // It's sculptie
                        {
                            IJ2KDecoder imgDecoder = m_scene.RequestModuleInterface <IJ2KDecoder>();
                            if (imgDecoder != null)
                            {
                                Image sculpt = imgDecoder.DecodeToImage(sculptAsset);
                                if (sculpt != null)
                                {
                                    renderMesh = m_primMesher.GenerateFacetedSculptMesh(omvPrim, (Bitmap)sculpt,
                                                                                        DetailLevel.Medium);
                                    sculpt.Dispose();
                                }
                            }
                        }
                    }
                }
            }

            // If not a mesh or sculptie, try the regular mesher
            if (renderMesh == null)
            {
                renderMesh = m_primMesher.GenerateFacetedMesh(omvPrim, DetailLevel.Medium);
            }

            if (renderMesh == null)
            {
                return;
            }

            string primID = prim.UUID.ToString();

            // Create the prim faces
            // TODO: Implement the useTextures flag behavior
            for (int i = 0; i < renderMesh.Faces.Count; i++)
            {
                Face   face     = renderMesh.Faces[i];
                string meshName = primID + i.ToString();

                // Avoid adding duplicate meshes to the scene
                if (renderer.Scene.objectData.ContainsKey(meshName))
                {
                    continue;
                }

                warp_Object faceObj = new warp_Object();
                for (int j = 0; j < face.Vertices.Count; j++)
                {
                    Vertex      v    = face.Vertices[j];
                    warp_Vector pos  = ConvertVector(v.Position);
                    warp_Vertex vert = new warp_Vertex(pos, v.TexCoord.X, v.TexCoord.Y);
                    faceObj.addVertex(vert);
                }

                for (int j = 0; j < face.Indices.Count; j += 3)
                {
                    faceObj.addTriangle(
                        face.Indices[j + 0],
                        face.Indices[j + 1],
                        face.Indices[j + 2]);
                }

                Primitive.TextureEntryFace teFace = prim.Shape.Textures.GetFace((uint)i);
                Color4 faceColor    = GetFaceColor(teFace);
                string materialName = String.Empty;
                if (m_texturePrims && primScaleLenSquared > m_texturePrimSize * m_texturePrimSize)
                {
                    materialName = GetOrCreateMaterial(renderer, faceColor, teFace.TextureID);
                }
                else
                {
                    materialName = GetOrCreateMaterial(renderer, faceColor);
                }

                warp_Vector     primPos = ConvertVector(prim.GetWorldPosition());
                warp_Quaternion primRot = ConvertQuaternion(prim.GetWorldRotation());
                warp_Matrix     m       = warp_Matrix.quaternionMatrix(primRot);
                faceObj.transform(m);
                faceObj.setPos(primPos);
                faceObj.scaleSelf(prim.Scale.X, prim.Scale.Z, prim.Scale.Y);

                renderer.Scene.addObject(meshName, faceObj);
                renderer.SetObjectMaterial(meshName, materialName);
            }
        }
예제 #16
0
        private void CreatePrim(WarpRenderer renderer, SceneObjectPart prim)
        {
            if ((PCode)prim.Shape.PCode != PCode.Prim)
            {
                return;
            }

            Vector3 ppos = prim.GetWorldPosition();

            if (ppos.Z < m_renderMinHeight || ppos.Z > m_renderMaxHeight)
            {
                return;
            }

            warp_Vector     primPos = ConvertVector(ppos);
            warp_Quaternion primRot = ConvertQuaternion(prim.GetWorldRotation());
            warp_Matrix     m       = warp_Matrix.quaternionMatrix(primRot);

            float screenFactor = renderer.Scene.EstimateBoxProjectedArea(primPos, ConvertVector(prim.Scale), m);

            if (screenFactor < 0)
            {
                return;
            }

            const float log2inv = -1.442695f;
            int         p2      = (int)((float)Math.Log(screenFactor) * log2inv * 0.25 - 1);

            if (p2 < 0)
            {
                p2 = 0;
            }
            else if (p2 > 3)
            {
                p2 = 3;
            }

            DetailLevel lod = (DetailLevel)(3 - p2);

            FacetedMesh renderMesh = null;
            Primitive   omvPrim    = prim.Shape.ToOmvPrimitive(prim.OffsetPosition, prim.RotationOffset);

            if (m_renderMeshes)
            {
                if (omvPrim.Sculpt != null && omvPrim.Sculpt.SculptTexture != UUID.Zero)
                {
                    // Try fetchinng the asset
                    AssetBase sculptAsset = m_scene.AssetService.Get(omvPrim.Sculpt.SculptTexture.ToString());
                    if (sculptAsset != null)
                    {
                        // Is it a mesh?
                        if (omvPrim.Sculpt.Type == SculptType.Mesh)
                        {
                            AssetMesh meshAsset = new AssetMesh(omvPrim.Sculpt.SculptTexture, sculptAsset.Data);
                            FacetedMesh.TryDecodeFromAsset(omvPrim, meshAsset, lod, out renderMesh);
                            meshAsset = null;
                        }
                        else // It's sculptie
                        {
                            if (m_imgDecoder != null)
                            {
                                Image sculpt = m_imgDecoder.DecodeToImage(sculptAsset.Data);
                                if (sculpt != null)
                                {
                                    renderMesh = m_primMesher.GenerateFacetedSculptMesh(omvPrim, (Bitmap)sculpt, lod);
                                    sculpt.Dispose();
                                }
                            }
                        }
                    }
                    else
                    {
                        m_log.WarnFormat("[Warp3D] failed to get mesh or sculpt asset {0} of prim {1} at {2}",
                                         omvPrim.Sculpt.SculptTexture.ToString(), prim.Name, prim.GetWorldPosition().ToString());
                    }
                }
            }

            // If not a mesh or sculptie, try the regular mesher
            if (renderMesh == null)
            {
                renderMesh = m_primMesher.GenerateFacetedMesh(omvPrim, lod);
            }

            if (renderMesh == null)
            {
                return;
            }

            string primID = prim.UUID.ToString();

            // Create the prim faces
            // TODO: Implement the useTextures flag behavior
            for (int i = 0; i < renderMesh.Faces.Count; i++)
            {
                Face   face     = renderMesh.Faces[i];
                string meshName = primID + i.ToString();

                // Avoid adding duplicate meshes to the scene
                if (renderer.Scene.objectData.ContainsKey(meshName))
                {
                    continue;
                }

                warp_Object faceObj = new warp_Object();

                Primitive.TextureEntryFace teFace = prim.Shape.Textures.GetFace((uint)i);
                Color4 faceColor = teFace.RGBA;
                if (faceColor.A == 0)
                {
                    continue;
                }

                string materialName = string.Empty;
                if (m_texturePrims)
                {
                    // if(lod > DetailLevel.Low)
                    {
                        // materialName = GetOrCreateMaterial(renderer, faceColor, teFace.TextureID, lod == DetailLevel.Low);
                        materialName = GetOrCreateMaterial(renderer, faceColor, teFace.TextureID, false, prim);
                        if (String.IsNullOrEmpty(materialName))
                        {
                            continue;
                        }
                        int c = renderer.Scene.material(materialName).getColor();
                        if ((c & warp_Color.MASKALPHA) == 0)
                        {
                            continue;
                        }
                    }
                }
                else
                {
                    materialName = GetOrCreateMaterial(renderer, faceColor);
                }

                if (renderer.Scene.material(materialName).getTexture() == null)
                {
                    // uv map details dont not matter for color;
                    for (int j = 0; j < face.Vertices.Count; j++)
                    {
                        Vertex      v    = face.Vertices[j];
                        warp_Vector pos  = ConvertVector(v.Position);
                        warp_Vertex vert = new warp_Vertex(pos, v.TexCoord.X, v.TexCoord.Y);
                        faceObj.addVertex(vert);
                    }
                }
                else
                {
                    float tu;
                    float tv;
                    float offsetu  = teFace.OffsetU + 0.5f;
                    float offsetv  = teFace.OffsetV + 0.5f;
                    float scaleu   = teFace.RepeatU;
                    float scalev   = teFace.RepeatV;
                    float rotation = teFace.Rotation;
                    float rc       = 0;
                    float rs       = 0;
                    if (rotation != 0)
                    {
                        rc = (float)Math.Cos(rotation);
                        rs = (float)Math.Sin(rotation);
                    }

                    for (int j = 0; j < face.Vertices.Count; j++)
                    {
                        warp_Vertex vert;
                        Vertex      v   = face.Vertices[j];
                        warp_Vector pos = ConvertVector(v.Position);
                        if (teFace.TexMapType == MappingType.Planar)
                        {
                            UVPlanarMap(v, prim.Scale, out tu, out tv);
                        }
                        else
                        {
                            tu = v.TexCoord.X - 0.5f;
                            tv = 0.5f - v.TexCoord.Y;
                        }
                        if (rotation != 0)
                        {
                            float tur = tu * rc - tv * rs;
                            float tvr = tu * rs + tv * rc;
                            tur *= scaleu;
                            tur += offsetu;

                            tvr *= scalev;
                            tvr += offsetv;
                            vert = new warp_Vertex(pos, tur, tvr);
                        }
                        else
                        {
                            tu  *= scaleu;
                            tu  += offsetu;
                            tv  *= scalev;
                            tv  += offsetv;
                            vert = new warp_Vertex(pos, tu, tv);
                        }

                        faceObj.addVertex(vert);
                    }
                }

                for (int j = 0; j < face.Indices.Count; j += 3)
                {
                    faceObj.addTriangle(
                        face.Indices[j + 0],
                        face.Indices[j + 1],
                        face.Indices[j + 2]);
                }

                faceObj.scaleSelf(prim.Scale.X, prim.Scale.Z, prim.Scale.Y);
                faceObj.transform(m);
                faceObj.setPos(primPos);

                renderer.Scene.addObject(meshName, faceObj);
                renderer.SetObjectMaterial(meshName, materialName);
            }
        }
        public static Color4 GetAverageColor(UUID textureID, byte [] j2kData, IScene scene)
        {
            ulong  r      = 0;
            ulong  g      = 0;
            ulong  b      = 0;
            ulong  a      = 0;
            Bitmap bitmap = null;

            try {
                if (j2kData.Length == 0)
                {
                    return(new Color4(1.0f, 0.0f, 1.0f, 1.0f));
                }

                IJ2KDecoder decoder = scene.RequestModuleInterface <IJ2KDecoder> ();
                bitmap = (Bitmap)decoder.DecodeToImage(j2kData);
                if (bitmap == null)
                {
                    return(new Color4(1.0f, 0.0f, 0.5f, 1.0f));
                }

                j2kData = null;
                int width  = bitmap.Width;
                int height = bitmap.Height;

                BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly,
                                                        bitmap.PixelFormat);
                int  pixelBytes = (bitmap.PixelFormat == PixelFormat.Format24bppRgb) ? 3 : 4;
                bool hasAlpha   = (pixelBytes == 4);

                // Sum up the individual channels
                unsafe
                {
                    for (int y = 0; y < height; y++)
                    {
                        byte *row = (byte *)bitmapData.Scan0 + (y * bitmapData.Stride);

                        for (int x = 0; x < width; x++)
                        {
                            b += row [x * pixelBytes + 0];
                            g += row [x * pixelBytes + 1];
                            r += row [x * pixelBytes + 2];
                            if (hasAlpha)
                            {
                                a += row [x * pixelBytes + 3];
                            }
                        }
                    }
                }

                // Get the averages for each channel
                const decimal OO_255      = 1m / 255m;
                decimal       totalPixels = (width * height);

                decimal rm = (r / totalPixels) * OO_255;
                decimal gm = (g / totalPixels) * OO_255;
                decimal bm = (b / totalPixels) * OO_255;
                decimal am;
                if (hasAlpha)
                {
                    am = (a / totalPixels) * OO_255;
                }
                else
                {
                    am = 1m;
                }

                return(new Color4((float)rm, (float)gm, (float)bm, (float)am));
            } catch (Exception ex) {
                MainConsole.Instance.WarnFormat("[WarpTile generator]: Error decoding JPEG2000 texture {0} ({1} bytes): {2}",
                                                textureID,
                                                j2kData.Length, ex.Message);
                return(new Color4(0.5f, 0.5f, 0.5f, 1.0f));
            } finally {
                if (bitmap != null)
                {
                    bitmap.Dispose();
                }
            }
        }
예제 #18
0
        public void ShadeWorld(string[] cmd)
        {
            if (MainConsole.Instance.ConsoleScene == null)
            {
                MainConsole.Instance.Output("Select a scene first");
                return;
            }
            bool  greyScale = MainConsole.Instance.Prompt("Greyscale (yes or no)?").ToLower() == "yes";
            int   R         = 0;
            int   G         = 0;
            int   B         = 0;
            float percent   = 0;

            if (!greyScale)
            {
                R       = int.Parse(MainConsole.Instance.Prompt("R color (0 - 255)"));
                G       = int.Parse(MainConsole.Instance.Prompt("G color (0 - 255)"));
                B       = int.Parse(MainConsole.Instance.Prompt("B color (0 - 255)"));
                percent = float.Parse(MainConsole.Instance.Prompt("Percent to merge in the shade (0 - 100)"));
            }
            if (percent > 1)
            {
                percent /= 100;
            }
            Color shader = Color.FromArgb(R, G, B);

            IJ2KDecoder j2kDecoder = MainConsole.Instance.ConsoleScene.RequestModuleInterface <IJ2KDecoder>();

            ISceneEntity[] entities = MainConsole.Instance.ConsoleScene.Entities.GetEntities();
            foreach (ISceneEntity entity in entities)
            {
                foreach (ISceneChildEntity child in entity.ChildrenEntities())
                {
                    UUID[] textures = GetTextures(child.Shape.Textures);
                    foreach (UUID t in textures)
                    {
                        if (m_previouslyConverted.ContainsKey(t))
                        {
                            child.Shape.Textures = SetTexture(child.Shape, m_previouslyConverted[t], t);
                        }
                        else
                        {
                            AssetBase a = MainConsole.Instance.ConsoleScene.AssetService.Get(t.ToString());
                            if (a != null)
                            {
                                Bitmap texture = (Bitmap)j2kDecoder.DecodeToImage(a.Data);
                                if (texture == null)
                                {
                                    continue;
                                }
                                a.ID    = UUID.Random();
                                texture = Shade(texture, shader, percent, greyScale);
                                a.Data  = OpenJPEG.EncodeFromImage(texture, false);
                                texture.Dispose();
                                a.ID = MainConsole.Instance.ConsoleScene.AssetService.Store(a);
                                child.Shape.Textures = SetTexture(child.Shape, a.ID, t);
                                m_previouslyConverted.Add(t, a.ID);
                                m_revertConverted.Add(a.ID, t);
                            }
                        }
                    }
                }
            }
        }
예제 #19
0
        public void ShadeWorld(IScene scene, string [] cmd)
        {
            bool  greyScale = MainConsole.Instance.Prompt("Greyscale (yes or no)?").ToLower() == "yes";
            int   R         = 0;
            int   G         = 0;
            int   B         = 0;
            float percent   = 0;

            if (!greyScale)
            {
                R       = int.Parse(MainConsole.Instance.Prompt("R color (0 - 255)"));
                G       = int.Parse(MainConsole.Instance.Prompt("G color (0 - 255)"));
                B       = int.Parse(MainConsole.Instance.Prompt("B color (0 - 255)"));
                percent = float.Parse(MainConsole.Instance.Prompt("Percent to merge in the shade (0 - 100)"));
            }
            if (percent > 1)
            {
                percent /= 100;
            }
            Color shader = Color.FromArgb(R, G, B);

            IJ2KDecoder j2kDecoder = scene.RequestModuleInterface <IJ2KDecoder> ();

            ISceneEntity [] entities = scene.Entities.GetEntities();
            foreach (ISceneEntity entity in entities)
            {
                foreach (ISceneChildEntity child in entity.ChildrenEntities())
                {
                    UUID [] textures = GetTextures(child.Shape.Textures);
                    foreach (UUID t in textures)
                    {
                        if (m_previouslyConverted.ContainsKey(t))
                        {
                            child.Shape.Textures = SetTexture(child.Shape, m_previouslyConverted [t], t);
                        }
                        else
                        {
                            AssetBase asset = scene.AssetService.Get(t.ToString());
                            if (asset != null)
                            {
                                Bitmap texture = null;
                                try {
                                    texture = (Bitmap)j2kDecoder.DecodeToImage(asset.Data);
                                } catch {
                                }
                                if (texture == null)
                                {
                                    asset.Dispose();
                                    continue;
                                }

                                asset.ID = UUID.Random();
                                try {
                                    texture = Shade(texture, shader, percent, greyScale);
                                } catch {
                                    asset.Dispose();
                                    continue;   // cannot convert this one...
                                }

                                asset.Data        = OpenJPEG.EncodeFromImage(texture, false);
                                asset.Description = t.ToString();
                                texture.Dispose();
                                asset.ID             = scene.AssetService.Store(asset);
                                child.Shape.Textures = SetTexture(child.Shape, asset.ID, t);
                                m_previouslyConverted.Add(t, asset.ID);
                                m_revertConverted.Add(asset.ID, t);

                                asset.Dispose();
                            }
                        }
                    }
                }
            }
            MainConsole.Instance.Warn("[Shader]: WARNING: You may not be able to revert this once you restart the instance");
        }