Esempio n. 1
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] {0, 0, 0};
            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, 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++;
        }
Esempio n. 2
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] {0, 0, 0};
            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, 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++;
        }