Пример #1
0
        public void EdgeOrientPointOnFringe()
        {
            var e1 = new EdgeEx(new PointF(0, 0), new PointF(2, 0));
            var e2 = new EdgeEx(new PointF(2, 0), new PointF(0, 2));
            var e3 = new EdgeEx(new PointF(0, 2), new PointF(0, 0));

            Assert.IsTrue(Math.Abs(e1.Orient(new PointF(1,0))) < float.Epsilon);
            Assert.IsTrue(Math.Abs(e3.Orient(new PointF(0,1))) < float.Epsilon);
        }
Пример #2
0
        public void EdgeOrientPointOutside()
        {
            var e1 = new EdgeEx(new PointF(0, 0), new PointF(2, 0));
            var e2 = new EdgeEx(new PointF(2, 0), new PointF(0, 2));
            var e3 = new EdgeEx(new PointF(0, 2), new PointF(0, 0));

            Assert.IsTrue(e1.Orient(new PointF(1,-1)) < 0);
            Assert.IsTrue(e2.Orient(new PointF(3,3)) < 0);
            Assert.IsTrue(e3.Orient(new PointF(-1,1)) < 0);
        }
Пример #3
0
        public void EdgeOrientPointInside()
        {
            var e1 = new EdgeEx(new PointF(0, 0), new PointF(2, 0));
            var e2 = new EdgeEx(new PointF(2, 0), new PointF(0, 2));
            var e3 = new EdgeEx(new PointF(0, 2), new PointF(0, 0));

            var p = new PointF(0.5f, 0.5f);

            Assert.IsTrue(e1.Orient(p) > 0);
            Assert.IsTrue(e2.Orient(p) > 0);
            Assert.IsTrue(e3.Orient(p) > 0);
        }
Пример #4
0
        private void DrawShadows(Light _light, PointF _avatarPoint)
        {
#if DEBUG
            using (new Profiler())
#endif
            {
                GL.Enable(EnableCap.Multisample);

                var lp = new PointF(_light.Point.X + 0.5f, _light.Point.Y + 0.5f);

                GL.Disable(EnableCap.Blend);
                GL.ClearColor(_light.LightSource.Color.R, _light.LightSource.Color.G, _light.LightSource.Color.B, 1f);
                GL.Clear(ClearBufferMask.ColorBufferBit);

                GL.Enable(EnableCap.Blend);

                #region Собираем все грани лицевые для источника освещения и попадающие в круг света

                var apnts = new HashSet <PointF>();

                var edgesCount = 0;
                var edges      = new EdgeEx[m_edgesCount];

                for (var i = 0; i < m_edgesCount; i++)
                {
                    if (_light.LiveMapCell != null && m_allEdges[i].LiveMapCell == _light.LiveMapCell)
                    {
                        continue;
                    }
                    if (EdgeEx.Distant(m_allEdges[i].P1, lp) >= _light.LightSource.Radius)
                    {
                        continue;
                    }
                    var orient = m_allEdges[i].Orient(lp);
                    if (orient <= 0)
                    {
                        continue;
                    }

                    if (m_allEdges[i].Orient(_avatarPoint) > 0 && !apnts.Contains(m_allEdges[i].CellCenter))
                    {
                        apnts.Add(m_allEdges[i].CellCenter);
                    }

                    edges[edgesCount]          = m_allEdges[i];
                    edges[edgesCount].Distance = Edge.Distant(m_allEdges[i].CellCenter, lp);
                    edges[edgesCount].Valid    = true;
                    edgesCount++;
                }

                Array.Sort(edges, 0, edgesCount, new DistanceComparer());

                #endregion

                GL.BlendFunc(BlendingFactorSrc.DstColor, BlendingFactorDest.OneMinusSrcAlpha);

                var pnts = new HashSet <PointF>();

                GL.Begin(BeginMode.Quads);
                {
                    for (var i = 0; i < edgesCount; i++)
                    {
                        if (!edges[i].Valid)
                        {
                            continue;
                        }

                        if (!pnts.Contains(edges[i].CellCenter))
                        {
                            pnts.Add(edges[i].CellCenter);
                        }

                        var color = edges[i].LiveMapCell.GetTransparentColor() * _light.LightSource.Color * (1f - edges[i].Opacity);

                        GL.Color4(color.R, color.G, color.B, 1f);

                        var pnt = new[]
                        {
                            edges[i].P2,
                            edges[i].P1,
                            GetFarPnt(lp, edges[i].P1),
                            GetFarPnt(lp, edges[i].P2)
                        };

                        GL.Vertex2(pnt[0].X, pnt[0].Y);
                        GL.Vertex2(pnt[1].X, pnt[1].Y);
                        GL.Vertex2(pnt[2].X, pnt[2].Y);
                        GL.Vertex2(pnt[3].X, pnt[3].Y);

                        #region Отбрасываем все грани вошедшие внутрь теневой трапеции

                        if (edges[i].Opacity > 0.9f)
                        {
                            var e1 = new EdgeEx(pnt[0], pnt[3]);
                            var e2 = new EdgeEx(pnt[2], pnt[1]);

                            for (var j = i + 1; j < edgesCount; j++)
                            {
                                if (!edges[j].Valid)
                                {
                                    continue;
                                }

                                if (!(e1.Orient(edges[j].P2) < -float.Epsilon) ||
                                    !(e2.Orient(edges[j].P1) < -float.Epsilon))
                                {
                                    continue;
                                }
                                if (!(e1.Orient(edges[j].P1) < -float.Epsilon) ||
                                    !(e2.Orient(edges[j].P2) < -float.Epsilon))
                                {
                                    continue;
                                }

                                edges[j].Valid = false;
                            }
                        }

                        #endregion
                    }
                }
                GL.End();

                GL.Disable(EnableCap.Blend);
                GL.Disable(EnableCap.Multisample);

                if (_light.LightSource is AvatarSight)
                {
                    GL.Color4(1f, 1f, 1f, 1f);
                    foreach (var pnt in pnts)
                    {
                        if (apnts.Contains(pnt))
                        {
                            GL.Vertex2(pnt.X, pnt.Y);
                        }
                    }
                }
                else
                {
                    GL.Begin(BeginMode.Points);
                    {
                        foreach (var pnt in pnts)
                        {
                            if (apnts.Contains(pnt) && pnt != _avatarPoint)
                            {
                                GL.Color4(1f, 1f, 1f, 1f);
                            }
                            else
                            {
                                GL.Color4(0f, 0f, 0f, 1f);
                            }
                            GL.Vertex2(pnt.X, pnt.Y);
                        }
                    }
                    GL.End();
                }
            }
        }
Пример #5
0
        private void СформироватьМассивГраней()
        {
#if DEBUG
            using (new Profiler())
#endif
            {
                m_edgesCount = 0;

                var hs = new Dictionary <Int32, int>();

                var doubles = 0;

                for (var i = 1; i < MAP_SIZE - 1; ++i)
                {
                    for (var j = 1; j < MAP_SIZE - 1; ++j)
                    {
                        var lmc = m_shadowCasters[i, j].LiveMapCell;
                        lmc.FinalLighted = FColor.Empty;
                        if (lmc == null)
                        {
                            continue;
                        }

                        var opacity = m_shadowCasters[i, j].Opacity;

                        if (opacity > 0)
                        {
                            if (m_shadowCasters[i, j - 1].Opacity != opacity ||
                                m_shadowCasters[i - 1, j - 1].Opacity != opacity ||
                                m_shadowCasters[i + 1, j - 1].Opacity != opacity ||
                                m_shadowCasters[i, j + 1].Opacity != opacity ||
                                m_shadowCasters[i - 1, j + 1].Opacity != opacity ||
                                m_shadowCasters[i + 1, j + 1].Opacity != opacity ||
                                m_shadowCasters[i, j].Opacity != opacity ||
                                m_shadowCasters[i - 1, j].Opacity != opacity ||
                                m_shadowCasters[i + 1, j].Opacity != opacity)
                            {
                                var rect = new RectangleF(i, j, 1, 1);

                                Action <PointF, PointF> add = (_a, _b) =>
                                {
                                    var edge = new EdgeEx(_a, _b);
                                    int doubleIndex;
                                    if (hs.TryGetValue(edge.GetHashCode(), out doubleIndex) &&
                                        m_allEdges[doubleIndex].Opacity == opacity)
                                    {
                                        hs.Remove(edge.GetHashCode());
                                        m_edgesCount--;
                                        doubles++;
                                        hs[m_allEdges[m_edgesCount].GetHashCode()] = doubleIndex;
                                        m_allEdges[doubleIndex] = m_allEdges[m_edgesCount];
                                        return;
                                    }
                                    hs[edge.GetHashCode()]     = m_edgesCount;
                                    m_allEdges[m_edgesCount++] = new EdgeEx(_a, _b)
                                    {
                                        Opacity     = opacity,
                                        LiveMapCell = lmc,
                                        CellCenter  = new PointF(i, j)
                                    };
                                };

                                add(new PointF(rect.Left, rect.Top), new PointF(rect.Right, rect.Top));
                                add(new PointF(rect.Right, rect.Bottom), new PointF(rect.Left, rect.Bottom));
                                add(new PointF(rect.Right, rect.Top), new PointF(rect.Right, rect.Bottom));
                                add(new PointF(rect.Left, rect.Bottom), new PointF(rect.Left, rect.Top));
                            }
                        }
                    }
                }
            }
        }