Exemple #1
0
        /// <summary>
        /// Update the contents of ConvexHullList and check if we need to recalculate vertices
        /// </summary>
        private void RefreshConvexHullList(ConvexHullList chList, Vector2 lightPos, Submarine sub)
        {
            var fullChList = ConvexHull.HullLists.Find(x => x.Submarine == sub);

            if (fullChList == null)
            {
                return;
            }

            chList.List = fullChList.List.FindAll(ch => ch.Enabled && MathUtils.CircleIntersectsRectangle(lightPos, range, ch.BoundingBox));

            NeedsHullCheck = true;
        }
        public ConvexHull(Vector2[] points, Color color, Entity parent)
        {
            if (shadowEffect == null)
            {
                shadowEffect = new BasicEffect(GameMain.Instance.GraphicsDevice);
                shadowEffect.VertexColorEnabled = true;
            }
            if (penumbraEffect == null)
            {
                penumbraEffect = new BasicEffect(GameMain.Instance.GraphicsDevice);
                penumbraEffect.TextureEnabled = true;
                //shadowEffect.VertexColorEnabled = true;
                penumbraEffect.LightingEnabled = false;
                penumbraEffect.Texture         = TextureLoader.FromFile("Content/Lights/penumbra.png");
            }

            parentEntity = parent;

            //cachedShadows = new Dictionary<LightSource, CachedShadow>();

            shadowVertices   = new VertexPositionColor[6 * 2];
            penumbraVertices = new VertexPositionTexture[6];

            //vertices = points;
            SetVertices(points);
            //CalculateDimensions();

            backFacing = new bool[4];
            ignoreEdge = new bool[4];

            Enabled = true;

            var chList = HullLists.Find(x => x.Submarine == parent.Submarine);

            if (chList == null)
            {
                chList = new ConvexHullList(parent.Submarine);
                HullLists.Add(chList);
            }

            foreach (ConvexHull ch in chList.List)
            {
                UpdateIgnoredEdges(ch);
                ch.UpdateIgnoredEdges(this);
            }

            chList.List.Add(this);
        }
Exemple #3
0
        /// <summary>
        /// Recheck which convex hulls are in range (if needed),
        /// and check if we need to recalculate vertices due to changes in the convex hulls
        /// </summary>
        private void CheckHullsInRange()
        {
            List <Submarine> subs = new List <Submarine>(Submarine.Loaded);

            subs.Add(null);

            foreach (Submarine sub in subs)
            {
                //find the list of convexhulls that belong to the sub
                var chList = hullsInRange.Find(x => x.Submarine == sub);

                //not found -> create one
                if (chList == null)
                {
                    chList = new ConvexHullList(sub);
                    hullsInRange.Add(chList);
                    NeedsRecalculation = true;
                }

                if (chList.List.Any(ch => ch.LastVertexChangeTime > lastRecalculationTime && !chList.IsHidden.Contains(ch)))
                {
                    NeedsRecalculation = true;
                }

                Vector2 lightPos = position;
                if (ParentSub == null)
                {
                    //light and the convexhulls are both outside
                    if (sub == null)
                    {
                        if (NeedsHullCheck)
                        {
                            RefreshConvexHullList(chList, lightPos, null);
                        }
                    }
                    //light is outside, convexhulls inside a sub
                    else
                    {
                        lightPos -= sub.Position;

                        Rectangle subBorders = sub.Borders;
                        subBorders.Location += sub.HiddenSubPosition.ToPoint() - new Point(0, sub.Borders.Height);

                        //only draw if the light overlaps with the sub
                        if (!MathUtils.CircleIntersectsRectangle(lightPos, range, subBorders))
                        {
                            if (chList.List.Count > 0)
                            {
                                NeedsRecalculation = true;
                            }
                            chList.List.Clear();
                            continue;
                        }

                        RefreshConvexHullList(chList, lightPos, sub);
                    }
                }
                else
                {
                    //light is inside, convexhull outside
                    if (sub == null)
                    {
                        continue;
                    }

                    //light and convexhull are both inside the same sub
                    if (sub == ParentSub)
                    {
                        if (NeedsHullCheck)
                        {
                            RefreshConvexHullList(chList, lightPos, sub);
                        }
                    }
                    //light and convexhull are inside different subs
                    else
                    {
                        if (sub.DockedTo.Contains(ParentSub) && !NeedsHullCheck)
                        {
                            continue;
                        }

                        lightPos -= (sub.Position - ParentSub.Position);

                        Rectangle subBorders = sub.Borders;
                        subBorders.Location += sub.HiddenSubPosition.ToPoint() - new Point(0, sub.Borders.Height);

                        //don't draw any shadows if the light doesn't overlap with the borders of the sub
                        if (!MathUtils.CircleIntersectsRectangle(lightPos, range, subBorders))
                        {
                            if (chList.List.Count > 0)
                            {
                                NeedsRecalculation = true;
                            }
                            chList.List.Clear();
                            continue;
                        }

                        //recalculate vertices if the subs have moved > 5 px relative to each other
                        Vector2 diff = ParentSub.WorldPosition - sub.WorldPosition;
                        Vector2 prevDiff;
                        if (!diffToSub.TryGetValue(sub, out prevDiff))
                        {
                            diffToSub.Add(sub, diff);
                            NeedsRecalculation = true;
                        }
                        else if (Vector2.DistanceSquared(diff, prevDiff) > 5.0f * 5.0f)
                        {
                            diffToSub[sub]     = diff;
                            NeedsRecalculation = true;
                        }

                        RefreshConvexHullList(chList, lightPos, sub);
                    }
                }
            }
        }
Exemple #4
0
        public ConvexHull(Vector2[] points, Color color, MapEntity parent)
        {
            if (shadowEffect == null)
            {
                shadowEffect = new BasicEffect(GameMain.Instance.GraphicsDevice)
                {
                    VertexColorEnabled = true
                };
            }
            if (penumbraEffect == null)
            {
                penumbraEffect = new BasicEffect(GameMain.Instance.GraphicsDevice)
                {
                    TextureEnabled  = true,
                    LightingEnabled = false,
                    Texture         = TextureLoader.FromFile("Content/Lights/penumbra.png")
                };
            }

            ParentEntity = parent;

            ShadowVertices   = new VertexPositionColor[6 * 4];
            PenumbraVertices = new VertexPositionTexture[6 * 4];

            backFacing = new bool[4];
            ignoreEdge = new bool[4];

            float minX = points[0].X, minY = points[0].Y, maxX = points[0].X, maxY = points[0].Y;

            for (int i = 1; i < vertices.Length; i++)
            {
                if (points[i].X < minX)
                {
                    minX = points[i].X;
                }
                if (points[i].Y < minY)
                {
                    minY = points[i].Y;
                }

                if (points[i].X > maxX)
                {
                    maxX = points[i].X;
                }
                if (points[i].Y > minY)
                {
                    maxY = points[i].Y;
                }
            }

            BoundingBox = new Rectangle((int)minX, (int)minY, (int)(maxX - minX), (int)(maxY - minY));

            isHorizontal = BoundingBox.Width > BoundingBox.Height;
            if (ParentEntity is Structure structure)
            {
                System.Diagnostics.Debug.Assert(!structure.Removed);
                isHorizontal = structure.IsHorizontal;
            }
            else if (ParentEntity is Item item)
            {
                System.Diagnostics.Debug.Assert(!item.Removed);
                var door = item.GetComponent <Door>();
                if (door != null)
                {
                    isHorizontal = door.IsHorizontal;
                }
            }

            SetVertices(points);

            Enabled = true;

            var chList = HullLists.Find(h => h.Submarine == parent.Submarine);

            if (chList == null)
            {
                chList = new ConvexHullList(parent.Submarine);
                HullLists.Add(chList);
            }

            foreach (ConvexHull ch in chList.List)
            {
                MergeOverlappingSegments(ch);
                ch.MergeOverlappingSegments(this);
            }

            chList.List.Add(this);
        }
Exemple #5
0
        public ConvexHull(Vector2[] points, Color color, MapEntity parent)
        {
            if (shadowEffect == null)
            {
                shadowEffect = new BasicEffect(GameMain.Instance.GraphicsDevice)
                {
                    VertexColorEnabled = true
                };
            }
            if (penumbraEffect == null)
            {
                penumbraEffect = new BasicEffect(GameMain.Instance.GraphicsDevice)
                {
                    TextureEnabled  = true,
                    LightingEnabled = false,
                    Texture         = TextureLoader.FromFile("Content/Lights/penumbra.png")
                };
            }

            ParentEntity = parent;

            ShadowVertices   = new VertexPositionColor[6 * 2];
            PenumbraVertices = new VertexPositionTexture[6];

            backFacing = new bool[4];
            ignoreEdge = new bool[4];

            SetVertices(points);

            Enabled = true;

            isHorizontal = BoundingBox.Width > BoundingBox.Height;
            if (ParentEntity is Structure structure)
            {
                isHorizontal = structure.IsHorizontal;
            }
            else if (ParentEntity is Item item)
            {
                var door = item.GetComponent <Door>();
                if (door != null)
                {
                    isHorizontal = door.IsHorizontal;
                }
            }

            var chList = HullLists.Find(h => h.Submarine == parent.Submarine);

            if (chList == null)
            {
                chList = new ConvexHullList(parent.Submarine);
                HullLists.Add(chList);
            }

            foreach (ConvexHull ch in chList.List)
            {
                MergeOverlappingSegments(ch);
                ch.MergeOverlappingSegments(this);
            }

            chList.List.Add(this);
        }