예제 #1
0
        public List <ObjectPlacementPathTileConnectionGridCell> Detect(ObjectPlacementPath path, float tileXZSize)
        {
            _tileXZSize = tileXZSize;

            List <ObjectPlacementBoxStackSegment> allPathSegments = path.GetAllSegments();

            if (allPathSegments.Count == 0)
            {
                return(new List <ObjectPlacementPathTileConnectionGridCell>());
            }

            // Create the grid cell instances which are occupied by tiles
            Vector3 gridOrigin         = path.ExtensionPlane.ProjectPoint(allPathSegments[0].GetStackByIndex(0).BasePosition);
            var     tileConnectionGrid = new ObjectPlacementPathTileConnectionGrid(_tileXZSize, gridOrigin, path);

            foreach (ObjectPlacementBoxStackSegment segment in allPathSegments)
            {
                for (int stackIndex = 0; stackIndex < segment.NumberOfStacks; ++stackIndex)
                {
                    ObjectPlacementBoxStack stack = segment.GetStackByIndex(stackIndex);
                    if (stack.IsOverlappedByAnotherStack)
                    {
                        continue;
                    }

                    var tileConnectionGridCell = new ObjectPlacementPathTileConnectionGridCell(tileConnectionGrid.CalculateCellIndicesFromPosition(stack.BasePosition), tileConnectionGrid);
                    tileConnectionGridCell.TileConnectionSegment = segment;
                    tileConnectionGridCell.TileConnectionStack   = stack;
                    tileConnectionGridCell.TileConnectionPath    = path;

                    if (!tileConnectionGrid.IsCellOccupied(tileConnectionGridCell.CellIndices))
                    {
                        tileConnectionGrid.AddCell(tileConnectionGridCell);
                    }
                }
            }

            tileConnectionGrid.EstablishCellNeighbours();
            tileConnectionGrid.DetectTileConnectionTypesForAllOccupiedCells();

            return(tileConnectionGrid.OccupiedTileConnectionCells);
        }
 public ObjectPlacementPathTileConnectionGridCell(ObjectPlacementPathTileConnectionGridCellIndices cellIndices, ObjectPlacementPathTileConnectionGrid parentGrid)
 {
     _cellIndices = cellIndices;
     _parentGrid  = parentGrid;
 }
예제 #3
0
        private List <ObjectPlacementData> GetPlacementDataForAutofillTiles(ObjectPlacementPathTileConnectionGrid tileConnectionGrid)
        {
            Prefab      autofillPrefab = _path.Settings.TileConnectionSettings.GetSettingsForTileConnectionType(ObjectPlacementPathTileConnectionType.Autofill).Prefab;
            OrientedBox autoFillPrefabWorldOrientedBox = autofillPrefab.UnityPrefab.GetHierarchyWorldOrientedBox();
            Vector3     autofillPrefabBoxSize          = autoFillPrefabWorldOrientedBox.ScaledSize;
            Plane       extensionPlane   = _path.ExtensionPlane;
            float       objectMissChance = _path.Settings.ManualConstructionSettings.ObjectMissChance;
            bool        usingSprites     = _path.Settings.TileConnectionSettings.UsesSprites();

            var     tileConnectionScaleCalculator         = new ObjectPlacementPathTileConnectionScaleCalculator();
            var     tileConnectionYOffsetVectorCalculator = new ObjectPlacementPathTileConnectionYOffsetVectorCalculator();
            Vector3 worldScale    = tileConnectionScaleCalculator.CalculateWorldScale(_tileConnectionXZSize, autofillPrefabBoxSize, autofillPrefab.UnityPrefab.transform, _path);
            Vector3 yOffsetVector = tileConnectionYOffsetVectorCalculator.Calculate(_path.Settings.TileConnectionSettings.GetSettingsForTileConnectionType(ObjectPlacementPathTileConnectionType.Autofill), _path);

            List <ObjectPlacementPathTileConnectionGridCell> autoFillTileConnectionGridCells = tileConnectionGrid.CreateAndReturnAutofillTileConnectionCells();

            if (autoFillTileConnectionGridCells.Count == 0)
            {
                return(new List <ObjectPlacementData>());
            }

            // Note: All autofill tiles have the same rotation.
            Quaternion worldRotation = (new ObjectPlacementPathTileConnectionRotationCalculator()).Calculate(autoFillTileConnectionGridCells[0]);
            var        objectPlacementDataInstances = new List <ObjectPlacementData>(autoFillTileConnectionGridCells.Count);

            foreach (ObjectPlacementPathTileConnectionGridCell autofillGridCell in autoFillTileConnectionGridCells)
            {
                if (ObjectPlacementMissChance.Missed(objectMissChance, ObjectPlacementPathManualConstructionSettings.MinObjectMissChance, ObjectPlacementPathManualConstructionSettings.MaxObjectMissChance))
                {
                    continue;
                }

                Vector3 cellPosition = tileConnectionGrid.CalculateCellPosition(autofillGridCell.CellIndices);
                Vector3 cellPositionOnPathExtensionPlane = extensionPlane.ProjectPoint(cellPosition);

                OrientedBox tileOrientedBox = new OrientedBox(autoFillPrefabWorldOrientedBox);
                tileOrientedBox.Center   = cellPositionOnPathExtensionPlane + extensionPlane.normal * (usingSprites ? 0.0f : autofillPrefabBoxSize.y * 0.5f);
                tileOrientedBox.Rotation = worldRotation;
                tileOrientedBox.Scale    = worldScale;
                if (!_allowObjectIntersection && ObjectQueries.IntersectsAnyObjectsInScene(tileOrientedBox, true))
                {
                    continue;
                }

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

                // Apply extrusion if necessary
                if (!usingSprites)
                {
                    List <OrientedBox> extrusionOrientedBoxes = ObjectPlacementPathTileConnectionExtrusion.GetTileConnectionExtrusionOrientedBoxes(autofillGridCell);
                    foreach (OrientedBox extrusionBox in extrusionOrientedBoxes)
                    {
                        if (ObjectPlacementMissChance.Missed(objectMissChance, ObjectPlacementPathManualConstructionSettings.MinObjectMissChance, ObjectPlacementPathManualConstructionSettings.MaxObjectMissChance))
                        {
                            continue;
                        }
                        if (!_allowObjectIntersection && ObjectQueries.IntersectsAnyObjectsInScene(extrusionBox, true))
                        {
                            continue;
                        }

                        objectPlacementData = new ObjectPlacementData();
                        objectPlacementData.WorldPosition = ObjectPositionCalculator.CalculateObjectHierarchyPosition(autofillPrefab, extrusionBox.Center, worldScale, worldRotation);
                        objectPlacementData.WorldScale    = worldScale;
                        objectPlacementData.WorldRotation = worldRotation;
                        objectPlacementData.Prefab        = autofillPrefab;
                        objectPlacementDataInstances.Add(objectPlacementData);
                    }
                }
            }

            return(objectPlacementDataInstances);
        }