| 443 | } |
| 444 | |
| 445 | m_Vec3 Map::CollideWithMap( |
| 446 | const m_Vec3 in_pos, const float height, const float radius, |
| 447 | const Time tick_delta, |
| 448 | bool& out_on_floor, MovementRestriction& out_movement_restriction ) const |
| 449 | { |
| 450 | m_Vec2 pos= in_pos.xy(); |
| 451 | out_on_floor= false; |
| 452 | |
| 453 | const float z_bottom= in_pos.z; |
| 454 | const float z_top= z_bottom + height; |
| 455 | float new_z= in_pos.z; |
| 456 | |
| 457 | // Store list of objects, collisions with which alread processed. |
| 458 | constexpr unsigned int c_max_collisions= 32u; |
| 459 | MapData::IndexElement processed_collisions[ c_max_collisions ]; |
| 460 | unsigned int processed_collisions_count= 0u; |
| 461 | const auto collision_processed= |
| 462 | [&]( const MapData::IndexElement& index_element ) |
| 463 | { |
| 464 | if( processed_collisions_count == c_max_collisions ) |
| 465 | return true; |
| 466 | for( unsigned int i= 0u; i < processed_collisions_count; i++ ) |
| 467 | if( std::memcmp( &processed_collisions[i], &index_element, sizeof(MapData::IndexElement) ) == 0 ) |
| 468 | return true; |
| 469 | return false; |
| 470 | }; |
| 471 | const auto process_collision= |
| 472 | [&]( const MapData::IndexElement& index_element ) |
| 473 | { |
| 474 | PC_ASSERT( processed_collisions_count < c_max_collisions ); |
| 475 | processed_collisions[ processed_collisions_count ]= index_element; |
| 476 | processed_collisions_count++; |
| 477 | }; |
| 478 | |
| 479 | const auto elements_process_func= |
| 480 | [&]( const MapData::IndexElement& index_element ) |
| 481 | { |
| 482 | if( collision_processed(index_element) ) |
| 483 | return; |
| 484 | |
| 485 | if( index_element.type == MapData::IndexElement::StaticWall ) |
| 486 | { |
| 487 | PC_ASSERT( index_element.index < map_data_->static_walls.size() ); |
| 488 | const MapData::Wall& wall= map_data_->static_walls[ index_element.index ]; |
| 489 | |
| 490 | const MapData::WallTextureDescription& tex= map_data_->walls_textures[ wall.texture_id ]; |
| 491 | if( tex.gso[0] ) |
| 492 | return; |
| 493 | |
| 494 | // Do not collide with wall, if we are behind it. But collide, if wall is transparent. |
| 495 | if( wall.texture_id < MapData::c_first_transparent_texture_id && |
| 496 | mVec2Cross( pos - wall.vert_pos[0], wall.vert_pos[1] - wall.vert_pos[0] ) > 0.0f ) |
| 497 | return; |
| 498 | |
| 499 | m_Vec2 new_pos; |
| 500 | if( CollideCircleWithLineSegment( |
| 501 | wall.vert_pos[0], wall.vert_pos[1], |
| 502 | pos, radius, |
nothing calls this directly
no test coverage detected