OpenVDB  11.0.0
common.h
Go to the documentation of this file.
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3 
4 #pragma once
5 
6 #define _USE_MATH_DEFINES
7 #include <cmath>
8 #include <chrono>
9 #include <fstream>
10 #include <nanovdb/NanoVDB.h>
11 #include "ComputePrimitives.h"
12 
13 inline __hostdev__ uint32_t CompactBy1(uint32_t x)
14 {
15  x &= 0x55555555;
16  x = (x ^ (x >> 1)) & 0x33333333;
17  x = (x ^ (x >> 2)) & 0x0f0f0f0f;
18  x = (x ^ (x >> 4)) & 0x00ff00ff;
19  x = (x ^ (x >> 8)) & 0x0000ffff;
20  return x;
21 }
22 
23 inline __hostdev__ uint32_t SeparateBy1(uint32_t x)
24 {
25  x &= 0x0000ffff;
26  x = (x ^ (x << 8)) & 0x00ff00ff;
27  x = (x ^ (x << 4)) & 0x0f0f0f0f;
28  x = (x ^ (x << 2)) & 0x33333333;
29  x = (x ^ (x << 1)) & 0x55555555;
30  return x;
31 }
32 
33 inline __hostdev__ void mortonDecode(uint32_t code, uint32_t& x, uint32_t& y)
34 {
35  x = CompactBy1(code);
36  y = CompactBy1(code >> 1);
37 }
38 
39 inline __hostdev__ void mortonEncode(uint32_t& code, uint32_t x, uint32_t y)
40 {
41  code = SeparateBy1(x) | (SeparateBy1(y) << 1);
42 }
43 
44 template<typename RenderFn, typename GridT>
45 inline float renderImage(bool useCuda, const RenderFn renderOp, int width, int height, float* image, const GridT* grid)
46 {
47  using ClockT = std::chrono::high_resolution_clock;
48  auto t0 = ClockT::now();
49 
51  useCuda, width * height, 512, __FILE__, __LINE__, [renderOp, image, grid] __hostdev__(int start, int end) {
52  renderOp(start, end, image, grid);
53  });
54  computeSync(useCuda, __FILE__, __LINE__);
55 
56  auto t1 = ClockT::now();
57  auto duration = std::chrono::duration_cast<std::chrono::microseconds>(t1 - t0).count() / 1000.f;
58  return duration;
59 }
60 
61 inline void saveImage(const std::string& filename, int width, int height, const float* image)
62 {
63  const auto isLittleEndian = []() -> bool {
64  static int x = 1;
65  static bool result = reinterpret_cast<uint8_t*>(&x)[0] == 1;
66  return result;
67  };
68 
69  float scale = 1.0f;
70  if (isLittleEndian())
71  scale = -scale;
72 
73  std::fstream fs(filename, std::ios::out | std::ios::binary);
74  if (!fs.is_open()) {
75  throw std::runtime_error("Unable to open file: " + filename);
76  }
77 
78  fs << "Pf\n"
79  << width << "\n"
80  << height << "\n"
81  << scale << "\n";
82 
83  for (int i = 0; i < width * height; ++i) {
84  float r = image[i];
85  fs.write((char*)&r, sizeof(float));
86  }
87 }
88 
89 template<typename Vec3T>
90 struct RayGenOp
91 {
92  float mWBBoxDimZ;
93  Vec3T mWBBoxCenter;
94 
95  inline RayGenOp(float wBBoxDimZ, Vec3T wBBoxCenter)
96  : mWBBoxDimZ(wBBoxDimZ)
97  , mWBBoxCenter(wBBoxCenter)
98  {
99  }
100 
101  inline __hostdev__ void operator()(int i, int w, int h, Vec3T& outOrigin, Vec3T& outDir) const
102  {
103  // perspective camera along Z-axis...
104  uint32_t x, y;
105 #if 0
106  mortonDecode(i, x, y);
107 #else
108  x = i % w;
109  y = i / w;
110 #endif
111  const float fov = 45.f;
112  const float u = (float(x) + 0.5f) / w;
113  const float v = (float(y) + 0.5f) / h;
114  const float aspect = w / float(h);
115  const float Px = (2.f * u - 1.f) * tanf(fov / 2 * 3.14159265358979323846f / 180.f) * aspect;
116  const float Py = (2.f * v - 1.f) * tanf(fov / 2 * 3.14159265358979323846f / 180.f);
117  const Vec3T origin = mWBBoxCenter + Vec3T(0, 0, mWBBoxDimZ);
118  Vec3T dir(Px, Py, -1.f);
119  dir.normalize();
120  outOrigin = origin;
121  outDir = dir;
122  }
123 };
124 
125 struct CompositeOp
126 {
127  inline __hostdev__ void operator()(float* outImage, int i, int w, int h, float value, float alpha) const
128  {
129  uint32_t x, y;
130  int offset;
131 #if 0
132  mortonDecode(i, x, y);
133  offset = x + y * w;
134 #else
135  x = i % w;
136  y = i / w;
137  offset = i;
138 #endif
139 
140  // checkerboard background...
141  const int mask = 1 << 7;
142  const float bg = ((x & mask) ^ (y & mask)) ? 1.0f : 0.5f;
143  outImage[offset] = alpha * value + (1.0f - alpha) * bg;
144  }
145 };
RayGenOp(float wBBoxDimZ, Vec3T wBBoxCenter)
Definition: common.h:95
Definition: common.h:90
void saveImage(const std::string &filename, int width, int height, const float *image)
Definition: common.h:61
MatType scale(const Vec3< typename MatType::value_type > &s)
Return a matrix that scales by s.
Definition: Mat.h:615
__hostdev__ void operator()(int i, int w, int h, Vec3T &outOrigin, Vec3T &outDir) const
Definition: common.h:101
float mWBBoxDimZ
Definition: common.h:92
Definition: common.h:125
Implements a light-weight self-contained VDB data-structure in a single file! In other words...
__hostdev__ void mortonEncode(uint32_t &code, uint32_t x, uint32_t y)
Definition: common.h:39
__hostdev__ void operator()(float *outImage, int i, int w, int h, float value, float alpha) const
Definition: common.h:127
A collection of parallel compute primitives.
void computeForEach(bool useCuda, int numItems, int blockSize, const char *file, int line, const FunctorT &op, Args...args)
Definition: ComputePrimitives.h:146
Vec3T mWBBoxCenter
Definition: common.h:93
__hostdev__ uint32_t CompactBy1(uint32_t x)
Definition: common.h:13
void computeSync(bool useCuda, const char *file, int line)
Definition: ComputePrimitives.h:125
float renderImage(bool useCuda, const RenderFn renderOp, int width, int height, float *image, const GridT *grid)
Definition: common.h:45
__hostdev__ void mortonDecode(uint32_t code, uint32_t &x, uint32_t &y)
Definition: common.h:33
__hostdev__ uint32_t SeparateBy1(uint32_t x)
Definition: common.h:23
#define __hostdev__
Definition: NanoVDB.h:213