Пример #1
0
    protected virtual void Update()
    {
        if (destructible == null) destructible = GetComponent<D2D_Destructible>();
        if (splittable   == null) splittable   = GetComponent<D2D_Splittable>();
        if (fracturer    == null) fracturer    = GetComponent<D2D_Fracturer>();

        var splitDepth = destructible.SplitDepth;
        var pixelCount = destructible.SolidPixelCount;

        if (pixelCount < MinPixelsForDestructible || splitDepth > MaxDepthForDestructible)
        {
            destructible.Indestructible = true;
        }

        if (splittable != null)
        {
            if (pixelCount < MinPixelsForSplitting || splitDepth > MaxDepthForSplitting)
            {
                D2D_Helper.Destroy(splittable);
            }
        }

        if (fracturer != null)
        {
            if (pixelCount < MinPixelsForFracturing || splitDepth > MaxDepthForFracturing)
            {
                D2D_Helper.Destroy(fracturer);
            }
        }
    }
Пример #2
0
    public void UpdateSplit()
    {
        if (destructible == null)
        {
            destructible = GetComponent <D2D_Destructible>();
        }

        BeginSplitting();
        {
            // Find which pixels are solid
            for (var y = 0; y < height; y++)
            {
                for (var x = 0; x < width; x++)
                {
                    cells.Add(alphaTex.GetPixel(x, y).a >= Threshold);
                }
            }

            // Go through all pixels
            for (var i = 0; i < total; i++)
            {
                // First pixel of unclaimed island?
                if (cells[i] == true)
                {
                    splitGroup = D2D_SplitBuilder.CreateGroup();

                    BeginFloodFill(i, i % width, i / width);
                }
            }
        }
        EndSplitting();
    }
Пример #3
0
    private static void Split(D2D_Destructible destructible, D2D_SplitGroup group, bool isClone)
    {
        var subX      = group.XMin;
        var subY      = group.YMin;
        var subWidth  = group.XMax - group.XMin + 1;
        var subHeight = group.YMax - group.YMin + 1;
        var subTotal  = subWidth * subHeight;
        var subAlpha  = new byte[subTotal];

        for (var i = group.Count - 1; i >= 0; i--)
        {
            var j = group.Indices[i];
            var a = group.Alphas[i];
            var x = (j % AlphaTexWidth) - subX;
            var y = (j / AlphaTexWidth) - subY;
            var s = x + y * subWidth;

            subAlpha[s] = a;
        }

        destructible.SubsetAlphaWith(subAlpha, subWidth, subHeight, subX, subY);

        // Split notification
        D2D_Helper.BroadcastMessage(destructible.transform, "OnDestructibleSplit", splitData, SendMessageOptions.DontRequireReceiver);
    }
Пример #4
0
    protected virtual void Update()
    {
        if (dirty == true)
        {
            dirty        = false;
            destructible = D2D_Helper.GetComponentUpwards <D2D_Destructible>(transform);

            if (destructible != null)
            {
                var alpha = destructible.GetAlpha(transform.TransformPoint(Offset));

                // Break fixture?
                if (alpha < Threshold)
                {
                    DestroyFixture();
                }
                // Break others?
                else if (fixtureID > 0)
                {
                    for (var i = AllFixtures.Count - 1; i >= 0; i--)
                    {
                        var fixture = AllFixtures[i];

                        if (fixture != null && fixture != this && fixture.fixtureID == fixtureID)
                        {
                            fixture.DestroyFixture();
                        }
                    }
                }
            }
        }
    }
Пример #5
0
    public void UpdateSplit()
    {
        if (destructible == null) destructible = GetComponent<D2D_Destructible>();

        BeginSplitting();
        {
            // Find which pixels are solid
            for (var y = 0; y < height; y++)
            {
                for (var x = 0; x < width; x++)
                {
                    cells.Add(alphaTex.GetPixel(x, y).a >= Threshold);
                }
            }

            // Go through all pixels
            for (var i = 0; i < total; i++)
            {
                // First pixel of unclaimed island?
                if (cells[i] == true)
                {
                    splitGroup = D2D_SplitBuilder.CreateGroup();

                    BeginFloodFill(i, i % width, i / width);
                }
            }
        }
        EndSplitting();
    }
Пример #6
0
	protected virtual void Update()
	{
		if (dirty == true)
		{
			dirty        = false;
			destructible = D2D_Helper.GetComponentUpwards<D2D_Destructible>(transform);
			
			if (destructible != null)
			{
				var alpha = destructible.GetAlpha(transform.position);
				
				// Break fixture?
				if (alpha < Threshold)
				{
					DestroyFixture();
				}
				// Break others?
				else if (fixtureID > 0)
				{
					for (var i = Fixtures.Count - 1; i >= 0; i--)
					{
						var fixture = Fixtures[i];
						
						if (fixture != null && fixture != this && fixture.fixtureID == fixtureID)
						{
							fixture.DestroyFixture();
						}
					}
				}
			}
		}
	}
Пример #7
0
    protected virtual void Update()
    {
        if (Input.GetMouseButtonDown(0) == true && Camera.main != null)
        {
            var ray      = Camera.main.ScreenPointToRay(Input.mousePosition);
            var distance = D2D_Helper.Divide(ray.origin.z, ray.direction.z);
            var point    = ray.origin - ray.direction * distance;

            D2D_Destructible.StampAll(point, Size, Angle, StampTex, Hardness, Layers);
        }
    }
Пример #8
0
    private static void GetPixels(D2D_Destructible destructible, int l, int b, int r, int t)
    {
        l = Mathf.Max(l, 0);
        b = Mathf.Max(b, 0);
        r = Mathf.Min(r, destructible.AlphaWidth);
        t = Mathf.Min(t, destructible.AlphaHeight);

        pixelsL = l;
        pixelsR = r;
        pixelsB = b;
        pixelsT = t;
        pixelsW = destructible.AlphaWidth;
        pixels  = destructible.AlphaData;
    }
Пример #9
0
    public static void BeginSplitting(D2D_Destructible newDestructible)
    {
        if (newDestructible != null)
        {
            D2D_ClassPool <D2D_SplitGroup> .Add(Groups, g => g.AddToPool());           // EndSplitting may not get called, so call here in case

            destructible = newDestructible;

            AlphaTex = newDestructible.AlphaTex;

            AlphaTexWidth  = AlphaTex.width;
            AlphaTexHeight = AlphaTex.height;
        }
    }
Пример #10
0
    public void Fracture()
    {
        if (destructible == null)
        {
            destructible = GetComponent <D2D_Destructible>();
        }

        alphaTex = destructible.AlphaTex;
        width    = alphaTex.width;
        height   = alphaTex.height;
        total    = width * height;

        D2D_SplitBuilder.BeginSplitting(destructible);
        {
            DoFracture();
        }
        D2D_SplitBuilder.EndSplitting(D2D_SplitOrder.Default, Blur);
    }
Пример #11
0
    protected virtual void Update()
    {
        if (Input.GetKey(Requires) == true && down == false)
        {
            down = true;
            startMousePosition = Input.mousePosition;
        }

        if (Input.GetKey(Requires) == false && down == true)
        {
            down = false;

            if (Camera.main != null)
            {
                var endMousePosition = Input.mousePosition;
                var startPos         = Camera.main.ScreenToWorldPoint(startMousePosition);
                var endPos           = Camera.main.ScreenToWorldPoint(endMousePosition);

                D2D_Destructible.SliceAll(startPos, endPos, Thickness, StampTex, Hardness);
            }
        }

        if (Indicator != null)
        {
            Indicator.enabled = down;

            if (Camera.main != null && down == true)
            {
                var currentMousePosition = Input.mousePosition;
                var startPos             = Camera.main.ScreenToWorldPoint(startMousePosition);
                var currentPos           = Camera.main.ScreenToWorldPoint(currentMousePosition);
                var scale       = Vector3.Distance(currentPos, startPos);
                var angle       = D2D_Helper.Atan2(currentPos - startPos) * Mathf.Rad2Deg;
                var newPosition = Camera.main.ScreenToWorldPoint(startMousePosition);

                newPosition.z = Indicator.transform.position.z;

                Indicator.transform.position      = newPosition;
                Indicator.transform.localRotation = Quaternion.Euler(0.0f, 0.0f, -angle);
                Indicator.transform.localScale    = new Vector3(Thickness, scale, scale);
            }
        }
    }
Пример #12
0
    private static void Split(D2D_Destructible destructible, Fill fill, bool isClone)
    {
        var clear = new Color32(0, 0, 0, 0);

        for (var i = 0; i < total; i++)
        {
            pixels[i] = clear;
        }

        for (var i = 0; i < fill.Count; i++)
        {
            pixels[fill.Indices[i]] = fill.Colours[i];
        }

        destructible.ReplaceAlphaWith(width, height, pixels);

        // Split notification
        destructible.BroadcastMessage("OnSpriteSplit", isClone, SendMessageOptions.DontRequireReceiver);
    }
Пример #13
0
    protected virtual void Update()
    {
        if (destructible == null)
        {
            destructible = GetComponent <D2D_Destructible>();
        }
        if (splittable == null)
        {
            splittable = GetComponent <D2D_Splittable>();
        }
        if (fracturer == null)
        {
            fracturer = GetComponent <D2D_Fracturer>();
        }

        var splitDepth = destructible.SplitDepth;
        var pixelCount = destructible.SolidPixelCount;

        if (pixelCount < MinPixelsForDestructible || splitDepth > MaxDepthForDestructible)
        {
            destructible.Indestructible = true;
        }

        if (splittable != null)
        {
            if (pixelCount < MinPixelsForSplitting || splitDepth > MaxDepthForSplitting)
            {
                D2D_Helper.Destroy(splittable);
            }
        }

        if (fracturer != null)
        {
            if (pixelCount < MinPixelsForFracturing || splitDepth > MaxDepthForFracturing)
            {
                D2D_Helper.Destroy(fracturer);
            }
        }
    }
Пример #14
0
    public static bool Generate(D2D_Destructible destructible, D2D_SpriteSplitOrder splitOrder)
    {
        cells.Clear();

        if (destructible != null && destructible.AlphaTex != null)
        {
            target = destructible;
            tex    = target.AlphaTex;
            width  = tex.width;
            height = tex.height;
            total  = width * height;
            pixels = tex.GetPixels32();

            if (cells.Capacity < total)
            {
                cells.Capacity = total;
            }

            var threshold = (byte)(target.SplitThreshold * 255.0f);

            for (var i = 0; i < total; i++)
            {
                cells.Add(pixels[i].a >= threshold);
            }

            fills.Clear();

            var validFillCount = 0;

            for (var i = 0; i < total; i++)
            {
                if (cells[i] == true)
                {
                    currentFill = new Fill(); fills.Add(currentFill);

                    currentFill.XMin = currentFill.XMax = i % width;
                    currentFill.YMin = currentFill.YMax = i / width;

                    BeginFloodFill(i, currentFill.XMin, currentFill.YMin);

                    // Skip the first floodfill
                    if (currentFill.Count >= target.SplitMinPixels)
                    {
                        currentFill.Valid = true; validFillCount += 1;
                    }
                }
            }

            // Can we split?
            if (validFillCount > 1)
            {
                var firstSet = false;

                switch (splitOrder)
                {
                case D2D_SpriteSplitOrder.KeepLargest:  fills.Sort((a, b) => b.Count.CompareTo(a.Count)); break;

                case D2D_SpriteSplitOrder.KeepSmallest: fills.Sort((a, b) => a.Count.CompareTo(b.Count)); break;
                }

                foreach (var fill in fills)
                {
                    if (fill.Valid == true)
                    {
                        if (firstSet == false)
                        {
                            firstSet = true;

                            Split(destructible, fill, false);
                        }
                        else
                        {
                            var clonedGameObject   = D2D_Helper.CloneGameObject(destructible.gameObject, destructible.transform.parent);
                            var clonedDestructible = clonedGameObject.GetComponent <D2D_Destructible>();

                            Split(clonedDestructible, fill, true);
                        }
                    }
                }

                return(true);
            }

            if (validFillCount == 0)
            {
                D2D_Helper.Destroy(destructible.gameObject);
            }
        }

        return(false);
    }
Пример #15
0
    protected override void Execute()
    {
//		var angle = transform.rotation.eulerAngles.z + AngleOffset + Random.Range(-0.5f, 0.5f) * AngleRandomness;

        D2D_Destructible.StampAll(transform.position, Size, 0f, StampTex, Hardness, Layers);
    }
Пример #16
0
    public static void EndSplitting(D2D_SplitOrder order, bool blur)
    {
        if (destructible != null)
        {
            if (Groups.Count > 0)
            {
                // Sort
                switch (order)
                {
                case D2D_SplitOrder.KeepLargest:  Groups.Sort((a, b) => b.Count.CompareTo(a.Count)); break;

                case D2D_SplitOrder.KeepSmallest: Groups.Sort((a, b) => a.Count.CompareTo(b.Count)); break;
                }

                // Store list of others
                splitData.SolidPixelCounts.Clear();

                for (var i = 0; i < Groups.Count; i++)
                {
                    splitData.SolidPixelCounts.Add(Groups[i].Count);
                }

                // Split
                for (var i = Groups.Count - 1; i >= 0; i--)
                {
                    var group = Groups[i];

                    splitData.Index   = i;
                    splitData.IsClone = i > 0;

                    // Split
                    if (i > 0)
                    {
                        var tempAlphaData = destructible.AlphaData;

                        destructible.AlphaData = null;

                        // Clone this destructible without alpha data, because we will manually set it after this
                        var clonedDestructible = D2D_Helper.CloneGameObject(destructible.gameObject, destructible.transform.parent).GetComponent <D2D_Destructible>();

                        destructible.AlphaData = tempAlphaData;

                        Split(clonedDestructible, group, true, blur);
                    }
                    // Overwrite original
                    else
                    {
                        Split(destructible, group, false, blur);
                    }
                }
            }
            else
            {
                D2D_Helper.Destroy(destructible.gameObject);
            }

            destructible = null;
        }

        D2D_ClassPool <D2D_SplitGroup> .Add(Groups, g => g.AddToPool());
    }
Пример #17
0
    // Go through all pixels in the defined area, convert them into cells, and find the lines that pass through the 0.5 opacity threshold
    public static void Calculate(D2D_Destructible destructible, int newXMin, int newXMax, int newYMin, int newYMax, bool cutEdges, bool binary)
    {
        cellCount      = 0;
        cellPointCount = 0;

        if (destructible != null)
        {
            if (cutEdges == true)
            {
                xMin = newXMin; if (xMin == 0)
                {
                    xMin -= 1;                                            // Expand left?
                }
                yMin = newYMin; if (yMin == 0)
                {
                    yMin -= 1;                                            // Expand bottom?
                }
                xMax = newXMax;
                yMax = newYMax;

                GetPixels(destructible, newXMin - 1, newYMin - 1, newXMax + 1, newYMax + 1);
            }
            else
            {
                xMin = newXMin - 1;
                yMin = newYMin - 1;
                xMax = newXMax + 1;
                yMax = newYMax + 1;

                GetPixels(destructible, newXMin, newYMin, newXMax, newYMax);
            }

            width  = xMax - xMin;
            height = yMax - yMin;

            if (width > 0 && height > 0)
            {
                if (cells.Capacity < width * height)
                {
                    cells.Capacity = width * height;
                }

                for (var y = 0; y < height; y++)
                {
                    var y0 = yMin + y;
                    var y1 = y0 + 1;

                    for (var x = 0; x < width; x++)
                    {
                        var x0 = xMin + x;
                        var x1 = x0 + 1;

                        var cell = GetNextCell();
                        var bl   = GetAlphaOrDefault(x0, y0);
                        var br   = GetAlphaOrDefault(x1, y0);
                        var tl   = GetAlphaOrDefault(x0, y1);
                        var tr   = GetAlphaOrDefault(x1, y1);

                        if (binary == true)
                        {
                            bl = bl > 0.5f ? 1.0f : 0.0f;
                            br = br > 0.5f ? 1.0f : 0.0f;
                            tl = tl > 0.5f ? 1.0f : 0.0f;
                            tr = tr > 0.5f ? 1.0f : 0.0f;
                        }

                        cell.X = x;
                        cell.Y = y;

                        translation.x = x0 + 0.5f;
                        translation.y = y0 + 0.5f;

                        CalculateCell(cell, bl, br, tl, tr, 0.5f);
                    }
                }
            }
        }
    }
	public static bool Generate(D2D_Destructible destructible, D2D_SpriteSplitOrder splitOrder)
	{
		cells.Clear();
		
		if (destructible != null && destructible.AlphaTex != null)
		{
			target = destructible;
			tex    = target.AlphaTex;
			width  = tex.width;
			height = tex.height;
			total  = width * height;
			pixels = tex.GetPixels32();
			
			if (cells.Capacity < total)
			{
				cells.Capacity = total;
			}
			
			var threshold = (byte)(target.SplitThreshold * 255.0f);
			
			for (var i = 0; i < total; i++)
			{
				cells.Add(pixels[i].a >= threshold);
			}
			
			fills.Clear();
			
			var validFillCount = 0;
			
			for (var i = 0; i < total; i++)
			{
				if (cells[i] == true)
				{
					currentFill = new Fill(); fills.Add(currentFill);
					
					currentFill.XMin = currentFill.XMax = i % width;
					currentFill.YMin = currentFill.YMax = i / width;
					
					BeginFloodFill(i, currentFill.XMin, currentFill.YMin);
					
					// Skip the first floodfill
					if (currentFill.Count >= target.SplitMinPixels)
					{
						currentFill.Valid = true; validFillCount += 1;
					}
				}
			}
			
			// Can we split?
			if (validFillCount > 1)
			{
				var firstSet = false;
				
				switch (splitOrder)
				{
					case D2D_SpriteSplitOrder.KeepLargest:  fills.Sort((a, b) => b.Count.CompareTo(a.Count)); break;
					case D2D_SpriteSplitOrder.KeepSmallest: fills.Sort((a, b) => a.Count.CompareTo(b.Count)); break;
				}
				
				foreach (var fill in fills)
				{
					if (fill.Valid == true)
					{
						if (firstSet == false)
						{
							firstSet = true;
							
							Split(destructible, fill, false);
						}
						else
						{
							var clonedGameObject   = D2D_Helper.CloneGameObject(destructible.gameObject, destructible.transform.parent);
							var clonedDestructible = clonedGameObject.GetComponent<D2D_Destructible>();
							
							Split(clonedDestructible, fill, true);
						}
					}
				}
				
				return true;
			}
			
			if (validFillCount == 0)
			{
				D2D_Helper.Destroy(destructible.gameObject);
			}
		}
		
		return false;
	}
Пример #19
0
    public void Explode()
    {
        var angle = transform.rotation.eulerAngles.z + AngleOffset + Random.Range(-0.5f, 0.5f) * AngleRandomness;

        D2D_Destructible.StampAll(transform.position, Size, angle, StampTex, Hardness, Layers);
    }
	private static void Split(D2D_Destructible destructible, Fill fill, bool isClone)
	{
		var clear = new Color32(0, 0, 0, 0);
		
		for (var i = 0; i < total; i++)
		{
			pixels[i] = clear;
		}
		
		for (var i = 0; i < fill.Count; i++)
		{
			pixels[fill.Indices[i]] = fill.Colours[i];
		}
		
		destructible.ReplaceAlphaWith(width, height, pixels);
		
		// Split notification
		destructible.BroadcastMessage("OnSpriteSplit", isClone, SendMessageOptions.DontRequireReceiver);
	}