Simple Walkthrough - ExeVirus/boxgen GitHub Wiki
This walkthrough will cover taking a watertight .obj file and generating collision boxes for it, with 3 different goals and two different export methods. The 3 goals are:
- Optimize for speed
- Optimize for accuracy
- Balanced approach
The two export methods are:
- To autobox's .box file
- With a special use .lua program for single node objects
Okay, with that out of the way, let's get crackin'
I'm doing my walkthroughs on windows, as these users tend to be the non-programmer types, so I will be setting up according to the Windows Setup Guide.
Here is a screenshot of my ready-to-go setup:
I'm going to cheat here with some .obj files I know are watertight, because I made them 😉. Specifically the one I will be using is called spike.obj from my rocks mod. It was coincindentally this mod that led me to create this program.
Anyways, here's a screenshot of that .obj:
Note that this object is mostly centered on 0,0,0 but it extends partially below -1.5 and so can/should be represented by 2 nodes. I did not have this program however, so I just did one node and left the bottom part of the object with a slgihtly improper collision box. These are decisions I leave to you, as the mod maker.
This time, however, we are going to do both methods so you can see how boxgen works. I reccomend grabing the same .obj yourself: download spike.obj-- save the file manually as "spike.obj".
Place spike.obj into your boxgen/models folder for use on the next step.
This is the hardish, but useful later way:
-
Open cmd.exe (command prompt)
-
Then type:
cd
with a space after.
-
Open file explorer and find the boxgen folder. Copy the address in the top of explorer once you get there.
-
Go back to your waiting command prompt and [right click] to paste the address. Hit [enter].
-
You are now in the right folder in command prompt, congradulations!
-
type this command:
run.bat run.lua -c models/spike.obj
or for linux:
luajit run.lua -c models/spike.obj
Congrats, you just generated your first boxes for spike.obj! You can view them by opening the boxes.html file that was generated in the boxgen folder:
Mine looks like this:
To see the rest of the options available, in command prompt type:
run.bat run.lua -h
output:
There are three ways to specify arguments for this program:
1. Interactively: "run.lua -i"
2. User specified .lua settings file: "run.lua -f <path+filename.lua>"
a. see settings.lua for example
3. Directly:
a. run.lua -c <filename> <relocate> <outfile> <spacing> <minfill> <minvol> <minqual>
b. eg: run.lua -c models/example.obj false - 0.2 - 0.08 0.1
c. If you specify "-" for any parameters, the default will be used.
By default, the provided settings.lua is used.
If that file is missing, internal defaults are used
Notice that the help.lua says there are other ways to specify how to run the program besides run.lua. I'm going to show you the setting file method, by overrideing settings.lua but keep in mind you can copy that file and specify any valid settings.lua file you want, just as the help says.
This is really simple to explain, just open the settings.lua file with a text editor (like notepad) and read it. It will explain all the values decently well.
For those who really want to be told, just change the 7th line to:
settings.filename = "models/spike.obj"
To run the lua program, just double click the "run.bat" file. (on linux, you have to still use the terminal, unless you write a bash script).
Okay with that out of the way, let's move onto trying to get a more optimized result from boxifying
So fun fact, we already generated a really large amount of boxes using the default settings, but let's push that envelope even further to try to get even more accurate (without getting too bored).
There are four parameters for every single execution of run.lua:
spacing: This is the space between the orange dots you see on boxes.html, and represents the precision of our calculations. smaller numbers are better to a point, but also lead to longer processing times. Basically, always go with the smallest spacing you're willing to wait, once you're done playing with the other values.
minfill: This is the minimum percentage of the mesh that a box must contain. All boxes will have at least this percentage of the mesh captured. Therefore, if we want to only enclose the mesh, we set this to 1.0 (100%). Note that boxes have corners, and so the corners of these boxes can technically stick out, but it's nearly imperceptable in gameplay.
minvol: This is the minimum volume any box can be. Any boxes that would be smaller are thrown out. We are optimizing for accuracy, so make this either 0 or really small like 0.0001
minqual: This is an advanced parameter that can help when you are trying to balance accuracy and speed. Essentially it stops boxes from growing in ways we would consider "stupid" 😉 For example, let's consider this 2D example where we have a box that, so far, contains only filled parts of the mesh:
But if it were to grow into the orange box area and capture that last voxel, then we would also capture a lot of voxels that aren't in the mesh. A human would say, "don't do it!" so, we have minqual to do that for us.
There are 10 total voxels to be captured in this example, and only one filled, so the ratio is 10%. If we specified 0.2 (20%) for minqual, this box would stop growing because that 10% filled area would be less than 20% mininum.
This happens even if growing wouldn't have made the total fileld to unfilled ratio less the minfill specifies, and is for cases exactly like this. Basically I reccomend this setting for meshes with lots of random protrusions.
So based on this discussion try running the object thorugh run.lua again but with:
-
spacing = 0.1 originally, this was 0.03, but that resulted in ~4000 boxes
-
minfill = 0.9 every box contains 90% mesh volume
-
minqual = 0.2 Zero "stupid" growth allowed
-
minvol = 0.0001 basically let everything through :)
If you are using command line the command is:
run.bat run.lua -c models/spike.obj - - 0.1 0.9 0.0001 0.2
and the results:
Notice that we are at nearly 300 collision boxes. Only the truly evil push that amount of calculation on a server for a single object.
Optimizing for speed can actually be slower (on the boxgen side) than opimtizing for accuracy. Why? Because we are focusing on using fewer boxes to represent our object, we must ensure those boxes are super accurate, and therefore we need a small value for spacing. For example, we'll be using 0.03 for this run.
Next, lets consider our other values. This is a rock, so we don't need to be perfectly acurrate, but we also don't want to make our players angry when they run into the rock even when they're obviously not touching it. So, we should lean towards a decent amount filled, say 0.65.
We don't care about quality of boxes in this case as much so let's just set quality to zero.
Finally, let's consider minimum volume. Oftentimes small boxes are the least useful, so we should raise this value to something like: 0.05 or even 0.1. (we'll use 0.05)
Let's see how it goes:
run.bat run.lua -c models/spike.obj - - 0.03 0.65 0.05 0
Output, 3 minutes later:
Not too shabby, and it's only using 11 boxes. Nice.
Balanced is up to every person to decide for themselves and their player base and server. I have not done enough testing to know the answer for every setup, but I consider 4-8 boxes for every node in size to be a decent balance. Our object has a volume of roughly 6 nodes (guesstimate), so we should target about 30-40 boxes for this object. Let's take a shot at guessing some good parameters:
run.bat run.lua -c models/spike.obj - - 0.06 0.72 0.02 0.08
Output:
Hmmm.. pretty accurate, but a few too many boxes. How about I show you what happens when we reduce the number of voxels with the same other 3 parameters:
run.bat run.lua -c models/spike.obj - - 0.08 0.72 0.02 0.08
and the output:
That's better, now we're at 36 boxes (and only 2 nodes required to represent it, notice that in the accuracy optimization, it needed 4).
While not as good as my hand calculated bounding boxes, I would consider this plenty good enough for my rocks mod. And for only about 30 minutes of typing all this up and actually running the walkthrough, it's actually faster than it took me to do collisions for this rock by hand, haha.
When using this program, you can figure on 4-8 minutes to get a new .obj to a .box file on average (when targeting balanced results & once you're good at it). As you'll see in the advanced walkthrough, not all meshes are created equal, though.
Okay, so after we have finished all our fiddling and are ready to get crackin and export this baby. Well, it already is exported. In your folder, you'll notice a "spike.box" file. This file contains the needed information for the autobox mod to load into minetest exactly what we see with boxes.html. Reccomended method!
But... lets say that you want to skip using autobox. Well, you can:
a. Write your own autobox equivalent.
b. Use only part of the exported data for your mesh collisions.
I'll explain option b now, and hopefully someone finds it useful. So meshes that are larger than 3x3x3 / not centered at the origin will result in boxes outside of the origin node. This means we need to use multiple nodes to represent the object. But, let's say that you don't want to do that and just use one node and collision box set and ignore the rest. For example, that's basically exactly what I do with spike.obj in my rocks mod, though by hand.
To get an idea of which set of boxes will be provided, look at boxes.html and note that the sets have numbers. The set centered around the origin is the set that will be exported. For example, the boxes.html for example.obj on default settings has an origin set named "set5". If you don't see a set near the origin, then you have no boxes near the origin and you should use my autobox mod (or move the mesh with blender or meshlab, etc).
Fun fact, you can turn off displayed sets in boxes.html by left clicking them. if you double click, only that set will be shown. Nifty for looking at the origin set boxes.
So, after looking at the boxes and approving of what you see, you can use this command in the boxgen folder:
lua ToByHand.lua spike.box
You will be asked to enter a filename, I use "spike.txt":
And now you'll find that text file in the boxgen folder. Open it and a nice explanation of how to add the collision box data for that single node definition is provided, as well as the text to copy-paste.
Again, this method is only useful for those who don't want to include/depend on autobox, and only for meshes very close or smaller than 3x3x3, centered around the origin.