News | Forum | People | FAQ | Links | Search | Register | Log in
Coding Help
This is a counterpart to the "Mapping Help" thread. If you need help with QuakeC coding, or questions about how to do some engine modification, this is the place for you! We've got a few coders here on the forum and hopefully someone knows the answer.
First | Previous | Next | Last
Thanks 
The only time you'd need to be able to tell the difference is when you have something like func_trains which expect bsp objects. I suggest you use spawnflags or something to say 'non-solid' instead.

That's exactly the scenario I had in mind. It seems like it would be annoying to users that even though you've obviously specified a non-BSP model, you also have to manually tell it "this is a non-BSP model" again. It would be nice to have the mod take the hassle out, or at least practice look-before-you-leap, but I suppose the crash is instant at least so people would catch and fix places where they forgot more or less instantly.

I have a plan in mind now that's slightly neater than a spawnflag...watch this space. 
 
some engines support non-bsp objects as SOLID_BSP pushers (even if its just a bbox). A non-solid flag should thus not be implied by the model type alone.
You wouldn't be saying 'this is a non-bsp model', you'd be saying 'this isn't solid', which might apply for evil trains too (mwahaha). The fact that the engine doesn't support solid trains isn't the mod's fault, its the engine's fault. That said, the mod probably should take efforts to ensure the bbox size is also tweakable if its a solid mdl. 
Fair Enough 
I think the plan will work just fine with that - people will be able make something that works in all engines or opt for taking advantage of a new engine's features - if they don't mind they've excluded classic engines in the process. 
BSP Tree Traversal 
I just want to make sure I'm doing this correctly, before I begin my bug-hunt.

To find the leaf the player is in, you take the root node, and see what side of that node's plane the player is on. If they're on the positive side, do the same using node children[0], if they're on the negative side, do the same using children[1]. During this "walking" you'll come to a point where the child you're told to check is a negative number. Discard the negative sign and add one. This is the leaf the player/camera is in, and using that leaf's PVS will render all leafs visible from that point.

Is this right, or am I making a poor assumption or oversimplification somewhere? 
@allcaps 
Discard the negative and subtract one, if you're using that order of operations.
-1 maps to leaf 0, not leaf 2.
Remember to decompress your pvs. 
Roger 
Got my bsp walking working. I can tell what leaf the camera is in now. Struggled for hours, then on a whim tried inverting the plane normal, and it now works as it should.

Nearly 100% of the stumbles I've run into have been in converting Quake-space to Unity-space, and the trend continues.

Working on decompressing and using PVS now. So close I can taste it. I keep saying I need to work on lightmaps, but this is more interesting. Lightmaps should (should) be pretty trivial, so blazing through that will hopefully be my reward for getting PVS working. 
Conflicting Documentation 
I'm reading all over trying to get a handle on reading and decompressing PVS data, but I'm having a hell of a time.

I have some embarrassingly elementary questions.

I read out the bytes in the vis data lump, and for the tiny map I'm using to debug this renderer, I get this:
255 10 255 2 207 10 207 10 243 2 243 2 255 10 255 10 0 1 15 255 15 0 1 7 205 11

What is the correct method for decompressing this? I'm not even sure I'm reading it out correctly, because looking at this it looks like there's going to be way too much data. This map only has 13 leafs, so something is wrong. Should I be reading these as shorts/ints instead of raw bytes?

This is an area where examining bspfile.h hasn't really helped, as there's no lump defined for this. 
 
look at Mod_DecompressVis in the source, that's where quake decompresses it.

Basically non-zero bytes are uncompressed. Every run of zeros is run-length encoded, a zero followed by a second byte which is a count.

And once uncompressed, there is 1 bit for every leaf. 
 
I've tried looking over other source for this, but I'll admit I don't know C well at all, so I can't really follow what's happening. 
Allcaps' Assumptions 
It's time for another episode of Allcaps' Assumptions.

I have a very small map I made for testing. It has 13 leafs. The visibility lump for this map is 26 bytes.

This means that in order to store a bit for every leaf, each leaf's PVS will be two bytes of data. (13 bits needed, add 7 then divide by 8 to find the number of whole bytes needed) Right?

Parsing the lump, should each byte be interpreted as a char, or an integer? I know that it represents bitfields, but no matter how I read this in it doesn't look at all like I expect it to going by various docs I can find. Reading the small map above's vis lump as chars gives me this:

10 2 10 10 2 2 10 10 0 1 15 15 0 1 7 11 0 105 0 0 123 10 34 115 112 97

This looks kind of okay. So I break it into two-byte sets (since each leaf's pvs is 13 bits, needing two bytes) and get:

10 2
10 10
2 2
10 10
0 1
15 15
0 1
7 11
0 105
0 0
123 10
34 115
112 97

Now it looks less okay. How can there be a set that is 0 0? How can there be 0 105? So there's a hundred and five zero bytes in that set? I'm going wrong somewhere pivotal and I'm really lost as to where. 
 
For the thousandth time, tronyn's is NOT BSP2, it's 2PSB.

Heh.

heh heh heh.

:-D 
 
Yeah, people ARE still talking about rmq even if this bug is the only legacy. Congratulations. :-) 
We Made It 
 
 
Heh. =)

=) 
 
Honestly though, gb, why bully me? 
Still PVS Mystery 
I've work on a few other things, like some groundwork for lightmap import, and BSP2 support, but I'm still totally lost on deciphering this PVS information.

C# has a bitarray datatype that would make this really easy to implement if I could just get the PVS data read and decompressed.

I feel like real doofus for asking but does anyone have a page with detailed information on reading and handling the PVS information? I've found so many pages that are just "here's how you do it" with a lump of C source that is a web of pointers, bitshifting, and variables with undescriptive names.

This is the last feature needed before the real fun stuff can begin. 
You're Doing Great 
My only question is will it support bsp2 :>

Sorry, don't have a link for what you're looking for. 
 
leafs (... leaves ...) contain an arbitary offset into the compressed pvs lump. They don't start at predictable places, and the qbsp is free to overlap duplicate sequences.
Breaking it into 'two byte sets' is thus a silly thing to do.
That said, I have no idea why you would find a 0 0 pair anywhere in the data unless it was unused, which is a possibility. 
Allcaps 
I think you're correct in identifying that the pairs after 7 11 do not parse correctly according to the decompression algorithm. Can you recheck the code that's getting the block of visdata? You may want to check if you get the same data by following the design of the original code more closely: reading each leaf, taking the visdata offset from that leaf, and then reading a pair of chars from that offset. 
Almost 
Leaf 0's pvs is always "everything is visible". Is this handled as a special case, or does the vis lump contain an entry for leaf 0 as well? 
Almost Almost 
Okay.

This is the compressed vis data for my testing map.

VisData: (26 bytes) 255 10 255 2 207 10 207 10 243 2 243 2 255 10 255 10 0 1 15 255 15 0 1 7 205 11

I'm inclined to think it's good, because when I use it the level renders correctly. I currently do not decompress the zeros, I can get away with this on my test map because the leafs are so few. Every leaf renders correctly except for 9 and 11, which are the only two leafs to include a zero in their PVS. Fair enough, since I'm not handling the zeros yet. I'm about to, and want to make sure my thinking is correct.

Take leaf 9. It's compressed vis bytes are 0 1. Each leaf takes two bytes of data to have enough bits. After the 0 1 in the data is a 15.

To make sure I'm thinking correctly, this really means it's vis bytes would be 0 15, because it means 0 (starting zero run) 1 (add one zero, done with zero run) 15 (non-zero, add directly).

Is this correct? 
Byte Back 
To make sure I'm thinking correctly, this really means it's vis bytes would be 0 15, because it means 0 (starting zero run) 1 (add one zero, done with zero run) 15 (non-zero, add directly).

Is this correct?


You are correct in how vis leaf 9 works. I think it does expose a problem though.

You started by calculating that each vis leaf requires 2 bytes to store the visibility data of 13 leaves. You then reported that this makes the size of the vis data 26 bytes. The crucial point is that 26 bytes is the size of the uncompressed vis data. We would expect the compressed data to be different in size, otherwise why bother with compression?

To complicate things further, there's an issue of map size. Your map, being unusually small, exposes a rare corner case of the compression algorithm. Leaf 9 has compressed vis data 0 1 15 - that's three bytes. Even if the other 12 leaves lacked zero bytes, that's 12 * 2 bytes + 3 bytes = 27 bytes. The algorithm has made the "compressed" data longer than the uncompressed data!

The important takeaway lesson is that we can't calculate how long the compressed vis data for a map will be from the number of leaves. In most real levels it will be smaller that the uncompressed data, in small box levels it will be larger. The only way to get the correct size is to parse it byte by byte from the file. 
Yes 
That's what I was doing. Sorry I didn't mean to make it look like I was trying to calculate the size of the compressed data using the number of leafs. It was only by chance that the number of bytes in the compressed data was twice the number of leafs, and that it was two bytes to store the uncompressed pvs for a leaf.

Great to have reassurance though :)

I think I may have it working, it works correctly on my tiny test map, and on Stalwart, a small-ish dm map. Time to get some bigger maps and see what happens. 
Models 
Alright, I have PVS working for the world itself. How are models other than 0 (the world) handled? Does a leaf's PVS information contain info on every leaf, or just leafs in the same bsp tree/model? It looks like it's just in that leaf's own tree/model.

Are other models just handled via frustum checks? 
 
pvs is used for 3 things:
bsp rendering (drawing less bsp faces).
entity(net) culling (reducing network traffic).
gamecode logic (trivially skipping tracelines).

the renderer might want to cull submodel faces based upon view position.
or it might batch the entire submodel and be faster if it doesn't then try to split it up.

the other two situations generally use positions relative to the world. submodel pvs information is likely not useful, although it might be handy if both positions are expressed relative to a submodel. such cases are both awkward and minor, as well as infrequent.

phs next? :P 
First | Previous | Next | Last
You must be logged in to post in this thread.
Website copyright © 2002-2024 John Fitzgibbons. All posts are copyright their respective authors.