private List <Vector3> CalculateOffsetsForAllTileConnectionsExceptAutofill() { var offsets = new List <Vector3>(ObjectPlacementPathTileConnectionTypes.Count); ObjectPlacementPathTileConnectionSettings tileConnectionSettings = _path.Settings.TileConnectionSettings; var tileConnectionYOffsetVectorCalculator = new ObjectPlacementPathTileConnectionYOffsetVectorCalculator(); List <ObjectPlacementPathTileConnectionType> allTileConnectionTypes = ObjectPlacementPathTileConnectionTypes.GetAllExceptAutofill(); foreach (ObjectPlacementPathTileConnectionType tileConnectionType in allTileConnectionTypes) { offsets.Add(tileConnectionYOffsetVectorCalculator.Calculate(tileConnectionSettings.GetSettingsForTileConnectionType(tileConnectionType), _path)); } return(offsets); }
private void RenderSetCommonYAxisRotationButton() { if (GUILayout.Button(GetContentForSetCommonYAxisRotationButton(), GUILayout.Width(_setCommonTilePropertyButtonWidth))) { List <ObjectPlacementPathTileConnectionType> allTileConnectionTypes = ObjectPlacementPathTileConnectionTypes.GetAll(); foreach (ObjectPlacementPathTileConnectionType tileConnectionType in allTileConnectionTypes) { UndoEx.RecordForToolAction(_settings.GetSettingsForTileConnectionType(tileConnectionType)); _settings.GetSettingsForTileConnectionType(tileConnectionType).YAxisRotation = _settings.CommonYAxisRotation; } } }
public void ApplyConfigurationDataToSettings(ObjectPlacementPathTileConnectionSettings tileConnectionSettings) { List <ObjectPlacementPathTileConnectionType> allTileConnectionTypes = ObjectPlacementPathTileConnectionTypes.GetAll(); foreach (ObjectPlacementPathTileConnectionType tileConnectionType in allTileConnectionTypes) { int tileConnectionIndex = (int)tileConnectionType; ObjectPlacementPathTileConnectionTypeSettings tileConnectionTypeSettings = tileConnectionSettings.GetSettingsForTileConnectionType(tileConnectionType); tileConnectionTypeSettings.YAxisRotation = _tileConnectionYAxisRotations[tileConnectionIndex]; tileConnectionTypeSettings.YOffset = _tileConnectionYOffsets[tileConnectionIndex]; tileConnectionTypeSettings.UpwardsExtrusionAmount = _tileConnectionUpwardsExtrusionAmount[tileConnectionIndex]; tileConnectionTypeSettings.DownwardsExtrusionAmount = _tileConnectionDownwardsExtrusionAmount[tileConnectionIndex]; tileConnectionTypeSettings.Prefab = _tileConnectionPrefabs[tileConnectionIndex]; } }
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)); } }
private void RenderPathUnderManualConstructionWhenUsingTileConnections(ObjectPlacementPath path, ObjectPlacementPathTileConnectionSettings tileConnectionSettings) { List <ObjectPlacementPathTileConnectionGridCell> tileConnectionGridCells = path.TileConnectionGridCells; ObjectPlacementPathManualConstructionRenderSettings renderSettings = path.RenderSettings.ManualConstructionRenderSettings; var tileConnectionYOffsetVectorCalculator = new ObjectPlacementPathTileConnectionYOffsetVectorCalculator(); // Loop through all tile connection grid cells. Each cell will give us access to all the information // that we need to perform the rendering operation. foreach (ObjectPlacementPathTileConnectionGridCell tileConnectionGridCell in tileConnectionGridCells) { // Use the cell to access the tile connection stack. If the stack is overlapped by another stack // or if no boxes exist in the stack, we can move on to the next cell. ObjectPlacementBoxStack tileConnectionStack = tileConnectionGridCell.TileConnectionStack; if (tileConnectionStack.IsOverlappedByAnotherStack || tileConnectionStack.NumberOfBoxes == 0) { continue; } // Calculate the Y offset vector which applies to all tiles in the current stack and then render each // box which resides inside the stack. Vector3 tileConnectionYOffsetVector = tileConnectionYOffsetVectorCalculator.Calculate(tileConnectionSettings.GetSettingsForTileConnectionType(tileConnectionGridCell.TileConnectionType), path); for (int boxIndex = 0; boxIndex < tileConnectionStack.NumberOfBoxes; ++boxIndex) { // If the box is hidden, we can move on to the next box ObjectPlacementBox placementBox = tileConnectionStack.GetBoxByIndex(boxIndex); if (placementBox.IsHidden) { continue; } // Retrieve the box and apply the Y offset vector. The render the box. OrientedBox orientedBox = placementBox.OrientedBox; orientedBox.Center += tileConnectionYOffsetVector; GizmosEx.RenderOrientedBoxEdges(orientedBox, renderSettings.BoxBorderLineColor); } // We have to take tile connection extrusion into account, so we will need to retrieve the extrusion // boxes and render those too. List <OrientedBox> extrusionOrientedBoxes = ObjectPlacementPathTileConnectionExtrusion.GetTileConnectionExtrusionOrientedBoxes(tileConnectionGridCell); foreach (OrientedBox extrusionBox in extrusionOrientedBoxes) { GizmosEx.RenderOrientedBoxEdges(extrusionBox, renderSettings.BoxBorderLineColor); } } }
private void UpdateTileConnectionInformation() { List <ObjectPlacementPathTileConnectionGridCell> tileConnectionGridCells = _tileConnectionDetector.Detect(_path, _tileConnectionXZSize); if (tileConnectionGridCells.Count == 0) { return; } _tileConnectionGridCells.Clear(); _tileConnectionGridCells.AddRange(tileConnectionGridCells); bool usingSprites = _pathSettings.TileConnectionSettings.UsesSprites(); List <OrientedBox> tileConnectionPrefabWorldOrientedBoxesExceptAutofill = PrefabQueries.GetHierarchyWorldOrientedBoxesForAllPrefabs(_tileConnectionSettings.GetAllTileConnectionPrefabs(true)); foreach (ObjectPlacementPathTileConnectionGridCell tileConnectionGridCell in _tileConnectionGridCells) { ObjectPlacementPathTileConnectionTypeSettings tileConnectionTypeSettings = _tileConnectionSettings.GetSettingsForTileConnectionType(tileConnectionGridCell.TileConnectionType); tileConnectionGridCell.TileConnectionStack.SetBoxSize(GetTileConnectionSize(tileConnectionPrefabWorldOrientedBoxesExceptAutofill[(int)tileConnectionTypeSettings.TileConnectionType], usingSprites)); tileConnectionGridCell.TileConnectionStack.PlaceOnPlane(_pathExtensionPlane.Plane); } }
public List <ObjectPlacementPathTileConnectionGridCell> CreateAndReturnAutofillTileConnectionCells() { ObjectPlacementPathTileConnectionSettings tileConnectionSettings = _path.Settings.TileConnectionSettings; if (!tileConnectionSettings.DoesAutofillTileConnectionHavePrefabAssociated()) { return(new List <ObjectPlacementPathTileConnectionGridCell>()); } Plane pathExtensionPlane = _path.ExtensionPlane; OrientedBox autofillPrefabOrientedBox = tileConnectionSettings.GetSettingsForTileConnectionType(ObjectPlacementPathTileConnectionType.Autofill).Prefab.UnityPrefab.GetHierarchyWorldOrientedBox(); Vector3 autofillStackBoxSize = new Vector3(_cellXZSize, autofillPrefabOrientedBox.ScaledSize.y, _cellXZSize); Quaternion autofillStackRotation = Quaternion.LookRotation(_path.ExtensionPlaneLookAxis, pathExtensionPlane.normal); bool[,] cellAutofillFlags = new bool[NumberOfCellsOnX, NumberOfCellsOnZ]; // We will first set all occupied cells to true foreach (var pair in _occupiedCells) { cellAutofillFlags[pair.Key.XIndex - MinCellIndexX, pair.Key.ZIndex - MinCellIndexZ] = true; } var autofillGridCells = new List <ObjectPlacementPathTileConnectionGridCell>(NumberOfCellsOnX * NumberOfCellsOnZ); for (int z = MinCellIndexZ; z <= MaxCellIndexZ; ++z) { for (int x = MinCellIndexX; x <= MaxCellIndexX; ++x) { if (cellAutofillFlags[x - MinCellIndexX, z - MinCellIndexZ]) { continue; } var traversedIndices = new HashSet <ObjectPlacementPathTileConnectionGridCellIndices>(); if (DetectCellsWhichLeadOutsideOfGridRecurse(cellAutofillFlags, x, z, traversedIndices)) { foreach (ObjectPlacementPathTileConnectionGridCellIndices indices in traversedIndices) { cellAutofillFlags[indices.XIndex - MinCellIndexX, indices.ZIndex - MinCellIndexZ] = true; } } if (!cellAutofillFlags[x - MinCellIndexX, z - MinCellIndexZ]) { var autofillGridCell = new ObjectPlacementPathTileConnectionGridCell(new ObjectPlacementPathTileConnectionGridCellIndices(x, z), this); autofillGridCells.Add(autofillGridCell); AddCell(autofillGridCell); var tileConnectionStack = new ObjectPlacementBoxStack(); tileConnectionStack.SetBoxSize(autofillStackBoxSize); tileConnectionStack.SetRotation(autofillStackRotation); tileConnectionStack.SetBasePosition(CalculateCellPosition(x, z)); tileConnectionStack.PlaceOnPlane(pathExtensionPlane); tileConnectionStack.GrowUpwards(1); autofillGridCell.TileConnectionStack = tileConnectionStack; autofillGridCell.TileConnectionPath = _path; autofillGridCell.TileConnectionType = ObjectPlacementPathTileConnectionType.Autofill; } } } return(autofillGridCells); }
private static void EnsureGuideUsesBeginTileConnectionPrefab() { ObjectPlacementPathTileConnectionSettings tileConnectionSettings = ObjectPlacement.Get().PathObjectPlacement.PathSettings.TileConnectionSettings; ObjectPlacementPathTileConnectionTypeSettings beginTileConnectionSettings = tileConnectionSettings.GetSettingsForTileConnectionType(ObjectPlacementPathTileConnectionType.Begin); if (CanRefreshGuideToUseBeginTileConnectionPrefab(beginTileConnectionSettings)) { PrefabCategory categoryWhichContainsBeginPrefab = PrefabCategoryDatabase.Get().GetPrefabCategoryWhichContainsPrefab(beginTileConnectionSettings.Prefab); if (categoryWhichContainsBeginPrefab == null) { return; } PrefabCategoryDatabase.Get().SetActivePrefabCategory(categoryWhichContainsBeginPrefab); categoryWhichContainsBeginPrefab.SetActivePrefab(beginTileConnectionSettings.Prefab); ObjectPlacement.Get().DestroyPlacementGuide(); ObjectPlacementGuide.CreateFromActivePrefabIfNotExists(); } // Note: When using tile connections, we will always use the original prefab scale if (ObjectPlacementGuide.ExistsInScene) { ObjectPlacementGuide.Instance.WorldScale = beginTileConnectionSettings.Prefab.InitialWorldScale; } }