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

Author Topic: What is this black magic thou speak of?  (Read 4249 times)

0 Members and 1 Guest are viewing this topic.

Weeve

  • Jr. Member
  • **
  • Posts: 87
  • C++ Programmer (Intermediate), 3D Artist (Skilled)
    • View Profile
    • Email
What is this black magic thou speak of?
« on: February 04, 2013, 01:59:33 am »
If a sf::Transform is a matrix, then its an odd one, since it contains position, but the position numbers are already filled in when I use sf::Sprite.getTransform(), another odd aspect is, not only the position is filled in, but it was the inverse of the object's matrix, at least the result was the inverse of what I expected when I used sf::Transform.transformPoint, whether that function inverted it, or it was inverted from .getTranform I don't know, but it needs looking into, inverse calculations are expensive on matrices. Also, perhaps weirder, when I use sf::Transform.getInverse(), then use the inverted matrix for the transformPoint() call I expected it to act as a world-space to object-space transformation, instead, I got a weird number, either aroun -3000 or +3000 on the x and y axis, when the distance between the two for each axis is only about 400-900;

I would like to know what the black magic of sf::Transform is, and why it is so difficult to use, and if there is a way I can just get a 2x2 matrix, like, two sf::Vector2<float>'s or (float,float,float,float)? or can someone give me the correct order of transformations to go from global space to object space(origin at sprite origin, same for rotation)?
Long live rapid project development! -- Kestrel3D Game-Engine nearing completion

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: What is this black magic thou speak of?
« Reply #1 on: February 04, 2013, 08:02:45 am »
Caml down... if it doesn't work as expected then show your code -- a complete and minimal one please, not your full project where 99% of the code is irrelevant.

Quote
If a sf::Transform is a matrix, then its an odd one, since it contains position
A NxN matrix is able to contain non-linear transformations for N-1 space. That's why a 3x3 matrix can contain translation components in 2D. That's also why you always deal with 4x4 matrices in 3D.

Quote
but the position numbers are already filled in when I use sf::Sprite.getTransform()
Uh? What else would you expect?
Laurent Gomila - SFML developer

Weeve

  • Jr. Member
  • **
  • Posts: 87
  • C++ Programmer (Intermediate), 3D Artist (Skilled)
    • View Profile
    • Email
Re: What is this black magic thou speak of?
« Reply #2 on: February 05, 2013, 09:32:58 pm »
you can see if I did anything wrong, but explaining what the function does will probably be easier, :) I'm not used to matrices with another row/column other than their orientation, explanation on how inverse() and transformPoint(), and getTransform() handle the position(and maybe they handle scale too, instead of just scaling the orientation?) coordinates would help alot  :D

bool Window::FishyCollision(MainFish* Fishy, EnemyFish* Fish){
        if (Fish->_Scale > Fishy->_Scale){
                // code here works
        }else{
                // invert the transform, sp that when applied, world coordinates of EnemyFish
                // become relative coordinates to MainFish
                sf::Transform transform = Fishy->_Sprite.getTransform().getInverse();
                // set up corners of the EnemyFish, hard-coded numbers are positions in the image
                // where the bounding box is
                sf::Vector2<float> Min = transform.transformPoint(sf::Vector2<float>(12,6)*Fish->_Scale+Fish->_MinCornerPos);
                sf::Vector2<float> Max = transform.transformPoint(sf::Vector2<float>(240,94)*Fish->_Scale+Fish->_MinCornerPos);
                sf::Vector2<float> C1 = transform.transformPoint(sf::Vector2<float>(12,94)*Fish->_Scale+Fish->_MinCornerPos);
                sf::Vector2<float> C2 = transform.transformPoint(sf::Vector2<float>(240,6)*Fish->_Scale+Fish->_MinCornerPos);
                // set up corners of the Main Fish
                sf::Vector2<float> FishyMin = sf::Vector2<float>(12,6)*Fishy->_Scale;
                sf::Vector2<float> FishyMax = sf::Vector2<float>(240,94)*Fishy->_Scale;
                /* check corners against each other, in a simple smaller-lesser than check, this part was omitted
                 at this point, FishyMin, and FishyMax are as expected, but the corners of EnemyFish are
                 definitely way off, so maybe I did something wrong in applying the ransformation,
                 there is too much unexplained on how the matrix handles it's position coordinates,
                 so guessing what I did wrong is near impossible, I gave it expected numbers, but got weird
                 effects, MainFish corner coordinates are at origin of the upper left corner, EnemyFish corner
                 coordinates are at origin 0,0 being global
                */

        }
        return false;
}
 
Long live rapid project development! -- Kestrel3D Game-Engine nearing completion

krzat

  • Full Member
  • ***
  • Posts: 107
    • View Profile
Re: What is this black magic thou speak of?
« Reply #3 on: February 05, 2013, 09:59:40 pm »
Use FloatRect's intersects method.
SFML.Utils - useful extensions for SFML.Net

Weeve

  • Jr. Member
  • **
  • Posts: 87
  • C++ Programmer (Intermediate), 3D Artist (Skilled)
    • View Profile
    • Email
Re: What is this black magic thou speak of?
« Reply #4 on: February 05, 2013, 10:05:44 pm »
I don't want to use rectangle intersections :-)

possible problem: transform's element 12 and 13 are off by 2,700 and 400 respectively, I suspect those are position elements of the transformation, that maybe your inverse() function messed with?
Long live rapid project development! -- Kestrel3D Game-Engine nearing completion

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: What is this black magic thou speak of?
« Reply #5 on: February 05, 2013, 10:37:58 pm »
Maybe you need to read more about matrices, there's nothing special in SFML, just the regular matrix operations that you can find in all other graphics libraries. Nothing fancy. And of course everything has widely been tested and works perfectly.

I asked for a complete and minimal code, in bold characters, because I can't help you with this small piece of code. It will take ages before we understand each other 100%. Please write a new simple code, that shows your problem and only it. No need to have fishes in it ;)

And while you do this, I'll try to guess what your problem is: your transform is the inverse transform of an entity, therefore it converts world coordinates to the local coordinate system of the entity. But what you transform doesn't look like world coordinates ((12, 6), (240, 94)), it rather looks like it is local to the other entity. Am I right?

And please explain what you're trying to do. I understand that you're checking collision but I don't understand how. Why don't you simply check the two AABB against each other?

sf::FloatRect FishBounds = Fish->_Sprite.getGlobalBounds();
sf::FloatRect FishyBounds = Fishy->_Sprite.getGlobalBounds();
bool intersects = FishBounds.intersects(FishyBounds);
« Last Edit: February 05, 2013, 10:43:05 pm by Laurent »
Laurent Gomila - SFML developer

Weeve

  • Jr. Member
  • **
  • Posts: 87
  • C++ Programmer (Intermediate), 3D Artist (Skilled)
    • View Profile
    • Email
Re: What is this black magic thou speak of?
« Reply #6 on: February 06, 2013, 01:34:05 am »
its global, the hard-coded numbers, multiplied by the scale factor results in local, plus the top-left hand corner position, resulting in global, I was wanting to see if I could program my own collision detection, just for the fun of it, but I guess its tome for me to give up and just use your functions. and as far as math, I have 3 large books next to me that I have been reading through for about a year on three dimensional space and linear mathematics :) I'm learning. my problem, was how to recognize when sfml's matrix is using its position coordinates (I would expect that transformPoint() would be a simple matrix multiplication, at origin 0,0; but was wrong)
Long live rapid project development! -- Kestrel3D Game-Engine nearing completion

Weeve

  • Jr. Member
  • **
  • Posts: 87
  • C++ Programmer (Intermediate), 3D Artist (Skilled)
    • View Profile
    • Email
Re: What is this black magic thou speak of?
« Reply #7 on: February 06, 2013, 01:56:14 am »
specifically when I added a SetScale call, as my fishes have :-)

is this what you meant by minimal?
int main(){
        sf::Sprite A;
        A.setScale(0.5,0.5);
        A.setPosition(640,640);
        sf::Sprite B;
        B.setPosition(320,320);
        sf::Transform transform = A.getTransform().getInverse();
        sf::Vector2<float> P = transform.transformPoint(B.getPosition());
        std::cout << P.x << ", " << P.y <<"\n";//Outputs '-640,-640'
        return 0;
}
 
Long live rapid project development! -- Kestrel3D Game-Engine nearing completion

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: What is this black magic thou speak of?
« Reply #8 on: February 06, 2013, 08:10:28 am »
Yes, thank you :)

Now we can work on a very simple base that we both understand, and which doesn't depend on a bigger project.

If A is scaled by x0.5 and translated by (640, 640), what is the inverse transformation? Obviously, without even calculating it, you can see that it will be a translation by (-640, -640) followed by a x2 scale:

P = (320, 320)

// add (-640, -640)
P = (-320, -320)

// multiply by 2
P = (-640, -640)

It's easy to understand, and we haven't talked about matrices or computed anything to demonstrate it.

What result did you expect from this code, and why?
Laurent Gomila - SFML developer

Weeve

  • Jr. Member
  • **
  • Posts: 87
  • C++ Programmer (Intermediate), 3D Artist (Skilled)
    • View Profile
    • Email
Re: What is this black magic thou speak of?
« Reply #9 on: February 06, 2013, 05:07:03 pm »
I expected -320,-320 because I didn't know you applied scale to your result, I had thought that the result was measured in pixels as a unit, and not a relative, but ty :D multiplying the result by scale fixed it

in the future, can I just have access to raw matrix data, its a-lot easier for me to make my own functions that I know exactly how work, maybe like a getMatrix()? ;)
Long live rapid project development! -- Kestrel3D Game-Engine nearing completion

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: What is this black magic thou speak of?
« Reply #10 on: February 06, 2013, 07:10:40 pm »
in the future, can I just have access to raw matrix data, its a-lot easier for me to make my own functions that I know exactly how work, maybe like a getMatrix()?
Guess how the sf::Transform method is called that gives you access to the matrix :P
Just take a look at the documentation.

But it sounds silly to re-implement functionality that is already available in SFML. You should rather use the existing interface and build your own layer on top of it (unless something is really not possible).
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: What is this black magic thou speak of?
« Reply #11 on: February 06, 2013, 07:34:21 pm »
I may be wrong of course, but my feeling is that you don't understand everything about transformations, and try to do complicated things that could be done very easily with the right algorithms (and with already available functions).

The scale is of course included in the transform, as well as the position. And pixels or units have nothing to do with that. Transforms (matrices) are a way to switch from one coordinate system to another. What you need to do when doing collision detection, is to transform bounding boxes to a common coordinate system, and then compare them. You don't need to care about translations, scales or rotations (the transform could include many other types of transformations -- they are just different ways to define the final matrix). So, I really don't understand what you're trying to do, but I'm pretty sure that you're doing it wrong.

If you want, you can explain us what you do, and why you think you need these complicated stuff. Then maybe we can spot what's wrong in your reasoning, and hopefully show you the right way to do what you want :)
Laurent Gomila - SFML developer

Weeve

  • Jr. Member
  • **
  • Posts: 87
  • C++ Programmer (Intermediate), 3D Artist (Skilled)
    • View Profile
    • Email
Re: What is this black magic thou speak of?
« Reply #12 on: February 08, 2013, 08:20:31 pm »
I want to do a simple collision between two sprites, one is rotated, other is not. My logic was, take bounding box coordinates(in the future, will use a bounding polygon), transform them to the coordinate space of my rotated sprite, then do a simple smaller than/greater than check if the points are inside of the bounding box.

Where I was having issues, is understanding how exactly sfml was doing everything, if I had access the the exact matrix data, I would implement it in my way, which would be: subtrace centre position from point, perform matrix multiplication, add relative position of sprite back to point, perform collision detect.

The reason I didn't want to use sfml's bounding box check, is that I plan on having a more complicated check in the future, like a bounding polygon, or a triangle seperation of the image, or whichever is my want at that point, and I find it easier to write my own functions for everything, commonly called "re-inventing the wheel", as it will eventually further my education, and lend some experience to areas in programming I sorely need.
Long live rapid project development! -- Kestrel3D Game-Engine nearing completion

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: What is this black magic thou speak of?
« Reply #13 on: February 08, 2013, 08:54:03 pm »
Quote
My logic was, take bounding box coordinates(in the future, will use a bounding polygon), transform them to the coordinate space of my rotated sprite, then do a simple smaller than/greater than check if the points are inside of the bounding box.
I don't think it's a good strategy: if you have a rotated rectangle and an aligned one, you will never have both aligned, whatever coordinates system you transform them to. You don't make things simpler by doing what you do.

Quote
Where I was having issues, is understanding how exactly sfml was doing everything
SFML does things the standard way. So if you don't understand SFML transformations, you probably need to read and practice more with transforms and matrices.

Quote
I find it easier to write my own functions for everything, commonly called "re-inventing the wheel", as it will eventually further my education, and lend some experience to areas in programming I sorely need.
I agree, re-inventeing the wheel is good for learning, I'd even say it's necessary at some point ;)

But don't invent everything from scratch, there are well known algorithms for every use case. For OBB vs OBB, which is a special case of convex vs convex, you should use the separating axis theorem.
Laurent Gomila - SFML developer