public void RegisterComponentInCurrentWorld(IPerPixelCollisionComponent perPixelCollidableComponent)
 {
     if (_shadowWorld != null)
     {
         _shadowWorld.RegisterComponentInCurrentWorld(perPixelCollidableComponent);
     }
 }
        private Rectangle CalculateBoundingBox(IHasTransform parent, IPerPixelCollisionComponent collisionComponent)
        {
            var transform =
                Matrix.CreateTranslation(-new Vector3(collisionComponent.RotationAnchor ?? Vector2.Zero, 0)) *
                Matrix.CreateFromQuaternion(parent.FinalTransform.AbsoluteRotation) *
                //Matrix.CreateTranslation(new Vector3(collisionComponent.RotationAnchor ?? Vector2.Zero, 0)) *
                Matrix.CreateTranslation(parent.FinalTransform.AbsolutePosition);

            var width  = collisionComponent.GetPixelWidth();
            var height = collisionComponent.GetPixelHeight();

            var tl = Vector2.Transform(Vector2.Zero, transform);
            var tr = Vector2.Transform(new Vector2(width, 0), transform);
            var bl = Vector2.Transform(new Vector2(0, height), transform);
            var br = Vector2.Transform(new Vector2(width, height), transform);

            var minX = Math.Min(Math.Min(tl.X, tr.X), Math.Min(bl.X, br.X));
            var minY = Math.Min(Math.Min(tl.Y, tr.Y), Math.Min(bl.Y, br.Y));
            var maxX = Math.Max(Math.Max(tl.X, tr.X), Math.Max(bl.X, br.X));
            var maxY = Math.Max(Math.Max(tl.Y, tr.Y), Math.Max(bl.Y, br.Y));

            return(new Rectangle(
                       (int)Math.Floor(minX),
                       (int)Math.Floor(minY),
                       (int)Math.Ceiling(maxX) - (int)Math.Floor(minX),
                       (int)Math.Ceiling(maxY) - (int)Math.Floor(minY)));
        }
        public void UnregisterComponentInCurrentWorld(IPerPixelCollisionComponent collisionComponent)
        {
            if (_waitForChanges)
            {
                _pendingChanges.Add(() =>
                {
                    var toRemove = new List <WeakReference <IPerPixelCollisionComponent> >();

                    foreach (var wr in _components)
                    {
                        IPerPixelCollisionComponent ppc;
                        if (wr.TryGetTarget(out ppc))
                        {
                            if (ReferenceEquals(ppc, collisionComponent))
                            {
                                toRemove.Add(wr);
                            }
                        }
                        else
                        {
                            toRemove.Add(wr);
                        }
                    }

                    foreach (var tr in toRemove)
                    {
                        _components.Remove(tr);
                    }
                });
            }
            else
            {
                var toRemove = new List <WeakReference <IPerPixelCollisionComponent> >();

                foreach (var wr in _components)
                {
                    IPerPixelCollisionComponent ppc;
                    if (wr.TryGetTarget(out ppc))
                    {
                        if (ReferenceEquals(ppc, collisionComponent))
                        {
                            toRemove.Add(wr);
                        }
                    }
                    else
                    {
                        toRemove.Add(wr);
                    }
                }

                foreach (var tr in toRemove)
                {
                    _components.Remove(tr);
                }
            }
        }
 public void RegisterComponentInCurrentWorld(IPerPixelCollisionComponent collisionComponent)
 {
     if (_waitForChanges)
     {
         _pendingChanges.Add(() =>
         {
             _components.Add(new WeakReference <IPerPixelCollisionComponent>(collisionComponent));
         });
     }
     else
     {
         _components.Add(new WeakReference <IPerPixelCollisionComponent>(collisionComponent));
     }
 }
        private bool IntersectPixels(
            IHasTransform aParent,
            IPerPixelCollisionComponent a,
            IHasTransform bParent,
            IPerPixelCollisionComponent b)
        {
            var transformA =
                Matrix.CreateTranslation(-new Vector3(a.RotationAnchor ?? Vector2.Zero, 0)) *
                Matrix.CreateFromQuaternion(aParent.FinalTransform.AbsoluteRotation) *
                //Matrix.CreateTranslation(new Vector3(a.RotationAnchor ?? Vector2.Zero, 0)) *
                Matrix.CreateTranslation(aParent.FinalTransform.AbsolutePosition);
            var transformB =
                Matrix.CreateTranslation(-new Vector3(b.RotationAnchor ?? Vector2.Zero, 0)) *
                Matrix.CreateFromQuaternion(bParent.FinalTransform.AbsoluteRotation) *
                //Matrix.CreateTranslation(new Vector3(b.RotationAnchor ?? Vector2.Zero, 0)) *
                Matrix.CreateTranslation(bParent.FinalTransform.AbsolutePosition);

            var widthA  = a.GetPixelWidth();
            var heightA = a.GetPixelHeight();
            var widthB  = b.GetPixelWidth();
            var heightB = b.GetPixelHeight();

            var dataA = a.GetPixelData();
            var dataB = b.GetPixelData();

            var transformAToB = transformA * Matrix.Invert(transformB);

            var stepX = Vector2.TransformNormal(Vector2.UnitX, transformAToB);
            var stepY = Vector2.TransformNormal(Vector2.UnitY, transformAToB);

            var yPosInB = Vector2.Transform(Vector2.Zero, transformAToB);

            for (var yA = 0; yA < heightA; yA++)
            {
                var posInB = yPosInB;

                for (var xA = 0; xA < widthA; xA++)
                {
                    var xB = (int)Math.Round(posInB.X);
                    var yB = (int)Math.Round(posInB.Y);

                    if (0 <= xB && xB < widthB &&
                        0 <= yB && yB < heightB)
                    {
                        var colorA = dataA[xA + yA * widthA];
                        var colorB = dataB[xB + yB * widthB];

                        if (colorA.A != 0 && colorB.A != 0)
                        {
                            return(true);
                        }
                    }

                    posInB += stepX;
                }

                yPosInB += stepY;
            }

            return(false);
        }