private void MakeSegmentFollowPath(ObjectPlacementBoxStackSegment segment)
        {
            float      angleFromFirstSegment = Vector3.Angle(_pathSegments[0].ExtensionDirection, segment.ExtensionDirection);
            Quaternion rotation = Quaternion.AngleAxis(angleFromFirstSegment, _pathExtensionPlane.Plane.normal);

            segment.SetRotationForAllStacks(rotation * _startObjectHierarchyWorldOrientedBox.Rotation);
        }
Пример #2
0
        public static List <ObjectPlacementBoxStack> GetOverlappedStacksInSegment(int segmentIndex, List <ObjectPlacementBoxStackSegment> pathSegments)
        {
            var overlappedStacks = new List <ObjectPlacementBoxStack>(pathSegments.Count * 10);

            ObjectPlacementBoxStackSegment possiblyOverlappedSegment = pathSegments[segmentIndex];

            for (int possiblyOverlappingSegmentIndex = segmentIndex - 1; possiblyOverlappingSegmentIndex >= 0; --possiblyOverlappingSegmentIndex)
            {
                ObjectPlacementBoxStackSegment possiblyOverlappingSegment = pathSegments[possiblyOverlappingSegmentIndex];

                if (possiblyOverlappingSegment.ExtensionVectorIntersects(possiblyOverlappedSegment) ||
                    possiblyOverlappingSegment.ExtensionVectorOverlaps(possiblyOverlappedSegment))
                {
                    for (int possiblyOverlappedStackIndex = 0; possiblyOverlappedStackIndex < possiblyOverlappedSegment.NumberOfStacks; ++possiblyOverlappedStackIndex)
                    {
                        ObjectPlacementBoxStack possiblyOverlappedStack = possiblyOverlappedSegment.GetStackByIndex(possiblyOverlappedStackIndex);
                        for (int possiblyOverlappingStackIndex = 0; possiblyOverlappingStackIndex < possiblyOverlappingSegment.NumberOfStacks; ++possiblyOverlappingStackIndex)
                        {
                            ObjectPlacementBoxStack possiblyOverlappingStack = possiblyOverlappingSegment.GetStackByIndex(possiblyOverlappingStackIndex);
                            if (IsStackOverlappedBy(possiblyOverlappedStack, possiblyOverlappingStack))
                            {
                                overlappedStacks.Add(possiblyOverlappedStack);
                            }
                        }
                    }
                }
            }

            return(overlappedStacks);
        }
Пример #3
0
        public bool ExtensionVectorIntersects(ObjectPlacementBoxStackSegment querySegment)
        {
            if (NumberOfStacks == 0 || querySegment.NumberOfStacks == 0)
            {
                return(false);
            }

            if (_extensionDirection.IsPerpendicularTo(querySegment.ExtensionDirection))
            {
                Plane   segmentBasePlane = GetBasePlane();
                Vector3 thisSegmentStart = segmentBasePlane.ProjectPoint(FirstStackBasePosition);
                Vector3 thisSegmentEnd   = segmentBasePlane.ProjectPoint(LastStackBasePosition);
                if (NumberOfStacks == 1)
                {
                    thisSegmentEnd = thisSegmentStart + _extensionDirection * 0.5f * GetBoxSizeAlongNormalizedDirection(_extensionDirection);
                }

                Vector3 querySegmentStart = segmentBasePlane.ProjectPoint(querySegment.FirstStackBasePosition);
                Vector3 querySegmentEnd   = segmentBasePlane.ProjectPoint(querySegment.LastStackBasePosition);
                if (querySegment.NumberOfStacks == 1)
                {
                    querySegmentEnd = querySegmentStart + querySegment.ExtensionDirection * 0.5f * querySegment.GetBoxSizeAlongNormalizedDirection(querySegment.ExtensionDirection);
                }

                Segment3D thisSegment3D  = new Segment3D(thisSegmentStart, thisSegmentEnd);
                Segment3D querySegment3D = new Segment3D(querySegmentStart, querySegmentEnd);

                return(thisSegment3D.IntersectsWith(querySegment3D));
            }

            return(false);
        }
Пример #4
0
        public bool ExtensionVectorOverlaps(ObjectPlacementBoxStackSegment querySegment)
        {
            if (NumberOfStacks == 0 || querySegment.NumberOfStacks == 0)
            {
                return(false);
            }

            if (_extensionDirection.IsAlignedWith(querySegment.ExtensionDirection))
            {
                Plane   segmentBasePlane = GetBasePlane();
                Vector3 thisSegmentStart = segmentBasePlane.ProjectPoint(FirstStackBasePosition);
                Vector3 thisSegmentEnd   = segmentBasePlane.ProjectPoint(LastStackBasePosition);
                if (NumberOfStacks == 1)
                {
                    thisSegmentEnd = thisSegmentStart + _extensionDirection * 0.5f * GetBoxSizeAlongNormalizedDirection(_extensionDirection);
                }

                Vector3 querySegmentStart = segmentBasePlane.ProjectPoint(querySegment.FirstStackBasePosition);
                Vector3 querySegmentEnd   = segmentBasePlane.ProjectPoint(querySegment.LastStackBasePosition);
                if (querySegment.NumberOfStacks == 1)
                {
                    querySegmentEnd = querySegmentStart + querySegment.ExtensionDirection * 0.5f * querySegment.GetBoxSizeAlongNormalizedDirection(querySegment.ExtensionDirection);
                }

                return(querySegmentStart.IsOnSegment(thisSegmentStart, thisSegmentEnd) || querySegmentEnd.IsOnSegment(thisSegmentStart, thisSegmentEnd) ||
                       thisSegmentStart.IsOnSegment(querySegmentStart, querySegmentEnd) || thisSegmentEnd.IsOnSegment(querySegmentStart, querySegmentEnd));
            }

            return(false);
        }
Пример #5
0
        private void CreateFirstSegmentInBlock()
        {
            ObjectPlacementBoxStackSegment firstSegmentInBlock = CreateNewSegment();

            firstSegmentInBlock.SetExtensionDirection(_segmentExtensionDirection);
            firstSegmentInBlock.SetFirstStackBasePosition(_startObjectHierarchyWorldOrientedBox.Center);
        }
Пример #6
0
        private Vector3 CalculateSegmentConnectionOffsetForNoCornerExclusion(ObjectPlacementBoxStackSegment sourceSegment, ObjectPlacementBoxStackSegment destinationSegment)
        {
            // No offset if the destination segment doesn't have any stacks
            if (destinationSegment.NumberOfStacks == 0)
            {
                return(Vector3.zero);
            }

            bool  srcPointsInSameDirAsDestination;
            bool  srcExtensionDirAlignedWithDestDir = sourceSegment.ExtensionDirection.IsAlignedWith(destinationSegment.ExtensionDirection, out srcPointsInSameDirAsDestination);
            float multiplicationSign = 1.0f;

            if (srcExtensionDirAlignedWithDestDir)
            {
                if (!srcPointsInSameDirAsDestination)
                {
                    multiplicationSign *= -1.0f;
                }
            }

            float   destBoxSizeAlongDestExtensionDir = destinationSegment.GetBoxSizeAlongNormalizedDirection(destinationSegment.ExtensionDirection);
            float   srcBoxSizeAlongDestExtensionDir  = sourceSegment.GetBoxSizeAlongNormalizedDirection(destinationSegment.ExtensionDirection);
            Vector3 offsetAlongDestExtensionDir      = destinationSegment.ExtensionDirection * (destBoxSizeAlongDestExtensionDir - srcBoxSizeAlongDestExtensionDir) * 0.5f;

            float   destBoxSizeAlongSrcExtensionDir = destinationSegment.GetBoxSizeAlongNormalizedDirection(sourceSegment.ExtensionDirection);
            float   srcBoxSizeAlongSrcExtensionDir  = sourceSegment.GetBoxSizeAlongNormalizedDirection(sourceSegment.ExtensionDirection);
            Vector3 offsetAlongSourceExtensionDir   = multiplicationSign * sourceSegment.ExtensionDirection * ((srcBoxSizeAlongSrcExtensionDir + destBoxSizeAlongSrcExtensionDir) * 0.5f + _paddingSettings.PaddingAlongExtensionPlane);

            return(offsetAlongDestExtensionDir + offsetAlongSourceExtensionDir);
        }
        public void AdjustSegmentHeight(ObjectPlacementBoxStackSegment segment, int indexOfFirstStackToAdjust, ObjectPlacementBlockAutomaticRandomHeightAdjustmentSettings automaticRandomHeightAdjustmentSettings)
        {
            Range <int> randomValueRange       = new Range <int>(automaticRandomHeightAdjustmentSettings.MinHeight, automaticRandomHeightAdjustmentSettings.MaxHeight);
            int         numberOfStacksToAdjust = segment.NumberOfStacks - indexOfFirstStackToAdjust;

            segment.SetHeightForStacksStartingAt(indexOfFirstStackToAdjust, RandomValueGeneration.GenerateIntRandomValuesInRange(randomValueRange, numberOfStacksToAdjust));
        }
Пример #8
0
        private void ReconnectAllSegments()
        {
            for (int segmentIndex = 1; segmentIndex < _pathSegments.Count; ++segmentIndex)
            {
                ObjectPlacementBoxStackSegment currentSegment  = _pathSegments[segmentIndex];
                ObjectPlacementBoxStackSegment previousSegment = _pathSegments[segmentIndex - 1];

                currentSegment.ConnectFirstStackToLastStackInSegment(previousSegment, CalculateSegmentConnectionOffset(currentSegment, previousSegment));
            }
        }
Пример #9
0
        private void AppendSegments(int numberOfSegmentsToAppend)
        {
            for (int segmentIndex = 0; segmentIndex < numberOfSegmentsToAppend; ++segmentIndex)
            {
                ObjectPlacementBoxStackSegment lastSegmentInBlock = LastSegment;
                ObjectPlacementBoxStackSegment segmentToAppend    = CreateNewSegment();
                segmentToAppend.SetExtensionDirection(_segmentExtensionDirection);
                segmentToAppend.Extend(FirstSegment.NumberOfStacks);

                AppendSegmentToSegment(segmentToAppend, lastSegmentInBlock);
            }
        }
        public void ApplyBordersToAllPathSegments(List <ObjectPlacementBoxStackSegment> pathSegments, ObjectPlacementPathBorderSettings borderSettings)
        {
            int totalNumberOfStacksInSegments = ObjectPlacementBoxStackSegmentQueries.GetTotalNumberOfStacksInSegments(pathSegments);
            int numberOfTraversedStacks       = 0;

            for (int segmentIndex = 0; segmentIndex < pathSegments.Count; ++segmentIndex)
            {
                ObjectPlacementBoxStackSegment segment = pathSegments[segmentIndex];
                for (int stackIndex = 0; stackIndex < segment.NumberOfStacks; ++stackIndex)
                {
                    ObjectPlacementBoxStack stack = segment.GetStackByIndex(stackIndex);
                    for (int boxIndex = 0; boxIndex < stack.NumberOfBoxes; ++boxIndex)
                    {
                        ObjectPlacementBox box = stack.GetBoxByIndex(boxIndex);
                        box.ClearHideFlag(ObjectPlacementBoxHideFlags.PathApplyBorders);   // Not hidden by default. We have to check against the borders to see if the box needs to be hidden.

                        // Check if the box is outside the bottom and top borders
                        if (boxIndex >= borderSettings.BottomBorderWidth && boxIndex < (stack.NumberOfBoxes - borderSettings.TopBorderWidth))
                        {
                            // Check special case in which the current segment has the same extension direction as the one which precedes it
                            // but is aiming in the opposite direction. In that case, the first stack will never be masked because it looks
                            // weird.
                            if (stackIndex == 0 && segmentIndex != 0)
                            {
                                ObjectPlacementBoxStackSegment previousSegment = pathSegments[segmentIndex - 1];
                                bool extendingInSameDirection;
                                if (previousSegment.ExtensionDirection.IsAlignedWith(segment.ExtensionDirection, out extendingInSameDirection))
                                {
                                    // If the segments are aligned but they are extending in opposite directions, it means that
                                    // we have to leave the boxes in this stack untouched.
                                    if (!extendingInSameDirection)
                                    {
                                        continue;
                                    }
                                }
                            }

                            if (numberOfTraversedStacks >= borderSettings.BeginBorderWidth &&
                                numberOfTraversedStacks < totalNumberOfStacksInSegments - borderSettings.EndBorderWidth)
                            {
                                box.SetHideFlag(ObjectPlacementBoxHideFlags.PathApplyBorders);
                            }
                        }
                    }

                    ++numberOfTraversedStacks;
                }
            }
        }
Пример #11
0
        private ObjectPlacementBoxStackSegment CreateNewSegment()
        {
            var newSegment = new ObjectPlacementBoxStackSegment();

            newSegment.SetExtensionDirection(_blockExtensionPlane.LookAxis);
            newSegment.SetGrowAxis(_blockExtensionPlane.UpAxis);
            newSegment.SetRotationForAllStacks(_startObjectHierarchyWorldOrientedBox.Rotation);
            newSegment.SetBoxSizeForAllStacks(_startObjectHierarchyWorldOrientedBox.ScaledSize);
            newSegment.SetPaddingAlongStackGrowDirection(_paddingSettings.PaddingAlongGrowDirection);
            newSegment.SetPaddingAlongExtensionDirection(_paddingSettings.PaddingAlongExtensionPlane);

            _blockSegments.Add(newSegment);

            return(newSegment);
        }
Пример #12
0
        private void AdjustHeightForStackRangeInSegment(ObjectPlacementBoxStackSegment segment, int indexOfFirstStackToAdjust)
        {
            ObjectPlacementPathHeightAdjustmentMode heightAdjustmentMode = _heightAdjustmentSettings.HeightAdjustmentMode;

            if (heightAdjustmentMode == ObjectPlacementPathHeightAdjustmentMode.Manual)
            {
                _manualHeightAdjuster.AdjustSegmentHeight(segment, indexOfFirstStackToAdjust, _currentManualPathHeight);
            }
            else if (heightAdjustmentMode == ObjectPlacementPathHeightAdjustmentMode.AutomaticRandom)
            {
                _automaticRandomHeightAdjuster.AdjustSegmentHeight(segment, indexOfFirstStackToAdjust, _heightAdjustmentSettings.AutomaticRandomHeightAdjustmentSettings);
            }
            else
            {
                _automaticPatternHeightAdjuster.AdjustSegmentHeight(segment, _pathSegments, _heightAdjustmentSettings.AutomaticPatternHeightAdjustmentSettings, ObjectPlacementPathHeightPatternDatabase.Get().ActivePattern);
            }
        }
Пример #13
0
 private Vector3 CalculateSegmentConnectionOffset(ObjectPlacementBoxStackSegment sourceSegment, ObjectPlacementBoxStackSegment destinationSegment)
 {
     if (!CanExcludeCorners())
     {
         return(CalculateSegmentConnectionOffsetForNoCornerExclusion(sourceSegment, destinationSegment));
     }
     else
     {
         // Note: Corner exclusion is applied only if the 2 segments are perpendicular.
         if (sourceSegment.ExtensionDirection.IsPerpendicularTo(destinationSegment.ExtensionDirection))
         {
             return(CalculateSegmentConnectionOffsetForCornerExclusion(sourceSegment, destinationSegment));
         }
         else
         {
             return(CalculateSegmentConnectionOffsetForNoCornerExclusion(sourceSegment, destinationSegment));
         }
     }
 }
Пример #14
0
        public void AdjustSegmentHeight(ObjectPlacementBoxStackSegment segment, List <ObjectPlacementBoxStackSegment> allPathSegments,
                                        ObjectPlacementPathAutomaticPatternHeightAdjustmentSettings automaticPatternHeightAdjustmentSettings, ObjectPlacementPathHeightPattern heightPattern)
        {
            int initialHeightValueIndex = 0;

            if (automaticPatternHeightAdjustmentSettings.ApplyPatternsContinuously)
            {
                int indexOfSegmentToAdjust = allPathSegments.FindIndex(0, item => item == segment);
                if (indexOfSegmentToAdjust >= 0)
                {
                    initialHeightValueIndex = ObjectPlacementBoxStackSegmentQueries.GetTotalNumberOfStacksInSegments(allPathSegments, indexOfSegmentToAdjust - 1);
                }
            }

            bool wrapPattern = automaticPatternHeightAdjustmentSettings.WrapPatterns;

            for (int stackIndex = 0; stackIndex < segment.NumberOfStacks; ++stackIndex)
            {
                segment.GetStackByIndex(stackIndex).SetHeight(heightPattern.GetHeightValue(initialHeightValueIndex + stackIndex, wrapPattern));
            }
        }
        public void Attach2NewSegments()
        {
            if (_isActive)
            {
                RemoveSegmentsWithNoStacks();

                // First create the 2 new segments which will replace the current penultimate and last segments
                ObjectPlacementBoxStackSegment oldLastSegment        = LastSegment;
                ObjectPlacementBoxStackSegment newPenultimateSegment = CreateNewSegment();
                CreateNewSegment();

                // We will want the first stack in the new penultimate segment to replace the last stack in 'LastSegment'.
                // Otherwise, when this function is called, an additional box will suddenly appear in the scene apparently
                // out of nowhere and it doesn't look very good. Not to mention that it can be quite confusing :).
                oldLastSegment.Shrink(1);
                newPenultimateSegment.Extend(1);

                newPenultimateSegment.SetExtensionDirection(oldLastSegment.ExtensionDirection);
                if (CanRotateObjectsToFollowPath())
                {
                    newPenultimateSegment.SetRotationForAllStacks(oldLastSegment.StackRotation);
                    MakeSegmentFollowPath(LastSegment);
                }
                newPenultimateSegment.ConnectFirstStackToLastStackInSegment(oldLastSegment, CalculateSegmentConnectionOffset(newPenultimateSegment, oldLastSegment));

                AdjustHeightForEntireSegment(PenultimateSegment);

                UpdateStackOverlapDataForLast2Segments();
                if (_borderSettings.UseBorders)
                {
                    _borderApplyOperation.ApplyBordersToAllPathSegments(_pathSegments, _borderSettings);
                }
                if (_tileConnectionSettings.UseTileConnections)
                {
                    UpdateTileConnectionInformation();
                }
            }
        }
Пример #16
0
        private Vector3 CalculateSegmentConnectionOffsetForCornerExclusion(ObjectPlacementBoxStackSegment sourceSegment, ObjectPlacementBoxStackSegment destinationSegment)
        {
            bool  srcPointsInSameDirAsDestination;
            bool  srcExtensionDirAlignedWithDestDir = sourceSegment.ExtensionDirection.IsAlignedWith(destinationSegment.ExtensionDirection, out srcPointsInSameDirAsDestination);
            float multiplicationSign = 1.0f;

            if (srcExtensionDirAlignedWithDestDir)
            {
                if (!srcPointsInSameDirAsDestination)
                {
                    multiplicationSign *= -1.0f;
                }
            }

            float   destBoxSizeAlongDestExtensionDir = destinationSegment.GetBoxSizeAlongNormalizedDirection(destinationSegment.ExtensionDirection);
            float   srcBoxSizeAlongDestExtensionDir  = sourceSegment.GetBoxSizeAlongNormalizedDirection(destinationSegment.ExtensionDirection);
            Vector3 offsetAlongDestExtensionDir      = destinationSegment.ExtensionDirection * Mathf.Abs((destBoxSizeAlongDestExtensionDir + srcBoxSizeAlongDestExtensionDir) * 0.5f);

            float   destBoxSizeAlongSrcExtensionDir = destinationSegment.GetBoxSizeAlongNormalizedDirection(sourceSegment.ExtensionDirection);
            float   srcBoxSizeAlongSrcExtensionDir  = sourceSegment.GetBoxSizeAlongNormalizedDirection(sourceSegment.ExtensionDirection);
            Vector3 offsetAlongSourceExtensionDir   = multiplicationSign * sourceSegment.ExtensionDirection * (srcBoxSizeAlongSrcExtensionDir + destBoxSizeAlongSrcExtensionDir) * 0.5f;

            return(offsetAlongDestExtensionDir + offsetAlongSourceExtensionDir);
        }
Пример #17
0
        public void ApplySubdivisionToEntireBlock(List <ObjectPlacementBoxStackSegment> allBlockSegments, ObjectPlacementBlockSubdivisionSettings subdivisionSettings)
        {
            // No subdivision required?
            if (!subdivisionSettings.SubdivideAlongGrowDirection && !subdivisionSettings.SubdivideAlongExtensionRight && !subdivisionSettings.SubdivideAlongExtensionLook)
            {
                return;
            }

            // Note: The following code assumes the segments' stacks extend along the extension plane right axis
            //       and the segments themselves are arranged along the plane's look axis.
            for (int segmentIndex = 0; segmentIndex < allBlockSegments.Count; ++segmentIndex)
            {
                int numberOfTraversedSegments          = segmentIndex + 1;
                ObjectPlacementBoxStackSegment segment = allBlockSegments[segmentIndex];
                segment.ClearHideFlagInAllStacks(ObjectPlacementBoxHideFlags.BlockApplySubdivisions);

                // If we must subdivide along the extension look axis, we may need to hide the entire segment based
                // on the number of segments we have traversed so far.
                if (subdivisionSettings.SubdivideAlongExtensionLook)
                {
                    // First calculate the remainder of how many pairs of <subidvision, gap> we have traversed
                    int subdivisionGapPairSize = subdivisionSettings.SubdivisionGapSizeAlongExtensionLook + subdivisionSettings.SubdivisionSizeAlongExtensionLook;
                    int remainder = numberOfTraversedSegments % subdivisionGapPairSize;

                    // If the remainder is 0 it means we are at the end of a pair and the end of a pair is always a gap. So we activate
                    // the hide flags. We also activate the hide flags if the remainder is bigger than the subdivision size. In that case
                    // it means we reside somewhere inside the gap.
                    if (remainder == 0 || remainder > subdivisionSettings.SubdivisionSizeAlongExtensionLook)
                    {
                        segment.SetHideFlagInAllStacks(ObjectPlacementBoxHideFlags.BlockApplySubdivisions);
                    }
                }

                for (int stackIndex = 0; stackIndex < segment.NumberOfStacks; ++stackIndex)
                {
                    int numberOfTraversedStacks   = stackIndex + 1;
                    ObjectPlacementBoxStack stack = segment.GetStackByIndex(stackIndex);
                    if (subdivisionSettings.SubdivideAlongExtensionRight)
                    {
                        int subdivisionGapPairSize = subdivisionSettings.SubdivisionGapSizeAlongExtensionRight + subdivisionSettings.SubdivisionSizeAlongExtensionRight;
                        int remainder = numberOfTraversedStacks % subdivisionGapPairSize;
                        if (remainder == 0 || remainder > subdivisionSettings.SubdivisionSizeAlongExtensionRight)
                        {
                            stack.SetHideFlagForAllBoxes(ObjectPlacementBoxHideFlags.BlockApplySubdivisions);
                        }
                    }

                    for (int boxIndex = 0; boxIndex < stack.NumberOfBoxes; ++boxIndex)
                    {
                        int numberOfTraversedBoxes = boxIndex + 1;
                        if (subdivisionSettings.SubdivideAlongGrowDirection)
                        {
                            int subdivisionGapPairSize = subdivisionSettings.SubdivisionGapSizeAlongGrowDirection + subdivisionSettings.SubdivisionSizeAlongGrowDirection;
                            int remainder = numberOfTraversedBoxes % subdivisionGapPairSize;
                            if (remainder == 0 || remainder > subdivisionSettings.SubdivisionSizeAlongGrowDirection)
                            {
                                stack.GetBoxByIndex(boxIndex).SetHideFlag(ObjectPlacementBoxHideFlags.BlockApplySubdivisions);
                            }
                        }
                    }
                }
            }
        }
Пример #18
0
 private void AppendSegmentToSegment(ObjectPlacementBoxStackSegment sourceSegment, ObjectPlacementBoxStackSegment destinationSegment)
 {
     sourceSegment.ConnectFirstStackToFirstStackInSegment(destinationSegment, GetSegmentConnectionOffsetForAppendOperation());
 }
Пример #19
0
        public List <ObjectPlacementData> Calculate()
        {
            if (_path == null || _path.NumberOfSegments == 0 || !ObjectPlacementGuide.ExistsInScene)
            {
                return(new List <ObjectPlacementData>());
            }

            Prefab     placementGuidePrefab     = ObjectPlacementGuide.Instance.SourcePrefab;
            Vector3    placementGuideWorldScale = ObjectPlacementGuide.Instance.WorldScale;
            float      objectMissChance         = _path.Settings.ManualConstructionSettings.ObjectMissChance;
            Vector3    yOffsetVector            = _path.ExtensionPlane.normal * _path.Settings.ManualConstructionSettings.OffsetAlongGrowDirection;
            bool       allowObjectIntersection  = ObjectPlacementSettings.Get().ObjectIntersectionSettings.AllowIntersectionForPathPlacement;
            Quaternion placementGuideRotation   = ObjectPlacementGuide.Instance.WorldRotation;

            bool    rotateObjectsToFollowPath = _path.Settings.ManualConstructionSettings.RotateObjectsToFollowPath;
            Vector3 pathExtensionPlaneNormal  = _path.ExtensionPlane.normal;
            Vector3 firstSegmentExtensionDir  = _path.GetSegmentByIndex(0).ExtensionDirection;

            Quaternion firstSegmentRotation = Quaternion.LookRotation(firstSegmentExtensionDir, pathExtensionPlaneNormal);

            bool           randomizePrefabs     = _path.Settings.ManualConstructionSettings.RandomizePrefabs;
            PrefabCategory activePrefabCategory = PrefabCategoryDatabase.Get().ActivePrefabCategory;

            var objectPlacementDataInstances = new List <ObjectPlacementData>(_path.NumberOfSegments * 10);

            for (int segmentIndex = 0; segmentIndex < _path.NumberOfSegments; ++segmentIndex)
            {
                ObjectPlacementBoxStackSegment segment = _path.GetSegmentByIndex(segmentIndex);

                Quaternion worldRotation = placementGuideRotation;

                if (rotateObjectsToFollowPath)
                {
                    // Note: ObjectPlacementPathManualConstructionSession.cs line 451. The design is a wreck. AGAIN :)
                    if ((segmentIndex == 0 && _path.NumberOfSegments > 1 && segment.NumberOfStacks == 1))
                    {
                        Vector3 dirBetweenStacks = segment.GetStackByIndex(0).BasePosition - _path.GetSegmentByIndex(1).GetStackByIndex(0).BasePosition;
                        dirBetweenStacks.Normalize();

                        Quaternion segmentRotation = Quaternion.LookRotation(dirBetweenStacks, pathExtensionPlaneNormal);
                        Quaternion fromPlacementGuideRotationToThis = QuaternionExtensions.GetRelativeRotation(placementGuideRotation, segmentRotation);
                        worldRotation = fromPlacementGuideRotationToThis * worldRotation;
                    }
                    else
                    if (segmentIndex != 0)
                    {
                        Quaternion segmentRotation = Quaternion.LookRotation(segment.ExtensionDirection, pathExtensionPlaneNormal);
                        Quaternion fromFirstToThis = QuaternionExtensions.GetRelativeRotation(firstSegmentRotation, segmentRotation);
                        worldRotation = fromFirstToThis * worldRotation;
                    }
                }
                for (int stackIndex = 0; stackIndex < segment.NumberOfStacks; ++stackIndex)
                {
                    ObjectPlacementBoxStack stack = segment.GetStackByIndex(stackIndex);
                    if (stack.IsOverlappedByAnotherStack)
                    {
                        continue;
                    }

                    for (int stackBoxIndex = 0; stackBoxIndex < stack.NumberOfBoxes; ++stackBoxIndex)
                    {
                        ObjectPlacementBox box = stack.GetBoxByIndex(stackBoxIndex);
                        if (box.IsHidden)
                        {
                            continue;
                        }

                        if (ObjectPlacementMissChance.Missed(objectMissChance, ObjectPlacementPathManualConstructionSettings.MinObjectMissChance, ObjectPlacementPathManualConstructionSettings.MaxObjectMissChance))
                        {
                            continue;
                        }
                        if (!allowObjectIntersection && ObjectQueries.IntersectsAnyObjectsInScene(box.OrientedBox, true))
                        {
                            continue;
                        }

                        Vector3 worldScale = placementGuideWorldScale;
                        Prefab  prefab     = placementGuidePrefab;
                        if (randomizePrefabs && activePrefabCategory.NumberOfPrefabs != 0)
                        {
                            int    randomPrefabIndex = UnityEngine.Random.Range(0, activePrefabCategory.NumberOfPrefabs);
                            Prefab randomPrefab      = activePrefabCategory.GetPrefabByIndex(randomPrefabIndex);
                            if (randomPrefab != null && randomPrefab.UnityPrefab != null)
                            {
                                prefab     = activePrefabCategory.GetPrefabByIndex(randomPrefabIndex);
                                worldScale = prefab.UnityPrefab.transform.lossyScale;
                            }
                        }

                        var objectPlacementData = new ObjectPlacementData();
                        objectPlacementData.WorldPosition = ObjectPositionCalculator.CalculateObjectHierarchyPosition(prefab, box.Center + yOffsetVector, worldScale, worldRotation);
                        objectPlacementData.WorldScale    = worldScale;
                        objectPlacementData.WorldRotation = worldRotation;
                        objectPlacementData.Prefab        = prefab;
                        objectPlacementDataInstances.Add(objectPlacementData);
                    }
                }
            }

            return(objectPlacementDataInstances);
        }
Пример #20
0
 private void AdjustCornerExlcusionHideFlagsInSegment(ObjectPlacementBoxStackSegment segment)
 {
     segment.GetStackByIndex(0).SetHideFlagForAllBoxes(ObjectPlacementBoxHideFlags.BlockExcludeCorners);
     segment.GetStackByIndex(LastSegment.NumberOfStacks - 1).SetHideFlagForAllBoxes(ObjectPlacementBoxHideFlags.BlockExcludeCorners);
 }
Пример #21
0
 public void AdjustSegmentHeight(ObjectPlacementBoxStackSegment segment, int indexOfFirstStackToAdjust, int desiredHeight)
 {
     segment.SetHeightForStacksStartingAt(indexOfFirstStackToAdjust, desiredHeight);
 }
Пример #22
0
        public List <ObjectPlacementData> Calculate()
        {
            if (_block == null || _block.NumberOfSegments == 0 || !ObjectPlacementGuide.ExistsInScene)
            {
                return(new List <ObjectPlacementData>());
            }

            Prefab     placementGuidePrefab        = ObjectPlacementGuide.Instance.SourcePrefab;
            Vector3    placementGuideWorldScale    = ObjectPlacementGuide.Instance.WorldScale;
            Quaternion placementGuideWorldRotation = ObjectPlacementGuide.Instance.WorldRotation;
            float      objectMissChance            = _block.Settings.ManualConstructionSettings.ObjectMissChance;
            ObjectRotationRandomizationSettings blockObjectRotationRandomizationSettings = _block.Settings.ManualConstructionSettings.ObjectRotationRandomizationSettings;
            bool           randomizeRotations = blockObjectRotationRandomizationSettings.RandomizeRotation;
            Vector3        objectOffsetAlongExtensionPlaneNormal = _block.Settings.ManualConstructionSettings.OffsetAlongGrowDirection * _block.ExtensionPlane.normal;
            bool           allowObjectIntersection = ObjectPlacementSettings.Get().ObjectIntersectionSettings.AllowIntersectionForBlockPlacement;
            bool           randomizePrefabs        = _block.Settings.ManualConstructionSettings.RandomizePrefabs;
            PrefabCategory activePrefabCategory    = PrefabCategoryDatabase.Get().ActivePrefabCategory;

            var objectPlacementDataInstances = new List <ObjectPlacementData>(_block.NumberOfSegments * 10);

            for (int segmentIndex = 0; segmentIndex < _block.NumberOfSegments; ++segmentIndex)
            {
                ObjectPlacementBoxStackSegment segment = _block.GetSegmentByIndex(segmentIndex);
                for (int stackIndex = 0; stackIndex < segment.NumberOfStacks; ++stackIndex)
                {
                    ObjectPlacementBoxStack stack = segment.GetStackByIndex(stackIndex);
                    if (stack.IsOverlappedByAnotherStack)
                    {
                        continue;
                    }

                    for (int stackBoxIndex = 0; stackBoxIndex < stack.NumberOfBoxes; ++stackBoxIndex)
                    {
                        ObjectPlacementBox box = stack.GetBoxByIndex(stackBoxIndex);
                        if (box.IsHidden)
                        {
                            continue;
                        }

                        if (ObjectPlacementMissChance.Missed(objectMissChance, ObjectPlacementBlockManualConstructionSettings.MinObjectMissChance, ObjectPlacementBlockManualConstructionSettings.MaxObjectMissChance))
                        {
                            continue;
                        }

                        if (!allowObjectIntersection && ObjectQueries.IntersectsAnyObjectsInScene(box.OrientedBox, true))
                        {
                            continue;
                        }

                        Quaternion worldRotation = placementGuideWorldRotation;
                        if (randomizeRotations)
                        {
                            worldRotation = ObjectRotationRandomization.GenerateRandomRotationQuaternion(blockObjectRotationRandomizationSettings);
                        }

                        Vector3 worldScale = placementGuideWorldScale;
                        Prefab  prefab     = placementGuidePrefab;
                        if (randomizePrefabs && activePrefabCategory.NumberOfPrefabs != 0)
                        {
                            int    randomPrefabIndex = UnityEngine.Random.Range(0, activePrefabCategory.NumberOfPrefabs);
                            Prefab randomPrefab      = activePrefabCategory.GetPrefabByIndex(randomPrefabIndex);
                            if (randomPrefab != null && randomPrefab.UnityPrefab != null)
                            {
                                prefab     = activePrefabCategory.GetPrefabByIndex(randomPrefabIndex);
                                worldScale = prefab.UnityPrefab.transform.lossyScale;
                            }
                        }

                        var objectPlacementData = new ObjectPlacementData();
                        objectPlacementData.WorldPosition = ObjectPositionCalculator.CalculateObjectHierarchyPosition(prefab, box.Center + objectOffsetAlongExtensionPlaneNormal, worldScale, placementGuideWorldRotation);
                        objectPlacementData.WorldScale    = worldScale;
                        objectPlacementData.WorldRotation = worldRotation;
                        objectPlacementData.Prefab        = prefab;
                        objectPlacementDataInstances.Add(objectPlacementData);
                    }
                }
            }

            return(objectPlacementDataInstances);
        }
Пример #23
0
 public void AdjustSegmentHeight(ObjectPlacementBoxStackSegment segment, int desiredHeight)
 {
     segment.SetHeightForAllStacks(desiredHeight);
 }
Пример #24
0
        public List <ObjectPlacementData> Calculate()
        {
            if (_block == null || _block.NumberOfSegments == 0 || !ObjectPlacementGuide.ExistsInScene)
            {
                return(new List <ObjectPlacementData>());
            }

            Prefab     placementGuidePrefab        = ObjectPlacementGuide.Instance.SourcePrefab;
            Vector3    placementGuideWorldScale    = ObjectPlacementGuide.Instance.WorldScale;
            Quaternion placementGuideWorldRotation = ObjectPlacementGuide.Instance.WorldRotation;
            float      objectMissChance            = _block.Settings.ManualConstructionSettings.ObjectMissChance;
            ObjectRotationRandomizationSettings blockObjectRotationRandomizationSettings = _block.Settings.ManualConstructionSettings.ObjectRotationRandomizationSettings;
            bool           randomizeRotations = blockObjectRotationRandomizationSettings.RandomizeRotation;
            Vector3        objectOffsetAlongExtensionPlaneNormal = _block.Settings.ManualConstructionSettings.OffsetAlongGrowDirection * _block.ExtensionPlane.normal;
            bool           allowObjectIntersection = ObjectPlacementSettings.Get().ObjectIntersectionSettings.AllowIntersectionForBlockPlacement;
            bool           randomizePrefabs        = _block.Settings.ManualConstructionSettings.RandomizePrefabs;
            PrefabCategory activePrefabCategory    = PrefabCategoryDatabase.Get().ActivePrefabCategory;
            ObjectPlacementBlockProjectionSettings projectionSettings = _block.Settings.BlockProjectionSettings;
            bool canProject = projectionSettings.ProjectOnSurface &&
                              (projectionSettings.CanProjectOnMesh || projectionSettings.CanProjectOnTerrain);

            var objectPlacementDataInstances = new List <ObjectPlacementData>(_block.NumberOfSegments * 10);

            for (int segmentIndex = 0; segmentIndex < _block.NumberOfSegments; ++segmentIndex)
            {
                ObjectPlacementBoxStackSegment segment = _block.GetSegmentByIndex(segmentIndex);
                for (int stackIndex = 0; stackIndex < segment.NumberOfStacks; ++stackIndex)
                {
                    ObjectPlacementBoxStack stack = segment.GetStackByIndex(stackIndex);
                    if (stack.IsOverlappedByAnotherStack || stack.NumberOfBoxes == 0)
                    {
                        continue;
                    }

                    Vector3          projectionOffset     = Vector3.zero;
                    Vector3          projectionDirection  = Vector3.zero;
                    Quaternion       prjAlignRotation     = Quaternion.identity;
                    GameObjectRayHit projectionSurfaceHit = null;

                    if (canProject)
                    {
                        Vector3 rayOrigin = stack.GetBoxByIndex(0).Center;
                        Vector3 rayDir    = Vector3.zero;

                        if (projectionSettings.ProjectionDirection == ObjectBlockProjectionDir.BlockUp)
                        {
                            rayDir = _block.ExtensionPlane.normal;
                        }
                        else
                        {
                            rayDir = -_block.ExtensionPlane.normal;
                        }

                        projectionDirection = rayDir;

                        Ray ray = new Ray(rayOrigin, rayDir);
                        GameObjectRayHit closestMeshHit    = null;
                        GameObjectRayHit closestTerrainHit = null;

                        if (projectionSettings.CanProjectOnMesh)
                        {
                            closestMeshHit = Octave3DScene.Get().RaycastAllMeshClosest(ray);
                        }
                        if (projectionSettings.CanProjectOnTerrain)
                        {
                            closestTerrainHit = Octave3DScene.Get().RaycastAllTerainsClosest(ray);
                        }

                        // Ignore stack if no surface was found and non-projectables must be rejected
                        if (closestMeshHit == null && closestTerrainHit == null)
                        {
                            if (projectionSettings.RejectNonProjectables)
                            {
                                continue;
                            }
                        }
                        else
                        {
                            projectionSurfaceHit = closestMeshHit;
                            if (closestMeshHit == null || (closestTerrainHit != null && closestMeshHit.HitEnter > closestTerrainHit.HitEnter))
                            {
                                projectionSurfaceHit = closestTerrainHit;
                            }
                        }

                        if (projectionSurfaceHit != null)
                        {
                            ObjectPlacementBox projectionBox = stack.GetBoxByIndex(0);
                            projectionOffset = projectionSurfaceHit.HitPoint - stack.GetBoxByIndex(0).Center;

                            if (projectionOffset.sqrMagnitude > (projectionSurfaceHit.HitPoint - stack.GetBoxByIndex(stack.NumberOfBoxes - 1).Center).sqrMagnitude)
                            {
                                projectionBox    = stack.GetBoxByIndex(stack.NumberOfBoxes - 1);
                                projectionOffset = projectionSurfaceHit.HitPoint - projectionBox.Center;
                            }

                            if (!projectionSettings.AlignToSurfaceNormal)
                            {
                                var     oobb      = projectionBox.OrientedBox;
                                Vector3 oldCenter = oobb.Center;
                                GameObjectExtensions.EmbedObjectBoxInSurface(oobb, projectionDirection, projectionSurfaceHit.HitObject);
                                projectionOffset = oobb.Center - oldCenter;
                            }
                        }
                    }

                    for (int stackBoxIndex = 0; stackBoxIndex < stack.NumberOfBoxes; ++stackBoxIndex)
                    {
                        ObjectPlacementBox box = stack.GetBoxByIndex(stackBoxIndex);
                        if (box.IsHidden)
                        {
                            continue;
                        }

                        if (ObjectPlacementMissChance.Missed(objectMissChance, ObjectPlacementBlockManualConstructionSettings.MinObjectMissChance,
                                                             ObjectPlacementBlockManualConstructionSettings.MaxObjectMissChance))
                        {
                            continue;
                        }

                        if (!allowObjectIntersection && ObjectQueries.IntersectsAnyObjectsInScene(box.OrientedBox, true))
                        {
                            continue;
                        }

                        Quaternion worldRotation = placementGuideWorldRotation;
                        if (randomizeRotations)
                        {
                            worldRotation = ObjectRotationRandomization.GenerateRandomRotationQuaternion(blockObjectRotationRandomizationSettings);
                        }

                        Vector3 worldScale = placementGuideWorldScale;
                        Prefab  prefab     = placementGuidePrefab;
                        if (randomizePrefabs && activePrefabCategory.NumberOfPrefabs != 0)
                        {
                            int    randomPrefabIndex = UnityEngine.Random.Range(0, activePrefabCategory.NumberOfPrefabs);
                            Prefab randomPrefab      = activePrefabCategory.GetPrefabByIndex(randomPrefabIndex);
                            if (randomPrefab != null && randomPrefab.UnityPrefab != null)
                            {
                                prefab     = activePrefabCategory.GetPrefabByIndex(randomPrefabIndex);
                                worldScale = prefab.UnityPrefab.transform.lossyScale;
                            }
                        }

                        Vector3 boxCenter = box.Center + objectOffsetAlongExtensionPlaneNormal + projectionOffset;
                        if (projectionSurfaceHit != null)
                        {
                            if (projectionSettings.AlignToSurfaceNormal)
                            {
                                worldRotation = AxisAlignment.CalculateRotationQuaternionForAxisAlignment(worldRotation, projectionSettings.AlignmentAxis, projectionSurfaceHit.HitNormal);
                                OrientedBox prefabWorldOOBB = prefab.UnityPrefab.GetHierarchyWorldOrientedBox();
                                Vector3     oobbSize        = prefabWorldOOBB.ScaledSize;
                                int         axisIndex       = (int)((int)(projectionSettings.AlignmentAxis) * 0.5f);
                                boxCenter = projectionSurfaceHit.HitPoint + projectionSurfaceHit.HitNormal * oobbSize[axisIndex] * 0.5f + (oobbSize[axisIndex] * stackBoxIndex * projectionSurfaceHit.HitNormal);
                            }
                        }

                        var objectPlacementData = new ObjectPlacementData();
                        objectPlacementData.WorldPosition = ObjectPositionCalculator.CalculateObjectHierarchyPosition(prefab, boxCenter, worldScale, worldRotation);
                        objectPlacementData.WorldScale    = worldScale;
                        objectPlacementData.WorldRotation = worldRotation;
                        objectPlacementData.Prefab        = prefab;
                        objectPlacementDataInstances.Add(objectPlacementData);
                    }
                }
            }

            return(objectPlacementDataInstances);
        }
        public Quaternion Calculate(ObjectPlacementPathTileConnectionGridCell tileConnectionGridCell)
        {
            ObjectPlacementPath path = tileConnectionGridCell.TileConnectionPath;
            ObjectPlacementPathTileConnectionSettings tileConnectionSettings = path.Settings.TileConnectionSettings;
            Plane extensionPlane = path.ExtensionPlane;
            ObjectPlacementBoxStackSegment tileConnectionSegment = tileConnectionGridCell.TileConnectionSegment;
            ObjectPlacementBoxStack        tileConnectionStack   = tileConnectionGridCell.TileConnectionStack;

            bool       usingSprites           = tileConnectionSettings.UsesSprites();
            float      yAxisRotationInDegrees = ObjectPlacementPathTileConnectionYAxisRotations.GetAngleInDegrees(tileConnectionSettings.GetSettingsForTileConnectionType(tileConnectionGridCell.TileConnectionType).YAxisRotation);
            Quaternion yAxisRotation          = Quaternion.AngleAxis(yAxisRotationInDegrees, extensionPlane.normal);

            Quaternion defaultRotation = Quaternion.LookRotation(path.ExtensionPlaneLookAxis, extensionPlane.normal);

            if (usingSprites)
            {
                defaultRotation = Quaternion.LookRotation(extensionPlane.normal, path.ExtensionPlaneLookAxis);
            }

            ObjectPlacementPathTileConnectionType tileConnectionType = tileConnectionGridCell.TileConnectionType;

            if (tileConnectionType == ObjectPlacementPathTileConnectionType.Autofill)
            {
                return(yAxisRotation * defaultRotation);
            }
            else
            if (tileConnectionType == ObjectPlacementPathTileConnectionType.Begin)
            {
                if (tileConnectionGridCell.NumberOfNeighbours == 0)
                {
                    return(yAxisRotation * defaultRotation);
                }
                else
                {
                    ObjectPlacementBoxStack neighbour = tileConnectionGridCell.GetFirstNeighbour().TileConnectionStack;
                    Vector3 toNeighbour = tileConnectionStack.GetNormalizedBasePositionConnectionVectorTo(neighbour);

                    if (usingSprites)
                    {
                        return(yAxisRotation * Quaternion.LookRotation(extensionPlane.normal, toNeighbour));
                    }
                    return(yAxisRotation * Quaternion.LookRotation(toNeighbour, extensionPlane.normal));
                }
            }
            else if (tileConnectionType == ObjectPlacementPathTileConnectionType.End)
            {
                ObjectPlacementBoxStack neighbour = tileConnectionGridCell.GetFirstNeighbour().TileConnectionStack;
                Vector3 toEndTile = neighbour.GetNormalizedBasePositionConnectionVectorTo(tileConnectionStack);

                if (usingSprites)
                {
                    return(yAxisRotation * Quaternion.LookRotation(extensionPlane.normal, toEndTile));
                }
                return(yAxisRotation * Quaternion.LookRotation(toEndTile, extensionPlane.normal));
            }
            else
            if (tileConnectionType == ObjectPlacementPathTileConnectionType.Cross)
            {
                return(yAxisRotation * defaultRotation);
            }
            else
            if (tileConnectionType == ObjectPlacementPathTileConnectionType.TJunction)
            {
                ObjectPlacementBoxStack baseOfTJunction = null;
                if (tileConnectionGridCell.RightNeighbour != null && tileConnectionGridCell.LeftNeighbour != null)
                {
                    baseOfTJunction = tileConnectionGridCell.ForwardNeighbour != null ? tileConnectionGridCell.ForwardNeighbour.TileConnectionStack : tileConnectionGridCell.BackNeighbour.TileConnectionStack;
                }
                else
                {
                    baseOfTJunction = tileConnectionGridCell.RightNeighbour != null ? tileConnectionGridCell.RightNeighbour.TileConnectionStack : tileConnectionGridCell.LeftNeighbour.TileConnectionStack;
                }

                Vector3 toTJunction = baseOfTJunction.GetNormalizedBasePositionConnectionVectorTo(tileConnectionStack);

                if (usingSprites)
                {
                    return(yAxisRotation * Quaternion.LookRotation(extensionPlane.normal, toTJunction));
                }
                return(yAxisRotation * Quaternion.LookRotation(toTJunction, extensionPlane.normal));
            }
            else
            if (tileConnectionType == ObjectPlacementPathTileConnectionType.Forward)
            {
                if (tileConnectionSegment.NumberOfStacks == 1)
                {
                    if (tileConnectionGridCell.HasForwardAndBackNeightbours())
                    {
                        ObjectPlacementBoxStack forwardNeighbour = tileConnectionGridCell.ForwardNeighbour.TileConnectionStack;
                        ObjectPlacementBoxStack backNeighbour    = tileConnectionGridCell.BackNeighbour.TileConnectionStack;
                        Vector3 toForwardNeighbour = backNeighbour.GetNormalizedBasePositionConnectionVectorTo(forwardNeighbour);

                        if (usingSprites)
                        {
                            return(yAxisRotation * Quaternion.LookRotation(extensionPlane.normal, toForwardNeighbour));
                        }
                        return(yAxisRotation * Quaternion.LookRotation(toForwardNeighbour, extensionPlane.normal));
                    }
                    else
                    {
                        ObjectPlacementBoxStack leftNeighbour  = tileConnectionGridCell.LeftNeighbour.TileConnectionStack;
                        ObjectPlacementBoxStack rightNeighbour = tileConnectionGridCell.RightNeighbour.TileConnectionStack;
                        Vector3 toRightNeighbour = leftNeighbour.GetNormalizedBasePositionConnectionVectorTo(rightNeighbour);

                        if (usingSprites)
                        {
                            return(yAxisRotation * Quaternion.LookRotation(extensionPlane.normal, toRightNeighbour));
                        }
                        return(yAxisRotation * Quaternion.LookRotation(toRightNeighbour, extensionPlane.normal));
                    }
                }
                else
                {
                    if (usingSprites)
                    {
                        return(yAxisRotation * Quaternion.LookRotation(extensionPlane.normal, tileConnectionSegment.ExtensionDirection));
                    }
                    return(yAxisRotation * Quaternion.LookRotation(tileConnectionSegment.ExtensionDirection, extensionPlane.normal));
                }
            }
            else
            {
                ObjectPlacementBoxStack firstNeighbour, secondNeighbour;
                if (tileConnectionGridCell.RightNeighbour != null)
                {
                    firstNeighbour  = tileConnectionGridCell.RightNeighbour.TileConnectionStack;
                    secondNeighbour = tileConnectionGridCell.ForwardNeighbour != null ? tileConnectionGridCell.ForwardNeighbour.TileConnectionStack : tileConnectionGridCell.BackNeighbour.TileConnectionStack;
                }
                else
                if (tileConnectionGridCell.LeftNeighbour != null)
                {
                    firstNeighbour  = tileConnectionGridCell.LeftNeighbour.TileConnectionStack;
                    secondNeighbour = tileConnectionGridCell.ForwardNeighbour != null ? tileConnectionGridCell.ForwardNeighbour.TileConnectionStack : tileConnectionGridCell.BackNeighbour.TileConnectionStack;
                }
                else
                if (tileConnectionGridCell.ForwardNeighbour != null)
                {
                    firstNeighbour  = tileConnectionGridCell.ForwardNeighbour.TileConnectionStack;
                    secondNeighbour = tileConnectionGridCell.RightNeighbour != null ? tileConnectionGridCell.RightNeighbour.TileConnectionStack : tileConnectionGridCell.LeftNeighbour.TileConnectionStack;
                }
                else
                {
                    firstNeighbour  = tileConnectionGridCell.BackNeighbour.TileConnectionStack;
                    secondNeighbour = tileConnectionGridCell.RightNeighbour != null ? tileConnectionGridCell.RightNeighbour.TileConnectionStack : tileConnectionGridCell.LeftNeighbour.TileConnectionStack;
                }

                Vector3 tileLook, tileRight;
                tileLook  = firstNeighbour.GetNormalizedBasePositionConnectionVectorTo(tileConnectionStack);
                tileRight = tileConnectionStack.GetNormalizedBasePositionConnectionVectorTo(secondNeighbour);

                Vector3 tileUp = Vector3.Cross(tileLook, tileRight);
                if (Vector3.Dot(tileUp, extensionPlane.normal) < 0.0f)
                {
                    tileLook = -tileRight;
                }

                if (usingSprites)
                {
                    return(yAxisRotation * Quaternion.LookRotation(extensionPlane.normal, tileLook));
                }
                return(yAxisRotation * Quaternion.LookRotation(tileLook, extensionPlane.normal));
            }
        }
Пример #26
0
        public void ConnectFirstStackToFirstStackInSegment(ObjectPlacementBoxStackSegment destinationSegment, Vector3 connectionOffset)
        {
            Vector3 newFirstStackBasePos = destinationSegment.FirstStackBasePosition + connectionOffset;

            SetFirstStackBasePosition(newFirstStackBasePos);
        }
        public void AdjustSegmentHeight(ObjectPlacementBoxStackSegment segment, ObjectPlacementPathAutomaticRandomHeightAdjustmentSettings automaticRandomHeightAdjustmentSettings)
        {
            Range <int> randomValueRange = new Range <int>(automaticRandomHeightAdjustmentSettings.MinHeight, automaticRandomHeightAdjustmentSettings.MaxHeight);

            segment.SetHeightForAllStacks(RandomValueGeneration.GenerateIntRandomValuesInRange(randomValueRange, segment.NumberOfStacks));
        }