public void UploadLotThumbnail() { if (!Screen.InLot) { return; } var lotID = JoinLotRegulator.GetCurrentLotID(); if (lotID == 0) { return; } var bigThumb = Screen.vm.Context.World.GetLotThumb(GameFacade.GraphicsDevice, null); byte[] data; using (var stream = new MemoryStream()) { var tex = TextureUtils.Decimate(bigThumb, GameFacade.GraphicsDevice, 2, false); tex.SaveAsPng(stream, bigThumb.Width / 2, bigThumb.Height / 2); Terrain.OverrideLotThumb(lotID, tex); //tex.Dispose(); data = stream.ToArray(); } DataService.Get <Lot>(lotID).ContinueWith(x => { var lot = x.Result; if (lot == null) { return; //uh, oops! } lot.Lot_Thumbnail = new Common.Serialization.Primitives.cTSOGenericData(data); DataService.Sync(lot, new string[] { "Lot_Thumbnail" }); }); }
public Rectangle GetEmoji(string emojiID) { int index; if (EmojiToIndex.TryGetValue(emojiID, out index)) { return(RectForIndex(index)); } else { index = NextIndex++; ExpandIfNeeded(); lock (IncompleteSpaces) IncompleteSpaces.Add(index); var client = new WebClient(); client.DownloadDataCompleted += (object sender, DownloadDataCompletedEventArgs e) => { if (e.Cancelled || e.Error != null || e.Result == null) { lock (ErrorSpaces) ErrorSpaces.Add(index); } else { GameThread.NextUpdate(x => { try { using (var mem = new MemoryStream(e.Result)) { var tex = Texture2D.FromStream(GD, mem); var decimated = TextureUtils.Decimate(tex, GD, 72 / DefaultRes, true); //blit this into our emoji buffer GD.SetRenderTarget(EmojiTex); if (needClear) { GD.Clear(Color.TransparentBlack); needClear = false; } EmojiBatch.Begin(blendState: BlendState.NonPremultiplied, sortMode: SpriteSortMode.Immediate); EmojiBatch.Draw(decimated, RectForIndex(index), Color.White); EmojiBatch.End(); GD.SetRenderTarget(null); } } catch (Exception) { lock (ErrorSpaces) ErrorSpaces.Add(index); } }); } lock (IncompleteSpaces) IncompleteSpaces.Remove(index); }; client.DownloadDataAsync(new Uri((emojiID[0] == '!')?(emojiID.Substring(1)):(Source + emojiID + ".png"))); Emojis.Add(emojiID); EmojiToIndex[emojiID] = index; return(RectForIndex(index)); } }
public override Texture2D GetIcon(GraphicsDevice gd, int store) { if (Avatar.Head == null && Avatar.Body == null) { return(null); } Outfit ThumbOutfit = (Avatar.Head == null) ? Avatar.Body : Avatar.Head; var AppearanceID = ThumbOutfit.GetAppearance(Avatar.Appearance); var Appearance = FSO.Content.Content.Get().AvatarAppearances.Get(AppearanceID); if (Appearance == null) { return(null); } var ico = FSO.Content.Content.Get().AvatarThumbnails.Get(Appearance.ThumbnailTypeID, Appearance.ThumbnailFileID)?.Get(gd); //todo: better dispose handling for these icons return((store > 0 && ico != null)?TextureUtils.Decimate(ico, gd, 1 << (2 - store)):ico); }
public Texture2D GetObjectThumb(ObjectComponent[] objects, Vector3[] positions, GraphicsDevice gd, WorldState state) { var cam = new WorldCamera3D(gd, Vector3.Zero, Vector3.Zero, Vector3.Up);// WorldCamera3D)state.Camera; var oldVp = state.ViewProjection; /** Center average position **/ Vector3 average = new Vector3(); for (int i = 0; i < positions.Length; i++) { average += positions[i]; } average /= positions.Length; cam.ProjectionOrigin = new Vector2(512, 512); cam.Target = average + new Vector3(0.5f, 0.5f, 0) * 3f; cam.Position = cam.Target + new Vector3(-9, 6, -9); state.DrawOOB = true; var _2d = state._2D; if (ObjThumbTarget == null) { ObjThumbTarget = new RenderTarget2D(gd, 1024, 1024, true, SurfaceFormat.Color, DepthFormat.Depth24); } gd.SetRenderTarget(ObjThumbTarget); var cpoints = new List <Vector3>(); var view = state.View; var vp = view * state.Projection; gd.BlendState = BlendState.NonPremultiplied; gd.RasterizerState = RasterizerState.CullNone; gd.DepthStencilState = DepthStencilState.Default; var effect = WorldContent.RCObject; effect.ViewProjection = vp; state.ViewProjection = vp; effect.SetTechnique(RCObjectTechniques.Draw); state.ClearLighting(false); Blueprint.SetLightColor(WorldContent.RCObject, Color.White, Color.White); var objs = objects.OrderBy(x => { x.UpdateDrawOrder(state); return(x.DrawOrder); }).ToList(); gd.Clear(Color.Transparent); for (int i = 0; i < objs.Count; i++) { var obj = objs[i]; var tilePosition = positions[Array.IndexOf(objects, obj)]; //we need to trick the object into believing it is in a set world state. var oldObjRot = obj.Direction; var oldObjPos = obj.UnmoddedPosition; var oldRoom = obj.Room; obj.Direction = Direction.NORTH; obj.Room = 65535; obj.OnRotationChanged(state); obj.OnZoomChanged(state); obj.Position = tilePosition; obj.Draw(gd, state); var mat = obj.World * vp; cpoints.AddRange(obj.GetBounds().GetCorners().Select(x => { var proj = Vector3.Transform(x, vp); proj.X /= proj.Z; proj.Y /= -proj.Z; proj.X += 1f; proj.X *= 512; proj.Y += 1f; proj.Y *= 512; return(proj); })); //return everything to normal obj.Direction = oldObjRot; obj.Room = oldRoom; obj.UnmoddedPosition = oldObjPos; obj.OnRotationChanged(state); obj.OnZoomChanged(state); } gd.SetRenderTarget(null); var bounds3d = (cpoints.Count > 0) ? BoundingBox.CreateFromPoints(cpoints) : new BoundingBox(); var bounds = new Rectangle((int)bounds3d.Min.X, (int)bounds3d.Min.Y, (int)(bounds3d.Max.X - bounds3d.Min.X), (int)(bounds3d.Max.Y - bounds3d.Min.Y)); bounds.Inflate(1, 1); bounds.X = Math.Max(0, Math.Min(1023, bounds.X)); bounds.Y = Math.Max(0, Math.Min(1023, bounds.Y)); if (bounds.Width + bounds.X > 1024) { bounds.Width = 1024 - bounds.X; } if (bounds.Height + bounds.Y > 1024) { bounds.Height = 1024 - bounds.Y; } bp.Changes.SetFlag(BlueprintGlobalChanges.LIGHTING_CHANGED); //return things to normal state.DrawOOB = false; state.ViewProjection = oldVp; gd.DepthStencilState = DepthStencilState.None; var clip = TextureUtils.Clip(gd, ObjThumbTarget, bounds); var dec = TextureUtils.Decimate(clip, gd, 3, true); return(dec); }