Forum

Bounding boxes

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

Moderator: InsideQC Admins

Postby andrewj » Tue Oct 12, 2010 5:29 pm

Error wrote:would it be possible to add more bounding box sizes to an engine/compiler? or are 3 the max?

There is a fourth unused hull in the BSP map format, its value is normally zero.

Modifying qbsp to generate that extra clipping hull (e.g. for crouching) would be trivial. Modifying the engine to load and use it would be fairly easy too (if you're a programmer etc etc).

P.S. rather than a new map format, I thinkk it would be better to simply not require clipping hulls at all --- just do clipping against the rendering hull. Doesn't Darkplaces already have the code for this?
andrewj
 
Posts: 133
Joined: Mon Aug 30, 2010 3:29 pm
Location: Australia

Postby frag.machine » Tue Oct 12, 2010 6:12 pm

The problem here is breaking compatibility with the legacy behavior. Otherwise yeah, that would be much better.
I know FrikaC made a cgi-bin version of the quakec interpreter once and wrote part of his website in QuakeC :) (LordHavoc)
User avatar
frag.machine
 
Posts: 2090
Joined: Sat Nov 25, 2006 1:49 pm

Postby mh » Tue Oct 12, 2010 8:27 pm

Speaking off the top of my head, but I wonder does QBSP construct the hull from the .map data or from the .bsp data? If the latter (which I suspect), then surely the engine itself could include the necessary code to construct any number of arbirtarily sized hulls? QBSP compile times can be pretty fast, and this is only a very small subset of that compile too, so I don't think worrying about excessive compile time is an issue here.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
User avatar
mh
 
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Postby leileilol » Tue Oct 12, 2010 8:53 pm

Baker wrote:Well if someone wants to make a Quake map format 2.0 I'd be all for it, but wouldn't the map compile times be unbearable for 10 hulls?

You mean Hexen II's?
i should not be here
leileilol
 
Posts: 2783
Joined: Fri Oct 15, 2004 3:23 am

Postby Spike » Tue Oct 12, 2010 9:52 pm

hexnII has different hull sizes depending upon worldspawn's spawnflags. how forward thinking they were!
Spike
 
Posts: 2892
Joined: Fri Nov 05, 2004 3:12 am
Location: UK

Postby Baker » Tue Oct 12, 2010 9:57 pm

Spike wrote:hexnII has different hull sizes depending upon worldspawn's spawnflags. how forward thinking they were!


I was going to suggest that earlier but I wasn't sure that the worldspawn information was available early enough in the map load process so I didn't think it would be viable, being still semi-bsp illiterate as I am.

Right now I am trying to add proper Kurok support and it has different hull sizes than standard Quake. So I am kind of dealing with this kind of thing right now ...

[But for Kurok, you already know you are running Kurok and the ASM code for the hull isn't much of a benefit so going with C is fine ...]
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

Postby frag.machine » Tue Oct 12, 2010 11:46 pm

mh wrote:Speaking off the top of my head, but I wonder does QBSP construct the hull from the .map data or from the .bsp data? If the latter (which I suspect), then surely the engine itself could include the necessary code to construct any number of arbirtarily sized hulls? QBSP compile times can be pretty fast, and this is only a very small subset of that compile too, so I don't think worrying about excessive compile time is an issue here.


Using FitzQuake 0.85 as reference...

in bspfile.h, we can confirm that, indeed, there are room for 4 hulls:
#define MAX_MAP_HULLS 4

(...)

in gl_model.h...
typedef struct model_s
{
// (...)
hull_t hulls[MAX_MAP_HULLS];
// (...)
} model_t;


and finally, in gl_model.c we confirm that only 3 hulls are defined:
Code: Select all
void Mod_LoadClipnodes (lump_t *l)
{
   dclipnode_t *in;
   mclipnode_t *out; //johnfitz -- was dclipnode_t
   int         i, count;
   hull_t      *hull;

   in = (void *)(mod_base + l->fileofs);
   if (l->filelen % sizeof(*in))
      Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
   count = l->filelen / sizeof(*in);
   out = Hunk_AllocName ( count*sizeof(*out), loadname);

   //johnfitz -- warn about exceeding old limits
   if (count > 32767)
      Con_Warning ("%i clipnodes exceeds standard limit of 32767.\n", count);
   //johnfitz

   loadmodel->clipnodes = out;
   loadmodel->numclipnodes = count;

   hull = &loadmodel->hulls[1];
   hull->clipnodes = out;
   hull->firstclipnode = 0;
   hull->lastclipnode = count-1;
   hull->planes = loadmodel->planes;
   hull->clip_mins[0] = -16;
   hull->clip_mins[1] = -16;
   hull->clip_mins[2] = -24;
   hull->clip_maxs[0] = 16;
   hull->clip_maxs[1] = 16;
   hull->clip_maxs[2] = 32;

   hull = &loadmodel->hulls[2];
   hull->clipnodes = out;
   hull->firstclipnode = 0;
   hull->lastclipnode = count-1;
   hull->planes = loadmodel->planes;
   hull->clip_mins[0] = -32;
   hull->clip_mins[1] = -32;
   hull->clip_mins[2] = -24;
   hull->clip_maxs[0] = 32;
   hull->clip_maxs[1] = 32;
   hull->clip_maxs[2] = 64;

   for (i=0 ; i<count ; i++, out++, in++)
   {
      out->planenum = LittleLong(in->planenum);

      //johnfitz -- bounds check
      if (out->planenum < 0 || out->planenum >= loadmodel->numplanes)
         Host_Error ("Mod_LoadClipnodes: planenum out of bounds");
      //johnfitz

      //johnfitz -- support clipnodes > 32k
      out->children[0] = (unsigned short)LittleShort(in->children[0]);
      out->children[1] = (unsigned short)LittleShort(in->children[1]);
      if (out->children[0] >= count)
         out->children[0] -= 65536;
      if (out->children[1] >= count)
         out->children[1] -= 65536;
      //johnfitz
   }
}


So, if I am not completely wrong, for adding a new hull (let's say, for a crouching player and maybe smaller monsters like the dog or the tarbaby) one could paste just before the line that says
Code: Select all
for (i=0 ; i<count ; i++, out++, in++)


something like:
Code: Select all
   hull = &loadmodel->hulls[3];
   hull->clipnodes = out;
   hull->firstclipnode = 0;
   hull->lastclipnode = count-1;
   hull->planes = loadmodel->planes;
   hull->clip_mins[0] = -16;
   hull->clip_mins[1] = -16;
   hull->clip_mins[2] =  0;  // pretty much like hull1, only shorter
   hull->clip_maxs[0] = 16;
   hull->clip_maxs[1] = 16;
   hull->clip_maxs[2] = 32;


But that's not enough, we just generated the data for a new hull. We need also to change this in world.c:

Code: Select all
/*
================
SV_HullForEntity

Returns a hull that can be used for testing or clipping an object of mins/maxs
size.
Offset is filled in to contain the adjustment that must be added to the
testing object's origin to get a point to use with the returned hull.
================
*/
hull_t *SV_HullForEntity (edict_t *ent, vec3_t mins, vec3_t maxs, vec3_t offset)
{
   model_t      *model;
   vec3_t      size;
   vec3_t      hullmins, hullmaxs;
   hull_t      *hull;

// decide which clipping hull to use, based on the size
   if (ent->v.solid == SOLID_BSP)
   {   // explicit hulls in the BSP model
      if (ent->v.movetype != MOVETYPE_PUSH)
         Sys_Error ("SOLID_BSP without MOVETYPE_PUSH");

      model = sv.models[ (int)ent->v.modelindex ];

      if (!model || model->type != mod_brush)
         Sys_Error ("MOVETYPE_PUSH with a non bsp model");

      VectorSubtract (maxs, mins, size);
      if (size[0] < 3)
         hull = &model->hulls[0];
      else if (size[0] <= 32)
         hull = &model->hulls[1];
      else
         hull = &model->hulls[2];

// calculate an offset value to center the origin
      VectorSubtract (hull->clip_mins, mins, offset);
      VectorAdd (offset, ent->v.origin, offset);
   }
   else
   {   // create a temp hull from bounding box sizes

      VectorSubtract (ent->v.mins, maxs, hullmins);
      VectorSubtract (ent->v.maxs, mins, hullmaxs);
      hull = SV_HullForBox (hullmins, hullmaxs);

      VectorCopy (ent->v.origin, offset);
   }


   return hull;
}



And that's a bit more complicated, but not much.
Anyone want to help in our collaborative tutorial ? :)
I know FrikaC made a cgi-bin version of the quakec interpreter once and wrote part of his website in QuakeC :) (LordHavoc)
User avatar
frag.machine
 
Posts: 2090
Joined: Sat Nov 25, 2006 1:49 pm

Postby Downsider » Wed Oct 13, 2010 12:30 am

Can't any size hull be emulated using the 0,0,0 hull?
User avatar
Downsider
 
Posts: 621
Joined: Tue Sep 16, 2008 1:35 am

Postby Error » Wed Oct 13, 2010 1:36 am

I do believe LordHavoc stated that he added a cvar that allows any size collision hull... I'm not sure though.
User avatar
Error
InsideQC Staff
 
Posts: 865
Joined: Fri Nov 05, 2004 5:15 am
Location: VA, USA

Postby mh » Wed Oct 13, 2010 1:49 am

In theory you just need one hull and you shrink the BSP to the appropriate size, then run your clipping. I think that's the way it works.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
User avatar
mh
 
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Postby andrewj » Wed Oct 13, 2010 5:28 am

mh wrote:Speaking off the top of my head, but I wonder does QBSP construct the hull from the .map data or from the .bsp data?

It's the former -- QBSP needs the brushes to construct the clipping hulls.

It works by making each brush bigger by the sizes of the corresponding bounding box (e.g. the player clipping hull makes the brushes 16 units fatter on each side, 24 units higher on top, and 32 units lower on the bottom). Then the CSG/BSP operations are done on this set of fattened brushes.

You could probably still generate them in an engine, but I really think your time would be better spent implementing collision code which supported arbitrary bboxes, especially if LordHavoc has already done most of it for you :P
andrewj
 
Posts: 133
Joined: Mon Aug 30, 2010 3:29 pm
Location: Australia

Postby r00k » Wed Oct 13, 2010 5:41 am

@frag.machine,
I have this in my engine already with the HL_BSPVERSION hulls,

but adding hulls[3] dont we also need to test for hulls[3[ in world.c?
Code: Select all
if (size[0] < 3)
{
   hull = &model->hulls[0];
}
else
{
   if (size[0] <= 32)
   {
      hull = &model->hulls[1];
   }
   else
   {
      if (size[0]<=16)
      {
         hull = &model->hulls[3];         
      }
        else
      {
         hull = &model->hulls[2];
      }
   }
}
r00k
 
Posts: 1110
Joined: Sat Nov 13, 2004 10:39 pm

Postby frag.machine » Wed Oct 13, 2010 12:04 pm

Yeah, that's the part I mentioned at the end (world.c, SV_HullForEntity). Also, I forgot to mention that everything I wrote assumed a BSP containing data to fill all the 4 hulls, of course. But after thinking about this, I think it's really better just scrap all but hull[0] and change the collision code.
I know FrikaC made a cgi-bin version of the quakec interpreter once and wrote part of his website in QuakeC :) (LordHavoc)
User avatar
frag.machine
 
Posts: 2090
Joined: Sat Nov 25, 2006 1:49 pm

Previous

Return to Engine Programming

Who is online

Users browsing this forum: No registered users and 1 guest