Forum

labeling edicts

Discuss programming topics for the various GPL'd game engine sources.

Moderator: InsideQC Admins

labeling edicts

Postby r00k » Tue Jun 05, 2012 4:59 am

I saw t00l_showbbox in enginex, so I sought out to duplicate the feature.
I already have the boxes working but some of the edict names are not showing up....
mostly for triggers.
this is the loop...
Code: Select all
   for (i = 0, ed = NEXT_EDICT(sv.edicts) ; i < sv.num_edicts ; i++, ed = NEXT_EDICT(ed))
   {      


and heres where i populate the variable
Code: Select all
      if (!strcmp((pr_strings + ed->v.classname),"player"))
         strlcpy(id->text, (pr_strings + ed->v.netname), 64);
      else
      {
         name = (pr_strings + ed->v.classname);
         strlcpy(id->text, name, 64);
      }


any suggestions? Do I need to run thru another link list for triggers??
Thanks
r00k
 
Posts: 1110
Joined: Sat Nov 13, 2004 10:39 pm

Re: labeling edicts

Postby Baker » Tue Jun 05, 2012 6:07 am

r00k wrote:I saw t00l_showbbox in enginex, so I sought out to duplicate the feature.
I already have the boxes working but some of the edict names are not showing up....


Just steal it in the entirety :D I mean it isn't like I haven't benefitted from all your Qrack enhancements :D And even if I didn't or you didn't, it's all GPL :)

As you see from my screen shots, Engine X has no problem showing the trigger entities (so I don't know why you'd be having this issue ???).

... Although maybe since I modified the progs interpreter stuff inspired from the Quore engine you are afraid of my macros? But those are harmless and rather simple really. Just diff the pr_whatever.c files and what I did with the macros is rather crystal clear.

#define PR_GETSTRING(x) pr_strings + x
#define PR_SETSTRING(x) x - pr_strings
#define PR_SETTMPSTRING(x) x - pr_strings


Image
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
User avatar
Baker
 
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Re: labeling edicts

Postby r00k » Tue Jun 05, 2012 6:30 am

Ya but your source wasnt up to date. it had the tools_showbbox cvar and nothing codewise. :(
Basically im using qglProject from FTE and the autoid code from ezQ as a reference.

So far this is what i have
Image
r00k
 
Posts: 1110
Joined: Sat Nov 13, 2004 10:39 pm

Re: labeling edicts

Postby Baker » Tue Jun 05, 2012 9:55 am

r00k wrote:Ya but your source wasnt up to date. it had the tools_showbbox cvar and nothing codewise. :(


At the moment I'm not understanding how that could have happened, but this does appear to be the case. :( My source seems to be missing an entire "folder" of gl_ files ... but I was using a single folder. I did bundle the source archive from my Mac and then flash drive it over to Windows prior to upload, but I fail to see how that could have anything to do with missing files.

And certainly not intentional.

[I find this a bit disturbing because I always make the assumption that uploading my source keeps me safe from possible file loss and I often treat uploaded source bases as perfectly deletable on my hard drive, mentally.]
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
User avatar
Baker
 
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Re: labeling edicts

Postby Baker » Tue Jun 05, 2012 11:42 am

I've re-zipped the source off my Windows desktop:

http://quakeone.com/proquake/interims/E ... in_src.rar

Code to look for: File = insertions_3d.c

Code: Select all
// insertions_3d.c -- Adds stuff to 3D world

#include "quakedef.h"

//qbool SV_InvisibleToClient(edict_t *viewer, edict_t *seen);
//void R_EmitBox (const vec_rgba_t myColor, const vec3_t centerpoint, const vec3_t xyz_mins, const vec3_t xyz_maxs, const qbool bTopMost, const qbool bLines, const float Expandsize);

qbool SV_InvisibleToClient(edict_t *viewer, edict_t *seen);

void ShowBBoxes_Draw (void)
{
   extern      edict_t *sv_player;
   edict_t      *ed;
   int         i;
   entity_t   *clent;

   // Cycle through the server entities

   for (i=1, ed=NEXT_EDICT(sv.edicts) ; i<sv.num_edicts ; i++, ed=NEXT_EDICT(ed))
   {
      char      *my_classname = PR_GETSTRING(ed->v.classname);
      vec_rgba_t   BoxColor;

      if (ed->free)
         continue;   // Free edict, just skip

      clent = NULL;
      if (i<cl.num_entities)      // Baker: Not all server ents get communicated to client.
         clent = cl_entities + i;


      if (ed == sv_player && !chase_active.integer)
         continue;   // Don't draw in this scenario

      // Obtain Quake specific super-special color
      do
      {
         int special_entity = 0;

         if      (COM_StringMatchCaseless (my_classname, "info_player_start"))      special_entity = 1;
         else if (COM_StringMatchCaseless (my_classname, "info_player_coop"))         special_entity = 2;
         else if (COM_StringMatchCaseless (my_classname, "info_player_deathmatch"))   special_entity = 3;

         switch (special_entity)
         {
         case 1:      VectorSetColor4f (BoxColor, 1, 0, 0, 0.40);   break;
         case 2:      VectorSetColor4f (BoxColor, 1, 1, 0, 0.30);   break;
         case 3:      VectorSetColor4f (BoxColor, 1, 0, 0, 0.40); break;
         }

         // If we already determined a color, exit stage left ...
         if (special_entity)
            continue;

         // normal color selection
         switch ((int)ed->v.solid)
         {
         case SOLID_NOT:      VectorSetColor4f (BoxColor, 1, 1, 1, 0.05);break;
         case SOLID_TRIGGER:  VectorSetColor4f (BoxColor, 1, 0, 1, 0.10);break;
         case SOLID_BBOX:     VectorSetColor4f (BoxColor, 0, 1, 0, 0.10);break;
         case SOLID_SLIDEBOX: VectorSetColor4f (BoxColor, 1, 0, 0, 0.10);break;
         case SOLID_BSP:      VectorSetColor4f (BoxColor, 0, 0, 1, 0.05);break;
         default:             VectorSetColor4f (BoxColor, 0, 0, 0, 0.50);break;
         }

      } while (0);

      // Render box phase

      do
      {
         qbool isPointEntity  = VectorCompare(ed->v.mins, ed->v.maxs); // point entities have 0 size

         if (isPointEntity)
         {
            qbool bRenderTopMost = false;
            qbool bRenderLines   = false;
            float size_adjust = 4.0f; // Give it a little bit of size

            R_EmitBox (BoxColor, ed->v.origin, NULL, NULL, bRenderTopMost, bRenderLines, size_adjust);
         }
         else
         {
            qbool bRenderTopMost = false;
            qbool bRenderLines   = false;
            float size_adjust     = -0.10f; // Pull size in just a little

            R_EmitBox (BoxColor, ed->v.origin, ed->v.mins, ed->v.maxs, bRenderTopMost, bRenderLines, size_adjust);
         }
      } while (0);

      // Render Caption phase

      do
      {
         extern vec3_t lastbox_mins, lastbox_maxs;   // Last box rendering result
         vec3_t caption_location;

         if (SV_InvisibleToClient (sv_player, ed))
            continue; //don't draw if entity cannot be seen

         // Averaging the vectors gives the center
         LerpVector (lastbox_mins, lastbox_maxs, 0.5, caption_location);

         // Except we want the caption to be at the top
         caption_location[2] = lastbox_maxs[2];

         // Add a couple of height units to make it overhead
         caption_location[2] = caption_location[2] + 20;

         // Depending on cvar value, have caption show different things

         switch (tool_showbboxes.integer)
         {
         default:
         case 1:      R_EmitCaption  (caption_location, my_classname);                        break;
         case 2:      R_EmitCaption  (caption_location, ed->v.model ? PR_GETSTRING(ed->v.model) : "No model");               break;
         case 3:      R_EmitCaption  (caption_location, va("ent #%i", i));                     break;
         case 4:      R_EmitCaption  (caption_location, va("modelindex %i", (int)ed->v.modelindex));   break;

                  // Baker: First ... this isn't how you do it with sprites.
         case 5:      // Client mirror
                  R_EmitCaption (caption_location,
                     va("\bServer model:\b\n"
                        "'%s'\n"
                        "\bClient model:\b\n"
                        "'%s'", ed->v.model ? PR_GETSTRING(ed->v.model) : "No model", clent ? clent->model->name : "No entity"));



                  break;


         }
      } while (0);

      // End of this entity
   }  // For Loop closing brace

   // Now do static entities

   for (i=0; i < cl.num_statics; i++)
   {
      vec_rgba_t   BoxColor;

      clent = &cl_static_entities[i];
      if (!(clent->visframe == r_framecount))
         continue; // Not visible this frame

      VectorSetColor4f (BoxColor, 1, 0.5, 0, 0.40);
      // Render box phase

      do
      {
         qbool isPointEntity  = VectorCompare(clent->model->mins, clent->model->maxs); // point entities have 0 size

         if (isPointEntity)
         {
            qbool bRenderTopMost = false;
            qbool bRenderLines   = false;
            float size_adjust = 4.0f; // Give it a little bit of size

            R_EmitBox (BoxColor, clent->currentorigin, NULL, NULL, bRenderTopMost, bRenderLines, size_adjust);
         }
         else
         {
            qbool bRenderTopMost = false;
            qbool bRenderLines   = false;
            float size_adjust     = -0.10f; // Pull size in just a little

            R_EmitBox (BoxColor, clent->currentorigin, clent->model->mins, clent->model->maxs, bRenderTopMost, bRenderLines, size_adjust);
         }
      } while (0);

      // Render Caption phase

      do
      {
         extern vec3_t lastbox_mins, lastbox_maxs;   // Last box rendering result
         vec3_t caption_location;

         // Averaging the vectors gives the center
         LerpVector (lastbox_mins, lastbox_maxs, 0.5, caption_location);

         // Except we want the caption to be at the top
         caption_location[2] = lastbox_maxs[2];

         // Add a couple of height units to make it overhead
         caption_location[2] = caption_location[2] + 20;

         // Depending on cvar value, have caption show different things

         R_EmitCaption (caption_location, va("\bStatic ent\b %i '%s'\n", clent- cl_static_entities, clent->model->name));

      } while (0);

      // End of this entity
   }  // For Loop closing brace


}


As you can see in this code, I didn't draw the captions in 2D. :D I drew them in 3D, hahaha :D

The 3D drawing of text works like this (really it is exactly the same as drawing a sprite) ...

Code: Select all
void R_EmitCaption (const vec3_t location, const char *caption)
{
   const int         string_length = strlen(caption);
   const float         charwidth   = 8;
   const float         charheight  = 8;
   
   vec3_t            point;
   vec3_t            right, up;
   
   int               string_columns, string_rows;
   float            string_width, string_height; // pixels
   fRect_t            captionbox;
   int               i, x, y;
   qbool            bronze = false;

   // Step 1: Detemine Rows and columns
   Text_Get_Columns_And_Rows (caption, &string_columns, &string_rows);
   string_width = (float)string_columns * charwidth;
   string_height = (float)string_rows * charheight;


   // Step 2: Calculate bounds of rectangle

   captionbox.top     = -(float)string_height/2;
   captionbox.bottom =  (float)string_height/2;
   captionbox.left   = -(float)string_width /2;
   captionbox.right  =  (float)string_width /2;

   // Copy the view origin up and right angles
   VectorCopy (vup, up);
   VectorCopy (vright, right);

   mglPushStates ();

   GL_Bind            (char_texture);
   MeglDisable         (GL_CULL_FACE);
   MeglEnable         (GL_ALPHA_TEST);

   MeglDepthRange (0, 0.3);   // Baker: The "hack the depth range" trick.  Not sure why this works, but it does ...

   mglFinishedStates ();
   
   for (i=0, x = 0, y =0; i<string_length; i++)
   {   
      // Deal with the string
      if (caption[i] == '\n')      { x = 0; y ++; continue; }      // Reset the row, ignore and carry on
      if (caption[i] == '\b')      
      {
         bronze = !bronze;
         continue;
      }   // Toggle the bronzing and carry on

      x++;   // New character to print
      {
         fRect_t            charcoords;
         float            s, t;
         int               charcode  = caption[i] | (bronze * 128);   // "ascii" ish character code, but Quake character code
         int               charrow   = charcode >> 4; // Fancy way of dividing by 16
         int               charcol   = charcode & 15; // column = mod (16-1)
         // Calculate s, t texture coords from character set image

//         if (bronze) charcode |=128;

         s = charcol * 0.0625f; // 0.0625 = 1/16th
         t = charrow * 0.0625f;

         // Calculate coords

//         charcoords.top     =    captionbox.top;
//         charcoords.bottom =  captionbox.bottom;
//         charcoords.left   =  captionbox.left + (x/string_length)*(captionbox.right - captionbox.left);
//         charcoords.right   = captionbox.left + ((x+1)/string_length)*(captionbox.right - captionbox.left);

//         charcoords.top     =    captionbox.top + (y/(float)string_rows)*(captionbox.bottom - captionbox.top);
//         charcoords.bottom =  captionbox.top + ((y+1)/(float)string_rows)*(captionbox.bottom - captionbox.top);

         charcoords.top     =    captionbox.top + ((string_rows - 1 - y)/(float)string_rows)*(captionbox.bottom - captionbox.top);
         charcoords.bottom =  captionbox.top + (((string_rows - 1 - y)+1)/(float)string_rows)*(captionbox.bottom - captionbox.top);         
         charcoords.left   =  captionbox.left + (x/(float)string_columns)*(captionbox.right - captionbox.left);
         charcoords.right  = captionbox.left + ((x+1)/(float)string_columns)*(captionbox.right - captionbox.left);


         // Draw box

         eglBegin (GL_QUADS);

         // top left      
         eglTexCoord2f (s, t + 0.03125);
         VectorMultiplyAdd (location, charcoords.top, up, point);
         VectorMultiplyAdd (point, charcoords.left, right, point);
         eglVertex3fv (point);

         // top, right
         eglTexCoord2f (s + 0.0625, t + 0.03125);   // 0.03125 = 1/32th;
         VectorMultiplyAdd (location, charcoords.top, up, point);
         VectorMultiplyAdd (point, charcoords.right, right, point);
         eglVertex3fv (point);

         // bottom right
         
         eglTexCoord2f (s + 0.0625, t);
         VectorMultiplyAdd (location, charcoords.bottom, up, point);
         VectorMultiplyAdd (point, charcoords.right, right, point);
         eglVertex3fv (point);

         // bottom, left
         eglTexCoord2f (s, t);
         VectorMultiplyAdd (location, charcoords.bottom, up, point);
         VectorMultiplyAdd (point, charcoords.left, right, point);
         eglVertex3fv (point);

         eglEnd ();
      }
   }

   MeglEnable         (GL_CULL_FACE);
   MeglDisable         (GL_ALPHA_TEST);
   MeglDepthRange (0, 1);

   mglPopStates ();
}


And as you can see, I used your anti-wallhack code to test for entity visibility to decide whether or not to display the text.

Obviously drawing the text in the 3D phase makes more sense since:

1. I'm drawing boxes around stuff anyways. That has to be in the 3D rendering phase.
2. The 2D phase would introduce irritating factors not drawing over the HUD, how to scale the text for screen resolution and other stuff I didn't want to do.
3. Why do unnecessary projection calculations in the 2D phase ... I mean that's just faking 3D anyway. So do it in the 3D phase. But at the end and ignore depth testing.
Last edited by Baker on Tue Jun 05, 2012 12:18 pm, edited 1 time in total.
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
User avatar
Baker
 
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Re: labeling edicts

Postby r00k » Tue Jun 05, 2012 12:13 pm

I've literally been sitting here all night...

weird thing is that if I do a Con_Printf("%s\n",(pr_strings + ed->v.classname)); it shows up
but after running that trace for culling, another Con_Printf("%s\n",(pr_strings + ed->v.classname)); gets lost... :(
Code: Select all
int qglProject (float objx, float objy, float objz, float *model, float *proj, int *view, float* winx, float* winy, float* winz)
{
   float in[4], out[4], dist, scale;
   int i;
   vec3_t org;

   org[0] = objx; org[1] = objy; org[2] = objz;
   in[0] = objx; in[1] = objy; in[2] = objz; in[3] = 1.0;

   if (R_CullSphere (org, 1))
      return 0;

   dist = VectorDistance(r_refdef.vieworg, org);   

   if (dist > r_farclip.value)
      return 0;

   for (i = 0; i < 4; i++)
      out[i] = in[0] * model[0 * 4 + i] + in[1] * model[1 * 4 + i] + in[2] * model[2 * 4 + i] + in[3] * model[3 * 4 + i];

   for (i = 0; i < 4; i++)
      in[i] =   out[0] * proj[0 * 4 + i] + out[1] * proj[1 * 4 + i] + out[2] * proj[2 * 4 + i] + out[3] * proj[3 * 4 + i];

   if (!in[3])
      return 0;

   VectorScale(in, 1 / in[3], in);
   
   *winx = view[0] + (1 + in[0]) * view[2] / 2;
   *winy = view[1] + (1 + in[1]) * view[3] / 2;

   scale = (1 / (dist / 128.0f));

   if (scale < 0.1)
      return 0;
   
   scale = bound(0.333f, scale, 1);

   *winz = scale;
   return 1;
}

void SCR_DrawAutoID (void)
{
   int i, x, y;

   extern void Draw_String_Scaled (int x, int y, char *str, float scale);
   float frametime   = fabs(cl.time - cl.oldtime);

   if (frametime < 0.01)
      return;

   if (!developer.value)
      return;

   for (i = 0; i < autoid_count; i++)
   {
      x =  autoids[i].x * vid.width / glwidth;
      y =  (glheight - autoids[i].y) * vid.height / glheight;

      if (autoids[i].classname)
         Draw_String_Scaled (x - strlen(autoids[i].classname) * 4 * autoids[i].scale, y - 8 * autoids[i].scale, autoids[i].classname, autoids[i].scale);
      
      if (autoids[i].origin)
         Draw_String_Scaled (x - strlen(autoids[i].origin) * 4 * (autoids[i].scale * 0.8), y + 8 * (autoids[i].scale * 0.8), autoids[i].origin, (autoids[i].scale * 0.8));
      
      if (autoids[i].modelname)
         Draw_String_Scaled (x - strlen(autoids[i].modelname) * 4 * (autoids[i].scale * 0.8), y + 16 * (autoids[i].scale * 0.8), autoids[i].modelname, (autoids[i].scale * 0.8));
   }
}

char *SCR_ED_Print (edict_t * ed, int i)
{
    int          *v;
    ddef_t       *d;
    char         *name;
   extern char *PR_ValueString (etype_t type, eval_t *val);

    d = &pr_fielddefs[i];
    name = pr_strings + d->s_name;
   
    v = (int *) ((char *) &ed->v + d->ofs * 4);

    name = PR_ValueString (d->type, (eval_t *) v);
   return va("%s",name);
}

void SCR_SetupTagEdicts (void)
{
   int view[4];
   float model[16], project[16], origin[3];
   edict_t   *ed;
   int   i;
   autoid_player_t *id;
   trace_t   trace;
   qboolean result;
   char *name;
   float frametime   = fabs(cl.time - cl.oldtime);
   extern cvar_t   sv_cullentities;

   entity_t *ent;

   if (frametime < 0.01)
      return;

   if (autoids[0].classname)
      memset(autoids,0,sizeof(autoids));// dont carry over

   if (!developer.value)
      return;
   
   if (!cl.worldmodel)//Level hasnt loaded yet...
      return;

   if (cl.maxclients > 1 || !r_drawentities.value || !sv.active)//only in singleplayer mode...
      return;

   autoid_count = 0;

   glGetFloatv(GL_MODELVIEW_MATRIX, model);
   glGetFloatv(GL_PROJECTION_MATRIX, project);
   glGetIntegerv(GL_VIEWPORT, (GLint *)view);

   for (i = 0, ed = NEXT_EDICT(sv.edicts) ; i < sv.num_edicts ; i++, ed = NEXT_EDICT(ed))
   {      
      Con_Printf("a:%s\n",(pr_strings + ed->v.classname));
      
      if (ed->culled)
         continue;
   
      if (ed->free)
         continue;

      origin[0] = ed->v.origin[0];
      origin[1] = ed->v.origin[1];
      origin[2] = ed->v.origin[2];
   
      id = &autoids[autoid_count];

      Con_Printf("b:%s\n",(pr_strings + ed->v.classname));

      if (sv_cullentities.value)   
      {
         memset (&trace, 0, sizeof(trace));
         trace.fraction = 1;

         result = SV_RecursiveHullCheck (cl.worldmodel->hulls, 0, 0, 1, r_refdef.vieworg, origin, &trace);
         
         if (!result)//hit something
         {
            Con_Printf("c:culled!\n");
            continue;
         }
      }

      origin[0] = ed->v.origin[0];
      origin[1] = ed->v.origin[1];
      origin[2] = ed->v.origin[2];

      if (qglProject(origin[0], origin[1], origin[2], model, project, view, &id->x, &id->y, &id->scale))
      {
         if (!strcmp((pr_strings + ed->v.classname),"player"))
         {
            strlcpy(id->classname, (pr_strings + ed->v.netname), 64);
            name = SCR_ED_Print (ed, 13);
            strlcpy(id->origin, name, 64);
            name = SCR_ED_Print (ed, 38);
            strlcpy(id->modelname, name, 64);
         }
         else
         {
            strlcpy(id->classname, (pr_strings + ed->v.classname), 64);
            
            Con_Printf("c:%s\n",id->classname);   //TESTING!

            name = SCR_ED_Print (ed, 38);
            strlcpy(id->modelname, name, 64);

            name = SCR_ED_Print (ed, 13);
            strlcpy(id->origin, name, 64);
         }            
         autoid_count++;
      }
   }

   for (i = 0, ent = cl_static_entities ; i < MAX_STATIC_ENTITIES ; i++, ent++)
   {
      if (ent->culled)
         continue;
   
      origin[0] = ed->v.origin[0];
      origin[1] = ed->v.origin[1];
      origin[2] = ed->v.origin[2];

      if (sv_cullentities.value)   
      {
         memset (&trace, 0, sizeof(trace));
         trace.fraction = 1;

         result = SV_RecursiveHullCheck (cl.worldmodel->hulls, 0, 0, 1, r_refdef.vieworg, origin, &trace);
         
         if (!result)//hit something
            continue;
      }

      id = &autoids[autoid_count];
      if (qglProject(origin[0], origin[1], origin[2], model, project, view, &id->x, &id->y, &id->scale))
      {
         name = "óôáôéã entity_t";
         strlcpy(id->classname, "óôáôéã entity_t", 64);

         name = va("%s",(ent->model->name));
         strlcpy(id->modelname, name, 64);

         name = va("%3.1f %3.1f %3.1f ",ent->origin[0],ent->origin[1],ent->origin[2]);
         strlcpy(id->origin, name, 64);
      
         autoid_count++;
      }
   }
}


My eyes are burning, I'll look at your code in a bit.
r00k
 
Posts: 1110
Joined: Sat Nov 13, 2004 10:39 pm

Re: labeling edicts

Postby Baker » Tue Jun 05, 2012 12:24 pm

r00k wrote:I've literally been sitting here all night...


I had some bang my head moments more than a few times (one stupid little mystery after another). But my code worked through all of those until none existed, and I commented it pretty well.

So read the comments in my code and note that every single line is doing something important (dealing with free edicts, situations where the server entity number is higher than the possible client entity numbers, stuff where I dealt with static entities, other stuff).
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
User avatar
Baker
 
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Re: labeling edicts

Postby r00k » Tue Jun 05, 2012 12:50 pm

AH, i just noticed using the "edicts" command that trigger_*" whatever doesnt use an origin field! Atleast thats what my edicts command shows!
So copying the origin field which is 0 culls out!

UGH :O

Edit ok that fixed it. Some edicts didnt have an "origin" field defined, some didnt have mins/maxs, so i had to construct the origin from the absmin/absmax... phew!
Code: Select all
int qglProject (float objx, float objy, float objz, float *model, float *proj, int *view, float* winx, float* winy, float* winz)
{
   float in[4], out[4], dist, scale;
   int i;
   vec3_t org;

   org[0] = objx; org[1] = objy; org[2] = objz;
   in[0] = objx; in[1] = objy; in[2] = objz; in[3] = 1.0;

   if (R_CullSphere (org, 1))
      return 0;

   dist = VectorDistance(r_refdef.vieworg, org);   

   if (dist > r_farclip.value)
      return 0;

   for (i = 0; i < 4; i++)
      out[i] = in[0] * model[0 * 4 + i] + in[1] * model[1 * 4 + i] + in[2] * model[2 * 4 + i] + in[3] * model[3 * 4 + i];

   for (i = 0; i < 4; i++)
      in[i] =   out[0] * proj[0 * 4 + i] + out[1] * proj[1 * 4 + i] + out[2] * proj[2 * 4 + i] + out[3] * proj[3 * 4 + i];

   if (!in[3])
      return 0;

   VectorScale(in, 1 / in[3], in);
   
   *winx = view[0] + (1 + in[0]) * view[2] / 2;
   *winy = view[1] + (1 + in[1]) * view[3] / 2;

   scale = (1 / (dist / 128.0f));

   if (scale < 0.1)
      return 0;
   
   scale = bound(0.4f, scale, 2);

   *winz = scale;
   return 1;
}

void SCR_DrawAutoID (void)
{
   int i, x, y;

   extern void Draw_String_Scaled (int x, int y, char *str, float scale);
   float frametime   = fabs(cl.time - cl.oldtime);

   if (frametime < 0.01)
      return;

   if (!developer.value)
      return;

   for (i = 0; i < autoid_count; i++)
   {
      x =  autoids[i].x * vid.width / glwidth;
      y =  (glheight - autoids[i].y) * vid.height / glheight;

      if (autoids[i].classname)
         Draw_String_Scaled (x - strlen(autoids[i].classname) * 4 * autoids[i].scale, y - 8 * autoids[i].scale, autoids[i].classname, autoids[i].scale);
      
      if (autoids[i].origin)
         Draw_String_Scaled (x - strlen(autoids[i].origin) * 4 * (autoids[i].scale * 0.8), y + 8 * (autoids[i].scale * 0.8), autoids[i].origin, (autoids[i].scale * 0.8));
      
      if (autoids[i].modelname)
         Draw_String_Scaled (x - strlen(autoids[i].modelname) * 4 * (autoids[i].scale * 0.8), y + 16 * (autoids[i].scale * 0.8), autoids[i].modelname, (autoids[i].scale * 0.8));
   }
}

void SCR_SetupTagEdicts (void)
{
   int view[4];
   float model[16], project[16];
   edict_t   *ed;
   int   i;
   autoid_player_t *id;
   trace_t   trace;
   qboolean result;
   char *name;
   float frametime   = fabs(cl.time - cl.oldtime);
   extern cvar_t   sv_cullentities;
   extern void GL_DrawSimpleBox(vec3_t org, float minx, float miny, float minz, float maxx, float maxy, float maxz, vec3_t color, qboolean cull);
   entity_t *ent;
   vec3_t   mins, maxs, origin;

   if (frametime < 0.01)
      return;

   if (autoids[0].classname)
      memset(autoids,0,sizeof(autoids));// dont carry over

   if (!developer.value)
      return;
   
   if (!cl.worldmodel)//Level hasnt loaded yet...
      return;

   if (cl.maxclients > 1 || !r_drawentities.value || !sv.active)//only in singleplayer mode...
      return;

   autoid_count = 0;

   glGetFloatv(GL_MODELVIEW_MATRIX, model);
   glGetFloatv(GL_PROJECTION_MATRIX, project);
   glGetIntegerv(GL_VIEWPORT, (GLint *)view);

   for (i = 0, ed = NEXT_EDICT(sv.edicts) ; i < sv.num_edicts ; i++, ed = NEXT_EDICT(ed))
   {      
      if (ed->free)
      {
         continue;
      }

      origin[0] = ed->v.origin[0];
      origin[1] = ed->v.origin[1];
      origin[2] = ed->v.origin[2];

      if (!VectorLength(origin))
      {
         VectorCopy (ed->v.absmin, mins);
         VectorCopy (ed->v.absmax, maxs);   
         LerpVector (mins, maxs, 0.5, origin);
      }

      if (sv_cullentities.value)   
      {
         memset (&trace, 0, sizeof(trace));
         trace.fraction = 1;

         result = SV_RecursiveHullCheck (cl.worldmodel->hulls, 0, 0, 1, r_refdef.vieworg, origin, &trace);
         
         if (!result)//hit something
         {
            continue;
         }
      }
      
      id = &autoids[autoid_count];

      if (qglProject(origin[0], origin[1], origin[2], model, project, view, &id->x, &id->y, &id->scale))
      {
         if (!strcmp((pr_strings + ed->v.classname),"player"))
         {
            strlcpy(id->classname, (pr_strings + ed->v.netname), 64);
            
            strlcpy(id->modelname, (pr_strings + ed->v.model), 64);
            
            name = va("%3.1f %3.1f %3.1f ", origin[0], origin[1], origin[2]);
            strlcpy(id->origin, name, 64);
         }
         else
         {
            strlcpy(id->classname, (pr_strings + ed->v.classname), 64);

            strlcpy(id->modelname, (pr_strings + ed->v.model), 64);

            name = va("%3.1f %3.1f %3.1f ", origin[0], origin[1], origin[2]);
            strlcpy(id->origin, name, 64);   
         }            
         autoid_count++;
      }
   }

   for (i = 0, ent = cl_static_entities ; i < MAX_STATIC_ENTITIES ; i++, ent++)
   {
      origin[0] = ent->origin[0];
      origin[1] = ent->origin[1];
      origin[2] = ent->origin[2];

      if (sv_cullentities.value)   
      {
         memset (&trace, 0, sizeof(trace));
         trace.fraction = 1;

         result = SV_RecursiveHullCheck (cl.worldmodel->hulls, 0, 0, 1, r_refdef.vieworg, origin, &trace);
         
         if (!result)//hit something
            continue;
      }

      id = &autoids[autoid_count];

      if (qglProject(origin[0], origin[1], origin[2], model, project, view, &id->x, &id->y, &id->scale))
      {
         name = "óôáôéã entity_t";
         strlcpy(id->classname, "óôáôéã entity_t", 64);

         name = va("%s",(ent->model->name));
         strlcpy(id->modelname, name, 64);

         name = va("%3.1f %3.1f %3.1f ",origin[0], origin[1], origin[2]);
         strlcpy(id->origin, name, 64);
      
         autoid_count++;
      }
   }
}


I tried using the SV_Invisible_to_client but it just raped my fps. So im just using a simple trace from r_redef.vieworg to the edict's origin(middle) seems soild.
r00k
 
Posts: 1110
Joined: Sat Nov 13, 2004 10:39 pm


Return to Engine Programming

Who is online

Users browsing this forum: No registered users and 1 guest