MidSplit now does two passes (structural/detail), like ChoosePlaneFromList.
Now, the first pass will pick among planes that have at least one structural face, and zero or more detail faces.
The second pass will pick among planes that have no structural faces, and zero or more detail faces.
This fixes the hull 1 leak in telefragged.map introduced when I added txqbsp's maxNodeSize feature,
and also reduces the cluster and portal count in jam6_ericwtronyn.map a bit.
Thanks to rebb for the idea, txqbsp has the workaround in SelectPartition that recomputes the surface bbox; I think this fixes the underlying bug though.
Note: this makes telefragged.map (from the RRP devkit) leak in hull 2.
However, the point file starts at a func_detail staircase that, if turned into func_wall, fixes the leak.
Here's another little tyrutils patch: in qbsp, I believe the
calculation of the "disksize" field of the miptex lumps when using
WAD3 textures is missing the size of the dmiptex_t struct (40 bytes),
causing the resulting bsp file to be slightly truncated.
I noticed this because one of Tronyn's levels (jam2_tronyn.bsp) was
crashing Quakespasm for me; it turned out the engine was trying to
read 40 bytes past the end of the file when loading the last texture
in the bsp. I got him to send over his map source, wads, and compiler;
he was using tyrutils 0.15 and wad3 format textures, and I confirmed
that this patch fixes the engine crash.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
The error message was actually displaying the edge vector, which is
always going to be ~(0,0,0). Pass in the edge end points and then we
can display both the length of the edge and the location of one end
point.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
To improve debug messages, save the line number of the faces as we
generate them and in the case of hull generation, save a pointer back
to the source brush.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Enables us to check if there is extra data on the same line, without
advancing the parser past the end of line.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Search the WADs for extra frames on any animated textures used and add
them to the bsp. This restores the old behaviour which was mistakenly
removed, but now we have the assurance that textures are added in
order and all lower numbered animation frames are added a warning is
printed if it is missing from the wad.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Turns out there are two types of "BSP2" format - one that I think was
created by MH and implemented in the RMQ project (this is the one I
implemented previously) and one by LordHavoc which exteneded the
coordinate limits beyond 32k, implemented in Darkplaces. The
Darkplaces version of BSP2 will get the name BSP2 and the RMQ version,
which is more limited, will get the name BSP2rmq.
qbsp will only create the BSP29 or BSP2 formats, but will cope with a
BSP2rmq format file for an -onlyents compile. The rest of the tools
can use any of the three formats.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Rename the default bsp29 data types and add the bsp2 data types to
the common bspfile.h. Propogate the bsp29 names into the other tools as
simple renames for now.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Won't produce a working bsp2 file yet, but if you ask for bsp2 on the
command line now, faces and edges will be output in bsp2 format.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Kind of taking a step backwards here to where we were, but make the
MemSizes array dynamically changable so that we can switch out and
allocate BSP2 sized elements when we want to write a file in that format.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Some of the bsp2 data structures are bigger than the bsp29 structures, so
we need to know the difference in allocation size. Stop using the data
structure enum for lump numbers.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
In preparation for bsp2 support, add the data types for bsp2 structures
to bspfile.h and rename the bsp29 structures to properly differentiate them.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Unable to represent this in the bsp29 format, so let the user know instead
of silently corrupting the bsp.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
We take care of adding extra animation frames during loading of the map
file to ensure that we add lower-numbered texture frames before the higher
numbered frames. Most Quake engines will choke on a BSP if the texture
frames are presented out of order (including the original).
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Normally we build a fast, unoptimized bsp tree for the world before
culling outside surfaces. This command line switch forces the use of
the more expensive algorithm for this processing stage. Seems to have
a positive effect on the final BSP in terms of reduced marksurfaces
and smaller file size, at the expense of longer processing time.
Marked experimental for now, as it may be removed later (either by
making this behaviour the default or removing it altogether).
Credit to Rebb from func_msgboard for implementing this tweak first in
his qbsp util.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Explicitly pass the face list around to be added to as needed instead
of implicit reference to the global 'newlist'.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Remove the global static buffer and allocate the superface when
processing tjuncs. Also check that we are not overflowing the buffer
before adding more vertices - probably something went wrong if this
ever overflows, so better to crash with a definite error than scribble
random memory.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
The way wedge_t and wvert_t were hashed and compared was resulting in
FixFaceEdges being able to get stuck in a loop adding verticies to a face
if two consecutive verticies were very close to EQUAL_EPSILON apart.
Avoid these problems by tweaking T_EPSILON to be slightly wider than
EQUAL_EPSILON.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Took me some time to work out what this was all representing and that t
was the parameter to the parametric equations of the edge's line in 3-d
space. May as well make it easier for others and my future self.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
No functional changes, just making the previous cleanup more consistent.
Pointer is non-const now, but no matter.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Mainly tidy up long lines and rename dir/test variables to edgevec[2]
since these are the edge vectors we are testing the angles between.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Since 'w' is commonly used for a winding variable, this makes the code
harder to read. Use the name 'edge' instead for these tjunc local types.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
If brushes in the map are textured with alt-animations, and the second
character (i.e. the 'a' in +abutton) is lower case then we have the
lowercase texture name in the miptex list, but when we add alt textures we
use the uppercase, so it gets duplicated. Duplicated animating textures
cause most engines to exit with an error.
Since the map file could use uppercase texture names as well, really we
should either be normalizing texture names to upper or lower case, or we
need to do case-insensitive matching - so I just changed to
case-insensitive matching.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Also do a quick sweep of the source and consistently use %d instead of
%i (no real difference, but just pick one).
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Not too intrusive, since the Message() layer still acts as a shim
here. Most of the changes are for the Makefile. Qbsp now links to
the threading code as a result, but no thread support... yet!
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Carry over some correctness fixes from recent changes to vis into the
qbsp versions of ClipWinding and make the implementations more
consistent overall.
Most importantly:
* Ensure we always have allocated one extra dists/sides slot for wrap around
* Check we have space for a new vertex every time we try to add one
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Factor out some of the processing involved with parsing a brush. When
checking for duplicate planes, use the same "PlaneEqual" functions as
used in brush.c.
Replace the enum style errors with the new Error_ function for all of
map.c so the error string is at the call site.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Call it Error_() for now while I work on transitioning away from the
arrays of global strings hidden away by error enums.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
We don't want to terminate the recursion in ClusterContents when we reach
a non-detail separator because we need to know the contents of the leafs!
This was working okay for simple cases but fails when the detail clusters
become more complex.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Don't count skip surface verticies at all in CountData_r because this
count actually gets used as the surfedge count and we need that to be
precise.
Don't try to save memory be allocating less verticies than edges, even
though many will probably be shared. The saving is not that significant
anyway.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
We still end up short if we just discard these counts - still don't
need faces for them, but every edge could be real unless it's shared
with another skip face.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
The old assumption about unique verticies is sometimes untrue when
skip faces are included in the map. Be more generous with the vertex
memory allocation. This is not an area of peak memory usage anyway, so
shouldn't be a big deal.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Extend skip support to recognise the liquid skip texturenames the same as
metlslime's "newskip" utility. Add documentation and describe hint
surfaces (briefly) as well.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
The old logic did not deal properly with the case where the source entity
did not add any brushes.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Normally the engine won't do collision detection against a bmodel
unless the entity being tested is within the model's bounds. This
means collision doesn't work as expected when a model has clip brushes
that extend beyond the bounds of any visible brushes. This fixes that
case.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
New version returns the list of copied faces. This was the last user of
the inside and outside globals outside of CSGFaces, so they now move onto
the local stack there.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
The list onto which to save the faces is now passed in instead of
implicitly using the global outside list.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Only used in two places and not a whole lot of calls, so just allocate the
map while it's needed and free it afterwards. There is no relationship
between the two users, so no need to share a common block of memory.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
We pass in the face list and the plane map to link the faces to. Update
the comments to make it clearer what the function actually does.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
At load time we defaulted to CONTENTS_EMPTY, but if part or all of the
brush lies underwater, then inherit the water contents type.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Check that the hint face would actually get split before we discount the
candidate split plane...
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Similar to the skip texture handling, add miptex flags, handle
appropriately in CSGFaces and SolidBSP, then remove the surfaces before
writing out the bsp.
Lightly tested, but seems to do all the right things.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
FreeInside was a strange name, since depending on the arguments we
actually wanted to keep the faces.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Now consolidate the leak state into a single leakstate_t struct. Rename
the leaks/numleaks/maxleaks members as portals/numportals/maxportals for
improved clarity. What was numportals previously is now numwritten.
Outleafs is now returned from the FillOutside_r function instead of
passing in a struct or int to be incremented by the function.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Finding leaks carries a lot more state which is not needed for the final
outside fill stage, so let's separate the two. Get rid of fillparms_t
since the only thing left was the fillmark.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
It seems clearer now that the numportals parameter is actually used to
check that the number of leak portals we accumulate doesn't exceed the
allocated memory. Update the structs to reflect that.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Move the 'firstone' global into the bspleak state as a flag to indicate
whether the header has been written yet, since that's why the flag exists.
Move numportals and hit_occupied (renamed to "entity") in there as well to
keep leak related data all together.
MarkLeakTrail now directly increments bspleak->numportals so doesn't need
to return a value indicating what was written.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Was showing up as blah.prt.por because we had messed with the filename to
remove the prt file previously.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Previously, leak files would only be written for a leak in hull 2. This is
actually pretty bad because a small leak in hull 0 or 1 might not show up
in hull 2 and you would never get a leak file to chase it down.
Place a flag in the global mapdata to indicate whether we have written a
leak file or not so we only write for the first hull that leaks. Hullnum
is no longer needed as a parameter to RecursiveFillOutside, so remove
that from the fillparms struct.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Remove the (file) global fillmark from outside.c and place into the global
mapadata. Pass the fillmark into RecursiveFillOutside as a read-only
parameter instead.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
This is not a yes/no flag it's an integer mark to see if we have visited
the node within the same fill pass.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Makes it kind of obvious now that there is a bug here - if we have a small
leak in hull 0 or 1 which is sealed in hull 2 (due to brush expansion), then
we won't get a leak trail!
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
The TEX_SKIP flag isn't needed and although it *shouldn't* upset any
engines, better to not write it out at all.
Well, even better to not write anything about the skip texture to the BSP
file, but need to re-organise things a bit more before that can happen.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Some editors will work with floating point rotations, so let them keep the
precise texture alignment written to the .map file.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Took a while to find this - need to make sure that we actually count and
write out the portals which get attached to the top node of a detail
cluster (with ->detail_separator set true).
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Update PortalThru() to take the portal as it's argument, then we can
examine the two nodes on either side of the cluster. The nodes could
either be leafs or clusters.
Walk the detail clusters recursively and if the contents are all the same,
return that, otherwise if there is some empty space, leave it as empty.
Similarly, if there is some water, return water, etc. Basically non-solids
take precedence over solids in calculating the contents of the cluster.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Kind of messy but necessary to either write the number of entries at the
start of the line or write a terminator for vis' fscanf style of parsing
to work easily on the .prt file. Writing a terminator is easier for the
way qbsp is currently set up, so do that.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Now that I've done this I realise there could be a more compact
representation by just specifying the number of leafs per cluster, since
leaves are sequentially numbered... but this format is okay as well. And
easy to parse, etc.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Fairly simple extension of the original "PRT1" format; the first four
lines are:
Identifier := "PRT2"
Number of Leafs := INTEGER
Number of Clusters := INTEGER
Number of Portals := INTEGER
Followed by one line for each portal made up of the following, separated
by whitespace:
Number of points on the portal winding := INTEGER
Cluster Number on the front side of the portal := INTEGER
Cluster Number on the back side of the portal := INTEGER
For each point, a coordinate in the format ( x y z ), where x, y, z are FLOATs.
After the portal descriptions, there will be one line for each cluster
which lists the leaf numbers included in that cluster.
LEAF1 LEAF2 LEAF3 ...
I should probably write this up in BNF somewhere, but it's pretty straight
forward.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
The test here was really to see if we need to add a portal between two
adjacent leafs with the given content. Rename and re-arrange the code a
little to make it a bit easier to read.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Need to be a little more careful to order brushes correctly when adding
detail to the worldspawn. CSGFaces assumes that the brushes are ordered
such that earlier brushes have chunks carved out of them by any later
brushes that intersect them.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
During conversion from map brushes to bsp brushes, set the brush detail
flag for later use in CSGFaces().
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Pull the progress output up into the caller (not ideal) to deal with the
fact we are making extra calls to load the detail entities for the
worldspawn.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
The first step towards supporting detail brushes for Quake 1. This gives
us a way to add detail brushes to a map within the existing mapping tools. A
mapper can simply add a definition for a "func_detail" entity to their
editor and create func_detail entities.
Of course, currently they will behave exactly like world brushes. Future
patches will start to treat them differently.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Make Brush_LoadEntity() take a source and destination entity arguments. In
order for this to work, intialisation is done before calling and then the
BSP brushes generated from the source entity's map brushes are added to
whatever is already in the destination entity.
Reasons for doing this will become obvious with the following patch! :)
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Less error prone as it's usually followed by a strn?cmp or something.
Callers that were relying on null checks updated.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Still have the limitations of MAX_FACES, etc. but in practice it's
probably not going to be an issue.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
We don't need very precise time - only used for telling the user how long
the compile took, so use the most portable API. Fixes compilation on
OpenBSD/FreeBSD.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
The previous code would possibly leak faces with weird effects if we
iterate over the face data e.g. 0 -> map.numfaces.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Instead of doing awkward gymnastics to try and load the brushes and faces
into memory in reverse order for compatibility with the original qbsp,
just load them in map file order.
Simplifies iteration over the data, particularly if I want to load less
items than the pre-parse found.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Future work will break the assumption that the number of used items will
be equal to the maximum number of items, so separate the two numbers.
Replace use of maxblah with numblah as appropriate.
This makes the reverse order loading or brushes, etc. look even more
painful, so will look at whether we can change that now. As far as I know
no editors do clever things that would make the map compile "better" in a
different order - it's just that it might break some previously working
maps if they were an edge case that different ordering makes the precision
flip in a non-favourable direction.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
It does make them somewhat less greppable, but makes the variable naming
style more consistent with the rest of the quake utilities.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Not enabled, but may as well keep it up to date in case we want to start
using it. Might be useful as a simple check that we aren't leaking memory
somewhere.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
The count members are actually where we store how much memory has been
allocated for each type of item in the mapdata struct, so rename these to
indicate these are the maximum counts.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
* ParseEntity/ParseBrush now take a mapface_t argument, endface
* mapbrush_t now defines a pointer to first face and count of faces
* entity->iFaces no longer needed
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Tidy up the functions that calculate the texinfo data for either QuakeEd
or QuArK texture coordinates.
* Remove cleverness in SetTexinfo_QuArK where checking style1 or style2
just expand the loop for both cases for increased clarity.
* Pass the face plane into SetTexinfo_QuakeEd so it doesn't need to rely
on map.iFaces.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Instead of iBrushStart and iBrushEnd, we now store a pointer into the
mapbrush array and store the count of brushes for this entity. pBrushes
and cBrushes members are renamed to brushes and numbrushes, respectively.
The iBrushes member of mapentity_t is no longer needed.
At this stage we still go through hoops to load the brushes in reverse.
The original comment indicates that this was needed for compatibility, I
may try simplifying and loading in map file order and see if that has any
ill effects on compilation of test maps.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Make the caller look up the fixed origin again if they need it rather than
always passing in/out an origin. FindTargetEntity also now returns a
pointer rather than entity number.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
* Pass in pointer to the entity and mapbrush instead of brush number
* Rename some local variables for better readability
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Stop RecursiveFillOutside from blowing up the stack by making sure it
doesn't pull in MarkLeakTrail when GCC optimiser starts inlining stuff.
Might be an idea to make a non-recursive version of FillOutside at some
point, since it can go *very* deep on complex maps.
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Set up a sphere around each face so we can do quick tests against planes to
see if there's any chance that it intersects the face. Since we're only using
it for a fast check, don't bother shrinking the sphere when a face gets cut or
split, just grow it when necessary (only in TryMerge AFIACT).
Signed-off-by: Tyrann <tyrann@disenchant.net>
The choice of the various epsilon values is critical to having geometrically
complex maps compile correctly.
The one which seems most important (so far) is the ANGLE_EPSILON. This one
needs to be quite tight to avoid "bad things" happening when you create small
angles between adjacent surfaces.
Another epsilon inter-relationship I discovered, is that it seems
CONTINUOUS_EPSILON needs to be larger than EQUAL_EPSILON. It seems to play
havoc with the t-junction code otherwise.
Signed-off-by: Tyrann <tyrann@disenchant.net>
Offsets pointing to clipnodes were originally used as signed short (16-bit)
numbers, so that negative numbers could represent the various content types of
leaf nodes. However, only a small number of these types are required, so we
now make use of the rest of the clipnode range.
Signed-off-by: Tyrann <tyrann@disenchant.net>
When writing out portals for a node, we can skip over portals that separate
volumes with the same contents. The existing logic I find very hard to follow,
so I've separated that out in an attempt to make it more understandable.
While we're at it, equivalent logic is required in NumberLeafs, so re-use.
Signed-off-by: Tyrann <tyrann@disenchant.net>
Remove the big union in mapentity_t, collecting together the information for
each lump in a struct. Still not 100% sure where I'm going with this, but I
think this will help me with removing some of the reliance on globals further
along (which will be important once it comes to multi-threading).
Signed-off-by: Tyrann <tyrann@disenchant.net>
Ugh, looks like this extraneous line snuck in with commit 6bb3ad32
While I'm here, I see no reason to zero pWorldEnt->cTexdata just above
either. It should already be zero'd memory from the malloc of map.rgEntities.
Signed-off-by: Tyrann <tyrann@disenchant.net>
Fix the logic that decided which edges were to be added to smooth the clipping
hulls. The original logic is completely backwards and throws away all the hull
edge clipping planes you want, while potentially keeping the worst corner
cases.
This patch corrects that logic - for that reason, regressions are expected as
we will now be adding more planes to the maps and clipping more things at
wierd angles. Compile times will probably increase and clipping errors will be
more common, at least until some more tuning of the various epsilons is done.
While we're hacking the function, hoist some calculations from the inner loops
up to the outermost loop. Not that this function is that performance critical.
Signed-off-by: Tyrann <tyrann@disenchant.net>
Small cleanup to TestAddPlane - re-use the PlaneEqual and PlaneInvEqual
functions and replace the "counts" array with simple booleans to record which
side of the plane has points.
Signed-off-by: Tyrann <tyrann@disenchant.net>
Use a hash to speed up FindPlane for maps that have huge numbers of
planes. Not many maps have enough planes that this is a win, but those maps
are the ones where speed matters most. :)
Signed-off-by: Tyrann <tyrann@disenchant.net>
Instead of just assuming that 9999 or similar is "big enough", use the
implementation defined type limits.
Signed-off-by: Tyrann <tyrann@disenchant.net>
Make ChooseMidPlaneFromList a bit more picky about the non-axial planes it
selects. This can matter a lot for maps which have a lot of non-axial-aligned
brushwork (e.g. terrain, etc.) The number of clipnodes can skyrocket if planes
are not chosen with at least a small amount of care.
Signed-off-by: Tyrann <tyrann@disenchant.net>
Factor out the common split plane metric code from the SelectPlane*
functions. While we're at it, make it also work for non-axial planes using the
DivideBounds function.
Signed-off-by: Tyrann <tyrann@disenchant.net>
To make testing easier, log the output of the job to mapname.log, rather than
qbsp.log. Probably more desirable to make the logfile selectable in the long
term, but this will help for now. Note that we now don't open the log file
until after parsing the command line options, so the Message function needs to
check the file handle before writing to it.
Signed-off-by: Tyrann <tyrann@disenchant.net>
Add the "-wadpath" command-line argument to allow the user to specify a
directory where wad files can be found. If no wadpath is given, the path
defaults to the directory where the map file is located. Absolute path names
in the worldspawn "wad" key should also work.
Signed-off-by: Tyrann <tyrann@disenchant.net>
If we run out of memory, then too bad. Qbsp never _really_ takes so long that
you'd really care too much about starting again. Simplifies portability.
Signed-off-by: Tyrann <tyrann@disenchant.net>
The options are currently parsed as a big text array, so that the parsing
function can be shared with the code to load options from a file. Anyway,
dynamically allocate the array to copy in the command line arguments rather
than restricting it to 512 bytes.
Signed-off-by: Tyrann <tyrann@disenchant.net>
Fix numerous places where epsilons have been hard-coded, substituting one of
the defines from qbsp.h.
A couple of epsilons have actually been changed in this patch; the one used to
detect degenerate QuArK texture coordinates has been loosened (so the test is
actually a little more strict). The other is the test for flipped portals. If
my understanding is correct, then result would actually be < 0 if the portal
winding normal flipped, so this change _should_ be harmless.
Signed-off-by: Tyrann <tyrann@disenchant.net>
Save some memory in CSGFaces by not splitting faces outside the brush being
processed. Normally these faces will be split by the planes of the brush, even
if the brush doesn't intersect with it at all. This also saves some time in
MergeFaces, since we don't need to re-assemble these faces again.
Signed-off-by: Tyrann <tyrann@disenchant.net>
Each of ClipWinding, DivideWinding and SplitFace need to calculate on which
side of the split plane each winding point lies. Split this operation out into
a shared function.
Signed-off-by: Tyrann <tyrann@disenchant.net>
Rather than using it's own type of winding, make face_t use the existing
winding_t struct to define it's edges. I tried dynamically allocating the
winding as needed, but it was a net performance loss (though much better for
memory usage). For now we'll just embed a winding_t struct inside face_t
instead.
Signed-off-by: Tyrann <tyrann@disenchant.net>
The number reported for peak memory usage by winding_t structs was not
accurate, due to just using the sizeof(winding_t) for accounting. Track the
_bytes_ used by each type in a separate array. This is pretty much redundant
for everything except windings, but it's the simplest way to implement it for
now.
Also tidied up the verbose memory output a bit - the total column is pretty
useless, so just don't print it. Re-align the other columns and special case
the "Total" line, as only the "Peak Bytes" value is really interesting.
Signed-off-by: Tyrann <tyrann@disenchant.net>
Make all WADList functions take a pointer to the first wad_t, rather than
embedding it inside the struct wadlist. wadlist_t is no longer needed.
Signed-off-by: Tyrann <tyrann@disenchant.net>
Begin breaking down the wadlist_t structure by having the Init function return
the number of wads loaded to the caller, rather than relying on just setting
it internally.
Signed-off-by: Tyrann <tyrann@disenchant.net>
If the map has no wad key, or none of the wad files found in the key can be
loaded, then try loading mapname.wad as a default.
Signed-off-by: Tyrann <tyrann@disenchant.net>
Add back the warning message about invalid wads. Don't bother to differentiate
between filesystem errors and bad magic, etc. The file is already open, so if
we can't read it's either too small or there might be some hardware problem
(not worth dealing with separately).
Signed-off-by: Tyrann <tyrann@disenchant.net>