Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        /// <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));
        }
Ejemplo n.º 3
0
        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));
        }