예제 #1
0
        public virtual void SubdividePolygon(int numverts, float[][] verts)
        {
            int   i, j, k;
            float m;

            float[][] front = Lib.CreateJaggedArray <float[][]>(64, 3);
            float[][] back = Lib.CreateJaggedArray <float[][]>(64, 3);
            int       f, b;

            float[] dist = new float[64];
            float   frac;

            if (numverts > 60)
            {
                Com.Error(Defines.ERR_DROP, "numverts = " + numverts);
            }
            float[] mins = Vec3Cache.Get();
            float[] maxs = Vec3Cache.Get();
            BoundPoly(numverts, verts, mins, maxs);
            float[] v;
            for (i = 0; i < 3; i++)
            {
                m = (mins[i] + maxs[i]) * 0.5F;
                m = SUBDIVIDE_SIZE * (float)Math.Floor(m / SUBDIVIDE_SIZE + 0.5F);
                if (maxs[i] - m < 8)
                {
                    continue;
                }
                if (m - mins[i] < 8)
                {
                    continue;
                }
                for (j = 0; j < numverts; j++)
                {
                    dist[j] = verts[j][i] - m;
                }

                dist[j] = dist[0];
                Math3D.VectorCopy(verts[0], verts[numverts]);
                f = b = 0;
                for (j = 0; j < numverts; j++)
                {
                    v = verts[j];
                    if (dist[j] >= 0)
                    {
                        Math3D.VectorCopy(v, front[f]);
                        f++;
                    }

                    if (dist[j] <= 0)
                    {
                        Math3D.VectorCopy(v, back[b]);
                        b++;
                    }

                    if (dist[j] == 0 || dist[j + 1] == 0)
                    {
                        continue;
                    }
                    if ((dist[j] > 0) != (dist[j + 1] > 0))
                    {
                        frac = dist[j] / (dist[j] - dist[j + 1]);
                        for (k = 0; k < 3; k++)
                        {
                            front[f][k] = back[b][k] = v[k] + frac * (verts[j + 1][k] - v[k]);
                        }
                        f++;
                        b++;
                    }
                }

                SubdividePolygon(f, front);
                SubdividePolygon(b, back);
                Vec3Cache.Release(2);
                return;
            }

            Vec3Cache.Release(2);
            glpoly_t poly = Polygon.Create(numverts + 2);

            poly.next      = warpface.polys;
            warpface.polys = poly;
            float[] total = Vec3Cache.Get();
            Math3D.VectorClear(total);
            float total_s = 0;
            float total_t = 0;
            float s, t;

            for (i = 0; i < numverts; i++)
            {
                poly.X(i + 1, verts[i][0]);
                poly.Y(i + 1, verts[i][1]);
                poly.Z(i + 1, verts[i][2]);
                s        = Math3D.DotProduct(verts[i], warpface.texinfo.vecs[0]);
                t        = Math3D.DotProduct(verts[i], warpface.texinfo.vecs[1]);
                total_s += s;
                total_t += t;
                Math3D.VectorAdd(total, verts[i], total);
                poly.S1(i + 1, s);
                poly.T1(i + 1, t);
            }

            float scale = 1F / numverts;

            poly.X(0, total[0] * scale);
            poly.Y(0, total[1] * scale);
            poly.Z(0, total[2] * scale);
            poly.S1(0, total_s * scale);
            poly.T1(0, total_t * scale);
            poly.X(i + 1, poly.X(1));
            poly.Y(i + 1, poly.Y(1));
            poly.Z(i + 1, poly.Z(1));
            poly.S1(i + 1, poly.S1(1));
            poly.T1(i + 1, poly.T1(1));
            poly.S2(i + 1, poly.S2(1));
            poly.T2(i + 1, poly.T2(1));
            Vec3Cache.Release();
        }
예제 #2
0
        public virtual Int32 RecursiveLightPoint(mnode_t node, Single[] start, Single[] end)
        {
            if (node.contents != -1)
            {
                return(-1);
            }
            cplane_t plane     = node.plane;
            var      front     = Math3D.DotProduct(start, plane.normal) - plane.dist;
            var      back      = Math3D.DotProduct(end, plane.normal) - plane.dist;
            var      side      = (front < 0);
            var      sideIndex = (side) ? 1 : 0;

            if ((back < 0) == side)
            {
                return(RecursiveLightPoint(node.children[sideIndex], start, end));
            }
            var frac = front / (front - back);

            Single[] mid = Vec3Cache.Get();
            mid[0] = start[0] + (end[0] - start[0]) * frac;
            mid[1] = start[1] + (end[1] - start[1]) * frac;
            mid[2] = start[2] + (end[2] - start[2]) * frac;
            var r = RecursiveLightPoint(node.children[sideIndex], start, mid);

            if (r >= 0)
            {
                Vec3Cache.Release();
                return(r);
            }

            if ((back < 0) == side)
            {
                Vec3Cache.Release();
                return(-1);
            }

            Math3D.VectorCopy(mid, lightspot);
            lightplane = plane;
            var        surfIndex = node.firstsurface;
            msurface_t surf;
            Int32      s, t, ds, dt;
            mtexinfo_t tex;
            ByteBuffer lightmap;
            Int32      maps;

            for (var i = 0; i < node.numsurfaces; i++, surfIndex++)
            {
                surf = r_worldmodel.surfaces[surfIndex];
                if ((surf.flags & (Defines.SURF_DRAWTURB | Defines.SURF_DRAWSKY)) != 0)
                {
                    continue;
                }
                tex = surf.texinfo;
                s   = ( Int32 )(Math3D.DotProduct(mid, tex.vecs[0]) + tex.vecs[0][3]);
                t   = ( Int32 )(Math3D.DotProduct(mid, tex.vecs[1]) + tex.vecs[1][3]);
                if (s < surf.texturemins[0] || t < surf.texturemins[1])
                {
                    continue;
                }
                ds = s - surf.texturemins[0];
                dt = t - surf.texturemins[1];
                if (ds > surf.extents[0] || dt > surf.extents[1])
                {
                    continue;
                }
                if (surf.samples == null)
                {
                    return(0);
                }
                ds     >>= 4;
                dt     >>= 4;
                lightmap = surf.samples;
                var lightmapIndex = 0;
                Math3D.VectorCopy(Globals.vec3_origin, pointcolor);
                if (lightmap != null)
                {
                    Single[] rgb;
                    lightmapIndex += 3 * (dt * ((surf.extents[0] >> 4) + 1) + ds);
                    Single scale0, scale1, scale2;
                    for (maps = 0; maps < Defines.MAXLIGHTMAPS && surf.styles[maps] != ( Byte )255; maps++)
                    {
                        rgb            = r_newrefdef.lightstyles[surf.styles[maps] & 0xFF].rgb;
                        scale0         = gl_modulate.value * rgb[0];
                        scale1         = gl_modulate.value * rgb[1];
                        scale2         = gl_modulate.value * rgb[2];
                        pointcolor[0] += (lightmap.Get(lightmapIndex + 0) & 0xFF) * scale0 * (1F / 255);
                        pointcolor[1] += (lightmap.Get(lightmapIndex + 1) & 0xFF) * scale1 * (1F / 255);
                        pointcolor[2] += (lightmap.Get(lightmapIndex + 2) & 0xFF) * scale2 * (1F / 255);
                        lightmapIndex += 3 * ((surf.extents[0] >> 4) + 1) * ((surf.extents[1] >> 4) + 1);
                    }
                }

                Vec3Cache.Release();
                return(1);
            }

            r = RecursiveLightPoint(node.children[1 - sideIndex], mid, end);
            Vec3Cache.Release();
            return(r);
        }