6 static const Real EPSILON = 1e-6;
11 #define APPLY_ENTITY_OPERATION_TO_CELL(nI,nJ,nK) \
13 SCell& sCell = GetCellAt((nI), (nJ), (nK)); \
14 if((sCell.Timestamp == m_unCurTimestamp) && \
15 (! sCell.Entities.empty())) { \
16 for(typename CSet<ENTITY*,SEntityComparator>::iterator it = sCell.Entities.begin(); \
17 it != sCell.Entities.end(); \
19 if(!c_operation(**it)) return; \
24 #define APPLY_ENTITY_OPERATION_TO_CELL_ALONG_RAY(nI,nJ,nK) \
26 SCell& sCell = GetCellAt(nI, nJ, nK); \
27 if((sCell.Timestamp == m_unCurTimestamp) && \
28 (! sCell.Entities.empty())) { \
29 for(typename CSet<ENTITY*,SEntityComparator>::iterator it = sCell.Entities.begin(); \
30 it != sCell.Entities.end(); \
32 if(!c_operation(**it)) return; \
34 if(b_stop_at_closest_match) return; \
38 #define APPLY_CELL_OPERATION_TO_CELL(nI,nJ,nK) \
40 SCell& sCell = GetCellAt((nI), (nJ), (nK)); \
41 if(!c_operation((nI), (nJ), (nK), sCell)) return; \
47 template<
class ENTITY>
53 m_cAreaMinCorner(c_area_min_corner),
54 m_cAreaMaxCorner(c_area_max_corner),
58 m_cRangeX(m_cAreaMinCorner.GetX(), m_cAreaMaxCorner.GetX()),
59 m_cRangeY(m_cAreaMinCorner.GetY(), m_cAreaMaxCorner.GetY()),
60 m_cRangeZ(m_cAreaMinCorner.GetZ(), m_cAreaMaxCorner.GetZ()),
62 m_pcUpdateEntityOperation(NULL) {
63 m_cCellSize.Set(m_cRangeX.GetSpan() / m_nSizeI,
64 m_cRangeY.GetSpan() / m_nSizeJ,
65 m_cRangeZ.GetSpan() / m_nSizeK);
66 m_cInvCellSize.Set(1.0f / m_cCellSize.GetX(),
67 1.0f / m_cCellSize.GetY(),
68 1.0f / m_cCellSize.GetZ());
69 m_psCells =
new SCell[m_nSizeI * m_nSizeJ * m_nSizeK];
75 template<
class ENTITY>
83 template<
class ENTITY>
90 template<
class ENTITY>
93 for(
SInt32 i = 0; i < m_nSizeI; ++i) {
94 for(
SInt32 j = 0; j < m_nSizeJ; ++j) {
95 for(
SInt32 k = 0; k < m_nSizeK; ++k) {
96 GetCellAt(i,j,k).Reset();
106 template<
class ENTITY>
113 template<
class ENTITY>
115 m_cEntities.insert(&c_entity);
121 template<
class ENTITY>
123 m_cEntities.erase(&c_entity);
129 template<
class ENTITY>
132 ForAllEntities(*m_pcUpdateEntityOperation);
138 template<
class ENTITY>
143 PositionToCell(i, j, k, c_position);
144 const SCell& sCell = GetCellAt(i, j, k);
145 if(sCell.Timestamp < m_unCurTimestamp) {
149 c_entities = sCell.Entities;
152 catch(CARGoSException& ex) {
153 THROW_ARGOSEXCEPTION_NESTED(
"CGrid<ENTITY>::GetEntitiesAt() : Position <" << c_position <<
"> out of bounds X -> " << m_cRangeX <<
" Y -> " << m_cRangeY <<
" Z -> " << m_cRangeZ, ex);
160 template<
class ENTITY>
163 it != m_cEntities.end() && c_operation(**it);
170 template<
class ENTITY>
175 SInt32 nIC, nJC, nKC, nIR, nJR, nKR;
176 PositionToCellUnsafe(nIC, nJC, nKC, c_center);
177 if(nKC >= 0 && nKC < m_nSizeK) {
181 nIR =
Floor(f_radius * m_cInvCellSize.GetX() + 0.5f);
182 nJR =
Floor(f_radius * m_cInvCellSize.GetY() + 0.5f);
184 if(nIC >= 0 && nIC < m_nSizeI) {
185 for(
SInt32 j = nJR; j > 0; --j) {
191 if(nJC >= 0 && nJC < m_nSizeJ) {
192 for(
SInt32 i = nIR; i > 0; --i) {
198 for(
SInt32 j = nJR; j > 0; --j) {
199 nIR =
Floor(
Sqrt(Max<Real>(0.0f, f_radius * f_radius - j * m_cCellSize.GetY() * j * m_cCellSize.GetY())) * m_cInvCellSize.GetX() + 0.5f);
200 for(
SInt32 i = nIR; i > 0; --i) {
209 nKR =
Floor(f_radius * m_cInvCellSize.GetZ() + 0.5f);
211 for(
SInt32 k = nKR; k > 0; --k) {
213 if((nIC >= 0 && nIC < m_nSizeI) && (nJC >= 0 && nJC < m_nSizeJ)) {
218 fCircleRadius2 = Max<Real>(0.0f, f_radius * f_radius - k * m_cCellSize.GetZ() * k * m_cCellSize.GetZ());
220 nIR =
Floor(
Sqrt(fCircleRadius2) * m_cInvCellSize.GetX() + 0.5f);
222 if(nJC >= 0 && nJC < m_nSizeJ) {
223 for(
SInt32 i = nIR; i > 0; --i) {
231 nJR =
Floor(
Sqrt(fCircleRadius2) * m_cInvCellSize.GetY() + 0.5f);
232 for(
SInt32 j = nJR; j > 0; --j) {
234 if(nIC >= 0 && nIC < m_nSizeI) {
241 nIR =
Floor(
Sqrt(Max<Real>(0.0f, fCircleRadius2 - j * m_cCellSize.GetY() * j * m_cCellSize.GetY())) * m_cInvCellSize.GetX() + 0.5f);
242 for(
SInt32 i = nIR; i > 0; --i) {
243 if(nIC + i >= 0 && nIC + i < m_nSizeI && nJC + j >= 0 && nJC + j < m_nSizeJ && nKC + k >= 0 && nKC + k < m_nSizeK)
APPLY_ENTITY_OPERATION_TO_CELL(nIC + i, nJC + j, nKC + k);
244 if(nIC + i >= 0 && nIC + i < m_nSizeI && nJC + j >= 0 && nJC + j < m_nSizeJ && nKC - k >= 0 && nKC - k < m_nSizeK)
APPLY_ENTITY_OPERATION_TO_CELL(nIC + i, nJC + j, nKC - k);
245 if(nIC + i >= 0 && nIC + i < m_nSizeI && nJC - j >= 0 && nJC - j < m_nSizeJ && nKC + k >= 0 && nKC + k < m_nSizeK)
APPLY_ENTITY_OPERATION_TO_CELL(nIC + i, nJC - j, nKC + k);
246 if(nIC + i >= 0 && nIC + i < m_nSizeI && nJC - j >= 0 && nJC - j < m_nSizeJ && nKC - k >= 0 && nKC - k < m_nSizeK)
APPLY_ENTITY_OPERATION_TO_CELL(nIC + i, nJC - j, nKC - k);
247 if(nIC - i >= 0 && nIC - i < m_nSizeI && nJC + j >= 0 && nJC + j < m_nSizeJ && nKC + k >= 0 && nKC + k < m_nSizeK)
APPLY_ENTITY_OPERATION_TO_CELL(nIC - i, nJC + j, nKC + k);
248 if(nIC - i >= 0 && nIC - i < m_nSizeI && nJC + j >= 0 && nJC + j < m_nSizeJ && nKC - k >= 0 && nKC - k < m_nSizeK)
APPLY_ENTITY_OPERATION_TO_CELL(nIC - i, nJC + j, nKC - k);
249 if(nIC - i >= 0 && nIC - i < m_nSizeI && nJC - j >= 0 && nJC - j < m_nSizeJ && nKC + k >= 0 && nKC + k < m_nSizeK)
APPLY_ENTITY_OPERATION_TO_CELL(nIC - i, nJC - j, nKC + k);
250 if(nIC - i >= 0 && nIC - i < m_nSizeI && nJC - j >= 0 && nJC - j < m_nSizeJ && nKC - k >= 0 && nKC - k < m_nSizeK)
APPLY_ENTITY_OPERATION_TO_CELL(nIC - i, nJC - j, nKC - k);
259 template<
class ENTITY>
264 SInt32 nI1, nJ1, nK1, nI2, nJ2, nK2;
265 PositionToCellUnsafe(nI1, nJ1, nK1, c_center - c_half_size);
266 ClampCoordinates(nI1, nJ1, nK1);
267 PositionToCellUnsafe(nI2, nJ2, nK2, c_center + c_half_size);
268 ClampCoordinates(nI2, nJ2, nK2);
270 for(
SInt32 k = nK1; k <= nK2; ++k) {
271 for(
SInt32 j = nJ1; j <= nJ2; ++j) {
272 for(
SInt32 i = nI1; i <= nI2; ++i) {
282 template<
class ENTITY>
287 if(! m_cRangeZ.WithinMinBoundIncludedMaxBoundIncluded(c_center.
GetZ()))
return;
290 PositionToCellUnsafe(nI, nJ, nK, c_center);
294 SInt32 nID =
Floor(f_radius * m_cInvCellSize.GetX() + 0.5f);
295 for(
SInt32 h = nID; h > 0; --h) {
300 SInt32 nJD =
Floor(f_radius * m_cInvCellSize.GetY() + 0.5f);
301 for(
SInt32 h = nJD; h > 0; --h) {
306 for(
SInt32 i = nID; i > 0; --i) {
307 nJD =
Floor(
Sqrt(f_radius * f_radius - i * m_cCellSize.GetX() * i * m_cCellSize.GetX()) * m_cInvCellSize.GetY() + 0.5f);
308 for(
SInt32 j = nJD; j > 0; --j) {
320 template<
class ENTITY>
325 SInt32 nI1 = Min<SInt32>(m_nSizeI-1, Max<SInt32>(0,
Floor((c_center.
GetX() - c_half_size.
GetX() - m_cAreaMinCorner.GetX()) * m_cInvCellSize.GetX())));
326 SInt32 nJ1 = Min<SInt32>(m_nSizeJ-1, Max<SInt32>(0,
Floor((c_center.
GetY() - c_half_size.
GetY() - m_cAreaMinCorner.GetY()) * m_cInvCellSize.GetY())));
327 SInt32 nI2 = Min<SInt32>(m_nSizeI-1, Max<SInt32>(0,
Floor((c_center.
GetX() + c_half_size.
GetX() - m_cAreaMinCorner.GetX()) * m_cInvCellSize.GetX())));
328 SInt32 nJ2 = Min<SInt32>(m_nSizeJ-1, Max<SInt32>(0,
Floor((c_center.
GetY() + c_half_size.
GetY() - m_cAreaMinCorner.GetY()) * m_cInvCellSize.GetY())));
329 SInt32 nK = Min<SInt32>(m_nSizeK-1, Max<SInt32>(0,
Floor((c_center.
GetZ() - m_cAreaMinCorner.GetZ()) * m_cInvCellSize.GetZ())));
331 for(
SInt32 j = nJ1; j <= nJ2; ++j) {
332 for(
SInt32 i = nI1; i <= nI2; ++i) {
341 template<
class ENTITY>
344 bool b_stop_at_closest_match) {
346 SInt32 nI1, nJ1, nK1, nI2, nJ2, nK2;
347 PositionToCellUnsafe(nI1, nJ1, nK1, c_ray.
GetStart());
348 ClampCoordinates(nI1, nJ1, nK1);
349 PositionToCellUnsafe(nI2, nJ2, nK2, c_ray.
GetEnd());
350 ClampCoordinates(nI2, nJ2, nK2);
360 SInt32 nSI(nI2 >= nI1 ? 1 : -1);
361 SInt32 nSJ(nJ2 >= nJ1 ? 1 : -1);
362 SInt32 nSK(nK2 >= nK1 ? 1 : -1);
364 SInt32 nI(nI1), nJ(nJ1), nK(nK1);
365 if(nDI >= nDJ && nDI >= nDK) {
368 SInt32 nEJ(3 * nDJ - nDI);
369 SInt32 nEK(3 * nDK - nDI);
372 for(
SInt32 nCell = nDI; nCell > 0; --nCell) {
377 if(nEJ > 0 && nEK > 0) {
379 if(nEJ * nDK > nEK * nDJ) {
391 nEJ += 2 * (nDJ - nDI);
392 nEK += 2 * (nDK - nDI);
398 nEJ += 2 * (nDJ - nDI);
407 nEK += 2 * (nDK - nDI);
415 else if(nDJ >= nDI && nDJ >= nDK) {
418 SInt32 nEI(3 * nDI - nDJ);
419 SInt32 nEK(3 * nDK - nDJ);
422 for(
SInt32 nCell = nDJ; nCell > 0; --nCell) {
427 if(nEI > 0 && nEK > 0) {
429 if(nEI * nDK > nEK * nDI) {
441 nEI += 2 * (nDI - nDJ);
442 nEK += 2 * (nDK - nDJ);
448 nEI += 2 * (nDI - nDJ);
457 nEK += 2 * (nDK - nDJ);
468 SInt32 nEI(3 * nDI - nDK);
469 SInt32 nEJ(3 * nDJ - nDK);
472 for(
SInt32 nCell = nDK; nCell > 0; --nCell) {
477 if(nEI > 0 && nEJ > 0) {
479 if(nEI * nDJ > nEJ * nDI) {
491 nEI += 2 * (nDI - nDK);
492 nEJ += 2 * (nDJ - nDK);
498 nEI += 2 * (nDI - nDK);
507 nEJ += 2 * (nDJ - nDK);
520 template<
class ENTITY>
522 for(
SInt32 k = 0; k < m_nSizeK; ++k) {
523 for(
SInt32 j = 0; j < m_nSizeJ; ++j) {
524 for(
SInt32 i = 0; i < m_nSizeI; ++i) {
534 template<
class ENTITY>
539 SInt32 nIC, nJC, nKC, nIR, nJR, nKR;
540 PositionToCellUnsafe(nIC, nJC, nKC, c_center);
541 if(nKC >= 0 && nKC < m_nSizeK) {
545 nIR =
Floor(f_radius * m_cInvCellSize.GetX() + 0.5f);
546 nJR =
Floor(f_radius * m_cInvCellSize.GetY() + 0.5f);
548 if(nIC >= 0 && nIC < m_nSizeI) {
549 for(
SInt32 j = nJR; j > 0; --j) {
555 if(nJC >= 0 && nJC < m_nSizeJ) {
556 for(
SInt32 i = nIR; i > 0; --i) {
562 for(
SInt32 j = nJR; j > 0; --j) {
563 nIR =
Floor(
Sqrt(Max<Real>(0.0f, f_radius * f_radius - j * m_cCellSize.GetY() * j * m_cCellSize.GetY())) * m_cInvCellSize.GetX() + 0.5f);
564 for(
SInt32 i = nIR; i > 0; --i) {
573 nKR =
Floor(f_radius * m_cInvCellSize.GetZ() + 0.5f);
575 for(
SInt32 k = nKR; k > 0; --k) {
577 if((nIC >= 0 && nIC < m_nSizeI) && (nJC >= 0 && nJC < m_nSizeJ)) {
582 fCircleRadius2 = Max<Real>(0.0f, f_radius * f_radius - k * m_cCellSize.GetZ() * k * m_cCellSize.GetZ());
584 nIR =
Floor(
Sqrt(fCircleRadius2) * m_cInvCellSize.GetX() + 0.5f);
586 if(nJC >= 0 && nJC < m_nSizeJ) {
587 for(
SInt32 i = nIR; i > 0; --i) {
595 nJR =
Floor(
Sqrt(fCircleRadius2) * m_cInvCellSize.GetY() + 0.5f);
596 for(
SInt32 j = nJR; j > 0; --j) {
598 if(nIC >= 0 && nIC < m_nSizeI) {
605 nIR =
Floor(
Sqrt(Max<Real>(0.0f, fCircleRadius2 - j * m_cCellSize.GetY() * j * m_cCellSize.GetY())) * m_cInvCellSize.GetX() + 0.5f);
606 for(
SInt32 i = nIR; i > 0; --i) {
607 if(nIC + i >= 0 && nIC + i < m_nSizeI && nJC + j >= 0 && nJC + j < m_nSizeJ && nKC + k >= 0 && nKC + k < m_nSizeK)
APPLY_CELL_OPERATION_TO_CELL(nIC + i, nJC + j, nKC + k);
608 if(nIC + i >= 0 && nIC + i < m_nSizeI && nJC + j >= 0 && nJC + j < m_nSizeJ && nKC - k >= 0 && nKC - k < m_nSizeK)
APPLY_CELL_OPERATION_TO_CELL(nIC + i, nJC + j, nKC - k);
609 if(nIC + i >= 0 && nIC + i < m_nSizeI && nJC - j >= 0 && nJC - j < m_nSizeJ && nKC + k >= 0 && nKC + k < m_nSizeK)
APPLY_CELL_OPERATION_TO_CELL(nIC + i, nJC - j, nKC + k);
610 if(nIC + i >= 0 && nIC + i < m_nSizeI && nJC - j >= 0 && nJC - j < m_nSizeJ && nKC - k >= 0 && nKC - k < m_nSizeK)
APPLY_CELL_OPERATION_TO_CELL(nIC + i, nJC - j, nKC - k);
611 if(nIC - i >= 0 && nIC - i < m_nSizeI && nJC + j >= 0 && nJC + j < m_nSizeJ && nKC + k >= 0 && nKC + k < m_nSizeK)
APPLY_CELL_OPERATION_TO_CELL(nIC - i, nJC + j, nKC + k);
612 if(nIC - i >= 0 && nIC - i < m_nSizeI && nJC + j >= 0 && nJC + j < m_nSizeJ && nKC - k >= 0 && nKC - k < m_nSizeK)
APPLY_CELL_OPERATION_TO_CELL(nIC - i, nJC + j, nKC - k);
613 if(nIC - i >= 0 && nIC - i < m_nSizeI && nJC - j >= 0 && nJC - j < m_nSizeJ && nKC + k >= 0 && nKC + k < m_nSizeK)
APPLY_CELL_OPERATION_TO_CELL(nIC - i, nJC - j, nKC + k);
614 if(nIC - i >= 0 && nIC - i < m_nSizeI && nJC - j >= 0 && nJC - j < m_nSizeJ && nKC - k >= 0 && nKC - k < m_nSizeK)
APPLY_CELL_OPERATION_TO_CELL(nIC - i, nJC - j, nKC - k);
623 template<
class ENTITY>
628 SInt32 nI1, nJ1, nK1, nI2, nJ2, nK2;
629 PositionToCellUnsafe(nI1, nJ1, nK1, c_center - c_half_size);
630 ClampCoordinates(nI1, nJ1, nK1);
631 PositionToCellUnsafe(nI2, nJ2, nK2, c_center + c_half_size);
632 ClampCoordinates(nI2, nJ2, nK2);
634 for(
SInt32 k = nK1; k <= nK2; ++k) {
635 for(
SInt32 j = nJ1; j <= nJ2; ++j) {
636 for(
SInt32 i = nI1; i <= nI2; ++i) {
646 template<
class ENTITY>
651 if(! m_cRangeZ.WithinMinBoundIncludedMaxBoundIncluded(c_center.
GetZ()))
return;
654 PositionToCellUnsafe(nI, nJ, nK, c_center);
658 SInt32 nID =
Floor(f_radius * m_cInvCellSize.GetX() + 0.5f);
659 for(
SInt32 h = nID; h > 0; --h) {
664 SInt32 nJD =
Floor(f_radius * m_cInvCellSize.GetY() + 0.5f);
665 for(
SInt32 h = nJD; h > 0; --h) {
670 for(
SInt32 i = nID; i > 0; --i) {
671 nJD =
Floor(
Sqrt(f_radius * f_radius - i * m_cCellSize.GetX() * i * m_cCellSize.GetX()) * m_cInvCellSize.GetY() + 0.5f);
672 for(
SInt32 j = nJD; j > 0; --j) {
684 template<
class ENTITY>
689 SInt32 nI1 = Min<SInt32>(m_nSizeI-1, Max<SInt32>(0,
Floor((c_center.
GetX() - c_half_size.
GetX() - m_cAreaMinCorner.GetX()) * m_cInvCellSize.GetX())));
690 SInt32 nJ1 = Min<SInt32>(m_nSizeJ-1, Max<SInt32>(0,
Floor((c_center.
GetY() - c_half_size.
GetY() - m_cAreaMinCorner.GetY()) * m_cInvCellSize.GetY())));
691 SInt32 nI2 = Min<SInt32>(m_nSizeI-1, Max<SInt32>(0,
Floor((c_center.
GetX() + c_half_size.
GetX() - m_cAreaMinCorner.GetX()) * m_cInvCellSize.GetX())));
692 SInt32 nJ2 = Min<SInt32>(m_nSizeJ-1, Max<SInt32>(0,
Floor((c_center.
GetY() + c_half_size.
GetY() - m_cAreaMinCorner.GetY()) * m_cInvCellSize.GetY())));
693 SInt32 nK = Min<SInt32>(m_nSizeK-1, Max<SInt32>(0,
Floor((c_center.
GetZ() - m_cAreaMinCorner.GetZ()) * m_cInvCellSize.GetZ())));
695 for(
SInt32 j = nJ1; j <= nJ2; ++j) {
696 for(
SInt32 i = nI1; i <= nI2; ++i) {
705 template<
class ENTITY>
709 SInt32 nI1, nJ1, nK1, nI2, nJ2, nK2;
710 PositionToCellUnsafe(nI1, nJ1, nK1, c_ray.
GetStart());
711 ClampCoordinates(nI1, nJ1, nK1);
712 PositionToCellUnsafe(nI2, nJ2, nK2, c_ray.
GetEnd());
713 ClampCoordinates(nI2, nJ2, nK2);
723 SInt32 nSI(nI2 >= nI1 ? 1 : -1);
724 SInt32 nSJ(nJ2 >= nJ1 ? 1 : -1);
725 SInt32 nSK(nK2 >= nK1 ? 1 : -1);
727 SInt32 nI(nI1), nJ(nJ1), nK(nK1);
728 if(nDI >= nDJ && nDI >= nDK) {
731 SInt32 nEJ(3 * nDJ - nDI);
732 SInt32 nEK(3 * nDK - nDI);
735 for(
SInt32 nCell = nDI; nCell > 0; --nCell) {
740 if(nEJ > 0 && nEK > 0) {
742 if(nEJ * nDK > nEK * nDJ) {
754 nEJ += 2 * (nDJ - nDI);
755 nEK += 2 * (nDK - nDI);
761 nEJ += 2 * (nDJ - nDI);
770 nEK += 2 * (nDK - nDI);
778 else if(nDJ >= nDI && nDJ >= nDK) {
781 SInt32 nEI(3 * nDI - nDJ);
782 SInt32 nEK(3 * nDK - nDJ);
785 for(
SInt32 nCell = nDJ; nCell > 0; --nCell) {
790 if(nEI > 0 && nEK > 0) {
792 if(nEI * nDK > nEK * nDI) {
804 nEI += 2 * (nDI - nDJ);
805 nEK += 2 * (nDK - nDJ);
811 nEI += 2 * (nDI - nDJ);
820 nEK += 2 * (nDK - nDJ);
831 SInt32 nEI(3 * nDI - nDK);
832 SInt32 nEJ(3 * nDJ - nDK);
835 for(
SInt32 nCell = nDK; nCell > 0; --nCell) {
840 if(nEI > 0 && nEJ > 0) {
842 if(nEI * nDJ > nEJ * nDI) {
854 nEI += 2 * (nDI - nDK);
855 nEJ += 2 * (nDJ - nDK);
861 nEI += 2 * (nDI - nDK);
870 nEJ += 2 * (nDJ - nDK);
883 template<
class ENTITY>
888 if((n_i >= 0) && (n_i < m_nSizeI) &&
889 (n_j >= 0) && (n_j < m_nSizeJ) &&
890 (n_k >= 0) && (n_k < m_nSizeK)) {
891 SCell& sCell = GetCellAt(n_i, n_j, n_k);
899 THROW_ARGOSEXCEPTION(
"CGrid<ENTITY>::UpdateCell() : index (" << n_i <<
"," << n_j <<
"," << n_k <<
") out of bounds (" << m_nSizeI-1 <<
"," << m_nSizeJ-1 <<
"," << m_nSizeK-1 <<
")");
906 template<
class ENTITY>
908 m_pcUpdateEntityOperation = pc_operation;
914 template<
class ENTITY>
919 if(m_cRangeX.WithinMinBoundIncludedMaxBoundIncluded(c_position.
GetX()) &&
920 m_cRangeY.WithinMinBoundIncludedMaxBoundIncluded(c_position.
GetY()) &&
921 m_cRangeZ.WithinMinBoundIncludedMaxBoundIncluded(c_position.
GetZ())) {
922 n_i =
Floor((c_position.
GetX() - m_cAreaMinCorner.GetX()) * m_cInvCellSize.GetX());
923 n_j =
Floor((c_position.
GetY() - m_cAreaMinCorner.GetY()) * m_cInvCellSize.GetY());
924 n_k =
Floor((c_position.
GetZ() - m_cAreaMinCorner.GetZ()) * m_cInvCellSize.GetZ());
927 THROW_ARGOSEXCEPTION(
"CGrid<ENTITY>::PositionToCell() : Position <" << c_position <<
"> out of bounds X -> " << m_cRangeX <<
" Y -> " << m_cRangeY <<
" Z -> " << m_cRangeZ);
934 template<
class ENTITY>
939 n_i =
Floor((c_position.
GetX() - m_cAreaMinCorner.GetX()) * m_cInvCellSize.GetX());
940 n_j =
Floor((c_position.
GetY() - m_cAreaMinCorner.GetY()) * m_cInvCellSize.GetY());
941 n_k =
Floor((c_position.
GetZ() - m_cAreaMinCorner.GetZ()) * m_cInvCellSize.GetZ());
947 template<
class ENTITY>
952 else if(n_i >= m_nSizeI) n_i = m_nSizeI - 1;
954 else if(n_j >= m_nSizeJ) n_j = m_nSizeJ - 1;
956 else if(n_k >= m_nSizeK) n_k = m_nSizeK - 1;
962 template<
class ENTITY>
964 if(c_pos.
GetX() < m_cRangeX.GetMin()) c_pos.
SetX(m_cRangeX.GetMin() + EPSILON);
965 else if(c_pos.
GetX() > m_cRangeX.GetMax()) c_pos.
SetX(m_cRangeX.GetMax() - EPSILON);
966 if(c_pos.
GetY() < m_cRangeY.GetMin()) c_pos.
SetY(m_cRangeY.GetMin() + EPSILON);
967 else if(c_pos.
GetY() > m_cRangeY.GetMax()) c_pos.
SetY(m_cRangeY.GetMax() - EPSILON);
968 if(c_pos.
GetZ() < m_cRangeZ.GetMin()) c_pos.
SetZ(m_cRangeZ.GetMin() + EPSILON);
969 else if(c_pos.
GetZ() > m_cRangeZ.GetMax()) c_pos.
SetZ(m_cRangeZ.GetMax() - EPSILON);
975 template<
class ENTITY>
979 return m_psCells[m_nSizeI * m_nSizeJ * n_k +
987 template<
class ENTITY>
991 return m_psCells[m_nSizeI * m_nSizeJ * n_k +
#define APPLY_ENTITY_OPERATION_TO_CELL(nI, nJ, nK)
#define APPLY_ENTITY_OPERATION_TO_CELL_ALONG_RAY(nI, nJ, nK)
#define APPLY_CELL_OPERATION_TO_CELL(nI, nJ, nK)
#define THROW_ARGOSEXCEPTION_NESTED(message, nested)
This macro throws an ARGoS exception with the passed message and nesting the passed exception.
#define THROW_ARGOSEXCEPTION(message)
This macro throws an ARGoS exception with the passed message.
signed int SInt32
32-bit signed integer.
float Real
Collects all ARGoS code.
The namespace containing all the ARGoS related code.
ticpp::Element TConfigurationNode
The ARGoS configuration XML node.
SInt32 Floor(Real f_value)
Rounds the passed floating-point value to the closest lower integer.
T Abs(const T &t_v)
Returns the absolute value of the passed argument.
virtual void Reset()
Resets the resource.
SCell & GetCellAt(SInt32 n_i, SInt32 n_j, SInt32 n_k)
virtual void Update()
Updates this positional index.
virtual void ForCellsInBoxRange(const CVector3 &c_center, const CVector3 &c_half_size, CCellOperation &c_operation)
void UpdateCell(SInt32 n_i, SInt32 n_j, SInt32 n_k, ENTITY &c_entity)
void ClampCoordinates(SInt32 &n_i, SInt32 &n_j, SInt32 &n_k) const
virtual void ForEntitiesInRectangleRange(const CVector3 &c_center, const CVector2 &c_half_size, CEntityOperation &c_operation)
Executes an operation on all entities within the specified rectangle range.
virtual void Init(TConfigurationNode &t_tree)
Initializes the resource.
virtual void Destroy()
Undoes whatever was done by Init().
virtual void ForEntitiesInSphereRange(const CVector3 &c_center, Real f_radius, CEntityOperation &c_operation)
Executes an operation on all entities within the specified sphere range.
virtual void ForEntitiesInCircleRange(const CVector3 &c_center, Real f_radius, CEntityOperation &c_operation)
Executes an operation on all entities within the specified circle range.
virtual void ForCellsAlongRay(const CRay3 &c_ray, CCellOperation &c_operation)
virtual void ForCellsInCircleRange(const CVector3 &c_center, Real f_radius, CCellOperation &c_operation)
virtual void AddEntity(ENTITY &c_entity)
Adds an entity to this index.
void PositionToCellUnsafe(SInt32 &n_i, SInt32 &n_j, SInt32 &n_k, const CVector3 &c_position) const
virtual void ForEntitiesAlongRay(const CRay3 &c_ray, CEntityOperation &c_operation, bool b_stop_at_closest_match=false)
Executes an operation on all entities that intersect the given ray.
void PositionToCell(SInt32 &n_i, SInt32 &n_j, SInt32 &n_k, const CVector3 &c_position) const
virtual void ForEntitiesInBoxRange(const CVector3 &c_center, const CVector3 &c_half_size, CEntityOperation &c_operation)
Executes an operation on all entities within the specified box range.
void SetUpdateEntityOperation(CEntityOperation *pc_operation)
virtual void RemoveEntity(ENTITY &c_entity)
Removes an entity from this index.
virtual void ForAllEntities(CEntityOperation &c_operation)
Executes an operation on all the indexed entities.
virtual void ForCellsInSphereRange(const CVector3 &c_center, Real f_radius, CCellOperation &c_operation)
virtual void ForCellsInRectangleRange(const CVector3 &c_center, const CVector2 &c_half_size, CCellOperation &c_operation)
virtual void ForAllCells(CCellOperation &c_operation)
virtual void GetEntitiesAt(CSet< ENTITY *, SEntityComparator > &c_entities, const CVector3 &c_position) const
Puts the entities located at the given point in the passed buffer.
CGrid(const CVector3 &c_area_min_corner, const CVector3 &c_area_max_corner, SInt32 n_size_i, SInt32 n_size_j, SInt32 n_size_k)
CSet< ENTITY *, SEntityComparator > Entities
The operation to perform on each entity found in range.
Defines a very simple double-linked list that stores unique elements.
void clear()
Erases the contents of the list.
Real GetY() const
Returns the y coordinate of this vector.
Real GetX() const
Returns the x coordinate of this vector.
void SetY(const Real f_y)
Sets the y coordinate of this vector.
Real GetX() const
Returns the x coordinate of this vector.
void SetX(const Real f_x)
Sets the x coordinate of this vector.
void SetZ(const Real f_z)
Sets the z coordinate of this vector.
Real GetY() const
Returns the y coordinate of this vector.
Real GetZ() const
Returns the z coordinate of this vector.