sf::IntRect pochylonego chunka mapy 3D w płaszczyźnie SFMLA 2D
Ostatnio zmodyfikowano 2026-10-28 20:46
tBane Temat założony przez niniejszego użytkownika |
sf::IntRect pochylonego chunka mapy 3D w płaszczyźnie SFMLA 2D » 2026-10-28 17:40:39 Cześć! :D Piszę mapę 2.5D w SFML 3.1. Mam problem z wyznaczeniem granic każdego chunka. Mapa jest odchylona o 45 stopni w osi X. Potrzebuję wyznaczyć granice chunku mapy w płaszczyźnie SFMLA XY tak, żeby sprawdzać czy chunk mieści się na ekranie. sf::IntRect Chunk::getRect() { sf::IntRect rect; rect.position.x = _coords.x * tilesCols * Tile::tileSize; rect.position.y = _coords.y * tilesRows * Tile::tileSize; rect.size.x = tilesCols * Tile::tileSize; rect.size.y = tilesRows * Tile::tileSize; return rect; }
uniform vec2 cameraCenter; uniform float cameraDistance; uniform float cameraAngle; uniform float aspect;
varying vec2 worldPos;
void main() { float angle = radians( cameraAngle ); float s = sin( angle ); float c = cos( angle ); vec4 pos = gl_Vertex; pos.xy -= cameraCenter; vec3 rotated = vec3( pos.x, pos.y * c, pos.y * s ); float depth = cameraDistance - rotated.z; float f = 1.7320508; gl_Position = vec4( rotated.x * f / aspect, - rotated.y * f, depth - 0.2, depth ); gl_TexCoord[ 0 ] = gl_TextureMatrix[ 0 ] * gl_MultiTexCoord0; worldPos = gl_Vertex.xy; gl_FrontColor = gl_Color; }
|
|
tBane Temat założony przez niniejszego użytkownika |
» 2026-10-28 18:01:09 sf::View view = Main::render_window->getView(); sf::FloatRect cameraRect( view.getCenter() - view.getSize() * 0.5f, view.getSize() ); sf::FloatRect chunkRect( chunk->getRect() );
if( cameraRect.findIntersection( chunkRect ) ) { chunk->setVisible(); }
sf::IntRect Chunk::getRect() { sf::IntRect rect; rect.position.x = _coords.x * tilesCols * Tile::tileSize; rect.position.y = _coords.y * tilesRows * Tile::tileSize; rect.size.x = tilesCols * Tile::tileSize; rect.size.y = tilesRows * Tile::tileSize; if( MapEditor::editor->_camera ) { sf::View view = Main::render_window->getView(); sf::Vector2f cameraCenter = view.getCenter(); sf::Vector2u windowSize = Main::render_window->getSize(); float zoom = MapEditor::editor->_camera->_zoom; if( windowSize.x == 0 || windowSize.y == 0 || zoom <= 0.f ) return sf::IntRect(); sf::Vector2f size( float( windowSize.x ) / zoom, float( windowSize.y ) / zoom ); float aspect = float( windowSize.x ) / windowSize.y; float fov = 60.f; float distance =( size.y * 0.5f ) / std::tan( fov * 0.5f * 3.14159265f / 180.f ); float angle = sf::degrees( MapEditor::editor->_camera->_angle ).asRadians(); float s = std::sin( angle ); float c = std::cos( angle ); float f = 1.7320508f; float width = float( tilesCols * Tile::tileSize ); float height = float( tilesRows * Tile::tileSize ); float x = float( _coords.x ) * width; float y = float( _coords.y ) * height; const sf::Vector2f points[ ] = { { x, y }, { x + width, y }, { x + width, y + height }, { x, y + height } }; float minX = std::numeric_limits < float >::max(); float minY = std::numeric_limits < float >::max(); float maxX = std::numeric_limits < float >::lowest(); float maxY = std::numeric_limits < float >::lowest(); for( const auto & point: points ) { float px = point.x - cameraCenter.x; float py = point.y - cameraCenter.y; float rotatedX = px; float rotatedY = py * c; float rotatedZ = py * s; float depth = distance - rotatedZ; if( depth <= 0.1f ) { minX = cameraCenter.x - size.x * 0.5f; minY = cameraCenter.y - size.y * 0.5f; maxX = cameraCenter.x + size.x * 0.5f; maxY = cameraCenter.y + size.y * 0.5f; break; } float ndcX =( rotatedX * f / aspect ) / depth; float ndcY =( - rotatedY * f ) / depth; float projectedX = cameraCenter.x + ndcX * size.x * 0.5f; float projectedY = cameraCenter.y - ndcY * size.y * 0.5f; minX = std::min( minX, projectedX ); minY = std::min( minY, projectedY ); maxX = std::max( maxX, projectedX ); maxY = std::max( maxY, projectedY ); } int left = int( std::floor( minX ) ); int top = int( std::floor( minY ) ); int right = int( std::ceil( maxX ) ); int bottom = int( std::ceil( maxY ) ); return sf::IntRect( sf::Vector2i( left, top ), sf::Vector2i( right - left, bottom - top ) ); } return rect; }
|
|
DejaVu |
» 2026-10-28 18:20:55 Jeżeli mapa jest 2D i masz kwadratowe tilesy to raczej nic Ci nie zmienia nachylenie kamery? |
|
tBane Temat założony przez niniejszego użytkownika |
» 2026-10-28 18:24:01 Mapa jest w 2.5D tj. jest rotowana shaderem i przeliczana przez perspektywę. Potrzebowałem granic chunka w płaszczyźnie XY SFMLa po to żeby w wygodny sposób sprawdzać czy mieści się chunk w widoku :-) Dzięki temu mogę rysować tylko te chunki maapy, które są widoczne w widoku, a nie wszystkie :-) |
|
| « 1 » |