bool LineOfSightCanSee(FogOfWarShape shape, Vector2 offset, float fogradius)
        {
            if (shape.lineOfSight == null)
            {
                return(true);
            }

            float idx = FogOfWarUtils.ClockwiseAngle(Vector2.up, offset) * shape.lineOfSight.Length / 360.0f;

            if (idx < 0)
            {
                idx += shape.lineOfSight.Length;
            }

            // sampling
            float value;

            if (_map.filterMode == FilterMode.Point)
            {
                value = shape.lineOfSight[Mathf.RoundToInt(idx) % shape.lineOfSight.Length];
            }
            else
            {
                int idxlow  = Mathf.FloorToInt(idx);
                int idxhigh = (idxlow + 1) % shape.lineOfSight.Length;
                value = Mathf.LerpUnclamped(shape.lineOfSight[idxlow], shape.lineOfSight[idxhigh], idx % 1);
            }

            float dist = value * fogradius;

            return(offset.sqrMagnitude < dist * dist);
        }
            public DrawInfo(FogOfWarMap map, FogOfWarShape shape, float xradius, float yradius)
            {
                // convert size to fog space
                fogForward   = shape.foward;
                forwardAngle = FogOfWarUtils.ClockwiseAngle(Vector2.up, fogForward) * Mathf.Deg2Rad;
                float   sin            = Mathf.Sin(-forwardAngle);
                float   cos            = Mathf.Cos(-forwardAngle);
                Vector2 relativeoffset = new Vector2(shape.offset.x * cos - shape.offset.y * sin, shape.offset.x * sin + shape.offset.y * cos);

                fogCenterPos = FogOfWarConversion.WorldToFog(FogOfWarConversion.WorldToFogPlane(shape.eyePosition, map.plane) + relativeoffset, map.offset, map.resolution, map.size);
                fogEyePos    = new Vector2i(FogOfWarConversion.WorldToFog(shape.eyePosition, map.plane, map.offset, map.resolution, map.size));

                // find ranges
                if (shape.visibleCells == null)
                {
                    xMin = Mathf.Max(0, Mathf.RoundToInt(fogCenterPos.x - xradius));
                    xMax = Mathf.Min(map.resolution.x - 1, Mathf.RoundToInt(fogCenterPos.x + xradius));
                    yMin = Mathf.Max(0, Mathf.RoundToInt(fogCenterPos.y - yradius));
                    yMax = Mathf.Min(map.resolution.y - 1, Mathf.RoundToInt(fogCenterPos.y + yradius));
                }
                else
                {
                    fogCenterPos = FogOfWarConversion.SnapToNearestFogPixel(fogCenterPos);
                    fogEyePos    = new Vector2i(FogOfWarConversion.SnapToNearestFogPixel(FogOfWarConversion.WorldToFog(shape.eyePosition, map.offset, map.resolution, map.size)));

                    Vector2i pos = new Vector2i(Mathf.RoundToInt(fogCenterPos.x), Mathf.RoundToInt(fogCenterPos.y));
                    Vector2i rad = new Vector2i(Mathf.RoundToInt(xradius), Mathf.RoundToInt(yradius));
                    xMin = Mathf.Max(0, Mathf.RoundToInt(pos.x - rad.x));
                    xMax = Mathf.Min(map.resolution.x - 1, Mathf.RoundToInt(pos.x + rad.x));
                    yMin = Mathf.Max(0, Mathf.RoundToInt(pos.y - rad.y));
                    yMax = Mathf.Min(map.resolution.y - 1, Mathf.RoundToInt(pos.y + rad.y));
                }
            }
        public override void Draw(FogOfWarShape shape, bool ismultithreaded)
        {
            DrawInfo info = new DrawInfo(_map, shape);

            _material.SetKeywordEnabled("SHAPE_CIRCLE", shape is FogOfWarShapeCircle);
            _material.SetKeywordEnabled("SHAPE_BOX", shape is FogOfWarShapeBox);
            _material.SetKeywordEnabled("LINE_OF_SIGHT", shape.lineOfSight != null);
            _material.SetKeywordEnabled("LINE_OF_SIGHT_CELLS", shape.visibleCells != null);

            _material.SetVector("_CenterPosition", info.fogCenterPos / (_map.size * _map.pixelSize));
            _material.SetVector("_EyePosition", info.fogEyePos.ToFloat() / (_map.size * _map.pixelSize));
            _material.SetVector("_EyeForward", info.fogForward);
            _material.SetFloat("_ForwardAngle", info.forwardAngle);
            _material.SetFloat("_Brightness", shape.brightness);

            SetupLineOfSight(shape);
            SetupLineOfSightCells(shape);

            Texture2D tex = null;

            if (shape is FogOfWarShapeCircle circle)
            {
                _material.SetVector("_Size", new Vector4(shape.radius / _map.size, circle.innerRadius, 1, 1));
                _material.SetFloat("_Angle", 1 - circle.angle / 90);
            }
            else if (shape is FogOfWarShapeBox box)
            {
                _material.SetVector("_Size", shape.size / _map.size);
                tex = box.texture;
            }

            _renderTexture.MarkRestoreExpected();
            Graphics.Blit(tex ?? _outputTexture, _renderTexture, _material);
        }
        void SetupLineOfSightCells(FogOfWarShape shape)
        {
            // prepare texture
            if (shape.visibleCells == null)
            {
                return;
            }

            if (_lineOfSightCellsTex == null || _lineOfSightCellsTex.width * _lineOfSightCellsTex.height < shape.visibleCells.Length)
            {
                if (_lineOfSightCellsTex != null)
                {
                    Object.Destroy(_lineOfSightCellsTex);
                }
                _lineOfSightCellsTex            = new Texture2D(shape.visibleCellsWidth, shape.visibleCells.Length / shape.visibleCellsWidth, TextureFormat.Alpha8, false);
                _lineOfSightCellsTex.filterMode = FilterMode.Point;
                _lineOfSightCellsTex.wrapMode   = TextureWrapMode.Clamp;
                _lineOfSightCellsCopyBuffer     = new byte[shape.visibleCells.Length];
            }

            for (int i = 0; i < shape.visibleCells.Length; ++i)
            {
                _lineOfSightCellsCopyBuffer[i] = shape.visibleCells[i] ? (byte)255 : (byte)0;
            }
            _lineOfSightCellsTex.LoadRawTextureData(_lineOfSightCellsCopyBuffer);
            _lineOfSightCellsTex.Apply(false, false);

            // setup material
            _material.SetTexture("_LineOfSightTex", _lineOfSightCellsTex);
            int pixelsize = (int)shape.CalculateMaxLineOfSightDistance() * 2 + 1;

            _material.SetFloat("_LineOfSightDistance", pixelsize / _map.size);
        }
        void SetupLineOfSight(FogOfWarShape shape)
        {
            // prepare texture
            if (shape.lineOfSight == null)
            {
                return;
            }

            if (_lineOfSightTex == null || _lineOfSightTex.width < shape.lineOfSight.Length)
            {
                if (_lineOfSightTex != null)
                {
                    Object.Destroy(_lineOfSightTex);
                }
                _lineOfSightTex            = new Texture2D(shape.lineOfSight.Length, 1, TextureFormat.RFloat, false);
                _lineOfSightTex.filterMode = FilterMode.Bilinear;
                _lineOfSightTex.wrapMode   = TextureWrapMode.Repeat;
                _lineOfSightCopyBuffer     = new byte[shape.lineOfSight.Length * sizeof(float)];
            }

            System.Buffer.BlockCopy(shape.lineOfSight, 0, _lineOfSightCopyBuffer, 0, shape.lineOfSight.Length * sizeof(float));
            _lineOfSightTex.LoadRawTextureData(_lineOfSightCopyBuffer);
            _lineOfSightTex.Apply(false, false);

            // setup material
            _material.SetTexture("_LineOfSightTex", _lineOfSightTex);
            _material.SetFloat("_LineOfSightDistance", shape.CalculateMaxLineOfSightDistance() / _map.size);
        }
Пример #6
0
        void ProcessUnits(bool checkstopwatch)
        {
            // remove any invalid units
            FogOfWarUnit.registeredUnits.RemoveAll(u => u == null);

            double millisecondfrequency = 1000.0 / System.Diagnostics.Stopwatch.Frequency;

            for (; _currentUnitProcessing < FogOfWarUnit.registeredUnits.Count; ++_currentUnitProcessing)
            {
                if (!FogOfWarUnit.registeredUnits[_currentUnitProcessing].isActiveAndEnabled || FogOfWarUnit.registeredUnits[_currentUnitProcessing].team != team)
                {
                    continue;
                }

                FogOfWarShape shape = FogOfWarUnit.registeredUnits[_currentUnitProcessing].GetShape(this, physics, plane);
                if (multithreaded && updateAutomatically)
                {
                    _threadPool.Run(() => _drawer.Draw(shape));
                }
                else
                {
                    _drawer.Draw(shape);
                }

                // do the timer check here so that at least one unit will be processed!
                if (checkstopwatch && _stopwatch.ElapsedTicks * millisecondfrequency >= maxMillisecondsPerFrame)
                {
                    ++_currentUnitProcessing;
                    break;
                }
            }
        }
Пример #7
0
        public FogOfWarShape GetShape(FogOfWar fow, FogOfWarPhysics physics, FogOfWarPlane plane)
        {
            FogOfWarShape shape = CreateShape(fow);

            if (shape == null)
            {
                return(null);
            }
            shape.lineOfSight  = CalculateLineOfSight(physics, shape.eyePosition, plane);
            shape.visibleCells = null;
            return(shape);
        }
Пример #8
0
        public void Draw(FogOfWarShape shape, bool ismultithreaded)
        {
            _isMultithreaded = ismultithreaded;

            if (shape is FogOfWarShapeCircle)
            {
                DrawCircle(shape as FogOfWarShapeCircle);
            }
            else if (shape is FogOfWarShapeBox)
            {
                DrawBox(shape as FogOfWarShapeBox);
            }
        }
Пример #9
0
 public void Draw(FogOfWarShape shape)
 {
     if (shape is FogOfWarShapeCircle)
     {
         DrawCircle(shape as FogOfWarShapeCircle);
     }
     else if (shape is FogOfWarShapeBox)
     {
         DrawBox(shape as FogOfWarShapeBox);
     }
     else if (shape is FogOfWarShapeTexture)
     {
         DrawTexture(shape as FogOfWarShapeTexture);
     }
 }
Пример #10
0
 void FillShape(FogOfWarShape shape)
 {
     if (antiFlicker)
     {
         // snap to nearest fog pixel
         shape.eyePosition = FogOfWarConversion.SnapWorldPositionToNearestFogPixel(FogOfWarConversion.WorldToFogPlane(_transform.position, FogOfWar.current.plane), FogOfWar.current.mapOffset, FogOfWar.current.mapResolution, FogOfWar.current.mapSize);
         shape.eyePosition = FogOfWarConversion.FogPlaneToWorld(shape.eyePosition.x, shape.eyePosition.y, _transform.position.y, FogOfWar.current.plane);
     }
     else
     {
         shape.eyePosition = _transform.position;
     }
     shape.foward = _transform.forward;
     shape.offset = offset;
     shape.radius = radius;
 }
Пример #11
0
        void ProcessUnits(System.Diagnostics.Stopwatch stopwatch)
        {
            // if we are not updating units and all units have finished processing
            if (!updateUnits && _currentUnitProcessing >= FogOfWarUnit.registeredUnits.Count)
            {
                return;
            }

            // remove any invalid units
            FogOfWarUnit.registeredUnits.RemoveAll(u => u == null);

            double millisecondfrequency = 1000.0 / System.Diagnostics.Stopwatch.Frequency;

            for (; _currentUnitProcessing < FogOfWarUnit.registeredUnits.Count; ++_currentUnitProcessing)
            {
                if (!FogOfWarUnit.registeredUnits[_currentUnitProcessing].isActiveAndEnabled || FogOfWarUnit.registeredUnits[_currentUnitProcessing].team != team)
                {
                    continue;
                }

                FogOfWarShape shape = FogOfWarUnit.registeredUnits[_currentUnitProcessing].GetShape(this, physics, plane);
                if (_isMultithreaded)
                {
                    ++_drawThreadTaskPoolCount;
                    while (_drawThreadTaskPoolCount > _drawThreadTaskPool.Count)
                    {
                        _drawThreadTaskPool.Add(new FogOfWarDrawThreadTask());
                    }

                    FogOfWarDrawThreadTask task = _drawThreadTaskPool[_drawThreadTaskPoolCount - 1];
                    task.drawer = _drawer;
                    task.shape  = shape;
                    _threadPool.Run(task);
                }
                else
                {
                    _drawer.Draw(shape, false);
                }

                // do the timer check here so that at least one unit will be processed
                if (stopwatch != null && _stopwatch.ElapsedTicks * millisecondfrequency >= maxMillisecondsPerFrame)
                {
                    ++_currentUnitProcessing;
                    break;
                }
            }
        }
Пример #12
0
            public DrawInfo(FogOfWarMap map, FogOfWarShape shape)
            {
                // convert size to fog space
                Vector2 radius = shape.CalculateRadius() * map.pixelSize;

                fogForward = shape.foward;
                Vector2 relativeoffset;

                if (shape.absoluteOffset)
                {
                    forwardAngle   = 0;
                    relativeoffset = shape.offset;
                }
                else
                {
                    forwardAngle = FogOfWarUtils.ClockwiseAngle(Vector2.up, fogForward) * Mathf.Deg2Rad;
                    float sin = Mathf.Sin(-forwardAngle);
                    float cos = Mathf.Cos(-forwardAngle);
                    relativeoffset = new Vector2(shape.offset.x * cos - shape.offset.y * sin, shape.offset.x * sin + shape.offset.y * cos);
                }

                fogCenterPos = FogOfWarConversion.WorldToFog(FogOfWarConversion.WorldToFogPlane(shape.eyePosition, map.plane) + relativeoffset, map.offset, map.resolution, map.size);
                fogEyePos    = FogOfWarConversion.WorldToFog(shape.eyePosition, map.plane, map.offset, map.resolution, map.size).ToInt();

                // find ranges
                if (shape.visibleCells == null)
                {
                    xMin = Mathf.Max(0, Mathf.RoundToInt(fogCenterPos.x - radius.x));
                    xMax = Mathf.Min(map.resolution.x - 1, Mathf.RoundToInt(fogCenterPos.x + radius.x));
                    yMin = Mathf.Max(0, Mathf.RoundToInt(fogCenterPos.y - radius.y));
                    yMax = Mathf.Min(map.resolution.y - 1, Mathf.RoundToInt(fogCenterPos.y + radius.y));
                }
                else
                {
                    fogCenterPos = FogOfWarConversion.SnapToNearestFogPixel(fogCenterPos);
                    fogEyePos    = FogOfWarConversion.SnapToNearestFogPixel(FogOfWarConversion.WorldToFog(shape.eyePosition, map.offset, map.resolution, map.size)).ToInt();

                    Vector2Int pos = fogCenterPos.ToInt();
                    Vector2Int rad = radius.ToInt();
                    xMin = Mathf.Max(0, Mathf.RoundToInt(pos.x - rad.x));
                    xMax = Mathf.Min(map.resolution.x - 1, Mathf.RoundToInt(pos.x + rad.x));
                    yMin = Mathf.Max(0, Mathf.RoundToInt(pos.y - rad.y));
                    yMax = Mathf.Min(map.resolution.y - 1, Mathf.RoundToInt(pos.y + rad.y));
                }
            }
Пример #13
0
 void FillShape(FogOfWar fow, FogOfWarShape shape)
 {
     if (antiFlicker)
     {
         // snap to nearest fog pixel
         shape.eyePosition = FogOfWarConversion.SnapWorldPositionToNearestFogPixel(fow, FogOfWarConversion.WorldToFogPlane(_transform.position, fow.plane), fow.mapOffset, fow.mapResolution, fow.mapSize);
         shape.eyePosition = FogOfWarConversion.FogPlaneToWorld(shape.eyePosition.x, shape.eyePosition.y, _transform.position.y, fow.plane);
     }
     else
     {
         shape.eyePosition = _transform.position;
     }
     shape.brightness     = brightness;
     shape.foward         = FogOfWarConversion.TransformFogPlaneForward(_transform, fow.plane);
     shape.absoluteOffset = absoluteOffset;
     shape.offset         = offset;
     shape.radius         = circleRadius;
     shape.size           = boxSize;
 }
Пример #14
0
        public override void Draw(FogOfWarShape shape, bool ismultithreaded)
        {
            _isMultithreaded = ismultithreaded;

            if (shape is FogOfWarShapeCircle circle)
            {
                DrawCircle(circle);
            }
            else if (shape is FogOfWarShapeBox box)
            {
                if (box.rotateToForward)
                {
                    DrawRotatedBox(box);
                }
                else
                {
                    DrawAxisAlignedBox(box);
                }
            }
        }
Пример #15
0
        public FogOfWarShape GetShape(FogOfWarPhysics physics, FogOfWarPlane plane)
        {
            FogOfWarShape shape = CreateShape();

            if (shape == null)
            {
                return(null);
            }

            if (cellBased)
            {
                shape.lineOfSight  = null;
                shape.visibleCells = CalculateLineOfSightCells(physics, shape.eyePosition);
            }
            else
            {
                shape.lineOfSight  = CalculateLineOfSight(physics, shape.eyePosition, plane);
                shape.visibleCells = null;
            }
            return(shape);
        }
        bool LineOfSightCanSeeCell(FogOfWarShape shape, Vector2i offset)
        {
            if (shape.visibleCells == null)
            {
                return(true);
            }

            int radius = Mathf.RoundToInt(shape.radius);
            int width  = radius + radius + 1;

            offset.x += radius;
            if (offset.x < 0 || offset.x >= width)
            {
                return(true);
            }

            offset.y += radius;
            if (offset.y < 0 || offset.y >= width)
            {
                return(true);
            }

            return(shape.visibleCells[offset.y * width + offset.x]);
        }
Пример #17
0
        bool LineOfSightCanSeeCell(FogOfWarShape shape, Vector2Int offset)
        {
            if (shape.visibleCells == null)
            {
                return(true);
            }

            // offset so it is relative to the center
            int halfwidth = shape.visibleCellsWidth >> 1;

            offset.x += halfwidth;
            if (offset.x < 0 || offset.x >= shape.visibleCellsWidth)
            {
                return(true);
            }

            offset.y += halfwidth;
            if (offset.y < 0 || offset.y >= shape.visibleCellsWidth)
            {
                return(true);
            }

            return(shape.visibleCells[offset.y * shape.visibleCellsWidth + offset.x]);
        }
Пример #18
0
 public abstract void Draw(FogOfWarShape shape, bool ismultithreaded);