Exemple #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);
        }