| 114 | } |
| 115 | |
| 116 | void MakeSDF(const uint32_t* img, uint32_t w, uint32_t h, float* output) |
| 117 | { |
| 118 | const float scale = 1.0f / max(w, h); |
| 119 | |
| 120 | std::vector<Coord2D> queue; |
| 121 | |
| 122 | // find surface points |
| 123 | for (uint32_t y=0; y < h; ++y) |
| 124 | { |
| 125 | for (uint32_t x=0; x < w; ++x) |
| 126 | { |
| 127 | if (EdgeDetect(img, w, h, x, y)) |
| 128 | { |
| 129 | Coord2D c = {(int)x, (int)y, 0.0f, (int)x, (int)y}; |
| 130 | queue.push_back(c); |
| 131 | } |
| 132 | |
| 133 | output[y*w + x] = FLT_MAX; |
| 134 | } |
| 135 | } |
| 136 | |
| 137 | std::make_heap(queue.begin(), queue.end()); |
| 138 | |
| 139 | while (!queue.empty()) |
| 140 | { |
| 141 | std::pop_heap(queue.begin(), queue.end()); |
| 142 | |
| 143 | Coord2D c = queue.back(); |
| 144 | queue.pop_back(); |
| 145 | |
| 146 | // freeze coord if not already frozen |
| 147 | if (output[c.j*w + c.i] == FLT_MAX) |
| 148 | { |
| 149 | output[c.j*w + c.i] = c.d; |
| 150 | |
| 151 | // update neighbours |
| 152 | int xmin = max(c.i-1, 0), xmax = min(c.i+1, int(w-1)); |
| 153 | int ymin = max(c.j-1, 0), ymax = min(c.j+1, int(h-1)); |
| 154 | |
| 155 | for (int y=ymin; y <= ymax; ++y) |
| 156 | { |
| 157 | for (int x=xmin; x <= xmax; ++x) |
| 158 | { |
| 159 | if (c.i != x || c.j != y) |
| 160 | { |
| 161 | int dx = x-c.si; |
| 162 | int dy = y-c.sj; |
| 163 | |
| 164 | // calculate distance to source coord |
| 165 | float d = sqrtf(float(dx*dx + dy*dy)); |
| 166 | |
| 167 | Coord2D newc = {x, y, d, c.si, c.sj}; |
| 168 | queue.push_back(newc); |
| 169 | std::push_heap(queue.begin(), queue.end()); |
| 170 | } |
| 171 | } |
| 172 | } |
| 173 | } |
no test coverage detected