Beispiel #1
0
    void FixedUpdate()
    {
        if (m_Center != null && m_Projector != null)
        {
            int gridX = Mathf.FloorToInt(m_Center.position.x * 2);
            int gridZ = Mathf.FloorToInt(m_Center.position.z * 2);

            // 0.5s 刷新一次
            if ((gridX != m_OldgridX || gridZ != m_OldgridZ) || (Time.fixedTime - m_LastUpdateTime > 0.2f))
            {
                m_OldgridX       = gridX;
                m_OldgridZ       = gridZ;
                m_LastUpdateTime = Time.fixedTime;


                /* Cause libfov to mark lit cells using the two callbacks given:
                 *  - opaque, which is used to determine information about your
                 *    map (a query you can define), and
                 *  - apply, which is used to modify your map once libfov
                 *    determines that a particular cell is lit (a command you can
                 *    define).
                 *
                 *  In this call, the light source is at (pX,pY).
                 */
                if (ViewBeam)
                {
                    float angle_n = Vector2.Angle(new Vector2(m_Center.forward.x, m_Center.forward.z), Vector2.up);
                    float angle_e = Vector2.Angle(new Vector2(m_Center.forward.x, m_Center.forward.z), Vector2.right);
                    float angle_w = Vector2.Angle(new Vector2(m_Center.forward.x, m_Center.forward.z), Vector2.left);
                    float angle_s = Vector2.Angle(new Vector2(m_Center.forward.x, m_Center.forward.z), Vector2.down);

                    float angle_ne = Vector2.Angle(new Vector2(m_Center.forward.x, m_Center.forward.z), new Vector2(1, 1));
                    float angle_se = Vector2.Angle(new Vector2(m_Center.forward.x, m_Center.forward.z), new Vector2(1, -1));
                    float angle_sw = Vector2.Angle(new Vector2(m_Center.forward.x, m_Center.forward.z), new Vector2(-1, -1));
                    float angle_nw = Vector2.Angle(new Vector2(m_Center.forward.x, m_Center.forward.z), new Vector2(-1, 1));

                    if (angle_s <= 22.5f)
                    {
                        ViewBeamDirection = fov_direction_type.FOV_NORTH;
                    }
                    else if (angle_e <= 22.5f)
                    {
                        ViewBeamDirection = fov_direction_type.FOV_EAST;
                    }
                    else if (angle_w <= 22.5f)
                    {
                        ViewBeamDirection = fov_direction_type.FOV_WEST;
                    }
                    else if (angle_n <= 22.5f)
                    {
                        ViewBeamDirection = fov_direction_type.FOV_SOUTH;
                    }
                    else if (angle_se <= 22.5f)
                    {
                        ViewBeamDirection = fov_direction_type.FOV_NORTHEAST;
                    }
                    else if (angle_ne <= 22.5f)
                    {
                        ViewBeamDirection = fov_direction_type.FOV_SOUTHEAST;
                    }
                    else if (angle_nw <= 22.5f)
                    {
                        ViewBeamDirection = fov_direction_type.FOV_SOUTHWEST;
                    }
                    else if (angle_sw <= 22.5f)
                    {
                        ViewBeamDirection = fov_direction_type.FOV_NORTHWEST;
                    }

                    m_BlockFov.fov_beam(fov_settings, m_BlockMap, Color.white, m_OldgridX, m_OldgridZ, ViewRadius, ViewBeamDirection, ViewBeamAngle);
                }
                else
                {
                    m_BlockFov.fov_circle(fov_settings, m_BlockMap, Color.white, m_OldgridX, m_OldgridZ, ViewRadius);
                }

                for (int y = 0; y < m_TexHeight; ++y)
                {
                    for (int x = 0; x < m_TexWidth; ++x)
                    {
                        if (m_BlockMap.isSeen(x, y))
                        {
                            m_TexColor[x + y * m_TexWidth] = new Color32(255, m_TexColor[x + y * m_TexWidth].r, 255, 255);
                        }
                        else if (m_BlockMap.isRemembered(x, y))
                        {
                            m_TexColor[x + y * m_TexWidth] = new Color32(DarkFogGray, m_TexColor[x + y * m_TexWidth].r, DarkFogGray, 255);
                        }
                        else
                        {
                            m_TexColor[x + y * m_TexWidth] = new Color32(0, m_TexColor[x + y * m_TexWidth].r, 0, 255);
                        }

                        m_BlockMap.setUnSeen(x, y);
                    }
                }

                m_TexColor[gridX + gridZ * m_TexWidth] = new Color32(255, 255, 255, 255);

                m_MaskTex.SetPixels32(m_TexColor);
                m_MaskTex.Apply();
                m_Projector.material.SetFloat("_StartTime", Time.timeSinceLevelLoad);
            }
        }
    }
Beispiel #2
0
        /**
         * Calculate a field of view from source at (x,y), pointing
         * in the given direction and with the given angle. The larger
         * the angle, the wider, "less focused" the beam. Each side of the
         * line pointing in the direction from the source will be half the
         * angle given such that the angle specified will be represented on
         * the raster.
         *
         * \param settings data structure containing settings.
         * \param map  map data structure to be passed to callbacks.
         * \param source data structure holding source of light.
         * \param source_x x-axis coordinate from which to start.
         * \param source_y y-axis coordinate from which to start.
         * \param radius Euclidean distance from (x,y) after which to stop.
         * \param direction One of eight directions the beam of light can point.
         * \param angle The angle at the base of the beam of light, in degrees.
         */
        public void fov_beam(fov_settings_type settings, map _map, Color source, int source_x, int source_y,
                             uint radius, fov_direction_type direction, float angle)
        {
            fov_private_data_type data = new fov_private_data_type();
            float start_slope, end_slope, a;

            data.settings = settings;
            data._map     = _map;
            data.source   = source;
            data.source_x = source_x;
            data.source_y = source_y;
            data.radius   = radius;

            if (angle <= 0.0f)
            {
                return;
            }
            else if (angle >= 360.0f)
            {
                _fov_circle(data);
            }

            /* Calculate the angle as a percentage of 45 degrees, halved (for
             * each side of the centre of the beam). e.g. angle = 180.0f means
             * half the beam is 90.0 which is 2x45, so the result is 2.0.
             */
            a = angle / 90.0f;

            if (direction == fov_direction_type.FOV_EAST)
            {
                end_slope = betweenf(a, 0.0f, 1.0f);
                _fov_octant_part(fov_octants_part.FOV_OCTANT_PPN, data, 1, 0.0f, end_slope);
                _fov_octant_part(fov_octants_part.FOV_OCTANT_PMN, data, 1, 0.0f, end_slope);

                if (a - 1.0f > Mathf.Epsilon)
                { /* a > 1.0f */
                    start_slope = betweenf(2.0f - a, 0.0f, 1.0f);
                    _fov_octant_part(fov_octants_part.FOV_OCTANT_PPY, data, 1, start_slope, 1.0f);
                    _fov_octant_part(fov_octants_part.FOV_OCTANT_MPY, data, 1, start_slope, 1.0f);
                }
                if (a - 2.0f > Mathf.Epsilon)
                { /* a > 2.0f */
                    end_slope = betweenf(a - 2.0f, 0.0f, 1.0f);
                    _fov_octant_part(fov_octants_part.FOV_OCTANT_PMY, data, 1, 0.0f, end_slope);
                    _fov_octant_part(fov_octants_part.FOV_OCTANT_MMY, data, 1, 0.0f, end_slope);
                }
                if (a - 3.0f > Mathf.Epsilon)
                { /* a > 3.0f */
                    start_slope = betweenf(4.0f - a, 0.0f, 1.0f);
                    _fov_octant_part(fov_octants_part.FOV_OCTANT_MPN, data, 1, start_slope, 1.0f);
                    _fov_octant_part(fov_octants_part.FOV_OCTANT_MMN, data, 1, start_slope, 1.0f);
                }
            }
            if (direction == fov_direction_type.FOV_WEST)
            {
                end_slope = betweenf(a, 0.0f, 1.0f);
                _fov_octant_part(fov_octants_part.FOV_OCTANT_MPN, data, 1, 0.0f, end_slope);
                _fov_octant_part(fov_octants_part.FOV_OCTANT_MMN, data, 1, 0.0f, end_slope);

                if (a - 1.0f > Mathf.Epsilon)
                { /* a > 1.0f */
                    start_slope = betweenf(2.0f - a, 0.0f, 1.0f);
                    _fov_octant_part(fov_octants_part.FOV_OCTANT_PMY, data, 1, start_slope, 1.0f);
                    _fov_octant_part(fov_octants_part.FOV_OCTANT_MMY, data, 1, start_slope, 1.0f);
                }
                if (a - 2.0f > Mathf.Epsilon)
                { /* a > 2.0f */
                    end_slope = betweenf(a - 2.0f, 0.0f, 1.0f);
                    _fov_octant_part(fov_octants_part.FOV_OCTANT_PPY, data, 1, 0.0f, end_slope);
                    _fov_octant_part(fov_octants_part.FOV_OCTANT_MPY, data, 1, 0.0f, end_slope);
                }
                if (a - 3.0f > Mathf.Epsilon)
                { /* a > 3.0f */
                    start_slope = betweenf(4.0f - a, 0.0f, 1.0f);
                    _fov_octant_part(fov_octants_part.FOV_OCTANT_PPN, data, 1, start_slope, 1.0f);
                    _fov_octant_part(fov_octants_part.FOV_OCTANT_PMN, data, 1, start_slope, 1.0f);
                }
            }
            if (direction == fov_direction_type.FOV_NORTH)
            {
                end_slope = betweenf(a, 0.0f, 1.0f);
                _fov_octant_part(fov_octants_part.FOV_OCTANT_MPY, data, 1, 0.0f, end_slope);
                _fov_octant_part(fov_octants_part.FOV_OCTANT_MMY, data, 1, 0.0f, end_slope);

                if (a - 1.0f > Mathf.Epsilon)
                { /* a > 1.0f */
                    start_slope = betweenf(2.0f - a, 0.0f, 1.0f);
                    _fov_octant_part(fov_octants_part.FOV_OCTANT_MMN, data, 1, start_slope, 1.0f);
                    _fov_octant_part(fov_octants_part.FOV_OCTANT_PMN, data, 1, start_slope, 1.0f);
                }
                if (a - 2.0f > Mathf.Epsilon)
                { /* a > 2.0f */
                    end_slope = betweenf(a - 2.0f, 0.0f, 1.0f);
                    _fov_octant_part(fov_octants_part.FOV_OCTANT_MPN, data, 1, 0.0f, end_slope);
                    _fov_octant_part(fov_octants_part.FOV_OCTANT_PPN, data, 1, 0.0f, end_slope);
                }
                if (a - 3.0f > Mathf.Epsilon)
                { /* a > 3.0f */
                    start_slope = betweenf(4.0f - a, 0.0f, 1.0f);
                    _fov_octant_part(fov_octants_part.FOV_OCTANT_PMY, data, 1, start_slope, 1.0f);
                    _fov_octant_part(fov_octants_part.FOV_OCTANT_PPY, data, 1, start_slope, 1.0f);
                }
            }
            if (direction == fov_direction_type.FOV_SOUTH)
            {
                end_slope = betweenf(a, 0.0f, 1.0f);
                _fov_octant_part(fov_octants_part.FOV_OCTANT_PMY, data, 1, 0.0f, end_slope);
                _fov_octant_part(fov_octants_part.FOV_OCTANT_PPY, data, 1, 0.0f, end_slope);

                if (a - 1.0f > Mathf.Epsilon)
                { /* a > 1.0f */
                    start_slope = betweenf(2.0f - a, 0.0f, 1.0f);
                    _fov_octant_part(fov_octants_part.FOV_OCTANT_MPN, data, 1, start_slope, 1.0f);
                    _fov_octant_part(fov_octants_part.FOV_OCTANT_PPN, data, 1, start_slope, 1.0f);
                }
                if (a - 2.0f > Mathf.Epsilon)
                { /* a > 2.0f */
                    end_slope = betweenf(a - 2.0f, 0.0f, 1.0f);
                    _fov_octant_part(fov_octants_part.FOV_OCTANT_MMN, data, 1, 0.0f, end_slope);
                    _fov_octant_part(fov_octants_part.FOV_OCTANT_PMN, data, 1, 0.0f, end_slope);
                }
                if (a - 3.0f > Mathf.Epsilon)
                { /* a > 3.0f */
                    start_slope = betweenf(4.0f - a, 0.0f, 1.0f);
                    _fov_octant_part(fov_octants_part.FOV_OCTANT_MMY, data, 1, start_slope, 1.0f);
                    _fov_octant_part(fov_octants_part.FOV_OCTANT_MPY, data, 1, start_slope, 1.0f);
                }
            }



            if (direction == fov_direction_type.FOV_NORTHEAST)
            {
                start_slope = betweenf(1.0f - a, 0.0f, 1.0f);
                _fov_octant_part(fov_octants_part.FOV_OCTANT_PMN, data, 1, start_slope, 1.0f);
                _fov_octant_part(fov_octants_part.FOV_OCTANT_MPY, data, 1, start_slope, 1.0f);

                if (a - 1.0f > Mathf.Epsilon)
                { /* a > 1.0f */
                    end_slope = betweenf(a - 1.0f, 0.0f, 1.0f);
                    _fov_octant_part(fov_octants_part.FOV_OCTANT_MMY, data, 1, 0.0f, end_slope);
                    _fov_octant_part(fov_octants_part.FOV_OCTANT_PPN, data, 1, 0.0f, end_slope);
                }
                if (a - 2.0f > Mathf.Epsilon)
                { /* a > 2.0f */
                    start_slope = betweenf(3.0f - a, 0.0f, 1.0f);
                    _fov_octant_part(fov_octants_part.FOV_OCTANT_MMN, data, 1, start_slope, 1.0f);
                    _fov_octant_part(fov_octants_part.FOV_OCTANT_PPY, data, 1, start_slope, 1.0f);
                }
                if (a - 3.0f > Mathf.Epsilon)
                { /* a > 3.0f */
                    end_slope = betweenf(a - 3.0f, 0.0f, 1.0f);
                    _fov_octant_part(fov_octants_part.FOV_OCTANT_MPN, data, 1, 0.0f, end_slope);
                    _fov_octant_part(fov_octants_part.FOV_OCTANT_PMY, data, 1, 0.0f, end_slope);
                }
            }
            if (direction == fov_direction_type.FOV_NORTHWEST)
            {
                start_slope = betweenf(1.0f - a, 0.0f, 1.0f);
                _fov_octant_part(fov_octants_part.FOV_OCTANT_MMN, data, 1, start_slope, 1.0f);
                _fov_octant_part(fov_octants_part.FOV_OCTANT_MMY, data, 1, start_slope, 1.0f);

                if (a - 1.0f > Mathf.Epsilon)
                { /* a > 1.0f */
                    end_slope = betweenf(a - 1.0f, 0.0f, 1.0f);
                    _fov_octant_part(fov_octants_part.FOV_OCTANT_MPN, data, 1, 0.0f, end_slope);
                    _fov_octant_part(fov_octants_part.FOV_OCTANT_MPY, data, 1, 0.0f, end_slope);
                }
                if (a - 2.0f > Mathf.Epsilon)
                { /* a > 2.0f */
                    start_slope = betweenf(3.0f - a, 0.0f, 1.0f);
                    _fov_octant_part(fov_octants_part.FOV_OCTANT_PMY, data, 1, start_slope, 1.0f);
                    _fov_octant_part(fov_octants_part.FOV_OCTANT_PMN, data, 1, start_slope, 1.0f);
                }
                if (a - 3.0f > Mathf.Epsilon)
                { /* a > 3.0f */
                    end_slope = betweenf(a - 3.0f, 0.0f, 1.0f);
                    _fov_octant_part(fov_octants_part.FOV_OCTANT_PPY, data, 1, 0.0f, end_slope);
                    _fov_octant_part(fov_octants_part.FOV_OCTANT_PPN, data, 1, 0.0f, end_slope);
                }
            }
            if (direction == fov_direction_type.FOV_SOUTHEAST)
            {
                start_slope = betweenf(1.0f - a, 0.0f, 1.0f);
                _fov_octant_part(fov_octants_part.FOV_OCTANT_PPN, data, 1, start_slope, 1.0f);
                _fov_octant_part(fov_octants_part.FOV_OCTANT_PPY, data, 1, start_slope, 1.0f);

                if (a - 1.0f > Mathf.Epsilon)
                { /* a > 1.0f */
                    end_slope = betweenf(a - 1.0f, 0.0f, 1.0f);
                    _fov_octant_part(fov_octants_part.FOV_OCTANT_PMY, data, 1, 0.0f, end_slope);
                    _fov_octant_part(fov_octants_part.FOV_OCTANT_PMN, data, 1, 0.0f, end_slope);
                }
                if (a - 2.0f > Mathf.Epsilon)
                { /* a > 2.0f */
                    start_slope = betweenf(3.0f - a, 0.0f, 1.0f);
                    _fov_octant_part(fov_octants_part.FOV_OCTANT_MPN, data, 1, start_slope, 1.0f);
                    _fov_octant_part(fov_octants_part.FOV_OCTANT_MPY, data, 1, start_slope, 1.0f);
                }
                if (a - 3.0f > Mathf.Epsilon)
                { /* a > 3.0f */
                    end_slope = betweenf(a - 3.0f, 0.0f, 1.0f);
                    _fov_octant_part(fov_octants_part.FOV_OCTANT_MMN, data, 1, 0.0f, end_slope);
                    _fov_octant_part(fov_octants_part.FOV_OCTANT_MMY, data, 1, 0.0f, end_slope);
                }
            }
            if (direction == fov_direction_type.FOV_SOUTHWEST)
            {
                start_slope = betweenf(1.0f - a, 0.0f, 1.0f);
                _fov_octant_part(fov_octants_part.FOV_OCTANT_PMY, data, 1, start_slope, 1.0f);
                _fov_octant_part(fov_octants_part.FOV_OCTANT_MPN, data, 1, start_slope, 1.0f);

                if (a - 1.0f > Mathf.Epsilon)
                { /* a > 1.0f */
                    end_slope = betweenf(a - 1.0f, 0.0f, 1.0f);
                    _fov_octant_part(fov_octants_part.FOV_OCTANT_PPY, data, 1, 0.0f, end_slope);
                    _fov_octant_part(fov_octants_part.FOV_OCTANT_MMN, data, 1, 0.0f, end_slope);
                }
                if (a - 2.0f > Mathf.Epsilon)
                { /* a > 2.0f */
                    start_slope = betweenf(3.0f - a, 0.0f, 1.0f);
                    _fov_octant_part(fov_octants_part.FOV_OCTANT_PPN, data, 1, start_slope, 1.0f);
                    _fov_octant_part(fov_octants_part.FOV_OCTANT_MMY, data, 1, start_slope, 1.0f);
                }
                if (a - 3.0f > Mathf.Epsilon)
                { /* a > 3.0f */
                    end_slope = betweenf(a - 3.0f, 0.0f, 1.0f);
                    _fov_octant_part(fov_octants_part.FOV_OCTANT_PMN, data, 1, 0.0f, end_slope);
                    _fov_octant_part(fov_octants_part.FOV_OCTANT_MPY, data, 1, 0.0f, end_slope);
                }
            }
        }