Exemplo n.º 1
0
        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);
        }
Exemplo n.º 2
0
        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);
        }