コード例 #1
0
        /*
         * ================
         * R_RenderBmodelFace
         * ================
         */
        static void R_RenderBmodelFace(bedge_t pedges, model.msurface_t psurf)
        {
            int  i;
            uint mask;

            model.mplane_t pplane;
            double         distinv;

            double[]      p_normal = new double[3];
            model.medge_t tedge    = new model.medge_t();
            clipplane_t   pclip;

            // skip out if no more surfs
            if (surface_p >= surf_max)
            {
                r_outofsurfaces++;
                return;
            }

            // ditto if not enough edges left, or switch to auxedges if possible
            if ((edge_p + psurf.numedges + 4) >= edge_max)
            {
                r_outofedges += psurf.numedges;
                return;
            }

            c_faceclip++;

            // this is a dummy to give the caching mechanism someplace to write to
            r_pedge = tedge;

            // set up clip planes
            pclip = null;

            for (i = 3, mask = 0x08; i >= 0; i--, mask >>= 1)
            {
                if ((r_clipflags & mask) != 0)
                {
                    view_clipplanes[i].next = pclip;
                    pclip = view_clipplanes[i];
                }
            }

            // push the edges through
            r_emitted    = 0;
            r_nearzi     = 0;
            r_nearzionly = false;
            makeleftedge = makerightedge = false;
            // FIXME: keep clipped bmodel edges in clockwise order so last vertex caching
            // can be used?
            r_lastvertvalid = false;

            for ( ; pedges != null; pedges = pedges.pnext)
            {
                r_leftclipped = r_rightclipped = false;
                R_ClipEdge(pedges.v[0], pedges.v[1], pclip);

                if (r_leftclipped)
                {
                    makeleftedge = true;
                }
                if (r_rightclipped)
                {
                    makerightedge = true;
                }
            }

            // if there was a clip off the left edge, add that edge too
            // FIXME: faster to do in screen space?
            // FIXME: share clipped edges?
            if (makeleftedge)
            {
                r_pedge = tedge;
                R_ClipEdge(r_leftexit, r_leftenter, pclip.next);
            }

            // if there was a clip off the right edge, get the right r_nearzi
            if (makerightedge)
            {
                r_pedge      = tedge;
                r_nearzionly = true;
                R_ClipEdge(r_rightexit, r_rightenter, view_clipplanes[1].next);
            }

            // if no edges made it out, return without posting the surface
            if (r_emitted == 0)
            {
                return;
            }

            r_polycount++;

            surfaces[surface_p].data       = psurf;
            surfaces[surface_p].nearzi     = r_nearzi;
            surfaces[surface_p].flags      = psurf.flags;
            surfaces[surface_p].insubmodel = true;
            surfaces[surface_p].spanstate  = 0;
            surfaces[surface_p].entity     = currententity;
            surfaces[surface_p].key        = r_currentbkey;
            surfaces[surface_p].spans      = null;

            pplane = psurf.plane;
            // FIXME: cache this?
            TransformVector(pplane.normal, ref p_normal);
            // FIXME: cache this?
            distinv = 1.0 / (pplane.dist - mathlib.DotProduct(modelorg, pplane.normal));

            surfaces[surface_p].d_zistepu  = p_normal[0] * xscaleinv * distinv;
            surfaces[surface_p].d_zistepv  = -p_normal[1] * yscaleinv * distinv;
            surfaces[surface_p].d_ziorigin = p_normal[2] * distinv -
                                             xcenter * surfaces[surface_p].d_zistepu -
                                             ycenter * surfaces[surface_p].d_zistepv;

            //JDC	VectorCopy (r_worldmodelorg, surface_p.modelorg);
            surface_p++;
        }
コード例 #2
0
        /*
         * ================
         * R_RenderFace
         * ================
         */
        static void R_RenderFace(model.msurface_t fa, int clipflags)
        {
            int  i, lindex;
            uint mask;

            model.mplane_t pplane;
            double         distinv;

            double[]        p_normal = new double[3];
            model.medge_t[] pedges;
            model.medge_t   tedge = new model.medge_t();
            clipplane_t     pclip;

            // skip out if no more surfs
            if ((surface_p) >= surf_max)
            {
                r_outofsurfaces++;
                return;
            }

            // ditto if not enough edges left, or switch to auxedges if possible
            if ((edge_p + fa.numedges + 4) >= edge_max)
            {
                r_outofedges += fa.numedges;
                return;
            }

            c_faceclip++;

            // set up clip planes
            pclip = null;

            for (i = 3, mask = 0x08; i >= 0; i--, mask >>= 1)
            {
                if ((clipflags & mask) != 0)
                {
                    view_clipplanes[i].next = pclip;
                    pclip = view_clipplanes[i];
                }
            }

            // push the edges through
            r_emitted       = 0;
            r_nearzi        = 0;
            r_nearzionly    = false;
            makeleftedge    = makerightedge = false;
            pedges          = currententity.model.edges;
            r_lastvertvalid = false;

            for (i = 0; i < fa.numedges; i++)
            {
                lindex = currententity.model.surfedges[fa.firstedge + i];

                if (lindex > 0)
                {
                    r_pedge = pedges[lindex];

                    // if the edge is cached, we can just reuse the edge
                    if (!insubmodel)
                    {
                        if ((r_pedge.cachededgeoffset & FULLY_CLIPPED_CACHED) != 0)
                        {
                            if ((r_pedge.cachededgeoffset & FRAMECOUNT_MASK) ==
                                r_framecount)
                            {
                                r_lastvertvalid = false;
                                continue;
                            }
                        }
                        else
                        {
                            if ((edge_p > r_pedge.cachededgeoffset) &&
                                (r_edges[r_pedge.cachededgeoffset].owner == r_pedge))
                            {
                                R_EmitCachedEdge();
                                r_lastvertvalid = false;
                                continue;
                            }
                        }
                    }

                    // assume it's cacheable
                    cacheoffset   = (uint)edge_p;
                    r_leftclipped = r_rightclipped = false;
                    R_ClipEdge(r_pcurrentvertbase[r_pedge.v[0]],
                               r_pcurrentvertbase[r_pedge.v[1]],
                               pclip);
                    r_pedge.cachededgeoffset = cacheoffset;

                    if (r_leftclipped)
                    {
                        makeleftedge = true;
                    }
                    if (r_rightclipped)
                    {
                        makerightedge = true;
                    }
                    r_lastvertvalid = true;
                }
                else
                {
                    lindex  = -lindex;
                    r_pedge = pedges[lindex];
                    // if the edge is cached, we can just reuse the edge
                    if (!insubmodel)
                    {
                        if ((r_pedge.cachededgeoffset & FULLY_CLIPPED_CACHED) != 0)
                        {
                            if ((r_pedge.cachededgeoffset & FRAMECOUNT_MASK) ==
                                r_framecount)
                            {
                                r_lastvertvalid = false;
                                continue;
                            }
                        }
                        else
                        {
                            // it's cached if the cached edge is valid and is owned
                            // by this medge_t
                            if ((edge_p > r_pedge.cachededgeoffset) &&
                                (r_edges[r_pedge.cachededgeoffset].owner == r_pedge))
                            {
                                R_EmitCachedEdge();
                                r_lastvertvalid = false;
                                continue;
                            }
                        }
                    }

                    // assume it's cacheable
                    cacheoffset   = (uint)edge_p;
                    r_leftclipped = r_rightclipped = false;
                    R_ClipEdge(r_pcurrentvertbase[r_pedge.v[1]],
                               r_pcurrentvertbase[r_pedge.v[0]],
                               pclip);
                    r_pedge.cachededgeoffset = cacheoffset;

                    if (r_leftclipped)
                    {
                        makeleftedge = true;
                    }
                    if (r_rightclipped)
                    {
                        makerightedge = true;
                    }
                    r_lastvertvalid = true;
                }
            }

            // if there was a clip off the left edge, add that edge too
            // FIXME: faster to do in screen space?
            // FIXME: share clipped edges?
            if (makeleftedge)
            {
                r_pedge         = tedge;
                r_lastvertvalid = false;
                R_ClipEdge(r_leftexit, r_leftenter, pclip.next);
            }

            // if there was a clip off the right edge, get the right r_nearzi
            if (makerightedge)
            {
                r_pedge         = tedge;
                r_lastvertvalid = false;
                r_nearzionly    = true;
                R_ClipEdge(r_rightexit, r_rightenter, view_clipplanes[1].next);
            }

            // if no edges made it out, return without posting the surface
            if (r_emitted == 0)
            {
                return;
            }

            r_polycount++;

            surfaces[surface_p].data       = fa;
            surfaces[surface_p].nearzi     = r_nearzi;
            surfaces[surface_p].flags      = fa.flags;
            surfaces[surface_p].insubmodel = insubmodel;
            surfaces[surface_p].spanstate  = 0;
            surfaces[surface_p].entity     = currententity;
            surfaces[surface_p].key        = r_currentkey++;
            surfaces[surface_p].spans      = null;

            pplane = fa.plane;
            // FIXME: cache this?
            TransformVector(pplane.normal, ref p_normal);
            // FIXME: cache this?
            distinv = 1.0 / (pplane.dist - mathlib.DotProduct(modelorg, pplane.normal));

            surfaces[surface_p].d_zistepu  = p_normal[0] * xscaleinv * distinv;
            surfaces[surface_p].d_zistepv  = -p_normal[1] * yscaleinv * distinv;
            surfaces[surface_p].d_ziorigin = p_normal[2] * distinv -
                                             xcenter * surfaces[surface_p].d_zistepu -
                                             ycenter * surfaces[surface_p].d_zistepv;

            //JDC	VectorCopy (r_worldmodelorg, surface_p->modelorg);
            surface_p++;
        }