<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>C++ | Ben Ahlbrand CV</title><link>https://benjamin.ahlbrand.me/tags/c++/</link><atom:link href="https://benjamin.ahlbrand.me/tags/c++/index.xml" rel="self" type="application/rss+xml"/><description>C++</description><generator>Hugo Blox Builder (https://hugoblox.com)</generator><language>en-us</language><lastBuildDate>Mon, 27 Jun 2022 00:00:00 +0000</lastBuildDate><image><url>https://benjamin.ahlbrand.me/media/sharing.png</url><title>C++</title><link>https://benjamin.ahlbrand.me/tags/c++/</link></image><item><title>Tutorial: Converting VDB files to NanoVDB via OpenVDB in C++</title><link>https://benjamin.ahlbrand.me/post/2022-06-27-tutorial-converting-vdb-files-to-nanovdb-via-openvdb-in-c/</link><pubDate>Mon, 27 Jun 2022 00:00:00 +0000</pubDate><guid>https://benjamin.ahlbrand.me/post/2022-06-27-tutorial-converting-vdb-files-to-nanovdb-via-openvdb-in-c/</guid><description>&lt;p>VDB files are commonly used for storing volumetric density grids, such as clouds or smoke. Blender, Embergen, Houdini are a few sources of such data. More recently there is a sparse specification, called NanoVDB, storing &lt;a href="https://en.wikipedia.org/wiki/Sparse_voxel_octree" target="_blank" rel="noopener">sparse voxel octrees&lt;/a> (SVOs) that is a more optimized representation for GPU rendering.&lt;/p>
&lt;p>I&amp;rsquo;m outlining steps for Ubuntu, but these libraries are supported on Windows as well with a bit more setup.&lt;/p>
&lt;ol>
&lt;li>
&lt;p>build / install OpenVDB check &lt;em>&lt;strong>&lt;a href="https://www.openvdb.org/documentation/doxygen/build.html#buildUsingOpenVDB" target="_blank" rel="noopener">here&lt;/a>&lt;/strong>&lt;/em> for cmake instructions&lt;/p>
&lt;/li>
&lt;li>
&lt;p>open your terminal and install &lt;strong>libtbb&lt;/strong>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">sudo apt install libtbb-dev
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>&lt;strong>OpenExr&lt;/strong> is a dependency of OpenVDB, so this should already be built w/your version of OpenVDB&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Here are the interesting excerpts from the OpenVDB library that you need to convert between VDB and NanoVDB:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">...
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">#include &amp;#34;nanovdb/util/OpenToNanoVDB.h&amp;#34;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">#include &amp;#34;nanovdb/util/IO.h&amp;#34;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">...
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> openvdb::initialize();
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> openvdb::io::File file(argv[1]);
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> file.open();
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> openvdb::GridBase::Ptr baseGrid;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> for (openvdb::io::File::NameIterator nameIter = file.beginName();
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> nameIter != file.endName(); ++nameIter) {
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> // TODO: deal with other channels if you have them
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> if (nameIter.gridName() == &amp;#34;density&amp;#34;) {
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> baseGrid = file.readGrid(nameIter.gridName());
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> }
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> }
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> file.close();
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> openvdb::FloatGrid::Ptr srcGrid = openvdb::gridPtrCast&amp;lt;openvdb::FloatGrid&amp;gt;(baseGrid);
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> auto handle = nanovdb::openToNanoVDB(*srcGrid);
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> // Write the NanoVDB grid to file
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> nanovdb::io::writeGrid(argv[2], handle);
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">...
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;/ol>
&lt;p>Find the complete source for my basic CLI example converting an input vdb file to a nanovdb file at &lt;a href="https://github.com/bmahlbrand/openvdb2nanovdb-util" target="_blank" rel="noopener">https://github.com/bmahlbrand/openvdb2nanovdb-util&lt;/a>&lt;/p></description></item><item><title>FABRIK</title><link>https://benjamin.ahlbrand.me/post/2021-12-04-fabrik/</link><pubDate>Wed, 10 Nov 2021 00:00:00 +0000</pubDate><guid>https://benjamin.ahlbrand.me/post/2021-12-04-fabrik/</guid><description>&lt;p>I added a FABRIK chain solver to my c++ animation engine from scratch, check out this basic test where it follows the target:&lt;/p>
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
&lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/WYZrSC9Hcrw?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video">&lt;/iframe>
&lt;/div></description></item><item><title>GLTF loader</title><link>https://benjamin.ahlbrand.me/post/2021-12-24-gltf-loader/</link><pubDate>Sun, 11 Apr 2021 00:00:00 +0000</pubDate><guid>https://benjamin.ahlbrand.me/post/2021-12-24-gltf-loader/</guid><description>&lt;p>I got GLTF loading working for skinned meshes in my C++ animation codebase, here&amp;rsquo;s a T-pose.&lt;/p></description></item><item><title>Procedural Night Sky</title><link>https://benjamin.ahlbrand.me/post/2021-12-08-procedural-night-sky/</link><pubDate>Mon, 07 Nov 2016 00:00:00 +0000</pubDate><guid>https://benjamin.ahlbrand.me/post/2021-12-08-procedural-night-sky/</guid><description>&lt;p>I generated a procedural night sky w/transparent quads w/a radial fall off in my c++ rendering framework.&lt;/p>
&lt;p>The algorithm is pretty simple and goes something like:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">// the trick is to sample an interesting distribution ;)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">pts = sampleRange(xMagnitude, yMagnitude, zMagnitude, numStars)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">render(pts)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">captureSkybox()
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">// typical main loop here
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">while (true) {
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> drawSkybox()
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> drawScene()
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ...
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item></channel></rss>