Tutorial: Visible bboxes
Moderator: InsideQC Admins
19 posts
• Page 1 of 2 • 1, 2
Tutorial: Visible bboxes
Tutorial: Visible bounding boxes
ello! I am about to explain the technique for getting your bounding boxes to be visible with only quakec. I am pretty sure that just about every quakec modder will find this very useful! NOT A BAD CREATION FOR SOMEONE AS NOOBY AS MYSELF, NO?
Picture paints a thousand words:
First I must explain a few things. This code utilizes TE_TEI_G3. It's an odd, undocumented extension in DP and probably FTE that draws a line (if a targa named nexbeam.tga is found in the particles folder (Here is an example), it will draw that instead) between two vectors, AKA sort of like a laser. That means that this will only work with engines that support this extension. Another thing is that this code can dramatically slow down the fps when updated frequently and/or used on many entities, so don’t go nuts with it. Lastly, this code reveals the many flaws with quake’s bounding box system; mainly you will notice that bounding boxes cannot change angles with the player, which is downright ridiculous.
So, onto the juicy code, shall we? Add the TE_TEI_G3 extension found below to either defs.qc or where it should’ve been, dpextensions.qc:
Ok, now to add my clever little code (best to add right below the te_tei_g3 code):
Ok, if you want to see a particular entity’s bbox, add one of these codes to the entity's spawn function (NOT before setsize is called):
OR
If one doesn’t work, the other probably will.
Because I love helping coders learn and I really do not want this to be yet another copy paste code, I will explain the above code in detail for those who don't understand. Whenever you setsize a code, you do something similar to this: setsize (self, '-5 -5 -5', '5 5 5');. You are giving the entity two vectors, a minimum and a maximum (setsize (self, SELF.MINS, SELF.MAXS);)
Now, above you see the line that reads:
minnx_x = self.mins_x;
The vector 'minnx' is getting it's 'x' variable equal to the entity's self.mins_x variable. In the end, the vector minnx becomes equal to 'self.mins_x 0 0'. Same thing with:
maxxx_x = self.maxs_x;
This time you are doing this, maxxx = 'self.maxs_x 0 0'. By giving each vector only one variable, adding them becomes less of a hassle because if you did this: self.origin + self.maxs_x, you would get a type mismatch error since you cannot add a vector and a float.
same case here:
minny_y = self.mins_y;
AKA:
minny = '0 self.mins_y 0';
maxxy_y = self.maxs_y;
AKA:
maxxy = '0 self.maxs_y 0';
and here:
minnz_z = self.mins_z;
AKA:
minnz = '0 0 self.mins_z';
maxxz_z = self.maxs_z;
AKA:
maxxz = '0 0 self.maxs_z';
Why add all these variables in the first place? Because of the following.
Quakec quirks make life hard sometimes. This is one case. Directly using an entity's mins or maxs vectors doesn't work for some strange reason, I don't know if it's quakec's fault or just my luck.
So, now how do i connect all the lines that form our bbox? Bear with this explanation:
minnx means backwards
maxxx means forwards
minny means to the left
maxxy means to the right
minnz means down
maxxz means up
remember this!
now:
te_tei_g3 (self.origin + minnx + minny + minnz, self.origin + minnx + minny + maxxz);
"self.origin + minnx + minny + minnz"
this translates into: start at the origin. go as backwards as you can, then go as left as you can, and then go as down as you can. You will be at the bottom left corner of your bbox, first point of line.
start again:
"self.origin + minnx + minny + maxxz"
this means: start at origin, go as backwards as you can, then go as left as you can, then go as UP as you can, you will be at the top left corner of your bbox! second point of line.
connect these points and you will have your first line that connects the bottom left corner and top left corner of your bbox!
The rest of it does the same. Since there are 12 edges in a cube, you find 12 variations of this code!
comprende?
===================================================
Compile and run! ;D
Hope you like it!
BONUS: DP’s other undocumented extensions:
ello! I am about to explain the technique for getting your bounding boxes to be visible with only quakec. I am pretty sure that just about every quakec modder will find this very useful! NOT A BAD CREATION FOR SOMEONE AS NOOBY AS MYSELF, NO?
Picture paints a thousand words:
First I must explain a few things. This code utilizes TE_TEI_G3. It's an odd, undocumented extension in DP and probably FTE that draws a line (if a targa named nexbeam.tga is found in the particles folder (Here is an example), it will draw that instead) between two vectors, AKA sort of like a laser. That means that this will only work with engines that support this extension. Another thing is that this code can dramatically slow down the fps when updated frequently and/or used on many entities, so don’t go nuts with it. Lastly, this code reveals the many flaws with quake’s bounding box system; mainly you will notice that bounding boxes cannot change angles with the player, which is downright ridiculous.
So, onto the juicy code, shall we? Add the TE_TEI_G3 extension found below to either defs.qc or where it should’ve been, dpextensions.qc:
- Code: Select all
void(vector start, vector end) te_tei_g3 =
{
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, 76);
WriteCoord (MSG_BROADCAST, start_x);
WriteCoord (MSG_BROADCAST, start_y);
WriteCoord (MSG_BROADCAST, start_z);
WriteCoord (MSG_BROADCAST, end_x);
WriteCoord (MSG_BROADCAST, end_y);
WriteCoord (MSG_BROADCAST, end_z);
WriteCoord (MSG_BROADCAST, 0);
WriteCoord (MSG_BROADCAST, 0);
WriteCoord (MSG_BROADCAST, 0);
};
Ok, now to add my clever little code (best to add right below the te_tei_g3 code):
- Code: Select all
void() viewbbox = //behind_you's visible bbox code
{
local vector minnx, minny, minnz, maxxx, maxxy, maxxz;// bunch of definitions for use
minnx_x = self.mins_x;
minny_y = self.mins_y;
minnz_z = self.mins_z;
maxxx_x = self.maxs_x;
maxxy_y = self.maxs_y;
maxxz_z = self.maxs_z;
//the code below connects all the points to form the bbox, using the fantabulous te_tei_g3 extension:
te_tei_g3 (self.origin + minnx + minny + minnz, self.origin + minnx + minny + maxxz);
te_tei_g3 (self.origin + maxxx + maxxy + minnz, self.origin + maxxx + maxxy + maxxz);
te_tei_g3 (self.origin + maxxx + minny + minnz, self.origin + maxxx + minny + maxxz);
te_tei_g3 (self.origin + minnx + maxxy + minnz, self.origin + minnx + maxxy + maxxz);
te_tei_g3 (self.origin + minnx + maxxy + maxxz, self.origin + maxxx + maxxy + maxxz);
te_tei_g3 (self.origin + minnx + minny + maxxz, self.origin + maxxx + minny + maxxz);
te_tei_g3 (self.origin + minnx + minny + maxxz, self.origin + minnx + maxxy + maxxz);
te_tei_g3 (self.origin + maxxx + minny + maxxz, self.origin + maxxx + maxxy + maxxz);
te_tei_g3 (self.origin + minnx + maxxy + minnz, self.origin + maxxx + maxxy + minnz);
te_tei_g3 (self.origin + minnx + minny + minnz, self.origin + maxxx + minny + minnz);
te_tei_g3 (self.origin + minnx + minny + minnz, self.origin + minnx + maxxy + minnz);
te_tei_g3 (self.origin + maxxx + minny + minnz, self.origin + maxxx + maxxy + minnz);
//there are 12 line codes above, and 12 edges in a cube.
self.nextthink = time + 0.1;//if game slows down too much, try increasing the 0.1
};
Ok, if you want to see a particular entity’s bbox, add one of these codes to the entity's spawn function (NOT before setsize is called):
- Code: Select all
viewbbox();
OR
- Code: Select all
self.think = viewbbox;
self.nextthink = time + 0.1;
If one doesn’t work, the other probably will.
Because I love helping coders learn and I really do not want this to be yet another copy paste code, I will explain the above code in detail for those who don't understand. Whenever you setsize a code, you do something similar to this: setsize (self, '-5 -5 -5', '5 5 5');. You are giving the entity two vectors, a minimum and a maximum (setsize (self, SELF.MINS, SELF.MAXS);)
Now, above you see the line that reads:
minnx_x = self.mins_x;
The vector 'minnx' is getting it's 'x' variable equal to the entity's self.mins_x variable. In the end, the vector minnx becomes equal to 'self.mins_x 0 0'. Same thing with:
maxxx_x = self.maxs_x;
This time you are doing this, maxxx = 'self.maxs_x 0 0'. By giving each vector only one variable, adding them becomes less of a hassle because if you did this: self.origin + self.maxs_x, you would get a type mismatch error since you cannot add a vector and a float.
same case here:
minny_y = self.mins_y;
AKA:
minny = '0 self.mins_y 0';
maxxy_y = self.maxs_y;
AKA:
maxxy = '0 self.maxs_y 0';
and here:
minnz_z = self.mins_z;
AKA:
minnz = '0 0 self.mins_z';
maxxz_z = self.maxs_z;
AKA:
maxxz = '0 0 self.maxs_z';
Why add all these variables in the first place? Because of the following.
Quakec quirks make life hard sometimes. This is one case. Directly using an entity's mins or maxs vectors doesn't work for some strange reason, I don't know if it's quakec's fault or just my luck.
So, now how do i connect all the lines that form our bbox? Bear with this explanation:
minnx means backwards
maxxx means forwards
minny means to the left
maxxy means to the right
minnz means down
maxxz means up
remember this!
now:
te_tei_g3 (self.origin + minnx + minny + minnz, self.origin + minnx + minny + maxxz);
"self.origin + minnx + minny + minnz"
this translates into: start at the origin. go as backwards as you can, then go as left as you can, and then go as down as you can. You will be at the bottom left corner of your bbox, first point of line.
start again:
"self.origin + minnx + minny + maxxz"
this means: start at origin, go as backwards as you can, then go as left as you can, then go as UP as you can, you will be at the top left corner of your bbox! second point of line.
connect these points and you will have your first line that connects the bottom left corner and top left corner of your bbox!
The rest of it does the same. Since there are 12 edges in a cube, you find 12 variations of this code!
comprende?
===================================================
Compile and run! ;D
Hope you like it!
BONUS: DP’s other undocumented extensions:
- Code: Select all
void(vector pos, vector dir, float howmuch) te_tei_smoke = //makes smoke effect, best when you edit effectinfo.txt as well
{
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, 77);
WriteCoord (MSG_BROADCAST, pos_x);
WriteCoord (MSG_BROADCAST, pos_y);
WriteCoord (MSG_BROADCAST, pos_z);
WriteCoord (MSG_BROADCAST, dir_x);
WriteCoord (MSG_BROADCAST, dir_y);
WriteCoord (MSG_BROADCAST, dir_z);
WriteByte (MSG_BROADCAST, howmuch);
};
void(vector pos) te_tei_bigexplosion = //bigger explosion
{
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, 78);
WriteCoord (MSG_BROADCAST, pos_x);
WriteCoord (MSG_BROADCAST, pos_y);
WriteCoord (MSG_BROADCAST, pos_z);
};
void(vector pos, vector dir, float howmuch) te_tei_plasmahit =// cool little plasma effect
{
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, 79);
WriteCoord (MSG_BROADCAST, pos_x);
WriteCoord (MSG_BROADCAST, pos_y);
WriteCoord (MSG_BROADCAST, pos_z);
WriteCoord (MSG_BROADCAST, dir_x);
WriteCoord (MSG_BROADCAST, dir_y);
WriteCoord (MSG_BROADCAST, dir_z);
WriteByte (MSG_BROADCAST, howmuch);
};
-

behind_you - Posts: 237
- Joined: Sat Feb 05, 2011 6:57 am
- Location: Tripoli, Libya
note that hull positions are not identical to bbox positions - anything clipping against world has a different bbox, which is a function of its absmin, the size of its bbox, and the hard-coded hull sizes of the qbsp+engine.
- Spike
- Posts: 2892
- Joined: Fri Nov 05, 2004 3:12 am
- Location: UK
OR! You could reduce that to 1 line of code:
- Code: Select all
r_showbboxes 1
- GiffE
- Posts: 170
- Joined: Sun Oct 08, 2006 3:39 pm
- Location: USA, CT
I thought it could be achieved by having some simple cube spawned 12 times (4 for top, 4 for bottom and 4 for sides) and stretched so, that they reates lines of bounding box.
Not sure if it is possible in Quake by either alias model or brush model. If it is possible it should work in vanilla Quake I guess.
Not sure if it is possible in Quake by either alias model or brush model. If it is possible it should work in vanilla Quake I guess.
Think, touch, movetype, solid, traceline ...
-

daemonicky - Posts: 185
- Joined: Wed Apr 13, 2011 1:34 pm
GiffE wrote:OR! You could reduce that to 1 line of code:
- Code: Select all
r_showbboxes 1
doesn't work in DP for me
-

behind_you - Posts: 237
- Joined: Sat Feb 05, 2011 6:57 am
- Location: Tripoli, Libya
That's specific to fitzquake iirc.GiffE wrote:OR! You could reduce that to 1 line of code:
- Code: Select all
r_showbboxes 1
Ken Thompson wrote:One of my most productive days was throwing away 1000 lines of code.
Get off my lawn!
-

dreadlorde - Posts: 268
- Joined: Tue Nov 24, 2009 2:20 am
behind_you wrote:GiffE wrote:OR! You could reduce that to 1 line of code:
- Code: Select all
r_showbboxes 1
doesn't work in DP for me
(Jan. 18th 2011 Build of DP)
- GiffE
- Posts: 170
- Joined: Sun Oct 08, 2006 3:39 pm
- Location: USA, CT
As Spike said, there are two different types of bounding boxes in use in the engine - server-side and client-side (or more specifically, renderer-side).
Regarding the size of the server-side bounding-boxes, assuming you don't want gameplay changes, the golden rule is - don't mess with them.
Client-side you can do what you want. Adapt MDL bounding boxes to per-frame, derive brush model bounding boxes from the actual surface vertex positions, rotate and scale them, whatever you want. They're only used for view frustum culling and so long as the resulting box is still valid for use with that, they're your's to play with.
Regarding the size of the server-side bounding-boxes, assuming you don't want gameplay changes, the golden rule is - don't mess with them.
Client-side you can do what you want. Adapt MDL bounding boxes to per-frame, derive brush model bounding boxes from the actual surface vertex positions, rotate and scale them, whatever you want. They're only used for view frustum culling and so long as the resulting box is still valid for use with that, they're your's to play with.
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
We knew the words, we knew the score, we knew what we were fighting for
-

mh - Posts: 2292
- Joined: Sat Jan 12, 2008 1:38 am
mh wrote:As Spike said, there are two different types of bounding boxes in use in the engine - server-side and client-side (or more specifically, renderer-side).
Regarding the size of the server-side bounding-boxes, assuming you don't want gameplay changes, the golden rule is - don't mess with them.
Client-side you can do what you want. Adapt MDL bounding boxes to per-frame, derive brush model bounding boxes from the actual surface vertex positions, rotate and scale them, whatever you want. They're only used for view frustum culling and so long as the resulting box is still valid for use with that, they're your's to play with.
Ok but why shouldn't you mess with them server side? And is it possible to actually rotate bboxes in csqc? how do u do that?
I figured out that r_showbboxes works in DP. Wow, there goes my efforts
-

behind_you - Posts: 237
- Joined: Sat Feb 05, 2011 6:57 am
- Location: Tripoli, Libya
behind_you wrote:Ok but why shouldn't you mess with them server side?
Because it's a gameplay change.
behind_you wrote:And is it possible to actually rotate bboxes in csqc? how do u do that?
No idea, sorry. I rotate them engine-side and it works quite fine; I've posted a tutorial somewhere here containing C code for it which might be translatable to CSQC. Ask me anything you want about the C side, but I really know virtually nothing about QC of any kind.
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
We knew the words, we knew the score, we knew what we were fighting for
-

mh - Posts: 2292
- Joined: Sat Jan 12, 2008 1:38 am
mh wrote:Because it's a gameplay change.
Ok, but modding is changing gameplay, so it's okay to rotate them server side? or am i misunderstanding?
-

behind_you - Posts: 237
- Joined: Sat Feb 05, 2011 6:57 am
- Location: Tripoli, Libya
behind_you wrote:mh wrote:Because it's a gameplay change.
Ok, but modding is changing gameplay, so it's okay to rotate them server side? or am i misunderstanding?
Not in the engine, because a change in the engine is going to affect all mods, including ID1.
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
We knew the words, we knew the score, we knew what we were fighting for
-

mh - Posts: 2292
- Joined: Sat Jan 12, 2008 1:38 am
mh wrote:behind_you wrote:mh wrote:Because it's a gameplay change.
Ok, but modding is changing gameplay, so it's okay to rotate them server side? or am i misunderstanding?
Not in the engine, because a change in the engine is going to affect all mods, including ID1.
I c. well I'm not modding engine, just qc. So I'll mess with them
-

behind_you - Posts: 237
- Joined: Sat Feb 05, 2011 6:57 am
- Location: Tripoli, Libya
i dont think changing your bboxes for mapping purposes will matter. if you cant fit through a hole you wont be able to no matter what, that's all dependent on something in the mapping side of things, i think.
(just assuming that's your reasoning)
(just assuming that's your reasoning)
-

ceriux - Posts: 2223
- Joined: Sat Sep 06, 2008 3:30 pm
- Location: Indiana, USA
1. you can't rotate bboxes in quakec; if you rotate the entity the box will stay un-rotated. They are literally "axis-aligned bounding boxes" which means they are always axis-aligned.
2. if you resize bboxes in quakec, it will work for entity-v-entity and traceline-v-entity collision, but entity-vs-world collision will still use one of the standard collision hull sizes.
2. if you resize bboxes in quakec, it will work for entity-v-entity and traceline-v-entity collision, but entity-vs-world collision will still use one of the standard collision hull sizes.
- metlslime
- Posts: 316
- Joined: Tue Feb 05, 2008 11:03 pm
19 posts
• Page 1 of 2 • 1, 2
Who is online
Users browsing this forum: No registered users and 1 guest