private void CreateFirst2Segments() { CreateNewSegment(); CreateNewSegment(); PenultimateSegment.SetFirstStackBasePosition(_startObjectHierarchyWorldOrientedBox.Center); PenultimateSegment.SetExtensionDirection(_pathExtensionPlane.LookAxis); PenultimateSegment.Extend(1); AdjustHeightForEntireSegment(PenultimateSegment); }
private void CreateFirst2Segments() { CreateNewSegment(); CreateNewSegment(); Vector3 camLookAxis = SceneViewCamera.Camera.transform.forward; Vector3 penultimateSegmentDir = _pathExtensionPlane.LookAxis; if (Mathf.Abs(Vector3.Dot(camLookAxis, _pathExtensionPlane.LookAxis)) < Mathf.Abs(Vector3.Dot(camLookAxis, _pathExtensionPlane.RightAxis))) { penultimateSegmentDir = _pathExtensionPlane.RightAxis; } PenultimateSegment.SetFirstStackBasePosition(_startObjectHierarchyWorldOrientedBox.Center); PenultimateSegment.SetExtensionDirection(penultimateSegmentDir); PenultimateSegment.Extend(1); AdjustHeightForEntireSegment(PenultimateSegment); }
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(); } }