Пример #1
0
    public static void BuildSurfaceDisplayList(msurface_t fa)
    {
        // reconstruct the polygon
        medge_t[] pedges    = currentmodel.edges;
        int       lnumverts = fa.numedges;

        //
        // draw texture
        //
        glpoly_t poly = new glpoly_t();

        poly.AllocVerts(lnumverts);
        poly.next  = fa.polys;
        poly.flags = fa.flags;
        fa.polys   = poly;

        ushort[] r_pedge_v;
        Vector3  vec;

        for (int i = 0; i < lnumverts; i++)
        {
            int lindex = currentmodel.surfedges[fa.firstedge + i];
            if (lindex > 0)
            {
                r_pedge_v = pedges[lindex].v;
                vec       = r_pcurrentvertbase[r_pedge_v[0]].position;
            }
            else
            {
                r_pedge_v = pedges[-lindex].v;
                vec       = r_pcurrentvertbase[r_pedge_v[1]].position;
            }
            float s = Mathlib.DotProduct(ref vec, ref fa.texinfo.vecs[0]) + fa.texinfo.vecs[0].W;
            s /= fa.texinfo.texture.width;

            float t = Mathlib.DotProduct(ref vec, ref fa.texinfo.vecs[1]) + fa.texinfo.vecs[1].W;
            t /= fa.texinfo.texture.height;

            poly.verts[i][0] = vec.X;
            poly.verts[i][1] = vec.Y;
            poly.verts[i][2] = vec.Z;
            poly.verts[i][3] = s;
            poly.verts[i][4] = t;

            //
            // lightmap texture coordinates
            //
            s  = Mathlib.DotProduct(ref vec, ref fa.texinfo.vecs[0]) + fa.texinfo.vecs[0].W;
            s -= fa.texturemins[0];
            s += fa.light_s * 16;
            s += 8;
            s /= BLOCK_WIDTH * 16;

            t  = Mathlib.DotProduct(ref vec, ref fa.texinfo.vecs[1]) + fa.texinfo.vecs[1].W;
            t -= fa.texturemins[1];
            t += fa.light_t * 16;
            t += 8;
            t /= BLOCK_HEIGHT * 16;

            poly.verts[i][5] = s;
            poly.verts[i][6] = t;
        }

        //
        // remove co-linear points - Ed
        //
        if (gl_keeptjunctions.value == 0 && (fa.flags & q_shared.SURF_UNDERWATER) == 0)
        {
            for (int i = 0; i < lnumverts; ++i)
            {
                if (IsCollinear(poly.verts[(i + lnumverts - 1) % lnumverts],
                                poly.verts[i],
                                poly.verts[(i + 1) % lnumverts]))
                {
                    int j;
                    for (j = i + 1; j < lnumverts; ++j)
                    {
                        //int k;
                        for (int k = 0; k < q_shared.VERTEXSIZE; ++k)
                        {
                            poly.verts[j - 1][k] = poly.verts[j][k];
                        }
                    }
                    --lnumverts;
                    ++nColinElim;
                    // retry next vertex next time, which is now current vertex
                    --i;
                }
            }
        }
        poly.numverts = lnumverts;
    }
Пример #2
0
    static void SubdividePolygon(int numverts, Vector3[] verts)
    {
        if (numverts > 60)
        {
            Sys_Error("numverts = {0}", numverts);
        }

        Vector3 mins, maxs;

        BoundPoly(numverts, verts, out mins, out maxs);

        float[] dist = new float[64];
        for (int i = 0; i < 3; i++)
        {
            double m = (Mathlib.Comp(ref mins, i) + Mathlib.Comp(ref maxs, i)) * 0.5;
            m = gl_subdivide_size.value * Math.Floor(m / gl_subdivide_size.value + 0.5);
            if (Mathlib.Comp(ref maxs, i) - m < 8)
            {
                continue;
            }

            if (m - Mathlib.Comp(ref mins, i) < 8)
            {
                continue;
            }

            for (int j = 0; j < numverts; j++)
            {
                dist[j] = (float)(Mathlib.Comp(ref verts[j], i) - m);
            }

            Vector3[] front = new Vector3[64];
            Vector3[] back  = new Vector3[64];

            // cut it

            // wrap cases
            dist[numverts]  = dist[0];
            verts[numverts] = verts[0]; // Uze: source array must be at least numverts + 1 elements long

            int f = 0, b = 0;
            for (int j = 0; j < numverts; j++)
            {
                if (dist[j] >= 0)
                {
                    front[f] = verts[j];
                    f++;
                }
                if (dist[j] <= 0)
                {
                    back[b] = verts[j];
                    b++;
                }
                if (dist[j] == 0 || dist[j + 1] == 0)
                {
                    continue;
                }
                if ((dist[j] > 0) != (dist[j + 1] > 0))
                {
                    // clip point
                    float frac = dist[j] / (dist[j] - dist[j + 1]);
                    front[f] = back[b] = verts[j] + (verts[j + 1] - verts[j]) * frac;
                    f++;
                    b++;
                }
            }

            SubdividePolygon(f, front);
            SubdividePolygon(b, back);
            return;
        }

        glpoly_t poly = new glpoly_t();

        poly.next       = _WarpFace.polys;
        _WarpFace.polys = poly;
        poly.AllocVerts(numverts);
        for (int i = 0; i < numverts; i++)
        {
            Copy(ref verts[i], poly.verts[i]);
            float s = Vector3.Dot(verts[i], _WarpFace.texinfo.vecs[0].Xyz);
            float t = Vector3.Dot(verts[i], _WarpFace.texinfo.vecs[1].Xyz);
            poly.verts[i][3] = s;
            poly.verts[i][4] = t;
        }
    }