9 #ifndef cpointsmap_crtp_common_H
10 #define cpointsmap_crtp_common_H
22 template <
class Derived>
23 struct loadFromRangeImpl
32 obj.mark_as_modified();
49 if (!
obj.insertionOptions.addToExistingPointsMap)
54 const int sizeRangeScan = rangeScan.
scan.
size();
56 if (!sizeRangeScan)
return;
59 if (
obj.m_x.size() + sizeRangeScan >
obj.m_x.capacity())
61 obj.reserve((
size_t)(
obj.m_x.size() * 1.2f) + 3 * sizeRangeScan);
71 float m00 = lric.
HM.get_unsafe(0, 0);
72 float m01 = lric.
HM.get_unsafe(0, 1);
73 float m03 = lric.
HM.get_unsafe(0, 3);
74 float m10 = lric.
HM.get_unsafe(1, 0);
75 float m11 = lric.
HM.get_unsafe(1, 1);
76 float m13 = lric.
HM.get_unsafe(1, 3);
77 float m20 = lric.
HM.get_unsafe(2, 0);
78 float m21 = lric.
HM.get_unsafe(2, 1);
79 float m23 = lric.
HM.get_unsafe(2, 3);
81 float lx_1, ly_1, lz_1, lx = 0, ly = 0,
93 const bool useMinDist =
94 obj.insertionOptions.minDistBetweenLaserPoints > 0;
95 const float minDistSqrBetweenLaserPoints =
96 square(
obj.insertionOptions.minDistBetweenLaserPoints);
101 bool lastPointWasValid =
true;
102 bool thisIsTheFirst =
true;
103 bool lastPointWasInserted =
false;
111 const size_t nPointsAtStart =
obj.size();
112 size_t nextPtIdx = nPointsAtStart;
115 const size_t expectedMaxSize =
118 (
obj.insertionOptions.also_interpolate ? 3 : 1));
119 obj.m_x.resize(expectedMaxSize);
120 obj.m_y.resize(expectedMaxSize);
121 obj.m_z.resize(expectedMaxSize);
130 sincos_vals =
obj.m_scans_sincos_cache.getSinCosForScan(rangeScan);
133 Eigen::Array<float, Eigen::Dynamic, 1> scan_gx(sizeRangeScan + 3),
134 scan_gy(sizeRangeScan + 3),
141 size_t nPackets = sizeRangeScan / 4;
142 if ((sizeRangeScan & 0x03) != 0) nPackets++;
152 const __m128 m00_4val =
154 const __m128 m01_4val = _mm_set1_ps(m01);
155 const __m128 m03_4val = _mm_set1_ps(m03);
157 const __m128 m10_4val = _mm_set1_ps(m10);
158 const __m128 m11_4val = _mm_set1_ps(m11);
159 const __m128 m13_4val = _mm_set1_ps(m13);
161 const __m128 m20_4val = _mm_set1_ps(m20);
162 const __m128 m21_4val = _mm_set1_ps(m21);
163 const __m128 m23_4val = _mm_set1_ps(m23);
172 const float* ptr_in_scan = &rangeScan.
scan[0];
173 const float* ptr_in_cos = &sincos_vals.
ccos[0];
174 const float* ptr_in_sin = &sincos_vals.
csin[0];
176 float* ptr_out_x = &scan_gx[0];
177 float* ptr_out_y = &scan_gy[0];
178 float* ptr_out_z = &scan_gz[0];
180 for (; nPackets; nPackets--, ptr_in_scan += 4, ptr_in_cos += 4,
181 ptr_in_sin += 4, ptr_out_x += 4, ptr_out_y += 4,
184 const __m128 scan_4vals =
185 _mm_loadu_ps(ptr_in_scan);
188 _mm_mul_ps(scan_4vals, _mm_load_ps(ptr_in_cos));
190 _mm_mul_ps(scan_4vals, _mm_load_ps(ptr_in_sin));
193 ptr_out_x, _mm_add_ps(
194 m03_4val, _mm_add_ps(
195 _mm_mul_ps(xs, m00_4val),
196 _mm_mul_ps(ys, m01_4val))));
198 ptr_out_y, _mm_add_ps(
199 m13_4val, _mm_add_ps(
200 _mm_mul_ps(xs, m10_4val),
201 _mm_mul_ps(ys, m11_4val))));
203 ptr_out_z, _mm_add_ps(
204 m23_4val, _mm_add_ps(
205 _mm_mul_ps(xs, m20_4val),
206 _mm_mul_ps(ys, m21_4val))));
208 #else // MRPT_HAS_SSE2
211 Eigen::Array<float, Eigen::Dynamic, 1> scan_x(sizeRangeScan + 3),
212 scan_y(sizeRangeScan + 3);
215 const Eigen::Map<Eigen::Matrix<float, Eigen::Dynamic, 1>> scan_vals(
216 const_cast<float*
>(&rangeScan.
scan[0]), rangeScan.
scan.
size(),
220 const Eigen::Map<Eigen::Matrix<float, Eigen::Dynamic, 1>> ccos(
221 const_cast<float*
>(&sincos_vals.
ccos[0]), rangeScan.
scan.
size(),
223 const Eigen::Map<Eigen::Matrix<float, Eigen::Dynamic, 1>> csin(
224 const_cast<float*
>(&sincos_vals.
csin[0]), rangeScan.
scan.
size(),
228 scan_x = scan_vals.array() * ccos.array();
229 scan_y = scan_vals.array() * csin.array();
233 scan_gx = m00 * scan_x + m01 * scan_y + m03;
234 scan_gy = m10 * scan_x + m11 * scan_y + m13;
235 scan_gz = m20 * scan_x + m21 * scan_y + m23;
236 #endif // MRPT_HAS_SSE2
239 for (
int i = 0; i < sizeRangeScan; i++)
250 obj, lx, ly, lz, lric);
252 lastPointWasInserted =
false;
255 bool pt_pass_min_dist =
true;
257 if (useMinDist ||
obj.insertionOptions.also_interpolate)
259 if (!lastPointWasValid)
260 pt_pass_min_dist =
false;
266 pt_pass_min_dist = (d2 > minDistSqrBetweenLaserPoints);
270 if (thisIsTheFirst || pt_pass_min_dist)
272 thisIsTheFirst =
false;
276 if (
obj.insertionOptions.also_interpolate && i > 1)
278 float changeInDirection;
279 const float d = std::sqrt(d2);
281 if ((lx != lx_1 || ly != ly_1) &&
282 (lx_1 != lx_2 || ly_1 != ly_2))
283 changeInDirection = atan2(ly - ly_1, lx - lx_1) -
284 atan2(ly_1 - ly_2, lx_1 - lx_2);
286 changeInDirection = 0;
291 .minDistBetweenLaserPoints &&
292 d <
obj.insertionOptions
293 .maxDistForInterpolatePoints &&
294 fabs(changeInDirection) <
DEG2RAD(5))
297 d / (2 * sqrt(minDistSqrBetweenLaserPoints)));
299 for (
int q = 1;
q < nInterpol;
q++)
301 float i_x = lx_1 +
q * (lx - lx_1) / nInterpol;
302 float i_y = ly_1 +
q * (ly - ly_1) / nInterpol;
303 float i_z = lz_1 +
q * (lz - lz_1) / nInterpol;
304 if (!
obj.m_heightfilter_enabled ||
305 (i_z >=
obj.m_heightfilter_z_min &&
306 i_z <=
obj.m_heightfilter_z_max))
308 obj.m_x.push_back(i_x);
309 obj.m_y.push_back(i_y);
310 obj.m_z.push_back(i_z);
321 if (!
obj.m_heightfilter_enabled ||
322 (lz >=
obj.m_heightfilter_z_min &&
323 lz <=
obj.m_heightfilter_z_max))
325 obj.m_x[nextPtIdx] = lx;
326 obj.m_y[nextPtIdx] = ly;
327 obj.m_z[nextPtIdx] = lz;
336 lastPointWasInserted =
true;
351 lastPointWasValid = rangeScan.
validRange[i] != 0;
355 if (lastPointWasValid && !lastPointWasInserted)
357 if (!
obj.m_heightfilter_enabled ||
358 (lz >=
obj.m_heightfilter_z_min &&
359 lz <=
obj.m_heightfilter_z_max))
361 obj.m_x[nextPtIdx] = lx;
362 obj.m_y[nextPtIdx] = ly;
363 obj.m_z[nextPtIdx] = lz;
373 obj.m_x.resize(nextPtIdx);
374 obj.m_y.resize(nextPtIdx);
375 obj.m_z.resize(nextPtIdx);
384 obj.mark_as_modified();
394 if (!
obj.insertionOptions.addToExistingPointsMap)
401 const size_t sizeRangeScan = rangeScan.
points3D_x.size();
404 if (
obj.m_x.size() + sizeRangeScan >
obj.m_x.capacity())
405 obj.reserve(
size_t(
obj.m_x.size() + 1.1 * sizeRangeScan));
412 float m00 = lric.
HM.get_unsafe(0, 0);
413 float m01 = lric.
HM.get_unsafe(0, 1);
414 float m02 = lric.
HM.get_unsafe(0, 2);
415 float m03 = lric.
HM.get_unsafe(0, 3);
416 float m10 = lric.
HM.get_unsafe(1, 0);
417 float m11 = lric.
HM.get_unsafe(1, 1);
418 float m12 = lric.
HM.get_unsafe(1, 2);
419 float m13 = lric.
HM.get_unsafe(1, 3);
420 float m20 = lric.
HM.get_unsafe(2, 0);
421 float m21 = lric.
HM.get_unsafe(2, 1);
422 float m22 = lric.
HM.get_unsafe(2, 2);
423 float m23 = lric.
HM.get_unsafe(2, 3);
425 float lx_1, ly_1, lz_1, lx = 0, ly = 0,
433 float minDistSqrBetweenLaserPoints =
434 square(
obj.insertionOptions.minDistBetweenLaserPoints);
437 if (
obj.insertionOptions.minDistBetweenLaserPoints <= 0)
438 minDistSqrBetweenLaserPoints = -1;
443 bool lastPointWasValid =
true;
444 bool thisIsTheFirst =
true;
445 bool lastPointWasInserted =
false;
450 for (
size_t i = 0; i < sizeRangeScan; i++)
455 obj.insertionOptions.insertInvalidPoints)
471 obj, lx, ly, lz, lric);
473 lastPointWasInserted =
false;
478 if (thisIsTheFirst ||
479 (lastPointWasValid && (d2 > minDistSqrBetweenLaserPoints)))
481 thisIsTheFirst =
false;
483 obj.m_x.push_back(lx);
484 obj.m_y.push_back(ly);
485 obj.m_z.push_back(lz);
491 lastPointWasInserted =
true;
498 lastPointWasValid =
true;
502 lastPointWasValid =
false;
510 if (lastPointWasValid && !lastPointWasInserted)
512 if (lx != 0 || ly != 0 || lz != 0)
514 obj.m_x.push_back(lx);
515 obj.m_y.push_back(ly);
516 obj.m_z.push_back(lz);