Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: How can I transform a Vector2f with the Opposite of the current getTransform()?  (Read 2259 times)

0 Members and 1 Guest are viewing this topic.

Miss__Aria

  • Newbie
  • *
  • Posts: 6
    • View Profile
I'm trying to grab an integer from an array that presumes the map is at 0, 0. How can I transform this position so it is relative to what the map thinks is 0, 0.

That may have been confusing to read, it was confusing for me to write. I've been expanding on a tile_map and scratching my head at this one point.

Here's my source,
#pragma once
#include <SFML\Graphics.hpp>

class Tile_map : public sf::Drawable, public sf::Transformable
{
public:
  Tile_map(const std::string& tileset_path, sf::Vector2u tile_size, std::vector<int> tiles, unsigned int width, unsigned int height) :  tileset_path(tileset_path),   tile_size(tile_size),
                                                                                                                                        tiles(tiles),                 width(width),
                                                                                                                                        height(height) {}
  bool load();
  int get_current_tile(const sf::Vector2f& position);
private:
  virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const;
  std::string tileset_path;
  sf::Vector2u tile_size;
  std::vector<int> tiles;
  unsigned int width, height;
  sf::VertexArray verticies;
  sf::Texture tileset;
};
 

#include "tilemap.h"

bool Tile_map::load()
{
  if (!tileset.loadFromFile(tileset_path))
    return false;

  verticies.setPrimitiveType(sf::Quads);
  //4 because each square has 4 points(vertexes)
  verticies.resize(width * height * 4);
  //this->setScale({ 2, 2 }); //Scales textures up from 16x16 to 32x32 so we can easily see them

  for (unsigned int i = 0; i < width; ++i) {
    for (unsigned int j = 0; j < height; ++j) {
      int tile_number = tiles[i + j * width] - 1; //-1 is for tiled, first sprite on sheet in tiled is 1 but when doing these calculations it's 0
      if (tile_number == -1) continue; // In tiled, 0 is transparent so 0 - 1 will hit this

      int tu = tile_number % (tileset.getSize().x / tile_size.x);
      int tv = tile_number / (tileset.getSize().x / tile_size.x);
      sf::Vertex* quad = &verticies[(i + j * width) * 4];

      quad[0].position = { (float)i * tile_size.x, (float)j * tile_size.y };
      quad[1].position = { (float)(i + 1) * tile_size.x, (float)j * tile_size.y };
      quad[2].position = { (float)(i + 1) * tile_size.x, (float)(j + 1) * tile_size.y };
      quad[3].position = { (float)i * tile_size.x, (float)(j + 1) * tile_size.y };

      quad[0].texCoords = { (float)tu * tile_size.x, (float)tv * tile_size.y };
      quad[1].texCoords = { (float)(tu + 1) * tile_size.x, (float)tv * tile_size.y };
      quad[2].texCoords = { (float)(tu + 1) * tile_size.x, (float)(tv + 1) * tile_size.y };
      quad[3].texCoords = { (float)tu * tile_size.x, (float)(tv + 1) * tile_size.y };
    }
  }

  return true;
}

int Tile_map::get_current_tile(const sf::Vector2f& position)
{
  auto newpos = position; //getTransform().transformPoint(position);
  return tiles[(newpos.x / tile_size.x) + (newpos.y / tile_size.y) * width] - 1;
}

void Tile_map::draw(sf::RenderTarget& target, sf::RenderStates states) const
{
  states.transform *= getTransform();
  states.texture = &tileset;
  target.draw(verticies, states);
}

inside Tile_map::get_current_tile is where the issue is. Maybe a better explanation is the one I gave my friend:
&#9825; aria.: http://www.snorflake.com/u/Wcij.png before moving
&#9825; aria.: get_current_tile should return 1
&#9825; aria.: which it does
&#9825; aria.: http://www.snorflake.com/u/Ok8E.png
&#9825; aria.: after moving
&#9825; aria.: get_current_tile should return 0
&#9825; aria.: but it doesn't, because it's not relative to it's transformation; it returns 1.
 
that chat log is after this test case
Tile_map map{"characters.png", { 32, 32 }, level, 16, 8};
  map.load();
  printf("%d\n", map.get_current_tile({32 * 10, 32 * 6}));
  map.move({ 32 * 2, 32 * 2 });
  printf("%d\n", map.get_current_tile({ 32 * 10, 32 * 6 }));

EDIT: This paticular issue is easily fixed by keeping the map at 0, 0 and using views (http://www.sfml-dev.org/tutorials/2.3/graphics-view.php) but the main question still stands, how can I transform a vector with the opposite of the current getTransform() ?
« Last Edit: May 19, 2016, 10:59:05 am by Miss__Aria »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Quote
the opposite of the current getTransform()
"Opposite" is "inverse" in the matrix world. So:
http://www.sfml-dev.org/documentation/2.3.2/classsf_1_1Transform.php#ab1c033198b0aae8cdb9daa3d3bef3fc1
Laurent Gomila - SFML developer

Miss__Aria

  • Newbie
  • *
  • Posts: 6
    • View Profile
Quote
the opposite of the current getTransform()
"Opposite" is "inverse" in the matrix world. So:
http://www.sfml-dev.org/documentation/2.3.2/classsf_1_1Transform.php#ab1c033198b0aae8cdb9daa3d3bef3fc1

I tried that, it didn't give me the intended result iirc.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Then show what you've tried, so that we can spot your mistake.
Laurent Gomila - SFML developer

Miss__Aria

  • Newbie
  • *
  • Posts: 6
    • View Profile
Then show what you've tried, so that we can spot your mistake.

auto newpos = getTransform().getInverse().transformPoint(position);

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Well, this line just shows that you're calling the function, there's nothing else we can say about it :P

A minimal and complete example, together with the expected and actual results, would be very useful.
Laurent Gomila - SFML developer

Miss__Aria

  • Newbie
  • *
  • Posts: 6
    • View Profile
Well, this line just shows that you're calling the function, there's nothing else we can say about it :P

A minimal and complete example, together with the expected and actual results, would be very useful.

That was a line exerpt from op, take a look at the function and replace the code.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
I know. But your code is far from being mnimal nor complete (read this).

Well, at least tell us what this code produces, and what you expect instead.
Laurent Gomila - SFML developer