/// <summary>
        /// Divide scope into portions as described by divisors list.
        /// Add snap planes at the dividend bounds if a snap id is given in the divisor.
        /// If any snap planes in the selector list are found within a dividend scope, snap the bounds to match the nearest snap plane of that selector type.
        /// </summary>
        /// <param name="divider"> </param>
        /// <returns></returns>
        public override ProductionScope[] Divide(DivideProduction divider)
        {
            // step 1: validate divisor magnitudes. scopeLength > absolute length; scopeLength - absolute lengths = availableRelLength
            var absSpan = divider.Divisors.Where(div => div.IsAbsolute).Sum(div => div.Magnitude);
            var relSpan = divider.Divisors.Where(div => !div.IsAbsolute).Sum(div => div.Magnitude);

            if (Math.Abs(relSpan - 1) > Mathf.Epsilon || absSpan > Bounds.size[(int)divider.DivisionAxis])
            {
                throw new Exception("Division length is invalid.");
            }

            var divAxisExtent = Vector3.zero;

            divAxisExtent[(int)divider.DivisionAxis] = Bounds.extents[(int)divider.DivisionAxis];
            var frontierPoint = Bounds.center - Rotation * (divAxisExtent);

            var dividends = new ProductionScope[divider.Divisors.Count()];

            for (var i = 0; i < divider.Divisors.Length; i++)
            {
                var divisor = divider.Divisors[i];

                // slice volume along our division axis, slicing off [magnitude] volume or [magnitude]% of the volume available for relative divisions
                Vector3 dividendSpan = Vector3.zero;
                dividendSpan[(int)divider.DivisionAxis] = divisor.IsAbsolute
                                               ? divisor.Magnitude
                                               : Bounds.size[(int)divider.DivisionAxis] * divisor.Magnitude;

                // compute dividend volume's center; just move from frontier point (min) to terminal point (max) along the division axis
                var dividendCenter = frontierPoint + (Rotation * (dividendSpan / 2f));
                var s = Bounds.size;
                s[(int)divider.DivisionAxis] = dividendSpan[(int)divider.DivisionAxis];
                var proposedBounds = new Bounds(dividendCenter, s);

                dividends[i] = new CubeProductionScope(SnapBoundsToSnapPlanes(divider.DivisionAxis, SelectSnapPlanes(divider.DivisionAxis, divider.SnapToPlanes), proposedBounds), Rotation);

                if (!string.IsNullOrEmpty(divisor.SnapPlaneKey))
                {
                    // add another snap plane to the module
                    AddSnapPlane(divider.DivisionAxis, divisor.SnapPlaneKey, dividends[i].Bounds);
                }
                if (dividends[i].Bounds.size.x <= 0 || dividends[i].Bounds.size.y <= 0 || dividends[i].Bounds.size.z <= 0)
                {
                    Debug.Log("Dividing to a negative size...");
                }
                // update frontier point
                frontierPoint = frontierPoint + Rotation * dividendSpan;
            }

            return(dividends);
        }
Beispiel #2
0
 public override ProductionScope[] Divide(DivideProduction divider)
 {
     throw new NotImplementedException();
 }
Beispiel #3
0
 public abstract ProductionScope[] Divide(DivideProduction divider);