Skip to content

Commit 43e99c4

Browse files
committed
better walk grid routine. V hard to validate exactly
1 parent 5a72824 commit 43e99c4

File tree

7 files changed

+81
-50
lines changed

7 files changed

+81
-50
lines changed

raylib/raycuboid.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@ Cuboid::Cuboid(const Eigen::Vector3d &min_bound, const Eigen::Vector3d &max_boun
1212
max_bound_ = max_bound;
1313
}
1414

15-
bool Cuboid::clipRay(Eigen::Vector3d &start, Eigen::Vector3d &end) const
15+
bool Cuboid::clipRay(Eigen::Vector3d &start, Eigen::Vector3d &end, double eps) const
1616
{
1717
double max_near_d = 0;
1818
double min_far_d = 1.0;
1919
Eigen::Vector3d centre = (min_bound_ + max_bound_) / 2.0;
20-
Eigen::Vector3d extent = (max_bound_ - min_bound_) / 2.0;
20+
Eigen::Vector3d extent = (max_bound_ - min_bound_) / 2.0 - Eigen::Vector3d(eps, eps, eps);
2121
Eigen::Vector3d to_centre = centre - start;
2222
Eigen::Vector3d dir = end - start;
2323
for (int ax = 0; ax < 3; ax++)

raylib/raycuboid.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class RAYLIB_EXPORT Cuboid
3737
}
3838

3939
/// clip ray to cuboid. Return false if no ray left.
40-
bool clipRay(Eigen::Vector3d &start, Eigen::Vector3d &end) const;
40+
bool clipRay(Eigen::Vector3d &start, Eigen::Vector3d &end, double eps = 0.0) const;
4141

4242
Eigen::Vector3d min_bound_, max_bound_;
4343
};

raylib/raydecimation.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,11 +182,12 @@ bool decimateRaysSpatial(const std::string &file_stub, double vox_width)
182182
subsampler.subsample.clear();
183183
for (int i = 0; i < (int)ends.size(); i++)
184184
{
185+
subsampler.index = i;
185186
#define END_FIRST // Testing on building.ply it finds more rays, so deemed to be more successful at filling space
186187
#if defined END_FIRST
187-
walkGrid(ends[i] / width, starts[i] / width, subsampler, i);
188+
walkGrid(ends[i] / width, starts[i] / width, subsampler);
188189
#else
189-
walkGrid(starts[i] / width, ends[i] / width, subsampler, i);
190+
walkGrid(starts[i] / width, ends[i] / width, subsampler);
190191
#endif
191192
}
192193
chunk.resize(subsampler.subsample.size());

raylib/raydecimation.h

Lines changed: 3 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -40,58 +40,19 @@ bool RAYLIB_EXPORT decimateAngular(const std::string &file_stub, double radius_p
4040

4141
struct Subsampler
4242
{
43-
inline bool operator()(const Eigen::Vector3i &p, int i)
43+
inline bool operator()(const Eigen::Vector3i &p, const Eigen::Vector3i &/*target*/, double /*in_length*/, double /*out_length*/, double /*max_length*/)
4444
{
4545
if (voxel_set.insert(p).second)
4646
{
47-
subsample.push_back(i);
47+
subsample.push_back(index);
4848
return true;
4949
}
5050
return false;
5151
}
5252
std::vector<int64_t> subsample;
5353
std::set<Eigen::Vector3i, ray::Vector3iLess> voxel_set;
54+
int index;
5455
};
55-
56-
inline int sign(double x)
57-
{
58-
return (x > 0.0) - (x < 0.0);
59-
}
60-
61-
// for similar appraoch see: https://github.com/StrandedKitty/tiles-intersect/blob/master/src/index.js
62-
template<class T>
63-
void walkGrid(const Eigen::Vector3d &start, const Eigen::Vector3d &end, T &object, int i)
64-
{
65-
Eigen::Vector3i p = Eigen::Vector3d(std::floor(start[0]), std::floor(start[1]), std::floor(start[2])).cast<int>();
66-
67-
if (object(p, i))
68-
{
69-
return; // only adding to one cell
70-
}
71-
72-
Eigen::Vector3i step(sign(end[0] - start[0]), sign(end[1] - start[1]), sign(end[2] - start[2]));
73-
Eigen::Vector3d tmax, tdelta;
74-
for (int j = 0; j<3; j++)
75-
{
76-
step[j] = sign(end[j] - start[j]);
77-
double to = std::abs(start[j] - p[j] - (double)std::max(0, step[j]));
78-
double dir = std::max(std::numeric_limits<double>::min(), std::abs(start[j] - end[j]));
79-
tmax[j] = to / dir;
80-
tdelta[j] = 1.0 / dir;
81-
}
82-
83-
Eigen::Vector3i target = Eigen::Vector3d(std::floor(end[0]), std::floor(end[1]), std::floor(end[2])).cast<int>();
84-
while (p != target)
85-
{
86-
int ax = tmax[0] < tmax[1] && tmax[0] < tmax[2] ? 0 : (tmax[1] < tmax[2] ? 1 : 2);
87-
p[ax] += step[ax];
88-
tmax[ax] += tdelta[ax];
89-
if (object(p, i))
90-
{
91-
break; // only adding to one cell
92-
}
93-
}
94-
}
9556
} // namespace ray
9657

9758
#endif // RAYLIB_RAYDECIMATION_H

raylib/rayrenderer.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,11 +279,16 @@ void DensityGrid::calculateDensities(const std::string &file_name)
279279
{
280280
Eigen::Vector3d start = starts[i];
281281
Eigen::Vector3d end = ends[i];
282-
if (!bounds_.clipRay(start, end))
282+
if (!bounds_.clipRay(start, end, 1e-10))
283283
{
284284
continue; // ray is outside of bounds
285285
}
286286

287+
#define NEW_METHOD
288+
#if defined NEW_METHOD
289+
bounded_ = colours[i].alpha > 0;
290+
walkGrid((start - bounds_.min_bound_) / voxel_width_, (end - bounds_.min_bound_) / voxel_width_, *this);
291+
#else
287292
// now walk the voxels
288293
Eigen::Vector3d dir = end - start;
289294
const Eigen::Vector3d source = (start - bounds_.min_bound_) / voxel_width_;
@@ -352,6 +357,7 @@ void DensityGrid::calculateDensities(const std::string &file_name)
352357
voxels_[index].addMissRay(static_cast<float>(minL * voxel_width_));
353358
}
354359
} while (depth <= maxDist);
360+
#endif
355361
}
356362
};
357363
Cloud::read(file_name, calculate);

raylib/rayrenderer.h

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,12 +107,15 @@ struct RAYLIB_EXPORT DensityGrid
107107
inline const std::vector<Voxel> &voxels() const { return voxels_; }
108108
inline Eigen::Vector3i dimensions(){ return voxel_dims_; }
109109
inline Cuboid bounds(){ return bounds_; }
110-
110+
inline double voxelWidth() const { return voxel_width_; }
111+
// used in walking grid only
112+
inline bool operator()(const Eigen::Vector3i &p, const Eigen::Vector3i &target, double in_length, double out_length, double max_length);
111113
private:
112114
Cuboid bounds_;
113115
std::vector<Voxel> voxels_;
114116
double voxel_width_;
115117
Eigen::Vector3i voxel_dims_;
118+
bool bounded_;
116119
};
117120

118121
// inline functions
@@ -168,6 +171,23 @@ int DensityGrid::getIndexFromPos(const Eigen::Vector3d &pos) const
168171
Eigen::Vector3d gridspace = (pos - bounds_.min_bound_) / voxel_width_;
169172
return getIndex(gridspace.cast<int>());
170173
}
171-
174+
inline bool DensityGrid::operator()(const Eigen::Vector3i &p, const Eigen::Vector3i &target, double in_length, double out_length, double max_length)
175+
{
176+
int index = getIndex(p);
177+
if (p == target && bounded_)
178+
{
179+
double length_in_voxel = std::min(out_length, max_length) - in_length;
180+
if (length_in_voxel > 1.733 || length_in_voxel < -1e-7)
181+
std::cout << "what's going on?" << out_length << ", " << max_length << ", " << in_length << std::endl;
182+
voxels_[index].addHitRay(static_cast<float>(length_in_voxel * voxel_width_));
183+
}
184+
else
185+
{
186+
if ((out_length - in_length) > 1.733 || (out_length - in_length) < -1e-7)
187+
std::cout << "what on earth's going on?" << (out_length - in_length) << std::endl;
188+
voxels_[index].addMissRay(static_cast<float>((out_length - in_length) * voxel_width_));
189+
}
190+
return false;
191+
}
172192
} // namespace ray
173193
#endif // RAYLIB_RAYRENDERER_H

raylib/rayutils.h

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,49 @@ inline std::ostream &logDuration(std::ostream &out, const D &duration)
361361
}
362362
return out;
363363
}
364+
365+
inline int sign(double x)
366+
{
367+
return (x > 0.0) - (x < 0.0);
368+
}
369+
370+
// for similar appraoch see: https://github.com/StrandedKitty/tiles-intersect/blob/master/src/index.js
371+
template<class T>
372+
void walkGrid(const Eigen::Vector3d &start, const Eigen::Vector3d &end, T &object)
373+
{
374+
Eigen::Vector3d direction = end - start;
375+
double max_length = direction.norm();
376+
Eigen::Vector3i p = Eigen::Vector3d(std::floor(start[0]), std::floor(start[1]), std::floor(start[2])).cast<int>();
377+
const Eigen::Vector3i target = Eigen::Vector3d(std::floor(end[0]), std::floor(end[1]), std::floor(end[2])).cast<int>();
378+
379+
const Eigen::Vector3i step(sign(direction[0]), sign(direction[1]), sign(direction[2]));
380+
direction /= max_length;
381+
Eigen::Vector3d lengths, length_delta;
382+
for (int j = 0; j<3; j++)
383+
{
384+
const double to = std::abs(start[j] - p[j] - (double)std::max(0, step[j]));
385+
const double dir = std::max(std::numeric_limits<double>::epsilon(), std::abs(direction[j]));
386+
lengths[j] = to / dir;
387+
length_delta[j] = 1.0 / dir;
388+
}
389+
int ax = lengths[0] < lengths[1] && lengths[0] < lengths[2] ? 0 : (lengths[1] < lengths[2] ? 1 : 2);
390+
if (object(p, target, 0.0, lengths[ax], max_length))
391+
{
392+
return; // only adding to one cell
393+
}
394+
395+
while (p != target)
396+
{
397+
p[ax] += step[ax];
398+
const double in_length = lengths[ax];
399+
lengths[ax] += length_delta[ax];
400+
ax = lengths[0] < lengths[1] && lengths[0] < lengths[2] ? 0 : (lengths[1] < lengths[2] ? 1 : 2);
401+
if (object(p, target, in_length, lengths[ax], max_length))
402+
{
403+
break; // only adding to one cell
404+
}
405+
}
406+
}
364407
} // namespace ray
365408

366409
#endif // RAYLIB_RAYUTILS_H

0 commit comments

Comments
 (0)