Esempio n. 1
0
        private void AppendOrRemoveSegmentsToBlock(int deltaNumberOfSegments)
        {
            if (deltaNumberOfSegments > 0)
            {
                // New segments will be added, so the last segment must have its exclude corners hide flags cleared.
                if (CanExcludeCorners())
                {
                    LastSegment.GetStackByIndex(0).ClearHideFlagForAllBoxes(ObjectPlacementBoxHideFlags.BlockExcludeCorners);
                    LastSegment.GetStackByIndex(LastSegment.NumberOfStacks - 1).ClearHideFlagForAllBoxes(ObjectPlacementBoxHideFlags.BlockExcludeCorners);
                }

                int currentNumberOfSegmentsInBlock = _blockSegments.Count;
                AppendSegments(deltaNumberOfSegments);
                AdjustHeightForSegmentRange(currentNumberOfSegmentsInBlock);
            }
            else
            {
                int absDelta = Mathf.Abs(deltaNumberOfSegments);
                if (absDelta == _blockSegments.Count)
                {
                    --absDelta;                                     // We always want at least one segment
                }
                RemoveLastNumberOfSegments(absDelta);
            }
        }
Esempio n. 2
0
 private void UpdateStackOverlapDataForLast2Segments()
 {
     PenultimateSegment.MarkAllStacksAsNotOverlapped();
     LastSegment.MarkAllStacksAsNotOverlapped();
     ObjectPlacementBoxStackActions.MarkStacksAsOverlapped(ObjectPlacementPathOverlappedStackDetection.GetOverlappedStacksInSegment(_pathSegments.Count - 2, _pathSegments));
     ObjectPlacementBoxStackActions.MarkStacksAsOverlapped(ObjectPlacementPathOverlappedStackDetection.GetOverlappedStacksInSegment(_pathSegments.Count - 1, _pathSegments));
 }
Esempio n. 3
0
        private void AppendOrRemoveStacksToAllSegments(int deltaNumberOfStacks)
        {
            if (deltaNumberOfStacks > 0)
            {
                if (CanExcludeCorners())
                {
                    LastSegment.GetStackByIndex(0).ClearHideFlagForAllBoxes(ObjectPlacementBoxHideFlags.BlockExcludeCorners);
                    LastSegment.GetStackByIndex(LastSegment.NumberOfStacks - 1).ClearHideFlagForAllBoxes(ObjectPlacementBoxHideFlags.BlockExcludeCorners);
                }

                int currentNumberOfStacksInSegments = FirstSegment.NumberOfStacks;
                ObjectPlacementBoxStackSegmentActions.ExtendSegmentsByAmount(_blockSegments, deltaNumberOfStacks);
                AdjustHeightForStackRangeInAllSegments(currentNumberOfStacksInSegments);
            }
            else
            {
                ObjectPlacementBoxStackSegmentActions.ShrinkSegmentsByAmount(_blockSegments, Mathf.Abs(deltaNumberOfStacks));
            }
        }
Esempio n. 4
0
 private void ClearCornerExclusionHideFlagsInFirstAndLastSegments()
 {
     FirstSegment.ClearHideFlagInAllStacks(ObjectPlacementBoxHideFlags.BlockExcludeCorners);
     LastSegment.ClearHideFlagInAllStacks(ObjectPlacementBoxHideFlags.BlockExcludeCorners);
 }
Esempio n. 5
0
        private void ExtendOrShrinkPathAlongExtensionPlane()
        {
            // Construct a new extension plane in order to take into account the block's Y offset. Otherwise,
            // it becomes harder to control the block extension.
            Plane   extensionPlane             = _pathExtensionPlane.Plane;
            Vector3 pointOnBlockExtensionPlane = _pathExtensionPlane.PlaneQuad.Center;

            pointOnBlockExtensionPlane += extensionPlane.normal * _manualConstructionSettings.OffsetAlongGrowDirection;
            extensionPlane              = new Plane(extensionPlane.normal, pointOnBlockExtensionPlane);

            // We will need to adjust the last 2 segments using the intersection point between the mouse cursor
            // and the extension plane, so the first thing that we will do is find this intersection point. This
            // intersection point will essentially help us visualize a triangle whose adjacent sides represent the
            // extension directions of the 2 segments. The hypotenuse represents the vector which goes from the
            // first stack in the penultimate segment to the last stack in the last segment.
            Vector3 extensionPlaneIntersectionPoint;

            if (MouseCursor.Instance.IntersectsPlane(extensionPlane, out extensionPlaneIntersectionPoint))
            {
                // We will need to adjust the number of stacks in each segment based on the length of the triangle's
                // adjacent sides. We will start with the penultimate segment and construct a vector which goes from
                // the first stack in the penultimate segment to the intersection point with the plane. Projecting this
                // vector on the extension direction of the penultimate segment will give us the length of the adjacent
                // side. This length is then used to calculate the number of stacks in the penultimate segment.
                Vector3 toIntersectionPoint = extensionPlaneIntersectionPoint - _pathExtensionPlane.Plane.ProjectPoint(PenultimateSegment.FirstStackBasePosition);
                if (!PenultimateSegment.ExtensionDirection.IsPointingInSameGeneralDirection(toIntersectionPoint))
                {
                    PenultimateSegment.ReverseExtensionDirection();
                }

                // Calculate the number of stacks in the penultimate segment
                float adjacentSideLength    = PenultimateSegment.ExtensionDirection.GetAbsDot(toIntersectionPoint);
                float numberOfStacks        = adjacentSideLength / (PenultimateSegment.GetBoxSizeAlongNormalizedDirection(PenultimateSegment.ExtensionDirection) + _paddingSettings.PaddingAlongExtensionPlane);
                int   integerNumberOfStacks = (int)numberOfStacks + 1;
                int   currentNumberOfStacks = PenultimateSegment.NumberOfStacks;
                int   deltaNumberOfStacks   = integerNumberOfStacks - currentNumberOfStacks;
                if (deltaNumberOfStacks > 0 || (deltaNumberOfStacks == 0 && _heightAdjustmentSettings.HeightAdjustmentMode == ObjectPlacementPathHeightAdjustmentMode.AutomaticPattern))
                {
                    PenultimateSegment.Extend(deltaNumberOfStacks);
                    AdjustHeightForStackRangeInSegment(PenultimateSegment, currentNumberOfStacks);
                }
                else
                {
                    PenultimateSegment.Shrink(Mathf.Abs(deltaNumberOfStacks));
                }

                // We will have to do the same thing for the last segment. However, this time we will first detect its extension direction. The extension direction
                // is one of the extension plane's axes (right or look). The one we choose has to be the one which is not aligned with the penultimate segment's
                // extension direction (i.e. it has to be perpendicular to it).
                toIntersectionPoint = extensionPlaneIntersectionPoint - _pathExtensionPlane.Plane.ProjectPoint(PenultimateSegment.LastStackBasePosition);
                Vector3 extensionPlaneRight           = _pathExtensionPlane.RightAxis;
                Vector3 extensionPlaneLook            = _pathExtensionPlane.LookAxis;
                Vector3 lastSegmentExtensionDirection = extensionPlaneRight;
                if (lastSegmentExtensionDirection.IsAlignedWith(PenultimateSegment.ExtensionDirection))
                {
                    lastSegmentExtensionDirection = extensionPlaneLook;
                }
                if (!lastSegmentExtensionDirection.IsPointingInSameGeneralDirection(toIntersectionPoint))
                {
                    lastSegmentExtensionDirection *= -1.0f;
                }
                LastSegment.SetExtensionDirection(lastSegmentExtensionDirection);

                // Calculate the number of stacks in the segment.
                // Note: We no longer add 1 to the integer number of stacks because that stack is actually the last stack in the penultimate segment
                numberOfStacks        = toIntersectionPoint.magnitude / (LastSegment.GetBoxSizeAlongNormalizedDirection(LastSegment.ExtensionDirection) + _paddingSettings.PaddingAlongExtensionPlane);
                integerNumberOfStacks = (int)numberOfStacks;
                currentNumberOfStacks = LastSegment.NumberOfStacks;
                deltaNumberOfStacks   = integerNumberOfStacks - currentNumberOfStacks;
                if (deltaNumberOfStacks > 0 || (deltaNumberOfStacks == 0 && _heightAdjustmentSettings.HeightAdjustmentMode == ObjectPlacementPathHeightAdjustmentMode.AutomaticPattern))
                {
                    LastSegment.Extend(deltaNumberOfStacks);
                    AdjustHeightForStackRangeInSegment(LastSegment, currentNumberOfStacks);
                }
                else
                {
                    LastSegment.Shrink(Mathf.Abs(deltaNumberOfStacks));
                }

                // We always have to ensure that the 2 segments are oriented accordingly because their extension directions may have changed
                if (CanRotateObjectsToFollowPath())
                {
                    PenultimateSegment.LookStacksAlongExtensionDirection();
                    LastSegment.LookStacksAlongExtensionDirection();

                    // Note: Handle special case when the first segment in the path has only one stack. In that case we want that
                    //       stack to be rotated in such a way that it follows the path to the second segment. Otherwise, it can
                    //       look weird for paths that use non-cube objects.
                    if (_pathSegments.Count == 2 && PenultimateSegment.NumberOfStacks == 1 && LastSegment.NumberOfStacks >= 1)
                    {
                        PenultimateSegment.LookStacksAlongDirection(LastSegment.ExtensionDirection);
                    }
                }

                LastSegment.ConnectFirstStackToLastStackInSegment(PenultimateSegment, CalculateSegmentConnectionOffset(LastSegment, PenultimateSegment));

                UpdateStackOverlapDataForLast2Segments();
                if (_borderSettings.UseBorders)
                {
                    _borderApplyOperation.ApplyBordersToAllPathSegments(_pathSegments, _borderSettings);
                }
                if (_tileConnectionSettings.UseTileConnections)
                {
                    UpdateTileConnectionInformation();
                }

                SceneView.RepaintAll();
            }
        }