Exemplo n.º 1
0
        public static void TrySplit(D2dDestructible destructible, int feather)
        {
            if (destructible != null)
            {
                Search(destructible);

                if (islands.Count > 1)
                {
                    var baseRect = new D2dRect(0, alphaWidth, 0, alphaHeight);

                    if (feather > 0)
                    {
                        baseField.Transform(baseRect, alphaWidth, alphaHeight, alphaData);

                        destructible.SplitBegin();

                        for (var i = islands.Count - 1; i >= 0; i--)
                        {
                            var island = islands[i];
                            var sprite = destructible.SplitNext(i == 0);
                            var rect   = new D2dRect(island.MinX, island.MaxX, island.MinY, island.MaxY); rect.Expand(feather); rect.ClampTo(baseRect);

                            D2dHelper.ReserveTempAlphaDataClear(rect.SizeX, rect.SizeY);

                            island.Fill(baseField, baseRect, rect);

                            sprite.SubsetAlphaWith(D2dHelper.tempAlphaData, rect, island.Count);
                        }
                    }
                    else
                    {
                        destructible.SplitBegin();

                        for (var i = islands.Count - 1; i >= 0; i--)
                        {
                            var island = islands[i];
                            var chunk  = destructible.SplitNext(i == 0);
                            var rect   = new D2dRect(island.MinX, island.MaxX, island.MinY, island.MaxY); rect.ClampTo(baseRect);

                            D2dHelper.ReserveTempAlphaDataClear(rect.SizeX, rect.SizeY);

                            island.Fill(rect);

                            chunk.SubsetAlphaWith(D2dHelper.tempAlphaData, rect);
                        }
                    }

                    destructible.SplitEnd();
                }
            }
        }
Exemplo n.º 2
0
        public static void TrySplit(D2dDestructible destructible, int feather, int healThreshold)
        {
            if (destructible != null)
            {
                Search(destructible);

                if (islands.Count > 1)
                {
                    var baseRect = new D2dRect(0, alphaWidth, 0, alphaHeight);

                    if (feather > 0)
                    {
                        baseField.Transform(baseRect, alphaWidth, alphaHeight, alphaData);

                        destructible.SplitBegin();

                        for (var i = islands.Count - 1; i >= 0; i--)
                        {
                            var island = islands[i];
                            var piece  = destructible.SplitNext(i == 0);
                            var rect   = default(D2dRect);

                            if (healThreshold >= 0 && island.Count >= healThreshold)
                            {
                                rect = baseRect;
                            }
                            else
                            {
                                rect.MinX = island.MinX;
                                rect.MaxX = island.MaxX;
                                rect.MinY = island.MinY;
                                rect.MaxY = island.MaxY;

                                rect.Expand(feather);

                                rect.ClampTo(baseRect);

                                piece.HealSnapshot = null;
                            }

                            D2dHelper.ReserveTempAlphaDataClear(rect.SizeX, rect.SizeY);

                            island.Fill(baseField, baseRect, rect);

                            piece.SubsetAlphaWith(D2dHelper.tempAlphaData, rect, island.Count);
                        }
                    }
                    else
                    {
                        destructible.SplitBegin();

                        for (var i = islands.Count - 1; i >= 0; i--)
                        {
                            var island = islands[i];
                            var chunk  = destructible.SplitNext(i == 0);
                            var rect   = new D2dRect(island.MinX, island.MaxX, island.MinY, island.MaxY); rect.ClampTo(baseRect);

                            D2dHelper.ReserveTempAlphaDataClear(rect.SizeX, rect.SizeY);

                            island.Fill(rect);

                            chunk.SubsetAlphaWith(D2dHelper.tempAlphaData, rect);
                        }
                    }

                    destructible.SplitEnd(D2dDestructible.SplitMode.Split);
                }
            }
        }
Exemplo n.º 3
0
        /// <summary>This method allows you to manually try and fracture the specified D2dDestructible.</summary>
        public static bool TryFracture(D2dDestructible destructible, int pointCount, bool splitAfterFracture, int splitFeather, int splitHealThreshold)
        {
            if (pointCount > 1 && destructible != null && destructible.Ready == true)
            {
                if (pointCount > 20)
                {
                    pointCount = 20;
                }

                var w = destructible.AlphaWidth;
                var h = destructible.AlphaHeight;
                var t = w * h;

                GenerateVoronoiPoints(pointCount, w, h);
                GenerateVoronoiData(pointCount, w, h, t);

                if (voronoiCount > 1)
                {
                    var alphaData = destructible.AlphaData;
                    var alphaRect = new D2dRect(0, w, 0, h);

                    destructible.SplitBegin();

                    chunks.Clear();

                    for (var i = pointCount - 1; i >= 0; i--)
                    {
                        var rect = voronoiRects[i];

                        if (rect.IsSet == true)
                        {
                            voronoiCount -= 1;

                            var chunk = destructible.SplitNext(voronoiCount == 0);

                            chunks.Add(chunk);

                            rect.Expand(1);
                            rect.ClampTo(alphaRect);

                            D2dHelper.ReserveTempAlphaData(rect.SizeX, rect.SizeY);

                            if (tempAlphaData == null || tempAlphaData.Length < rect.SizeX * rect.SizeY)
                            {
                                tempAlphaData = new Color32[rect.SizeX * rect.SizeY];
                            }

                            // Write black and white mask
                            for (var y = rect.MinY; y < rect.MaxY; y++)
                            {
                                var o = y * w;
                                var z = (y - rect.MinY) * rect.SizeX - rect.MinX;

                                for (var x = rect.MinX; x < rect.MaxX; x++)
                                {
                                    var alpha = voronoi[o + x] == i ? 255 : 0;

                                    D2dHelper.tempAlphaData[z + x] = new Color32(255, 255, 255, (byte)alpha);
                                }
                            }

                            // Blur
                            D2dBlur.BlurHorizontally(D2dHelper.tempAlphaData, tempAlphaData, rect.SizeX, rect.SizeY);
                            D2dBlur.BlurVertically(tempAlphaData, D2dHelper.tempAlphaData, rect.SizeX, rect.SizeY);

                            // Combine alpha
                            for (var y = rect.MinY; y < rect.MaxY; y++)
                            {
                                var o = y * w;
                                var z = (y - rect.MinY) * rect.SizeX - rect.MinX;

                                for (var x = rect.MinX; x < rect.MaxX; x++)
                                {
                                    var index      = z + x;
                                    var maskPixel  = D2dHelper.tempAlphaData[index];
                                    var alphaPixel = alphaData[o + x];

                                    alphaPixel.a = (byte)(alphaPixel.a * (maskPixel.a * recip255));

                                    D2dHelper.tempAlphaData[index] = alphaPixel;
                                }
                            }

                            chunk.SubsetAlphaWith(D2dHelper.tempAlphaData, rect);
                        }
                    }

                    destructible.SplitEnd(D2dDestructible.SplitMode.Fracture);

                    if (splitAfterFracture == true)
                    {
                        for (var i = chunks.Count - 1; i >= 0; i--)
                        {
                            var chunk = chunks[i];

                            if (chunk != null)
                            {
                                D2dSplitter.TrySplit(chunk, splitFeather, splitHealThreshold);
                            }
                        }
                    }

                    return(true);
                }
            }

            return(false);
        }