예제 #1
0
    private CellAction EvaluatePoint(Vector3 position)
    {
        byte neighborCount = 0;
        int  neighbors     = 0;

        /*
         * A cell has 26 possible neighbors; All we care about is whether or not an adjacent cell is occupied.
         * So, we are going to store that in an int and use only 26 of the bits, where each adjacent cell is represented by a bit,
         * with 0 meaning that the cell is empty, and 1 meaning that it is occupied.
         *
         * A cell's neighbors are organized into three layers:
         *                               TOP3      MID3      BTM3
         *              (1,1,1)------>  X X X    X X X    X X X
         *                              X X X    X O X    X X X
         *                              X X X    X X X    X X X (-1,-1,-1) <-------
         *      ... where X's are adjacent to the cell of interest O
         * We store that as this:
         *      TOP3:          MID3:           BTM3:
         *         top mid btm    top ... ...   ... ... ...
         *         XXX XXX XXX    XXX XOX XXX   XXX XXX XXX
         *         [0, 1, 2, ...               ..., 24, 25]
         */
        bool isCellOccupied = _cells.ContainsKey(position);

        for (float x = position.x - xUnit; x <= position.x + xUnit; x++)
        {
            for (float y = position.x - yUnit; y <= position.y + yUnit; y++)
            {
                for (float z = position.z - zUnit; z <= position.z + zUnit; z++)
                {
                    var vec = new Vector3(x, y, z);
                    if (_interestingCells.ContainsKey(vec))
                    {
                        if (position != vec)
                        {
                            // set this cell's bit to 1;
                            neighbors++;
                            neighborCount++;
                        }
                    }
                    // shift bit to the left;
                    neighbors <<= 1;
                }
            }
        }

        if (neighborCount == 0 && isCellOccupied == false)
        {
            return(new CellAction(position, CellActionID.IgnorePos));
        }
        else
        {
            return(new CellAction(position, ruleSet.CellRule(neighbors, neighborCount, isCellOccupied)));
        }
    }