private bool PlacableFilter(Vector4 Position)
        {
            Vector3 Extends = new Vector3(OriginPlacable.MinScale, OriginPlacable.MinScale, OriginPlacable.MinScale);              // check extends
            bool    ConnectionPointOverlap = false;

            ModularPieceExtensions.ForEachOverlapping <ModularConnectionPoint>(new Vector3(Position.x, Position.y, Position.z), Extends, GameManager.I.Modular.ModularPieceTempLayer + GameManager.I.Modular.ModularPieceLayer, (ModularConnectionPoint Point) => {
                ConnectionPointOverlap = true;
            });

            return(Mathf.Round(Position.w) <= 0f && !ConnectionPointOverlap);
        }
        private bool[] CheckForConnection(Vector3 Point, Vector3[] Directions, Quaternion Rotation)
        {
            Point.y += 0.05F;
            Vector3[]             CheckDirections  = ModularPieceExtensions.DirectionToWorldDirection(Directions, Rotation); // calculate check vectors
            ConnectionDirection[] CheckConnections = ModularPieceExtensions.VectorsToDirections(CheckDirections);            // calculate check connections
            bool[] Results = new bool[CheckDirections.Length];

            for (int i = 0; i < Results.Length; i++)               // check for connections
            {
                Results[i] = ModularPieceExtensions.CheckForConnection(Point, OriginPlacable.Scale, OriginPlacable.StrokeCategory, CheckDirections[i], CheckConnections[i], GameManager.I.Modular.ModularPieceTempLayer + GameManager.I.Modular.ModularPieceLayer) != null;
            }

            return(Results);
        }
        private Vector4[] ForEachStrokePoint(System.Action <Vector4, StrokeType, Quaternion> ForEachPoint, System.Action <GameObject> ForEachOverlapping, System.Action <Vector4, StrokeType, Quaternion> ForEachNewlyPlaced = null)
        {
            // Step 1 calculate snap points
            Vector4[] SnapPoints = CalculateWorldSnapPositions(StrokeStartPos, MousePosition, Distance, (Vector4 Vector) => {
                return(Vector);
            }, true, GameManager.I.Constants.TerrainLayer);

            // Step 2 Calculate initial data
            Vector3 RealDirection = (SnapPoints [SnapPoints.Length - 1] - SnapPoints [0]).normalized;

            RealDirection.y = 0;
            Quaternion Rotation = ModularPieceExtensions.LookRotation(RealDirection);

            // Step 3 calculate surrounding data
            Vector3[] SurroundingData  = new Vector3[(SnapPoints.Length * 3) + 2];             // init position temp array
            bool[]    SurroundingBools = new bool[(SnapPoints.Length * 3) + 2];                // init bool temp array
            UpdateConnection(SnapPoints, Rotation, ref SurroundingData, ref SurroundingBools); // update connection arrays

            // Step 4 - 5 hide overlapping pieces / calculate draw data
            for (int i = 0; i < SnapPoints.Length; i++)
            {
                int  PointIndex  = 2 + (i * 3);
                bool Overlapping = false;

                // invoke
                ModularPieceExtensions.ForEachOverlapping <StrokeModularPiece>(SnapPoints[i], new Vector3(OriginPlacable.MinScale, OriginPlacable.MinScale, OriginPlacable.MinScale), GameManager.I.Modular.ModularPieceTempLayer + GameManager.I.Modular.ModularPieceLayer, (StrokeModularPiece Piece) => {
                    if (Piece.StrokeCategory == OriginPlacable.StrokeCategory)
                    {
                        ForEachOverlapping.Invoke(Piece.gameObject);                         // invoke overlapping item
                        if (!Overlapping)
                        {
                            Overlapping = true;
                        }                                                              // is overlapping
                    }
                });
                ModularPieceExtensions.GetStrokeStateInformation(SnapPoints [i], OriginPlacable.Scale, GetConnectionsOfPoint(PointIndex, Rotation, ref SurroundingBools), OriginSetData, (bool Could, StrokeType Type, int YRotation) => {
                    ForEachPoint.Invoke(SnapPoints[i], Type, Quaternion.Euler(0, YRotation, 0));
                    if (!Overlapping && ForEachNewlyPlaced != null)
                    {
                        ForEachNewlyPlaced.Invoke(SnapPoints[i], Type, Quaternion.Euler(0, YRotation, 0));
                    }
                });
            }
            return(SnapPoints);
        }
        private ConnectionDirection[] GetConnectionsOfPoint(int Index, Quaternion Rotation, ref bool[] SurroundingBools)
        {
            List <ConnectionDirection> Connections = new List <ConnectionDirection> ();

            // Add connections
            if (SurroundingBools [Index + 1])
            {
                Connections.Add(ConnectionDirection.Left);
            }                                                                                           // Add Left
            if (SurroundingBools [Index - 1])
            {
                Connections.Add(ConnectionDirection.Right);
            }                                                                                            // Add Right
            if (SurroundingBools [Mathf.Clamp(Index + 3, 0, SurroundingBools.Length - 1)])
            {
                Connections.Add(ConnectionDirection.Front);
            }                                                                                                                                       // Add Up
            if (SurroundingBools [Mathf.Clamp(Index - 3, 0, SurroundingBools.Length - 1)])
            {
                Connections.Add(ConnectionDirection.Back);
            }                                                                                                                                      // Add Down

            return(ModularPieceExtensions.ConnectionToWorldConnection(Connections.ToArray(), Rotation));
        }