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); }
/// <summary> /// Gets an object group's thumbnail provided an array of objects. /// </summary> /// <param name="objects">The object components to draw.</param> /// <param name="gd">GraphicsDevice instance.</param> /// <param name="state">WorldState instance.</param> /// <returns>Object's ID if the object was found at the given position.</returns> public Texture2D GetObjectThumb(ObjectComponent[] objects, Vector3[] positions, GraphicsDevice gd, WorldState state) { var oldZoom = state.Zoom; var oldRotation = state.Rotation; /** Center average position **/ Vector3 average = new Vector3(); for (int i = 0; i < positions.Length; i++) { average += positions[i]; } average /= positions.Length; state.SilentZoom = WorldZoom.Near; state.SilentRotation = WorldRotation.BottomRight; state.WorldSpace.Invalidate(); state.InvalidateCamera(); state.TempDraw = true; var pxOffset = new Vector2(442, 275) - state.WorldSpace.GetScreenFromTile(average); var _2d = state._2D; Promise <Texture2D> bufferTexture = null; Promise <Texture2D> depthTexture = null; state._2D.OBJIDMode = false; Rectangle bounds = new Rectangle(); using (var buffer = state._2D.WithBuffer(BUFFER_THUMB, ref bufferTexture, BUFFER_THUMB_DEPTH, ref depthTexture)) { _2d.SetScroll(new Vector2()); while (buffer.NextPass()) { for (int i = 0; i < objects.Length; i++) { var obj = objects[i]; var tilePosition = positions[i]; //we need to trick the object into believing it is in a set world state. var oldObjRot = obj.Direction; var oldRoom = obj.Room; obj.Direction = Direction.NORTH; obj.Room = 65535; state.SilentZoom = WorldZoom.Near; state.SilentRotation = WorldRotation.BottomRight; obj.OnRotationChanged(state); obj.OnZoomChanged(state); _2d.OffsetPixel(state.WorldSpace.GetScreenFromTile(tilePosition) + pxOffset); _2d.OffsetTile(tilePosition); _2d.SetObjID(obj.ObjectID); obj.Draw(gd, state); //return everything to normal obj.Direction = oldObjRot; obj.Room = oldRoom; state.SilentZoom = oldZoom; state.SilentRotation = oldRotation; obj.OnRotationChanged(state); obj.OnZoomChanged(state); } bounds = _2d.GetSpriteListBounds(); } } 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; } //return things to normal state.WorldSpace.Invalidate(); state.InvalidateCamera(); state.TempDraw = false; var tex = bufferTexture.Get(); return(TextureUtils.Clip(gd, tex, bounds)); }
public Texture2D GetObjectThumb(ObjectComponent[] objects, Vector3[] positions, GraphicsDevice gd, WorldState state) { var oldZoom = state.Zoom; var oldRotation = state.Rotation; var oldPreciseZoom = state.PreciseZoom; /** Center average position **/ Vector3 average = new Vector3(); for (int i = 0; i < positions.Length; i++) { average += positions[i]; } average /= positions.Length; state.ForceCamera(Utils.Camera.CameraControllerType._2D); state.RenderingThumbnail = true; state.SilentZoom = WorldZoom.Near; state.SilentRotation = WorldRotation.BottomRight; state.SilentPreciseZoom = 1; state._2D.PreciseZoom = state.PreciseZoom; state.WorldSpace.Invalidate(); state.InvalidateCamera(); state.DrawOOB = true; var pxOffset = new Vector2(442, 275) - state.WorldSpace.GetScreenFromTile(average); var _2d = state._2D; Promise <Texture2D> bufferTexture = null; Promise <Texture2D> depthTexture = null; state._2D.OBJIDMode = false; Rectangle?bounds = null; state.ClearLighting(false); //Blueprint.SetLightColor(WorldContent._2DWorldBatchEffect, Color.White, Color.White); //Blueprint.SetLightColor(WorldContent.GrassEffect, Color.White, Color.White); //Blueprint.SetLightColor(Vitaboy.Avatar.Effect, Color.White, Color.White); var oldDS = gd.DepthStencilState; gd.DepthStencilState = DepthStencilState.Default; state.PrepareCamera(); using (var buffer = state._2D.WithBuffer(_2DWorldBatch.BUFFER_THUMB, ref bufferTexture, _2DWorldBatch.BUFFER_THUMB_DEPTH, ref depthTexture)) { _2d.SetScroll(new Vector2()); while (buffer.NextPass()) { _2d.PrepareImmediate(Effects.WorldBatchTechniques.drawZSpriteDepthChannel); for (int i = 0; i < objects.Length; i++) { var obj = objects[i]; var tilePosition = positions[i]; var tileOff = tilePosition - obj.Position; //we need to trick the object into believing it is in a set world state. var oldObjRot = obj.Direction; var oldRoom = obj.Room; obj.Direction = Direction.NORTH; obj.Room = 65535; state.SilentZoom = WorldZoom.Near; state.SilentRotation = WorldRotation.BottomRight; var thumbOffset = state.WorldSpace.GetScreenFromTile(tileOff); _2d.SetShaderOffsets(pxOffset + thumbOffset, WorldSpace.GetWorldFromTile(tileOff)); //offset object into rotated position obj.OnRotationChanged(state); obj.OnZoomChanged(state); var oPx = state.WorldSpace.GetScreenFromTile(tilePosition) + pxOffset; obj.ValidateSprite(state); var offBound = obj.Bounding; if (offBound.Width != 0) { offBound.Offset(pxOffset + thumbOffset); if (offBound.Location.X != int.MaxValue) { if (bounds == null) { bounds = offBound; } else { bounds = Rectangle.Union(offBound, bounds.Value); } } } obj.Draw(gd, state); //return everything to normal obj.Direction = oldObjRot; obj.Room = oldRoom; state.SilentZoom = oldZoom; state.SilentRotation = oldRotation; obj.OnRotationChanged(state); obj.OnZoomChanged(state); } _2d.EndImmediate(); } } var b = bounds ?? new Rectangle(); b.Inflate(1, 1); //bounds = new Rectangle(0, 0, 1024, 1024); b.X = Math.Max(0, Math.Min(1023, b.X)); b.Y = Math.Max(0, Math.Min(1023, b.Y)); if (b.Width + b.X > 1024) { b.Width = 1024 - b.X; } if (b.Height + b.Y > 1024) { b.Height = 1024 - b.Y; } //return things to normal state.DrawOOB = false; state.SilentPreciseZoom = oldPreciseZoom; state.WorldSpace.Invalidate(); state.InvalidateCamera(); state.RenderingThumbnail = false; gd.DepthStencilState = oldDS; var tex = bufferTexture.Get(); return(TextureUtils.Clip(gd, tex, b)); }