Пример #1
0
        /*
         * ================
         * R_Alias_clip_z
         *
         * pfv0 is the unclipped vertex, pfv1 is the z-clipped vertex
         * ================
         */
        static void R_Alias_clip_z(draw.finalvert_t pfv0, draw.finalvert_t pfv1, ref draw.finalvert_t @out)
        {
            double    scale;
            auxvert_t pav0, pav1, avout = new auxvert_t();

            pav0 = av[av0];
            pav1 = av[av1];

            if (pfv0.v[1] >= pfv1.v[1])
            {
                scale = (ALIAS_Z_CLIP_PLANE - pav0.fv[2]) /
                        (pav1.fv[2] - pav0.fv[2]);

                avout.fv[0] = pav0.fv[0] + (pav1.fv[0] - pav0.fv[0]) * scale;
                avout.fv[1] = pav0.fv[1] + (pav1.fv[1] - pav0.fv[1]) * scale;
                avout.fv[2] = ALIAS_Z_CLIP_PLANE;

                @out.v[2] = (int)(pfv0.v[2] + (pfv1.v[2] - pfv0.v[2]) * scale);
                @out.v[3] = (int)(pfv0.v[3] + (pfv1.v[3] - pfv0.v[3]) * scale);
                @out.v[4] = (int)(pfv0.v[4] + (pfv1.v[4] - pfv0.v[4]) * scale);
            }
            else
            {
                scale = (ALIAS_Z_CLIP_PLANE - pav1.fv[2]) /
                        (pav0.fv[2] - pav1.fv[2]);

                avout.fv[0] = pav1.fv[0] + (pav0.fv[0] - pav1.fv[0]) * scale;
                avout.fv[1] = pav1.fv[1] + (pav0.fv[1] - pav1.fv[1]) * scale;
                avout.fv[2] = ALIAS_Z_CLIP_PLANE;

                @out.v[2] = (int)(pfv1.v[2] + (pfv0.v[2] - pfv1.v[2]) * scale);
                @out.v[3] = (int)(pfv1.v[3] + (pfv0.v[3] - pfv1.v[3]) * scale);
                @out.v[4] = (int)(pfv1.v[4] + (pfv0.v[4] - pfv1.v[4]) * scale);
            }

            R_AliasProjectFinalVert(@out, avout);

            if (@out.v[0] < r_refdef.aliasvrect.x)
            {
                @out.flags |= ALIAS_LEFT_CLIP;
            }
            if (@out.v[1] < r_refdef.aliasvrect.y)
            {
                @out.flags |= ALIAS_TOP_CLIP;
            }
            if (@out.v[0] > r_refdef.aliasvrectright)
            {
                @out.flags |= ALIAS_RIGHT_CLIP;
            }
            if (@out.v[1] > r_refdef.aliasvrectbottom)
            {
                @out.flags |= ALIAS_BOTTOM_CLIP;
            }
        }
Пример #2
0
        static void r_alias_init()
        {
            finalverts = new draw.finalvert_t[MAXALIASVERTS];
            auxverts   = new auxvert_t[MAXALIASVERTS];

            for (int kk = 0; kk < MAXALIASVERTS; kk++)
            {
                finalverts[kk] = new draw.finalvert_t();
                auxverts[kk]   = new auxvert_t();
            }
        }
Пример #3
0
        /*
         * ================
         * R_AliasProjectFinalVert
         * ================
         */
        static void R_AliasProjectFinalVert(draw.finalvert_t fv, auxvert_t av)
        {
            double zi;

            // project points
            zi = 1.0 / av.fv[2];

            fv.v[5] = (int)(zi * ziscale);

            fv.v[0] = (int)((av.fv[0] * aliasxscale * zi) + aliasxcenter);
            fv.v[1] = (int)((av.fv[1] * aliasyscale * zi) + aliasycenter);
        }
Пример #4
0
        /*
         * ================
         * R_AliasTransformFinalVert
         * ================
         */
        static void R_AliasTransformFinalVert(draw.finalvert_t fv, auxvert_t av,
                                              model.trivertx_t pverts, model.stvert_t pstverts)
        {
            int    temp;
            double lightcos;

            double[] plightnormal;

            av.fv[0] = mathlib.DotProduct(pverts.v, aliastransform[0]) +
                       aliastransform[0][3];
            av.fv[1] = mathlib.DotProduct(pverts.v, aliastransform[1]) +
                       aliastransform[1][3];
            av.fv[2] = mathlib.DotProduct(pverts.v, aliastransform[2]) +
                       aliastransform[2][3];

            fv.v[2] = pstverts.s;
            fv.v[3] = pstverts.t;

            fv.flags = pstverts.onseam;

            // lighting
            plightnormal = r_avertexnormals[pverts.lightnormalindex];
            lightcos     = mathlib.DotProduct(plightnormal, r_plightvec);
            temp         = r_ambientlight;

            if (lightcos < 0)
            {
                temp += (int)(r_shadelight * lightcos);

                // clamp; because we limited the minimum ambient and shading light, we
                // don't have to clamp low light, just bright
                if (temp < 0)
                {
                    temp = 0;
                }
            }

            fv.v[4] = temp;
        }
Пример #5
0
        static render()
        {
            int kk;
            int i, j;

            for (kk = 0; kk < 4; kk++)
            {
                screenedge[kk] = new model.mplane_t();
            }
            for (kk = 0; kk < 4; kk++)
            {
                view_clipplanes[kk] = new render.clipplane_t();
            }
            for (kk = 0; kk < 16; kk++)
            {
                world_clipplanes[kk] = new render.clipplane_t();
            }
            for (i = 0; i < 2; i++)
            {
                for (j = 0; j < MAXWORKINGVERTS; j++)
                {
                    clip_verts[i][j] = new double[5];
                }
            }
            for (i = 0; i < 2; i++)
            {
                for (j = 0; j < 8; j++)
                {
                    fva[i][j] = new draw.finalvert_t();
                }
            }
            for (kk = 0; kk < 8; kk++)
            {
                av[kk] = new auxvert_t();
            }
            r_alias_init();
        }
Пример #6
0
        /*
        ================
        R_Alias_clip_z

        pfv0 is the unclipped vertex, pfv1 is the z-clipped vertex
        ================
        */
        static void R_Alias_clip_z(draw.finalvert_t pfv0, draw.finalvert_t pfv1, ref draw.finalvert_t @out)
        {
            double		scale;
            auxvert_t	pav0, pav1, avout = new auxvert_t();

            pav0 = av[av0];
            pav1 = av[av1];

            if (pfv0.v[1] >= pfv1.v[1])
            {
                scale = (ALIAS_Z_CLIP_PLANE - pav0.fv[2]) /
                        (pav1.fv[2] - pav0.fv[2]);

                avout.fv[0] = pav0.fv[0] + (pav1.fv[0] - pav0.fv[0]) * scale;
                avout.fv[1] = pav0.fv[1] + (pav1.fv[1] - pav0.fv[1]) * scale;
                avout.fv[2] = ALIAS_Z_CLIP_PLANE;

                @out.v[2] =	(int)(pfv0.v[2] + (pfv1.v[2] - pfv0.v[2]) * scale);
                @out.v[3] =	(int)(pfv0.v[3] + (pfv1.v[3] - pfv0.v[3]) * scale);
                @out.v[4] =	(int)(pfv0.v[4] + (pfv1.v[4] - pfv0.v[4]) * scale);
            }
            else
            {
                scale = (ALIAS_Z_CLIP_PLANE - pav1.fv[2]) /
                        (pav0.fv[2] - pav1.fv[2]);

                avout.fv[0] = pav1.fv[0] + (pav0.fv[0] - pav1.fv[0]) * scale;
                avout.fv[1] = pav1.fv[1] + (pav0.fv[1] - pav1.fv[1]) * scale;
                avout.fv[2] = ALIAS_Z_CLIP_PLANE;

                @out.v[2] =	(int)(pfv1.v[2] + (pfv0.v[2] - pfv1.v[2]) * scale);
                @out.v[3] =	(int)(pfv1.v[3] + (pfv0.v[3] - pfv1.v[3]) * scale);
                @out.v[4] =	(int)(pfv1.v[4] + (pfv0.v[4] - pfv1.v[4]) * scale);
            }

            R_AliasProjectFinalVert (@out, avout);

            if (@out.v[0] < r_refdef.aliasvrect.x)
                @out.flags |= ALIAS_LEFT_CLIP;
            if (@out.v[1] < r_refdef.aliasvrect.y)
                @out.flags |= ALIAS_TOP_CLIP;
            if (@out.v[0] > r_refdef.aliasvrectright)
                @out.flags |= ALIAS_RIGHT_CLIP;
            if (@out.v[1] > r_refdef.aliasvrectbottom)
                @out.flags |= ALIAS_BOTTOM_CLIP;
        }
Пример #7
0
 static render()
 {
     int kk;
     int i,j;
     for(kk = 0; kk < 4; kk++) screenedge[kk] = new model.mplane_t();
     for(kk = 0; kk < 4; kk++) view_clipplanes[kk] = new render.clipplane_t();
     for(kk = 0; kk < 16; kk++) world_clipplanes[kk] = new render.clipplane_t();
     for(i = 0; i < 2; i++)
         for(j = 0; j < MAXWORKINGVERTS; j++)
             clip_verts[i][j] = new double[5];
     for(i = 0; i < 2; i++)
         for(j = 0; j < 8; j++)
             fva[i][j] = new draw.finalvert_t();
     for(kk = 0; kk < 8; kk++) av[kk] = new auxvert_t();
     r_alias_init();
 }
Пример #8
0
        static void r_alias_init()
        {
            finalverts = new draw.finalvert_t[MAXALIASVERTS];
            auxverts = new auxvert_t[MAXALIASVERTS];

            for (int kk = 0; kk < MAXALIASVERTS; kk++)
            {
                finalverts[kk] = new draw.finalvert_t();
                auxverts[kk] = new auxvert_t();
            }
        }
Пример #9
0
        /*
        ================
        R_AliasTransformFinalVert
        ================
        */
        static void R_AliasTransformFinalVert(draw.finalvert_t fv, auxvert_t av,
            model.trivertx_t pverts, model.stvert_t pstverts)
        {
            int		    temp;
            double      lightcos;
            double[]    plightnormal;

            av.fv[0] = mathlib.DotProduct(pverts.v, aliastransform[0]) +
                    aliastransform[0][3];
            av.fv[1] = mathlib.DotProduct(pverts.v, aliastransform[1]) +
                    aliastransform[1][3];
            av.fv[2] = mathlib.DotProduct(pverts.v, aliastransform[2]) +
                    aliastransform[2][3];

            fv.v[2] = pstverts.s;
            fv.v[3] = pstverts.t;

            fv.flags = pstverts.onseam;

            // lighting
            plightnormal = r_avertexnormals[pverts.lightnormalindex];
            lightcos = mathlib.DotProduct(plightnormal, r_plightvec);
            temp = r_ambientlight;

            if (lightcos < 0)
            {
                temp += (int)(r_shadelight * lightcos);

            // clamp; because we limited the minimum ambient and shading light, we
            // don't have to clamp low light, just bright
                if (temp < 0)
                    temp = 0;
            }

            fv.v[4] = temp;
        }
Пример #10
0
        /*
        ================
        R_AliasProjectFinalVert
        ================
        */
        static void R_AliasProjectFinalVert(draw.finalvert_t fv, auxvert_t av)
        {
            double	zi;

            // project points
            zi = 1.0 / av.fv[2];

            fv.v[5] = (int)(zi * ziscale);

            fv.v[0] = (int)((av.fv[0] * aliasxscale * zi) + aliasxcenter);
            fv.v[1] = (int)((av.fv[1] * aliasyscale * zi) + aliasycenter);
        }
Пример #11
0
        /*
        ================
        R_AliasCheckBBox
        ================
        */
        static bool R_AliasCheckBBox()
        {
            int					    i, flags, frame, numv;
            model.aliashdr_t	    pahdr;
            double				    zi, v0, v1, frac;
            double[][]              basepts = new double[8][];
            draw.finalvert_t		pv0, pv1;
            draw.finalvert_t[]      viewpts = new draw.finalvert_t[16];
            auxvert_t			    pa0, pa1;
            auxvert_t[]             viewaux = new auxvert_t[16];
            model.maliasframedesc_t	pframedesc;
            bool			        zclipped, zfullyclipped;
            uint    			    anyclip, allclip;
            int					    minz;

            int kk;
            for (kk = 0; kk < 16; kk++) viewpts[kk] = new draw.finalvert_t();
            for (kk = 0; kk < 16; kk++) viewaux[kk] = new auxvert_t();
            for (kk = 0; kk < 8; kk++) basepts[kk] = new double[3] {0, 0, 0};

            // expand, rotate, and translate points into worldspace

            currententity.trivial_accept = 0;
            pmodel = currententity.model;
            pahdr = (model.aliashdr_t)model.Mod_Extradata (pmodel);
            pmdl = (model.mdl_t)pahdr.model;

            R_AliasSetUpTransform (0);

            // construct the base bounding box for this frame
            frame = currententity.frame;
            // TODO: don't repeat this check when drawing?
            if ((frame >= pmdl.numframes) || (frame < 0))
            {
                console.Con_DPrintf ("No such frame " + frame + " " + pmodel.name + "\n");
                frame = 0;
            }

            pframedesc = pahdr.frames[frame];

            // x worldspace coordinates
            basepts[0][0] = basepts[1][0] = basepts[2][0] = basepts[3][0] =
                    (double)pframedesc.bboxmin.v[0];
            basepts[4][0] = basepts[5][0] = basepts[6][0] = basepts[7][0] =
                    (double)pframedesc.bboxmax.v[0];

            // y worldspace coordinates
            basepts[0][1] = basepts[3][1] = basepts[5][1] = basepts[6][1] =
                    (double)pframedesc.bboxmin.v[1];
            basepts[1][1] = basepts[2][1] = basepts[4][1] = basepts[7][1] =
                    (double)pframedesc.bboxmax.v[1];

            // z worldspace coordinates
            basepts[0][2] = basepts[1][2] = basepts[4][2] = basepts[5][2] =
                    (double)pframedesc.bboxmin.v[2];
            basepts[2][2] = basepts[3][2] = basepts[6][2] = basepts[7][2] =
                    (double)pframedesc.bboxmax.v[2];

            zclipped = false;
            zfullyclipped = true;

            minz = 9999;
            for (i=0; i<8 ; i++)
            {
                R_AliasTransformVector  (basepts[i], viewaux[i].fv);

                if (viewaux[i].fv[2] < ALIAS_Z_CLIP_PLANE)
                {
                // we must clip points that are closer than the near clip plane
                    viewpts[i].flags = ALIAS_Z_CLIP;
                    zclipped = true;
                }
                else
                {
                    if (viewaux[i].fv[2] < minz)
                        minz = (int)viewaux[i].fv[2];
                    viewpts[i].flags = 0;
                    zfullyclipped = false;
                }
            }

            if (zfullyclipped)
            {
                return false;	// everything was near-z-clipped
            }

            numv = 8;

            if (zclipped)
            {
            // organize points by edges, use edges to get new points (possible trivial
            // reject)
                for (i=0 ; i<12 ; i++)
                {
                // edge endpoints
                    pv0 = viewpts[aedges[i].index0];
                    pv1 = viewpts[aedges[i].index1];
                    pa0 = viewaux[aedges[i].index0];
                    pa1 = viewaux[aedges[i].index1];

                // if one end is clipped and the other isn't, make a new point
                    if ((pv0.flags ^ pv1.flags) != 0)
                    {
                        frac = (ALIAS_Z_CLIP_PLANE - pa0.fv[2]) /
                               (pa1.fv[2] - pa0.fv[2]);
                        viewaux[numv].fv[0] = pa0.fv[0] +
                                (pa1.fv[0] - pa0.fv[0]) * frac;
                        viewaux[numv].fv[1] = pa0.fv[1] +
                                (pa1.fv[1] - pa0.fv[1]) * frac;
                        viewaux[numv].fv[2] = ALIAS_Z_CLIP_PLANE;
                        viewpts[numv].flags = 0;
                        numv++;
                    }
                }
            }

            // project the vertices that remain after clipping
            anyclip = 0;
            allclip = ALIAS_XY_CLIP_MASK;

            // TODO: probably should do this loop in ASM, especially if we use floats
            for (i=0 ; i<numv ; i++)
            {
            // we don't need to bother with vertices that were z-clipped
                if ((viewpts[i].flags & ALIAS_Z_CLIP) != 0)
                    continue;

                zi = 1.0 / viewaux[i].fv[2];

            // FIXME: do with chop mode in ASM, or convert to float
                v0 = (viewaux[i].fv[0] * xscale * zi) + xcenter;
                v1 = (viewaux[i].fv[1] * yscale * zi) + ycenter;

                flags = 0;

                if (v0 < r_refdef.fvrectx)
                    flags |= ALIAS_LEFT_CLIP;
                if (v1 < r_refdef.fvrecty)
                    flags |= ALIAS_TOP_CLIP;
                if (v0 > r_refdef.fvrectright)
                    flags |= ALIAS_RIGHT_CLIP;
                if (v1 > r_refdef.fvrectbottom)
                    flags |= ALIAS_BOTTOM_CLIP;

                anyclip |= (uint)flags;
                allclip &= (uint)flags;
            }

            if (allclip != 0)
                return false;	// trivial reject off one side

            currententity.trivial_accept = ((anyclip == 0) && !zclipped) ? 1 : 0;

            if (currententity.trivial_accept != 0)
            {
                if (minz > (r_aliastransition + (pmdl.size * r_resfudge)))
                {
                    currententity.trivial_accept |= 2;
                }
            }

            return true;
        }
Пример #12
0
        /*
         * ================
         * R_AliasCheckBBox
         * ================
         */
        static bool R_AliasCheckBBox()
        {
            int i, flags, frame, numv;

            model.aliashdr_t pahdr;
            double           zi, v0, v1, frac;

            double[][]         basepts = new double[8][];
            draw.finalvert_t   pv0, pv1;
            draw.finalvert_t[] viewpts = new draw.finalvert_t[16];
            auxvert_t          pa0, pa1;

            auxvert_t[]             viewaux = new auxvert_t[16];
            model.maliasframedesc_t pframedesc;
            bool zclipped, zfullyclipped;
            uint anyclip, allclip;
            int  minz;

            int kk;

            for (kk = 0; kk < 16; kk++)
            {
                viewpts[kk] = new draw.finalvert_t();
            }
            for (kk = 0; kk < 16; kk++)
            {
                viewaux[kk] = new auxvert_t();
            }
            for (kk = 0; kk < 8; kk++)
            {
                basepts[kk] = new double[3];
            }

            // expand, rotate, and translate points into worldspace

            currententity.trivial_accept = 0;
            pmodel = currententity.model;
            pahdr  = (model.aliashdr_t)model.Mod_Extradata(pmodel);
            pmdl   = (model.mdl_t)pahdr.model;

            R_AliasSetUpTransform(0);

            // construct the base bounding box for this frame
            frame = currententity.frame;
            // TODO: don't repeat this check when drawing?
            if ((frame >= pmdl.numframes) || (frame < 0))
            {
                console.Con_DPrintf("No such frame " + frame + " " + pmodel.name + "\n");
                frame = 0;
            }

            pframedesc = pahdr.frames[frame];

            // x worldspace coordinates
            basepts[0][0] = basepts[1][0] = basepts[2][0] = basepts[3][0] =
                (double)pframedesc.bboxmin.v[0];
            basepts[4][0] = basepts[5][0] = basepts[6][0] = basepts[7][0] =
                (double)pframedesc.bboxmax.v[0];

            // y worldspace coordinates
            basepts[0][1] = basepts[3][1] = basepts[5][1] = basepts[6][1] =
                (double)pframedesc.bboxmin.v[1];
            basepts[1][1] = basepts[2][1] = basepts[4][1] = basepts[7][1] =
                (double)pframedesc.bboxmax.v[1];

            // z worldspace coordinates
            basepts[0][2] = basepts[1][2] = basepts[4][2] = basepts[5][2] =
                (double)pframedesc.bboxmin.v[2];
            basepts[2][2] = basepts[3][2] = basepts[6][2] = basepts[7][2] =
                (double)pframedesc.bboxmax.v[2];

            zclipped      = false;
            zfullyclipped = true;

            minz = 9999;
            for (i = 0; i < 8; i++)
            {
                R_AliasTransformVector(basepts[i], ref viewaux[i].fv);

                if (viewaux[i].fv[2] < ALIAS_Z_CLIP_PLANE)
                {
                    // we must clip points that are closer than the near clip plane
                    viewpts[i].flags = ALIAS_Z_CLIP;
                    zclipped         = true;
                }
                else
                {
                    if (viewaux[i].fv[2] < minz)
                    {
                        minz = (int)viewaux[i].fv[2];
                    }
                    viewpts[i].flags = 0;
                    zfullyclipped    = false;
                }
            }

            if (zfullyclipped)
            {
                return(false);          // everything was near-z-clipped
            }

            numv = 8;

            if (zclipped)
            {
                // organize points by edges, use edges to get new points (possible trivial
                // reject)
                for (i = 0; i < 12; i++)
                {
                    // edge endpoints
                    pv0 = viewpts[aedges[i].index0];
                    pv1 = viewpts[aedges[i].index1];
                    pa0 = viewaux[aedges[i].index0];
                    pa1 = viewaux[aedges[i].index1];

                    // if one end is clipped and the other isn't, make a new point
                    if ((pv0.flags ^ pv1.flags) != 0)
                    {
                        frac = (ALIAS_Z_CLIP_PLANE - pa0.fv[2]) /
                               (pa1.fv[2] - pa0.fv[2]);
                        viewaux[numv].fv[0] = pa0.fv[0] +
                                              (pa1.fv[0] - pa0.fv[0]) * frac;
                        viewaux[numv].fv[1] = pa0.fv[1] +
                                              (pa1.fv[1] - pa0.fv[1]) * frac;
                        viewaux[numv].fv[2] = ALIAS_Z_CLIP_PLANE;
                        viewpts[numv].flags = 0;
                        numv++;
                    }
                }
            }

            // project the vertices that remain after clipping
            anyclip = 0;
            allclip = ALIAS_XY_CLIP_MASK;

            // TODO: probably should do this loop in ASM, especially if we use floats
            for (i = 0; i < numv; i++)
            {
                // we don't need to bother with vertices that were z-clipped
                if ((viewpts[i].flags & ALIAS_Z_CLIP) != 0)
                {
                    continue;
                }

                zi = 1.0 / viewaux[i].fv[2];

                // FIXME: do with chop mode in ASM, or convert to float
                v0 = (viewaux[i].fv[0] * xscale * zi) + xcenter;
                v1 = (viewaux[i].fv[1] * yscale * zi) + ycenter;

                flags = 0;

                if (v0 < r_refdef.fvrectx)
                {
                    flags |= ALIAS_LEFT_CLIP;
                }
                if (v1 < r_refdef.fvrecty)
                {
                    flags |= ALIAS_TOP_CLIP;
                }
                if (v0 > r_refdef.fvrectright)
                {
                    flags |= ALIAS_RIGHT_CLIP;
                }
                if (v1 > r_refdef.fvrectbottom)
                {
                    flags |= ALIAS_BOTTOM_CLIP;
                }

                anyclip |= (uint)flags;
                allclip &= (uint)flags;
            }

            if (allclip != 0)
            {
                return(false);          // trivial reject off one side
            }
            currententity.trivial_accept = ((anyclip == 0) && !zclipped) ? 1 : 0;

            if (currententity.trivial_accept != 0)
            {
                if (minz > (r_aliastransition + (pmdl.size * r_resfudge)))
                {
                    currententity.trivial_accept |= 2;
                }
            }

            return(true);
        }