Saturday, July 27, 2013

Evaluating PolyVox

In my pursuit of simulating soil digging, I started to evaluate the PolyVox library. This is a report on that evaluation.

Building on MacOSX is tricky. With LLVM version 4.2 (clang-425.0.28) installed, this error comes up when compiling the very first file: fatal error: 'cstdint' file not found. According to this StackOverflow thread this should be solved by invoking with: /usr/bin/clang++ -std=c++11 but I found this not to be the case. So instead I decided to just drag in the source files into a new XCode project.

After dragging in sources and headers, you need to set the project's header include path. It needs to find its way to polyvox/library/PolyVoxCore/include/ e.g.

In PolyVoxCore two warnings are issued by the compiler for SurfaceMesh::addVertex() and SurfaceMesh::getNoOfIndices() because they return 32 bit ints, and vector::size() returns 64 bit ints. Other than this, the code is very clean. Even LLVM's Analyzer does not find anything else on it.

PolyVox can store the volume as a series of 32x32x32 blocks. It would make sense to do the surface extraction on a per-block basis. That way, if voxels change, you only have to create new OpenGL VBOs for the blocks that are affected. It's not entirely clear how to do this. It may be enough to create multiple extractors on 32/32/32 boundaries, and then only execute extractors for blocks that have changed.

1 comment:

  1. Hey Bram, thanks for trying out PolyVox. I'll put my responses here in case they are useful to other people who come across this blog.

    Firstly I'm glad it works. We test with VS and GCC and aim to keep it warning free, so we'll address the Clang warnings. Overall the code is indeed kept tidy and clean though the heavy use of templates can make it harder to understand.

    When you create a surface extractor object you can pass a 'region' parameter to control which part of the volume it will extract. You can use this to generate multiple non-overlapping meshes and then only regenerate the ones which have changed. You can just create a MarchingCubesSurfaceExtractor on the stack, call it's execute() method, and then let it get destroyed. To be honest it does not need to be a class - long term we will replace it with a simple function 'extractMarchingCubesSurface()' or something.

    Important note - the blocks which you use to represent your volume do not need to match the regions which you extract. PolyVox will seamlessly extract across block boundaries if you wish. 32x32x32 is a good size for the blocks stored in memory, but you might want your meshes to be 16x16x16 (probably on mobile) or 64x64x64. PolyVox will handle this fine. You can even store your data in a RawVolume (so not using blocks) and still just extract certain regions.

    Let me know if you have any more questions :-)