コード例 #1
0
        public bool CollidesWith(float x, float y, IViewport viewport)
        {
            var boundingBoxesComponent = _boundingBox;

            if (boundingBoxesComponent == null)
            {
                return(false);
            }
            if (_crop?.IsGuaranteedToFullyCrop() ?? false)
            {
                //This should not be needed as the bounding box should be cropped anyway.
                //However, for a performance optimization if an entity is guaranteed to be fully cropped (like items in the bottom of a long listbox) the bounding box is not calculated, so we need to take it into account here.
                return(false);
            }
            AGSBoundingBox boundingBox           = boundingBoxesComponent.WorldBoundingBox;
            var            pixelPerfectComponent = _pixelPerfect;
            IArea          pixelPerfect          = pixelPerfectComponent == null || !pixelPerfectComponent.IsPixelPerfect ? null : pixelPerfectComponent.PixelPerfectHitTestArea;

            var drawable = _drawableInfo;

            if (drawable != null && !drawable.IgnoreViewport)
            {
                var matrix = viewport.GetMatrix(drawable.RenderLayer);
                matrix.Invert();
                Vector3 xyz = new Vector3(x, y, 0f);
                Vector3.Transform(ref xyz, ref matrix, out xyz);
                //todo: (support ignore scaling areas = false?)
                x = xyz.X;
                y = xyz.Y;
            }

            if (pixelPerfect == null || !pixelPerfect.Enabled)
            {
                if (!boundingBox.IsValid)
                {
                    return(false);
                }
                if (boundingBox.Contains(new Vector2(x, y)))
                {
                    return(true);
                }
            }
            else
            {
                var   obj       = _obj;
                float objScaleX = obj == null ? 1f : obj.CurrentSprite.ScaleX;
                float objScaleY = obj == null ? 1f : obj.CurrentSprite.ScaleY;
                var   scale     = _scale;
                float scaleX    = scale == null ? 1f : scale.ScaleX;
                float scaleY    = scale == null ? 1f : scale.ScaleY;
                if (pixelPerfect.IsInArea(new PointF(x, y), boundingBox, scaleX * objScaleX, scaleY * objScaleY))
                {
                    return(true);
                }
            }
            return(false);
        }
コード例 #2
0
ファイル: AGSCollider.cs プロジェクト: jeancallisti/MonoAGS
        public bool CollidesWith(float x, float y, IViewport viewport)
        {
            var boundingBoxesComponent = _boundingBox;

            if (boundingBoxesComponent == null)
            {
                return(false);
            }
            AGSBoundingBox boundingBox           = boundingBoxesComponent.WorldBoundingBox;
            var            pixelPerfectComponent = _pixelPerfect;
            IArea          pixelPerfect          = pixelPerfectComponent == null || !pixelPerfectComponent.IsPixelPerfect ? null : pixelPerfectComponent.PixelPerfectHitTestArea;

            if (!(_drawableInfo?.IgnoreViewport ?? false))
            {
                var matrix = viewport.GetMatrix(_drawableInfo.RenderLayer);
                matrix.Invert();
                Vector3 xyz = new Vector3(x, y, 0f);
                Vector3.Transform(ref xyz, ref matrix, out xyz);
                //todo: (support ignore scaling areas = false?)
                x = xyz.X;
                y = xyz.Y;
            }

            if (pixelPerfect == null || !pixelPerfect.Enabled)
            {
                if (!boundingBox.IsValid)
                {
                    return(false);
                }
                if (boundingBox.Contains(new Vector2(x, y)))
                {
                    return(true);
                }
            }
            else
            {
                var   obj       = _obj;
                float objScaleX = obj == null ? 1f : obj.CurrentSprite.ScaleX;
                float objScaleY = obj == null ? 1f : obj.CurrentSprite.ScaleY;
                var   scale     = _scale;
                float scaleX    = scale == null ? 1f : scale.ScaleX;
                float scaleY    = scale == null ? 1f : scale.ScaleY;
                if (pixelPerfect.IsInArea(new PointF(x, y), boundingBox, scaleX * objScaleX, scaleY * objScaleY))
                {
                    return(true);
                }
            }
            return(false);
        }
コード例 #3
0
ファイル: MousePosition.cs プロジェクト: jeancallisti/MonoAGS
        /// <summary>
        /// Get the mouse position in a specific viewport coordinates, projected onto
        /// a specific object's world.
        /// </summary>
        /// <returns>The projected point.</returns>
        /// <param name="viewport">Viewport.</param>
        /// <param name="projectedInto">Projected into.</param>
        public Vector2 GetProjectedPoint(IViewport viewport, IObject projectedInto)
        {
            float windowWidth         = GetWindowWidth();
            float windowHeight        = GetWindowHeight();
            var   projectBottom       = windowHeight - viewport.ProjectionBox.Y * windowHeight;
            var   projectTop          = projectBottom - viewport.ProjectionBox.Height * windowHeight;
            var   projectLeft         = viewport.ProjectionBox.X * windowWidth;
            var   projectRight        = projectLeft + viewport.ProjectionBox.Width * windowWidth;
            var   parentBoundingBoxes = viewport.Parent?.GetBoundingBoxes(_mainViewport);

            if (parentBoundingBoxes != null)
            {
                projectLeft   += parentBoundingBoxes.ViewportBox.MinX;
                projectRight  += parentBoundingBoxes.ViewportBox.MinX;
                projectBottom -= parentBoundingBoxes.ViewportBox.MinY;
                projectTop    -= parentBoundingBoxes.ViewportBox.MinY;
            }
            float y = MathUtils.Lerp(projectTop, VirtualResolution.Height, projectBottom, 0f, YWindow);
            float x = MathUtils.Lerp(projectLeft, 0f, projectRight, VirtualResolution.Width, XWindow);

            var matrix = viewport.GetMatrix(projectedInto.RenderLayer);

            matrix.Invert();
            Vector3 xyz = new Vector3(x, y, 0f);

            Vector3.Transform(ref xyz, ref matrix, out xyz);
            x = xyz.X;
            y = xyz.Y;

            var hitTestBox = projectedInto.TreeNode.Parent?.WorldBoundingBox;

            if (hitTestBox?.IsValid ?? false)
            {
                x -= hitTestBox.Value.MinX;
                y -= hitTestBox.Value.MinY;
            }
            var renderLayer = projectedInto.RenderLayer;

            if (renderLayer?.IndependentResolution != null)
            {
                float maxX = renderLayer.IndependentResolution.Value.Width;
                float maxY = renderLayer.IndependentResolution.Value.Height;
                x = MathUtils.Lerp(0f, 0f, VirtualResolution.Width, maxX, x);
                y = MathUtils.Lerp(0f, 0f, VirtualResolution.Height, maxY, y);
            }
            return(new Vector2(x, y));
        }
コード例 #4
0
        public PointF WindowToObject(IViewport viewport, IObject obj, PointF position)
        {
            var projectBottom       = Window.AppWindowHeight - viewport.ScreenArea.Y - viewport.ProjectionBox.Y * viewport.ScreenArea.Height;
            var projectTop          = projectBottom - viewport.ProjectionBox.Height * viewport.ScreenArea.Height;
            var parentBoundingBoxes = viewport.Parent?.GetBoundingBoxes(_mainViewport);

            if (parentBoundingBoxes != null)
            {
                projectBottom -= parentBoundingBoxes.ViewportBox.MinY;
                projectTop    -= parentBoundingBoxes.ViewportBox.MinY;
            }

            var   projectLeft  = viewport.ScreenArea.X;
            var   projectRight = projectLeft + viewport.ScreenArea.Width;
            float y            = MathUtils.Lerp(projectTop, _virtualResolution.Height, projectBottom, 0f, position.Y);
            float x            = MathUtils.Lerp(projectLeft, 0f, projectRight, _virtualResolution.Width, position.X);

            var matrix = viewport.GetMatrix(obj.RenderLayer);

            matrix.Invert();
            Vector3 xyz = new Vector3(x, y, 0f);

            Vector3.Transform(ref xyz, ref matrix, out xyz);
            x = xyz.X;
            y = xyz.Y;

            var hitTestBox = obj.TreeNode.Parent?.WorldBoundingBox;

            if (hitTestBox?.IsValid ?? false)
            {
                x -= hitTestBox.Value.MinX;
                y -= hitTestBox.Value.MinY;
            }
            var renderLayer = obj.RenderLayer;

            if (renderLayer?.IndependentResolution != null)
            {
                float maxX = renderLayer.IndependentResolution.Value.Width;
                float maxY = renderLayer.IndependentResolution.Value.Height;
                x = MathUtils.Lerp(0f, 0f, _virtualResolution.Width, maxX, x);
                y = MathUtils.Lerp(0f, 0f, _virtualResolution.Height, maxY, y);
            }
            return(new PointF(x, y));
        }
コード例 #5
0
        private AGSBoundingBoxes recalculate(IViewport viewport, ViewportBoundingBoxes viewportBoxes)
        {
            var  boundingBoxes     = viewportBoxes.BoundingBoxes;
            var  drawable          = _drawable;
            var  matrix            = _matrix;
            var  scale             = _scale;
            var  sprite            = _image?.CurrentSprite;
            bool isHitTestBoxDirty = _isHitTestBoxDirty;

            if (scale == null || drawable == null || matrix == null)
            {
                return(boundingBoxes);
            }

            var baseSize = sprite?.BaseSize ?? scale.BaseSize;

            if (isHitTestBoxDirty)
            {
                _isCropDirty       = true;
                _isHitTestBoxDirty = false;
                updateHitTestBox(baseSize, drawable, matrix);
            }
            var crop = _crop;

            _areViewportsDirty    = false;
            viewportBoxes.IsDirty = false;

            bool resolutionMatches = AGSModelMatrixComponent.GetVirtualResolution(false, _settings.VirtualResolution,
                                                                                  drawable, null, out PointF _, out Size _);

            var            viewportMatrix = drawable.IgnoreViewport ? Matrix4.Identity : viewport.GetMatrix(drawable.RenderLayer);
            AGSBoundingBox intermediateBox, hitTestBox;

            hitTestBox = _hitTestBox;

            float width   = baseSize.Width;
            float height  = baseSize.Height;

            if (resolutionMatches)
            {
                intermediateBox = _intermediateBox;
            }
            else
            {
                var modelMatrices = matrix.GetModelMatrices();
                var modelMatrix   = modelMatrices.InObjResolutionMatrix;
                intermediateBox = _boundingBoxBuilder.BuildIntermediateBox(width, height, ref modelMatrix);
            }

            var renderBox = _boundingBoxBuilder.BuildRenderBox(ref intermediateBox, ref viewportMatrix, out PointF renderCropScale);

            PointF hitTestCropScale = renderCropScale;

            if (MathUtils.FloatEquals(hitTestCropScale.X, 1f) && MathUtils.FloatEquals(hitTestCropScale.Y, 1f))
            {
                hitTestCropScale = new PointF(_hitTestBox.Width / renderBox.Width, _hitTestBox.Height / renderBox.Height);
            }

            var cropInfo = renderBox.Crop(BoundingBoxType.Render, crop, renderCropScale);

            boundingBoxes.PreCropViewportBox = renderBox;
            renderBox = cropInfo.BoundingBox;
            boundingBoxes.ViewportBox = renderBox;
            if (cropInfo.TextureBox != null)
            {
                boundingBoxes.TextureBox = cropInfo.TextureBox;
            }
            else
            {
                var textureOffset = _textureOffset;
                var image         = sprite?.Image;
                // ReSharper disable CompareOfFloatsByEqualityOperator
                if (image != null && (width != image.Width || height != image.Height ||
                                      // ReSharper restore CompareOfFloatsByEqualityOperator
                                      (!textureOffset?.TextureOffset.Equals(PointF.Empty) ?? false)))
                {
                    var offset = textureOffset?.TextureOffset ?? PointF.Empty;
                    setProportionalTextureSize(boundingBoxes, image, width, height, offset);
                }
                else
                {
                    boundingBoxes.TextureBox = null;
                }
            }

            if (cropInfo.Equals(_defaultCropInfo))
            {
                boundingBoxes.WorldBox = default;
            }
            else
            {
                hitTestBox             = hitTestBox.Crop(BoundingBoxType.HitTest, crop, hitTestCropScale).BoundingBox;
                boundingBoxes.WorldBox = hitTestBox;
            }
            _isCropDirty = false;

            return(boundingBoxes);
        }