Ticket #3685: roundObstructions.diff
File roundObstructions.diff, 29.2 KB (added by , 8 years ago) |
---|
-
binaries/data/mods/public/simulation/templates/structures/brit_wonder.xml
10 10 <History>Stonehenge is a monumental structure built by pre-historic peoples from Britain from approximately 2500 BC to 2000 BC. Evidence suggests that the structure and the surrounding site served as a place of religious significance, time-keeping, and other societal functions, like burial.</History> 11 11 </Identity> 12 12 <Obstruction> 13 <Static width=" 30.0" depth="30.0"/>13 <Static width="60.0" depth="60.0" circular="true"/> 14 14 </Obstruction> 15 15 <VisualActor> 16 16 <FoundationActor>structures/fndn_theatron.xml</FoundationActor> -
source/simulation2/components/CCmpObstruction.cpp
57 57 58 58 entity_pos_t m_Size0; // radius or width 59 59 entity_pos_t m_Size1; // radius or depth 60 bool m_Circular; // set for circular shapes 60 61 flags_t m_TemplateFlags; 61 62 entity_pos_t m_Clearance; 62 63 … … 64 65 entity_pos_t dx, dz; 65 66 entity_angle_t da; 66 67 entity_pos_t size0, size1; 68 bool circular; 67 69 flags_t flags; 68 70 } Shape; 69 71 … … 122 124 "<param name='minInclusive'>1.5</param>" 123 125 "</data>" 124 126 "</attribute>" 127 "<optional>" 128 "<attribute name='circular'>" 129 "<data type='boolean'/>" 130 "</attribute>" 131 "</optional>" 125 132 "</element>" 126 133 "<element name='Unit'>" 127 134 "<empty/>" … … 140 147 "<data type='decimal'/>" 141 148 "</attribute>" 142 149 "</optional>" 150 "<optional>" 151 "<attribute name='circular'>" 152 "<data type='boolean'/>" 153 "</attribute>" 154 "</optional>" 143 155 "<attribute name='width'>" 144 156 "<data type='decimal'>" 145 157 "<param name='minInclusive'>1.5</param>" … … 218 230 m_Size1 = paramNode.GetChild("Static").GetChild("@depth").ToFixed(); 219 231 ENSURE(m_Size0 > minObstruction); 220 232 ENSURE(m_Size1 > minObstruction); 233 m_Circular = paramNode.GetChild("Static").GetChild("@circular").ToBool(); 234 ENSURE(!m_Circular || m_Size0 == m_Size1); 221 235 } 222 236 else 223 237 { … … 232 246 b.size1 = it->second.GetChild("@depth").ToFixed(); 233 247 ENSURE(b.size0 > minObstruction); 234 248 ENSURE(b.size1 > minObstruction); 249 b.circular = it->second.GetChild("@circular").ToBool(); 250 ENSURE(!b.circular || b.size0 == b.size1); 235 251 b.dx = it->second.GetChild("@x").ToFixed(); 236 252 b.dz = it->second.GetChild("@z").ToFixed(); 237 253 b.da = entity_angle_t::FromInt(0); … … 244 260 } 245 261 m_Size0 = fixed::FromInt(2).Multiply(MAX(max.X, -min.X)); 246 262 m_Size1 = fixed::FromInt(2).Multiply(MAX(max.Y, -min.Y)); 263 m_Circular = false; 247 264 } 248 265 249 266 m_Active = paramNode.GetChild("Active").ToBool(); … … 335 352 // Need to create a new pathfinder shape: 336 353 if (m_Type == STATIC) 337 354 m_Tag = cmpObstructionManager->AddStaticShape(GetEntityId(), 338 data.x, data.z, data.a, m_Size0, m_Size1, m_ Flags, m_ControlGroup, m_ControlGroup2);355 data.x, data.z, data.a, m_Size0, m_Size1, m_Circular, m_Flags, m_ControlGroup, m_ControlGroup2); 339 356 else if (m_Type == UNIT) 340 357 m_Tag = cmpObstructionManager->AddUnitShape(GetEntityId(), 341 358 data.x, data.z, m_Clearance, (flags_t)(m_Flags | (m_Moving ? ICmpObstructionManager::FLAG_MOVING : 0)), m_ControlGroup); … … 392 409 CFixedVector2D pos = cmpPosition->GetPosition2D(); 393 410 if (m_Type == STATIC) 394 411 m_Tag = cmpObstructionManager->AddStaticShape(GetEntityId(), 395 pos.X, pos.Y, cmpPosition->GetRotation().Y, m_Size0, m_Size1, m_ Flags, m_ControlGroup, m_ControlGroup2);412 pos.X, pos.Y, cmpPosition->GetRotation().Y, m_Size0, m_Size1, m_Circular, m_Flags, m_ControlGroup, m_ControlGroup2); 396 413 else if (m_Type == UNIT) 397 414 m_Tag = cmpObstructionManager->AddUnitShape(GetEntityId(), 398 415 pos.X, pos.Y, m_Clearance, (flags_t)(m_Flags | (m_Moving ? ICmpObstructionManager::FLAG_MOVING : 0)), m_ControlGroup); … … 492 509 if (m_Type == UNIT) 493 510 out = cmpObstructionManager->GetUnitShapeObstruction(pos.X, pos.Y, m_Clearance); 494 511 else 495 out = cmpObstructionManager->GetStaticShapeObstruction(pos.X, pos.Y, cmpPosition->GetRotation().Y, m_Size0, m_Size1 );512 out = cmpObstructionManager->GetStaticShapeObstruction(pos.X, pos.Y, cmpPosition->GetRotation().Y, m_Size0, m_Size1, m_Circular); 496 513 return true; 497 514 } 498 515 … … 508 525 { 509 526 if (m_Type == UNIT) 510 527 return m_Clearance; 528 else if (m_Circular) 529 return m_Size0; 511 530 else 512 531 return CFixedVector2D(m_Size0 / 2, m_Size1 / 2).Length(); 513 532 } … … 562 581 if (m_Type == UNIT) 563 582 return cmpPathfinder->CheckUnitPlacement(filter, pos.X, pos.Y, m_Clearance, passClass, onlyCenterPoint); 564 583 else 565 return cmpPathfinder->CheckBuildingPlacement(filter, pos.X, pos.Y, cmpPosition->GetRotation().Y, m_Size0, m_Size1, GetEntityId(), passClass, onlyCenterPoint);584 return cmpPathfinder->CheckBuildingPlacement(filter, pos.X, pos.Y, cmpPosition->GetRotation().Y, m_Size0, m_Size1, m_Circular, GetEntityId(), passClass, onlyCenterPoint); 566 585 } 567 586 568 587 virtual bool CheckDuplicateFoundation() … … 594 613 if (m_Type == UNIT) 595 614 return !cmpObstructionManager->TestUnitShape(filter, pos.X, pos.Y, m_Clearance, NULL); 596 615 else 597 return !cmpObstructionManager->TestStaticShape(filter, pos.X, pos.Y, cmpPosition->GetRotation().Y, m_Size0, m_Size1, NULL );616 return !cmpObstructionManager->TestStaticShape(filter, pos.X, pos.Y, cmpPosition->GetRotation().Y, m_Size0, m_Size1, m_Circular, NULL ); 598 617 } 599 618 600 619 virtual std::vector<entity_id_t> GetUnitCollisions() … … 710 729 ICmpObstructionManager::FLAG_BLOCK_FOUNDATION); 711 730 712 731 std::vector<entity_id_t> collisions; 713 if (cmpObstructionManager->TestStaticShape(filter, pos.X, pos.Y, cmpPosition->GetRotation().Y, m_Size0, m_Size1, &collisions))732 if (cmpObstructionManager->TestStaticShape(filter, pos.X, pos.Y, cmpPosition->GetRotation().Y, m_Size0, m_Size1, m_Circular, &collisions)) 714 733 { 715 734 std::vector<entity_id_t> persistentEnts, normalEnts; 716 735 … … 770 789 flags &= (flags_t)(~ICmpObstructionManager::FLAG_BLOCK_PATHFINDING); 771 790 772 791 m_Tag = cmpObstructionManager->AddStaticShape(GetEntityId(), 773 x, z, a, m_Size0, m_Size1, flags, m_ControlGroup, m_ControlGroup2);792 x, z, a, m_Size0, m_Size1, m_Circular, flags, m_ControlGroup, m_ControlGroup2); 774 793 775 794 fixed s, c; 776 795 sincos_approx(a, s, c); … … 779 798 { 780 799 Shape& b = m_Shapes[i]; 781 800 tag_t tag = cmpObstructionManager->AddStaticShape(GetEntityId(), 782 x + b.dx.Multiply(c) + b.dz.Multiply(s), z + b.dz.Multiply(c) - b.dx.Multiply(s), a + b.da, b.size0, b.size1, b. flags, m_ControlGroup, m_ControlGroup2);801 x + b.dx.Multiply(c) + b.dz.Multiply(s), z + b.dz.Multiply(c) - b.dx.Multiply(s), a + b.da, b.size0, b.size1, b.circular, b.flags, m_ControlGroup, m_ControlGroup2); 783 802 m_ClusterTags.push_back(tag); 784 803 } 785 804 } -
source/simulation2/components/CCmpObstructionManager.cpp
67 67 entity_pos_t x, z; // world-space coordinates 68 68 CFixedVector2D u, v; // orthogonal unit vectors - axes of local coordinate space 69 69 entity_pos_t hw, hh; // half width/height in local coordinate space 70 bool circular; 70 71 ICmpObstructionManager::flags_t flags; 71 72 entity_id_t group; 72 73 entity_id_t group2; … … 289 290 return UNIT_INDEX_TO_TAG(id); 290 291 } 291 292 292 virtual tag_t AddStaticShape(entity_id_t ent, entity_pos_t x, entity_pos_t z, entity_angle_t a, entity_pos_t w, entity_pos_t h, flags_t flags, entity_id_t group, entity_id_t group2 /* = INVALID_ENTITY */) 293 virtual tag_t AddStaticShape(entity_id_t ent, entity_pos_t x, entity_pos_t z, 294 entity_angle_t a, entity_pos_t w, entity_pos_t h, bool circular, 295 flags_t flags, entity_id_t group, entity_id_t group2 /* = INVALID_ENTITY */) 293 296 { 294 297 fixed s, c; 295 298 sincos_approx(a, s, c); … … 296 299 CFixedVector2D u(c, -s); 297 300 CFixedVector2D v(s, c); 298 301 299 StaticShape shape = { ent, x, z, u, v, w/2, h/2, flags, group, group2 };302 StaticShape shape = { ent, x, z, u, v, w/2, h/2, circular, flags, group, group2 }; 300 303 u32 id = m_StaticShapeNext++; 301 304 m_StaticShapes[id] = shape; 302 305 … … 317 320 return o; 318 321 } 319 322 320 virtual ObstructionSquare GetStaticShapeObstruction(entity_pos_t x, entity_pos_t z, entity_angle_t a, entity_pos_t w, entity_pos_t h )323 virtual ObstructionSquare GetStaticShapeObstruction(entity_pos_t x, entity_pos_t z, entity_angle_t a, entity_pos_t w, entity_pos_t h, bool circular) 321 324 { 322 325 fixed s, c; 323 326 sincos_approx(a, s, c); … … 324 327 CFixedVector2D u(c, -s); 325 328 CFixedVector2D v(s, c); 326 329 327 ObstructionSquare o = { x, z, u, v, w/2, h/2 };330 ObstructionSquare o = { x, z, u, v, w/2, h/2, circular }; 328 331 return o; 329 332 } 330 333 … … 460 463 else 461 464 { 462 465 StaticShape& shape = m_StaticShapes[TAG_TO_INDEX(tag)]; 463 ObstructionSquare o = { shape.x, shape.z, shape.u, shape.v, shape.hw, shape.hh };466 ObstructionSquare o = { shape.x, shape.z, shape.u, shape.v, shape.hw, shape.hh, shape.circular }; 464 467 return o; 465 468 } 466 469 } 467 470 468 471 virtual bool TestLine(const IObstructionTestFilter& filter, entity_pos_t x0, entity_pos_t z0, entity_pos_t x1, entity_pos_t z1, entity_pos_t r, bool relaxClearanceForUnits = false); 469 virtual bool TestStaticShape(const IObstructionTestFilter& filter, entity_pos_t x, entity_pos_t z, entity_pos_t a, entity_pos_t w, entity_pos_t h, std::vector<entity_id_t>* out);472 virtual bool TestStaticShape(const IObstructionTestFilter& filter, entity_pos_t x, entity_pos_t z, entity_pos_t a, entity_pos_t w, entity_pos_t h, bool circular, std::vector<entity_id_t>* out); 470 473 virtual bool TestUnitShape(const IObstructionTestFilter& filter, entity_pos_t x, entity_pos_t z, entity_pos_t r, std::vector<entity_id_t>* out); 471 474 472 475 virtual void Rasterize(Grid<NavcellData>& grid, const std::vector<PathfinderPassability>& passClasses, bool fullUpdate); … … 711 714 712 715 bool CCmpObstructionManager::TestStaticShape(const IObstructionTestFilter& filter, 713 716 entity_pos_t x, entity_pos_t z, entity_pos_t a, entity_pos_t w, entity_pos_t h, 714 std::vector<entity_id_t>* out)717 bool circular, std::vector<entity_id_t>* out) 715 718 { 716 719 PROFILE("TestStaticShape"); 717 720 … … 746 749 747 750 CFixedVector2D center1(it->second.x, it->second.z); 748 751 749 if (Geometry::PointIsInSquare(center1 - center, u, v, CFixedVector2D(halfSize.X + it->second.clearance, halfSize.Y + it->second.clearance))) 752 bool isInShape; 753 if (circular) 754 isInShape = (center1 - center).CompareLength(halfSize.X) > 0; 755 else 756 isInShape = Geometry::PointIsInSquare(center1 - center, u, v, CFixedVector2D(halfSize.X + it->second.clearance, halfSize.Y + it->second.clearance)); 757 758 if (isInShape) 750 759 { 751 760 if (out) 752 761 out->push_back(it->second.entity); … … 762 771 763 772 CFixedVector2D center1(it->second.x, it->second.z); 764 773 CFixedVector2D halfSize1(it->second.hw, it->second.hh); 765 if (Geometry::TestSquareSquare(center, u, v, halfSize, center1, it->second.u, it->second.v, halfSize1)) 774 bool isInShape; 775 if (circular) 776 isInShape = Geometry::DistanceToSquare(center - center1, it->second.u, it->second.v, halfSize1, true) < halfSize.X; 777 else 778 isInShape = Geometry::TestSquareSquare(center, u, v, halfSize, center1, it->second.u, it->second.v, halfSize1); 779 780 if (isInShape) 766 781 { 767 782 if (out) 768 783 out->push_back(it->second.entity); … … 894 909 continue; 895 910 896 911 // TODO: it might be nice to rasterize with rounded corners for large 'expand' values. 897 ObstructionSquare square = { shape.x, shape.z, shape.u, shape.v, shape.hw, shape.hh };912 ObstructionSquare square = { shape.x, shape.z, shape.u, shape.v, shape.hw, shape.hh, shape.circular }; 898 913 SimRasterize::Spans spans; 899 914 SimRasterize::RasterizeRectWithClearance(spans, square, clearance, Pathfinding::NAVCELL_SIZE); 900 915 for (SimRasterize::Span& span : spans) … … 986 1001 987 1002 // TODO: maybe we should use Geometry::GetHalfBoundingBox to be more precise? 988 1003 989 squares.emplace_back(ObstructionSquare{ it->second.x, it->second.z, it->second.u, it->second.v, it->second.hw, it->second.hh });1004 squares.emplace_back(ObstructionSquare{ it->second.x, it->second.z, it->second.u, it->second.v, it->second.hw, it->second.hh, it->second.circular }); 990 1005 } 991 1006 } 992 1007 -
source/simulation2/components/CCmpPathfinder.cpp
826 826 } 827 827 828 828 ICmpObstruction::EFoundationCheck CCmpPathfinder::CheckBuildingPlacement(const IObstructionTestFilter& filter, 829 entity_pos_t x, entity_pos_t z, entity_pos_t a, entity_pos_t w, 830 entity_pos_t h, entity_id_t id, pass_class_t passClass)829 entity_pos_t x, entity_pos_t z, entity_pos_t a, entity_pos_t w, entity_pos_t h, 830 bool circular, entity_id_t id, pass_class_t passClass) 831 831 { 832 return CCmpPathfinder::CheckBuildingPlacement(filter, x, z, a, w, h, id, passClass, false);832 return CCmpPathfinder::CheckBuildingPlacement(filter, x, z, a, w, h, circular, id, passClass, false); 833 833 } 834 834 835 835 836 836 ICmpObstruction::EFoundationCheck CCmpPathfinder::CheckBuildingPlacement(const IObstructionTestFilter& filter, 837 entity_pos_t x, entity_pos_t z, entity_pos_t a, entity_pos_t w, 838 entity_pos_t h, entity_id_t id, pass_class_t passClass, bool UNUSED(onlyCenterPoint))837 entity_pos_t x, entity_pos_t z, entity_pos_t a, entity_pos_t w, entity_pos_t h, 838 bool circular, entity_id_t id, pass_class_t passClass, bool UNUSED(onlyCenterPoint)) 839 839 { 840 840 // Check unit obstruction 841 841 CmpPtr<ICmpObstructionManager> cmpObstructionManager(GetSystemEntity()); … … 842 842 if (!cmpObstructionManager) 843 843 return ICmpObstruction::FOUNDATION_CHECK_FAIL_ERROR; 844 844 845 if (cmpObstructionManager->TestStaticShape(filter, x, z, a, w, h, NULL))845 if (cmpObstructionManager->TestStaticShape(filter, x, z, a, w, h, circular, NULL)) 846 846 return ICmpObstruction::FOUNDATION_CHECK_FAIL_OBSTRUCTS_FOUNDATION; 847 847 848 848 // Test against terrain: -
source/simulation2/components/CCmpPathfinder_Common.h
214 214 215 215 virtual ICmpObstruction::EFoundationCheck CheckUnitPlacement(const IObstructionTestFilter& filter, entity_pos_t x, entity_pos_t z, entity_pos_t r, pass_class_t passClass, bool onlyCenterPoint); 216 216 217 virtual ICmpObstruction::EFoundationCheck CheckBuildingPlacement(const IObstructionTestFilter& filter, entity_pos_t x, entity_pos_t z, entity_pos_t a, entity_pos_t w, entity_pos_t h, entity_id_t id, pass_class_t passClass);217 virtual ICmpObstruction::EFoundationCheck CheckBuildingPlacement(const IObstructionTestFilter& filter, entity_pos_t x, entity_pos_t z, entity_pos_t a, entity_pos_t w, entity_pos_t h, bool circular, entity_id_t id, pass_class_t passClass); 218 218 219 virtual ICmpObstruction::EFoundationCheck CheckBuildingPlacement(const IObstructionTestFilter& filter, entity_pos_t x, entity_pos_t z, entity_pos_t a, entity_pos_t w, entity_pos_t h, entity_id_t id, pass_class_t passClass, bool onlyCenterPoint);219 virtual ICmpObstruction::EFoundationCheck CheckBuildingPlacement(const IObstructionTestFilter& filter, entity_pos_t x, entity_pos_t z, entity_pos_t a, entity_pos_t w, entity_pos_t h, bool circular, entity_id_t id, pass_class_t passClass, bool onlyCenterPoint); 220 220 221 221 virtual void FinishAsyncRequests(); 222 222 -
source/simulation2/components/ICmpObstructionManager.h
98 98 * @param a angle of rotation (clockwise from +Z direction) 99 99 * @param w width (size along X axis) 100 100 * @param h height (size along Z axis) 101 * @param circular (set to true if obstruction is cicular) 101 102 * @param flags a set of EFlags values 102 103 * @param group primary control group of the shape. Must be a valid control group ID. 103 104 * @param group2 Optional; secondary control group of the shape. Defaults to INVALID_ENTITY. … … 104 105 * @return a valid tag for manipulating the shape 105 106 * @see StaticShape 106 107 */ 107 virtual tag_t AddStaticShape(entity_id_t ent, entity_pos_t x, entity_pos_t z, entity_angle_t a, 108 entity_pos_t w, entity_pos_t h, flags_t flags, entity_id_t group, entity_id_t group2 = INVALID_ENTITY) = 0; 108 virtual tag_t AddStaticShape(entity_id_t ent, entity_pos_t x, entity_pos_t z, 109 entity_angle_t a, entity_pos_t w, entity_pos_t h, bool circular, 110 flags_t flags, entity_id_t group, entity_id_t group2 = INVALID_ENTITY) = 0; 109 111 110 112 /** 111 113 * Register a unit shape. … … 186 188 */ 187 189 virtual bool TestStaticShape(const IObstructionTestFilter& filter, 188 190 entity_pos_t x, entity_pos_t z, entity_pos_t a, entity_pos_t w, entity_pos_t h, 189 std::vector<entity_id_t>* out) = 0;191 bool circular, std::vector<entity_id_t>* out) = 0; 190 192 191 193 /** 192 194 * Collision test a unit shape against the current set of registered shapes, and optionally writes a list of the colliding … … 226 228 entity_pos_t x, z; // position of center 227 229 CFixedVector2D u, v; // 'horizontal' and 'vertical' orthogonal unit vectors, representing orientation 228 230 entity_pos_t hw, hh; // half width, half height of square 231 bool circular; // set to true if the obstruction is circle-shaped 229 232 }; 230 233 231 234 /** … … 259 262 260 263 virtual ObstructionSquare GetUnitShapeObstruction(entity_pos_t x, entity_pos_t z, entity_pos_t clearance) = 0; 261 264 262 virtual ObstructionSquare GetStaticShapeObstruction(entity_pos_t x, entity_pos_t z, entity_angle_t a, entity_pos_t w, entity_pos_t h ) = 0;265 virtual ObstructionSquare GetStaticShapeObstruction(entity_pos_t x, entity_pos_t z, entity_angle_t a, entity_pos_t w, entity_pos_t h, bool circular) = 0; 263 266 264 267 /** 265 268 * Set the passability to be restricted to a circular map. -
source/simulation2/components/ICmpPathfinder.h
146 146 * @return ICmpObstruction::FOUNDATION_CHECK_SUCCESS if the placement is okay, else 147 147 * a value describing the type of failure. 148 148 */ 149 virtual ICmpObstruction::EFoundationCheck CheckBuildingPlacement(const IObstructionTestFilter& filter, entity_pos_t x, entity_pos_t z, entity_pos_t a, entity_pos_t w, entity_pos_t h, entity_id_t id, pass_class_t passClass) = 0;149 virtual ICmpObstruction::EFoundationCheck CheckBuildingPlacement(const IObstructionTestFilter& filter, entity_pos_t x, entity_pos_t z, entity_pos_t a, entity_pos_t w, entity_pos_t h, bool circular, entity_id_t id, pass_class_t passClass) = 0; 150 150 151 151 /** 152 152 * Check whether a building placed here is valid and doesn't hit any obstructions … … 155 155 * @return ICmpObstruction::FOUNDATION_CHECK_SUCCESS if the placement is okay, else 156 156 * a value describing the type of failure. 157 157 */ 158 virtual ICmpObstruction::EFoundationCheck CheckBuildingPlacement(const IObstructionTestFilter& filter, entity_pos_t x, entity_pos_t z, entity_pos_t a, entity_pos_t w, entity_pos_t h, entity_id_t id, pass_class_t passClass, bool onlyCenterPoint) = 0;158 virtual ICmpObstruction::EFoundationCheck CheckBuildingPlacement(const IObstructionTestFilter& filter, entity_pos_t x, entity_pos_t z, entity_pos_t a, entity_pos_t w, entity_pos_t h, bool circular, entity_id_t id, pass_class_t passClass, bool onlyCenterPoint) = 0; 159 159 160 160 161 161 /** -
source/simulation2/components/tests/test_ObstructionManager.h
111 111 TS_ASSERT_EQUALS(ent3, out[0]); 112 112 out.clear(); 113 113 114 cmp->TestStaticShape(nullFilter, ent3x, ent3z, fixed::Zero(), fixed::FromInt(1), fixed::FromInt(1), &out);114 cmp->TestStaticShape(nullFilter, ent3x, ent3z, fixed::Zero(), fixed::FromInt(1), fixed::FromInt(1), false, &out); 115 115 TS_ASSERT_EQUALS(1U, out.size()); 116 116 TS_ASSERT_EQUALS(ent3, out[0]); 117 117 out.clear(); … … 125 125 TS_ASSERT_VECTOR_CONTAINS(out, ent2); 126 126 out.clear(); 127 127 128 cmp->TestStaticShape(nullFilter, ent2x, ent2z, fixed::Zero(), ent2c, ent2c, &out);128 cmp->TestStaticShape(nullFilter, ent2x, ent2z, fixed::Zero(), ent2c, ent2c, false, &out); 129 129 TS_ASSERT_EQUALS(2U, out.size()); 130 130 TS_ASSERT_VECTOR_CONTAINS(out, ent1); 131 131 TS_ASSERT_VECTOR_CONTAINS(out, ent2); … … 152 152 TS_ASSERT_VECTOR_CONTAINS(out, ent3); 153 153 out.clear(); 154 154 155 cmp->TestStaticShape(nullFilter, ent1x, ent1z, fixed::Zero(), fixed::FromInt(10), fixed::FromInt(10), &out);155 cmp->TestStaticShape(nullFilter, ent1x, ent1z, fixed::Zero(), fixed::FromInt(10), fixed::FromInt(10), false, &out); 156 156 TS_ASSERT_EQUALS(3U, out.size()); 157 157 TS_ASSERT_VECTOR_CONTAINS(out, ent1); 158 158 TS_ASSERT_VECTOR_CONTAINS(out, ent2); … … 180 180 TS_ASSERT_VECTOR_CONTAINS(out, ent3); 181 181 out.clear(); 182 182 183 cmp->TestStaticShape(ignoreMoving, ent1x, ent1z, fixed::Zero(), fixed::FromInt(10), fixed::FromInt(10), &out);183 cmp->TestStaticShape(ignoreMoving, ent1x, ent1z, fixed::Zero(), fixed::FromInt(10), fixed::FromInt(10), false, &out); 184 184 TS_ASSERT_EQUALS(2U, out.size()); 185 185 TS_ASSERT_VECTOR_CONTAINS(out, ent2); 186 186 TS_ASSERT_VECTOR_CONTAINS(out, ent3); … … 205 205 TS_ASSERT_EQUALS(ent1, out[0]); 206 206 out.clear(); 207 207 208 cmp->TestStaticShape(ignoreShape2, ent2x, ent2z, fixed::Zero(), ent2c, ent2c, &out);208 cmp->TestStaticShape(ignoreShape2, ent2x, ent2z, fixed::Zero(), ent2c, ent2c, false, &out); 209 209 TS_ASSERT_EQUALS(1U, out.size()); 210 210 TS_ASSERT_EQUALS(ent1, out[0]); 211 211 out.clear(); … … 230 230 TS_ASSERT_EQUALS(ent3, out[0]); 231 231 out.clear(); 232 232 233 cmp->TestStaticShape(skipShape1RequireBlockMovement, ent1x, ent1z, fixed::Zero(), fixed::FromInt(10), fixed::FromInt(10), &out);233 cmp->TestStaticShape(skipShape1RequireBlockMovement, ent1x, ent1z, fixed::Zero(), fixed::FromInt(10), fixed::FromInt(10), false, &out); 234 234 TS_ASSERT_EQUALS(1U, out.size()); 235 235 TS_ASSERT_EQUALS(ent3, out[0]); 236 236 out.clear(); … … 247 247 TS_ASSERT_VECTOR_CONTAINS(out, ent3); 248 248 out.clear(); 249 249 250 cmp->TestStaticShape(skipShape1RequireAnyFlag, ent1x, ent1z, fixed::Zero(), fixed::FromInt(10), fixed::FromInt(10), &out);250 cmp->TestStaticShape(skipShape1RequireAnyFlag, ent1x, ent1z, fixed::Zero(), fixed::FromInt(10), fixed::FromInt(10), false, &out); 251 251 TS_ASSERT_EQUALS(2U, out.size()); 252 252 TS_ASSERT_VECTOR_CONTAINS(out, ent2); 253 253 TS_ASSERT_VECTOR_CONTAINS(out, ent3); … … 262 262 TS_ASSERT_EQUALS(0U, out.size()); 263 263 out.clear(); 264 264 265 cmp->TestStaticShape(skipShape1RejectAll, ent1x, ent1z, fixed::Zero(), fixed::FromInt(10), fixed::FromInt(10), &out);265 cmp->TestStaticShape(skipShape1RejectAll, ent1x, ent1z, fixed::Zero(), fixed::FromInt(10), fixed::FromInt(10), false, &out); 266 266 TS_ASSERT_EQUALS(0U, out.size()); 267 267 out.clear(); 268 268 } … … 290 290 TS_ASSERT_EQUALS(ent3, out[0]); 291 291 out.clear(); 292 292 293 cmp->TestStaticShape(skipGroup1ReqFoundConstr, ent1x, ent1z, fixed::Zero(), fixed::FromInt(10), fixed::FromInt(10), &out);293 cmp->TestStaticShape(skipGroup1ReqFoundConstr, ent1x, ent1z, fixed::Zero(), fixed::FromInt(10), fixed::FromInt(10), false, &out); 294 294 TS_ASSERT_EQUALS(1U, out.size()); 295 295 TS_ASSERT_EQUALS(ent3, out[0]); 296 296 out.clear(); … … 306 306 TS_ASSERT_EQUALS(0U, out.size()); 307 307 out.clear(); 308 308 309 cmp->TestStaticShape(skipGroup1And3ReqFoundConstr, ent1x, ent1z, fixed::Zero(), fixed::FromInt(10), fixed::FromInt(10), &out);309 cmp->TestStaticShape(skipGroup1And3ReqFoundConstr, ent1x, ent1z, fixed::Zero(), fixed::FromInt(10), fixed::FromInt(10), false, &out); 310 310 TS_ASSERT_EQUALS(0U, out.size()); 311 311 out.clear(); 312 312 … … 323 323 TS_ASSERT_VECTOR_CONTAINS(out, ent2); 324 324 out.clear(); 325 325 326 cmp->TestStaticShape(skipGroup3RequireAnyFlag, ent1x, ent1z, fixed::Zero(), fixed::FromInt(10), fixed::FromInt(10), &out);326 cmp->TestStaticShape(skipGroup3RequireAnyFlag, ent1x, ent1z, fixed::Zero(), fixed::FromInt(10), fixed::FromInt(10), false, &out); 327 327 TS_ASSERT_EQUALS(2U, out.size()); 328 328 TS_ASSERT_VECTOR_CONTAINS(out, ent1); 329 329 TS_ASSERT_VECTOR_CONTAINS(out, ent2); … … 339 339 TS_ASSERT_EQUALS(0U, out.size()); 340 340 out.clear(); 341 341 342 cmp->TestStaticShape(skipGroup3RequireNoFlags, ent1x, ent1z, fixed::Zero(), fixed::FromInt(10), fixed::FromInt(10), &out);342 cmp->TestStaticShape(skipGroup3RequireNoFlags, ent1x, ent1z, fixed::Zero(), fixed::FromInt(10), fixed::FromInt(10), false, &out); 343 343 TS_ASSERT_EQUALS(0U, out.size()); 344 344 out.clear(); 345 345 … … 378 378 TS_ASSERT_VECTOR_CONTAINS(out, ent3); 379 379 out.clear(); 380 380 381 cmp->TestStaticShape(skipGroup1SecAnd4SecRequireAny, ent1x, ent1z, fixed::Zero(), fixed::FromInt(10), fixed::FromInt(10), &out);381 cmp->TestStaticShape(skipGroup1SecAnd4SecRequireAny, ent1x, ent1z, fixed::Zero(), fixed::FromInt(10), fixed::FromInt(10), false, &out); 382 382 TS_ASSERT_EQUALS(2U, out.size()); 383 383 TS_ASSERT_VECTOR_CONTAINS(out, ent2); 384 384 TS_ASSERT_VECTOR_CONTAINS(out, ent3); … … 397 397 TS_ASSERT_VECTOR_CONTAINS(out, ent3); 398 398 out.clear(); 399 399 400 cmp->TestStaticShape(skipGroup1SecAnd4PrimRequireAny, ent1x, ent1z, fixed::Zero(), fixed::FromInt(10), fixed::FromInt(10), &out);400 cmp->TestStaticShape(skipGroup1SecAnd4PrimRequireAny, ent1x, ent1z, fixed::Zero(), fixed::FromInt(10), fixed::FromInt(10), false, &out); 401 401 TS_ASSERT_EQUALS(2U, out.size()); 402 402 TS_ASSERT_VECTOR_CONTAINS(out, ent2); 403 403 TS_ASSERT_VECTOR_CONTAINS(out, ent3); … … 423 423 ent4x = ent3x + ent3c + ent4w/2, // make ent4 adjacent to ent3 424 424 ent4z = ent3z; 425 425 426 cmp->TestStaticShape(nullFilter, ent4x, ent4z, ent4a, ent4w, ent4h, &out);426 cmp->TestStaticShape(nullFilter, ent4x, ent4z, ent4a, ent4w, ent4h, false, &out); 427 427 TS_ASSERT_EQUALS(1U, out.size()); 428 428 TS_ASSERT_EQUALS(ent3, out[0]); 429 429 out.clear(); … … 435 435 436 436 // now do the same tests, but move the shape a little bit to the right so that it doesn't touch anymore 437 437 438 cmp->TestStaticShape(nullFilter, ent4x + fixed::FromFloat(1e-5f), ent4z, ent4a, ent4w, ent4h, &out);438 cmp->TestStaticShape(nullFilter, ent4x + fixed::FromFloat(1e-5f), ent4z, ent4a, ent4w, ent4h, false, &out); 439 439 TS_ASSERT_EQUALS(0U, out.size()); 440 440 out.clear(); 441 441 -
source/simulation2/helpers/Rasterize.cpp
56 56 return; // empty bounds - this shouldn't happen 57 57 58 58 59 rasterClearance= rasterClearance.Multiply(rasterClearance);59 entity_pos_t rasterClearanceSq = rasterClearance.Multiply(rasterClearance); 60 60 61 61 spans.reserve(j1 - j0); 62 62 … … 80 80 continue; 81 81 } 82 82 83 if (Geometry::DistanceToSquareSquared(CFixedVector2D(cellSize*(i+1)-shape.x, cellSize*j-shape.z), 84 shape.u, shape.v, shapeHalfSize, true) > rasterClearance) 83 CFixedVector2D diff(cellSize*(i+1)-shape.x, cellSize*j-shape.z); 84 bool isOutShape; 85 if (shape.circular) 86 isOutShape = diff.CompareLength(rasterClearance + shapeHalfSize.X) > 0; 87 else 88 isOutShape = Geometry::DistanceToSquareSquared(diff, shape.u, shape.v, shapeHalfSize, true) > rasterClearanceSq; 89 if (isOutShape) 85 90 { 86 91 if (previousInside) 87 92 break; … … 89 94 continue; 90 95 } 91 96 92 if (Geometry::DistanceToSquareSquared(CFixedVector2D(cellSize*(i+1)-shape.x, cellSize*(j+1)-shape.z), 93 shape.u, shape.v, shapeHalfSize, true) > rasterClearance) 97 diff.Y += cellSize; // one to the right 98 if (shape.circular) 99 isOutShape = diff.CompareLength(rasterClearance + shapeHalfSize.X) > 0; 100 else 101 isOutShape = Geometry::DistanceToSquareSquared(diff, shape.u, shape.v, shapeHalfSize, true) > rasterClearanceSq; 102 if (isOutShape) 94 103 { 95 104 if (previousInside) 96 105 break; … … 100 109 101 110 if (!previousInside) 102 111 { 103 if (Geometry::DistanceToSquareSquared(CFixedVector2D(cellSize*i-shape.x, cellSize*j-shape.z), 104 shape.u, shape.v, shapeHalfSize, true) > rasterClearance) 112 diff.X -= cellSize; // one step backwards 113 if (shape.circular) 114 isOutShape = diff.CompareLength(rasterClearance + shapeHalfSize.X) > 0; 115 else 116 isOutShape = Geometry::DistanceToSquareSquared(diff, shape.u, shape.v, shapeHalfSize, true) > rasterClearanceSq; 117 if (isOutShape) 105 118 continue; 106 119 107 if (Geometry::DistanceToSquareSquared(CFixedVector2D(cellSize*i-shape.x, cellSize*(j+1)-shape.z), 108 shape.u, shape.v, shapeHalfSize, true) > rasterClearance) 120 diff.Y -= cellSize; // one to the left 121 if (shape.circular) 122 isOutShape = diff.CompareLength(rasterClearance + shapeHalfSize.X) > 0; 123 else 124 isOutShape = Geometry::DistanceToSquareSquared(diff, shape.u, shape.v, shapeHalfSize, true) > rasterClearanceSq; 125 if (isOutShape) 109 126 continue; 110 127 111 128 previousInside = true;