public List <ObjectPlacementData> Calculate() { if (!ValidatePlacementDataCalculationConditions()) { return(new List <ObjectPlacementData>()); } _allowObjectIntersection = ObjectPlacementSettings.Get().ObjectIntersectionSettings.AllowIntersectionForPathPlacement; List <ObjectPlacementBoxStackSegment> allPathSegments = _path.GetAllSegments(); float objectMissChance = _path.Settings.ManualConstructionSettings.ObjectMissChance; bool usingSprites = _path.Settings.TileConnectionSettings.UsesSprites(); var tileConnectionDetector = new ObjectPlacementPathTileConnectionDetector(); var tileConnectionRotationCalculator = new ObjectPlacementPathTileConnectionRotationCalculator(); List <ObjectPlacementPathTileConnectionGridCell> tileConnectionGridCells = tileConnectionDetector.Detect(_path, _tileConnectionXZSize); if (tileConnectionGridCells.Count == 0) { return(new List <ObjectPlacementData>()); } List <Prefab> tileConnectionPrefabsExceptAutofill = PathObjectPlacement.Get().PathSettings.TileConnectionSettings.GetAllTileConnectionPrefabs(true); List <Vector3> tileConnectionWorldScaleValuesExceptAutofill = CalculateWorldScaleForAllTileConnectionPrefabsExceptAutofill(PrefabQueries.GetTransformsForAllPrefabs(tileConnectionPrefabsExceptAutofill), PrefabQueries.GetHierarchyWorldOrientedBoxesForAllPrefabs(tileConnectionPrefabsExceptAutofill)); List <Vector3> tileConnectionOffsetsExceptAutofill = CalculateOffsetsForAllTileConnectionsExceptAutofill(); var objectPlacementDataInstances = new List <ObjectPlacementData>(allPathSegments.Count * 10); foreach (ObjectPlacementPathTileConnectionGridCell tileConnectionGridCell in tileConnectionGridCells) { ObjectPlacementPathTileConnectionType tileConnectionType = tileConnectionGridCell.TileConnectionType; ObjectPlacementBoxStack tileConnectionStack = tileConnectionGridCell.TileConnectionStack; if (tileConnectionStack.IsOverlappedByAnotherStack) { continue; } Prefab tileConnectionPrefab = tileConnectionPrefabsExceptAutofill[(int)tileConnectionType]; Quaternion tileConnectionRotation = tileConnectionRotationCalculator.Calculate(tileConnectionGridCell); Vector3 tileConnectionWorldScale = tileConnectionWorldScaleValuesExceptAutofill[(int)tileConnectionType]; Vector3 tileConnectionOffset = tileConnectionOffsetsExceptAutofill[(int)tileConnectionType]; for (int stackBoxIndex = 0; stackBoxIndex < tileConnectionStack.NumberOfBoxes; ++stackBoxIndex) { ObjectPlacementBox box = tileConnectionStack.GetBoxByIndex(stackBoxIndex); if (box.IsHidden) { continue; } if (ObjectPlacementMissChance.Missed(objectMissChance, ObjectPlacementPathManualConstructionSettings.MinObjectMissChance, ObjectPlacementPathManualConstructionSettings.MaxObjectMissChance)) { continue; } if (!_allowObjectIntersection && ObjectQueries.IntersectsAnyObjectsInScene(box.OrientedBox, true)) { continue; } var objectPlacementData = new ObjectPlacementData(); objectPlacementData.WorldPosition = ObjectPositionCalculator.CalculateObjectHierarchyPosition(tileConnectionPrefab, box.Center, tileConnectionWorldScale, tileConnectionRotation); objectPlacementData.WorldPosition += tileConnectionOffset; objectPlacementData.WorldScale = tileConnectionWorldScale; objectPlacementData.WorldRotation = tileConnectionRotation; objectPlacementData.Prefab = tileConnectionPrefab; objectPlacementDataInstances.Add(objectPlacementData); } // Apply extrusion if necessary if (!usingSprites) { List <OrientedBox> extrusionOrientedBoxes = ObjectPlacementPathTileConnectionExtrusion.GetTileConnectionExtrusionOrientedBoxes(tileConnectionGridCell); foreach (OrientedBox extrusionBox in extrusionOrientedBoxes) { if (ObjectPlacementMissChance.Missed(objectMissChance, ObjectPlacementPathManualConstructionSettings.MinObjectMissChance, ObjectPlacementPathManualConstructionSettings.MaxObjectMissChance)) { continue; } if (!_allowObjectIntersection && ObjectQueries.IntersectsAnyObjectsInScene(extrusionBox, true)) { continue; } var objectPlacementData = new ObjectPlacementData(); objectPlacementData.WorldPosition = ObjectPositionCalculator.CalculateObjectHierarchyPosition(tileConnectionPrefab, extrusionBox.Center, tileConnectionWorldScale, tileConnectionRotation); objectPlacementData.WorldScale = tileConnectionWorldScale; objectPlacementData.WorldRotation = tileConnectionRotation; objectPlacementData.Prefab = tileConnectionPrefab; objectPlacementDataInstances.Add(objectPlacementData); } } } ObjectPlacementPathTileConnectionSettings tileConnectionSettings = _path.Settings.TileConnectionSettings; if (tileConnectionSettings.DoesAutofillTileConnectionHavePrefabAssociated()) { objectPlacementDataInstances.AddRange(GetPlacementDataForAutofillTiles(tileConnectionGridCells[0].ParentGrid)); } return(objectPlacementDataInstances); }
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); }