private void lockBoxes(ViewportBoundingBoxes boxes)
 {
     boxes.PreLockBoundingBoxes = new AGSBoundingBoxes
     {
         WorldBox           = boxes.BoundingBoxes.WorldBox,
         PreCropViewportBox = boxes.BoundingBoxes.PreCropViewportBox,
         ViewportBox        = boxes.BoundingBoxes.ViewportBox,
         TextureBox         = boxes.BoundingBoxes.TextureBox
     };
 }
        public AGSBoundingBoxComponent(IRuntimeSettings settings,
                                       IBoundingBoxBuilder boundingBoxBuilder, IGameState state, IGameEvents events,
                                       IBlockingEvent onBoundingBoxChanged)
        {
            _createNewViewportBoundingBoxes = viewport => new ViewportBoundingBoxes(viewport);
            _boundingBoxes             = new ConcurrentDictionary <IViewport, ViewportBoundingBoxes>(new IdentityEqualityComparer <IViewport>());
            _mainViewportBoundingBoxes = new ViewportBoundingBoxes(state.Viewport);
            _settings = settings;
            _events   = events;
            _state    = state;
            OnBoundingBoxesChanged = onBoundingBoxChanged;
            _boundingBoxBuilder    = boundingBoxBuilder;

            _onHitTextBoxShouldChangeCallback = onHitTextBoxShouldChange;
            _onCropShouldChangeCallback       = onCropShouldChange;
            _onImageChangedCallback           = onImageChanged;
            _onDrawableChangedCallback        = onDrawableChanged;
            _onTextureOffsetChangedCallback   = onTextureOffsetChanged;

            boundingBoxBuilder.OnNewBoxBuildRequired.Subscribe(_onHitTextBoxShouldChangeCallback);
            events.OnRoomChanging.Subscribe(_onHitTextBoxShouldChangeCallback);
            onHitTextBoxShouldChange();
        }
        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);
        }
Ejemplo n.º 4
0
        private AGSBoundingBoxes recalculate(IViewport viewport, ViewportBoundingBoxes viewportBoxes)
        {
            var  boundingBoxes     = viewportBoxes.BoundingBoxes;
            var  animation         = _animation;
            var  drawable          = _drawable;
            var  matrix            = _matrix;
            bool isHitTestBoxDirty = _isHitTestBoxDirty;

            if (animation?.Animation?.Sprite?.Image == null || drawable == null || matrix == null)
            {
                return(boundingBoxes);
            }

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

            _isCropDirty          = false;
            _areViewportsDirty    = false;
            viewportBoxes.IsDirty = false;

            var    layerViewport = _layerViewports.GetViewport(drawable.RenderLayer.Z);
            Size   resolution;
            PointF resolutionFactor;
            bool   resolutionMatches = AGSModelMatrixComponent.GetVirtualResolution(false, _settings.VirtualResolution,
                                                                                    drawable, null, out resolutionFactor, out resolution);

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

            hitTestBox = _hitTestBox;

            var   sprite     = animation.Animation.Sprite;
            float width      = sprite.BaseSize.Width;
            float height     = sprite.BaseSize.Height;

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

            PointF renderCropScale;
            var    renderBox = _boundingBoxBuilder.BuildRenderBox(ref intermediateBox, ref viewportMatrix, out 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.PreCropRenderBox = renderBox;
            renderBox = cropInfo.BoundingBox;
            boundingBoxes.RenderBox = renderBox;
            if (cropInfo.TextureBox != null)
            {
                boundingBoxes.TextureBox = cropInfo.TextureBox;
            }
            else
            {
                var textureOffset = _textureOffset;
                if (width != sprite.Image.Width || height != sprite.Image.Height ||
                    (!textureOffset?.TextureOffset.Equals(Vector2.Zero) ?? false))
                {
                    var offset = textureOffset?.TextureOffset ?? PointF.Empty;
                    setProportionalTextureSize(boundingBoxes, sprite, width, height, offset);
                }
                else
                {
                    boundingBoxes.TextureBox = null;
                }
            }

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

            return(boundingBoxes);
        }