Exemplo n.º 1
0
        // Returns the point where the bolt is at a given fraction of the way through the bolt. Passing
        // zero will return the start of the bolt, and passing 1 will return the end.
        public virtual CCPoint GetPoint(float position)
        {
//            var start = _Start;
//            float length = CCPoint.Distance(start, _End);
//            CCPoint dir = (_End - start) / length;
            float u = position;

            position = u * _TrackLength;

            float rem = position;

            for (int i = 0; i < _SegmentLengths.Length; i++)
            {
                if (rem - _SegmentLengths[i] <= 0f)
                {
                    // Query is on this segment
                    CCPoint dir = _Track[i * 2 + 1] - _Track[i * 2];
                    dir.Normalize();
                    CCPoint pt = _Track[i * 2] + dir * rem;
                    // CCLog.Log("GetPoint() position = {0}, segment={1}, pt={2}, end={3}", position, i, pt, _End);
                    return(pt);
                }
                else
                {
                    // Query after this segment
                    rem -= _SegmentLengths[i];
                }
            }
            // New algorithm did not work, so use the old algorithm
            position = u * _Length;
            for (int i = 0; i < _Track.Count; i += 2)
            {
                if (CCPoint.Dot(_Track[i] - _Start, _uDir) >= position)
                {
                    float lineStartPos = CCPoint.Dot(_Track[i] - _Start, _uDir);
                    float lineEndPos   = CCPoint.Dot(_Track[i + 1] - _Start, _uDir);
                    float linePos      = (position - lineStartPos) / (lineEndPos - lineStartPos);

                    return(CCPoint.Lerp(_Track[i], _Track[i + 1], linePos));
                }
            }
            // Here means we are beyond the length of the track, which may happen due to floating point
            // precision error. Just return the end.
            return(_End);
        }
Exemplo n.º 2
0
        // Returns the point where the bolt is at a given fraction of the way through the bolt. Passing
        // zero will return the start of the bolt, and passing 1 will return the end.
        private CCPoint GetPoint(BoltStatus b, float position)
        {
            var     start  = b.Bolt.Start;
            float   length = CCPoint.Distance(start, b.Bolt.End);
            CCPoint dir    = (b.Bolt.End - start) / length;

            position *= length;

            for (int i = 0; i < b.Segments.Count; i += 2)
            {
                if (CCPoint.Dot(b.Segments[i] - start, dir) >= position)
                {
                    float lineStartPos = CCPoint.Dot(b.Segments[i] - start, dir);
                    float lineEndPos   = CCPoint.Dot(b.Segments[i + 1] - start, dir);
                    float linePos      = (position - lineStartPos) / (lineEndPos - lineStartPos);

                    return(CCPoint.Lerp(b.Segments[i], b.Segments[i + 1], linePos));
                }
            }
            return(CCPoint.Zero);
        }
Exemplo n.º 3
0
        public void DrawPolygon(CCPoint[] verts, int count, CCColor4F fillColor, float borderWidth,
                                CCColor4F borderColor)
        {
            var extrude = new ExtrudeVerts[count];

            for (int i = 0; i < count; i++)
            {
                var v0 = verts[(i - 1 + count) % count];
                var v1 = verts[i];
                var v2 = verts[(i + 1) % count];

                var n1 = CCPoint.Normalize(CCPoint.Perp(v1 - v0));
                var n2 = CCPoint.Normalize(CCPoint.Perp(v2 - v1));

                var offset = (n1 + n2) * (1.0f / (CCPoint.Dot(n1, n2) + 1.0f));
                extrude[i] = new ExtrudeVerts()
                {
                    offset = offset, n = n2
                };
            }

            bool outline = (fillColor.A > 0.0f && borderWidth > 0.0f);

            float inset = (!outline ? 0.5f : 0.0f);

            for (int i = 0; i < count - 2; i++)
            {
                var v0 = verts[0] - (extrude[0].offset * inset);
                var v1 = verts[i + 1] - (extrude[i + 1].offset * inset);
                var v2 = verts[i + 2] - (extrude[i + 2].offset * inset);

                m_pVertices.Add(new VertexPositionColor(v0, fillColor)); //__t(v2fzero)
                m_pVertices.Add(new VertexPositionColor(v1, fillColor)); //__t(v2fzero)
                m_pVertices.Add(new VertexPositionColor(v2, fillColor)); //__t(v2fzero)
            }

            for (int i = 0; i < count; i++)
            {
                int j  = (i + 1) % count;
                var v0 = verts[i];
                var v1 = verts[j];

                var n0 = extrude[i].n;

                var offset0 = extrude[i].offset;
                var offset1 = extrude[j].offset;

                if (outline)
                {
                    var inner0 = (v0 - (offset0 * borderWidth));
                    var inner1 = (v1 - (offset1 * borderWidth));
                    var outer0 = (v0 + (offset0 * borderWidth));
                    var outer1 = (v1 + (offset1 * borderWidth));

                    m_pVertices.Add(new VertexPositionColor(inner0, borderColor)); //__t(v2fneg(n0))
                    m_pVertices.Add(new VertexPositionColor(inner1, borderColor)); //__t(v2fneg(n0))
                    m_pVertices.Add(new VertexPositionColor(outer1, borderColor)); //__t(n0)

                    m_pVertices.Add(new VertexPositionColor(inner0, borderColor)); //__t(v2fneg(n0))
                    m_pVertices.Add(new VertexPositionColor(outer0, borderColor)); //__t(n0)
                    m_pVertices.Add(new VertexPositionColor(outer1, borderColor)); //__t(n0)
                }
                else
                {
                    var inner0 = (v0 - (offset0 * 0.5f));
                    var inner1 = (v1 - (offset1 * 0.5f));
                    var outer0 = (v0 + (offset0 * 0.5f));
                    var outer1 = (v1 + (offset1 * 0.5f));

                    m_pVertices.Add(new VertexPositionColor(inner0, fillColor)); //__t(v2fzero)
                    m_pVertices.Add(new VertexPositionColor(inner1, fillColor)); //__t(v2fzero)
                    m_pVertices.Add(new VertexPositionColor(outer1, fillColor)); //__t(n0)

                    m_pVertices.Add(new VertexPositionColor(inner0, fillColor)); //__t(v2fzero)
                    m_pVertices.Add(new VertexPositionColor(outer0, fillColor)); //__t(n0)
                    m_pVertices.Add(new VertexPositionColor(outer1, fillColor)); //__t(n0)
                }
            }

            m_bDirty = true;
        }
Exemplo n.º 4
0
        private void VertexLineToPolygon(CCPoint[] points, float stroke, CCV3F_C4B_T2F[] vertices, int offset, int nuPoints)
        {
            nuPoints += offset;
            if (nuPoints <= 1)
            {
                return;
            }

            stroke *= 0.5f;

            int idx;
            int nuPointsMinus = nuPoints - 1;

            float rad70  = MathHelper.ToRadians(70);
            float rad170 = MathHelper.ToRadians(170);

            for (int i = offset; i < nuPoints; i++)
            {
                idx = i * 2;
                CCPoint p1 = points[i];
                CCPoint perpVector;

                if (i == 0)
                {
                    perpVector = CCPoint.Perp(CCPoint.Normalize(p1 - points[i + 1]));
                }
                else if (i == nuPointsMinus)
                {
                    perpVector = CCPoint.Perp(CCPoint.Normalize(points[i - 1] - p1));
                }
                else
                {
                    CCPoint p2 = points[i + 1];
                    CCPoint p0 = points[i - 1];

                    CCPoint p2p1 = CCPoint.Normalize(p2 - p1);
                    CCPoint p0p1 = CCPoint.Normalize(p0 - p1);

                    // Calculate angle between vectors
                    var angle = (float)Math.Acos(CCPoint.Dot(p2p1, p0p1));

                    if (angle < rad70)
                    {
                        perpVector = CCPoint.Perp(CCPoint.Normalize(CCPoint.Midpoint(p2p1, p0p1)));
                    }
                    else if (angle < rad170)
                    {
                        perpVector = CCPoint.Normalize(CCPoint.Midpoint(p2p1, p0p1));
                    }
                    else
                    {
                        perpVector = CCPoint.Perp(CCPoint.Normalize(p2 - p0));
                    }
                }

                perpVector = perpVector * stroke;

                vertices[idx].Vertices     = new CCVertex3F(p1.X + perpVector.X, p1.Y + perpVector.Y, 0);
                vertices[idx + 1].Vertices = new CCVertex3F(p1.X - perpVector.X, p1.Y - perpVector.Y, 0);
            }

            // Validate vertexes
            offset = (offset == 0) ? 0 : offset - 1;
            for (int i = offset; i < nuPointsMinus; i++)
            {
                idx = i * 2;
                int idx1 = idx + 2;

                CCVertex3F p1 = vertices[idx].Vertices;
                CCVertex3F p2 = vertices[idx + 1].Vertices;
                CCVertex3F p3 = vertices[idx1].Vertices;
                CCVertex3F p4 = vertices[idx1 + 1].Vertices;

                float s;
                bool  fixVertex = !ccVertexLineIntersect(p1.X, p1.Y, p4.X, p4.Y, p2.X, p2.Y, p3.X, p3.Y, out s);
                if (!fixVertex)
                {
                    if (s < 0.0f || s > 1.0f)
                    {
                        fixVertex = true;
                    }
                }

                if (fixVertex)
                {
                    vertices[idx1].Vertices     = p4;
                    vertices[idx1 + 1].Vertices = p3;
                }
            }
        }