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

Author Topic: Transformable initial state not identity  (Read 1848 times)

0 Members and 1 Guest are viewing this topic.

Groogy

  • Hero Member
  • *****
  • Posts: 1469
    • MSN Messenger - groogy@groogy.se
    • View Profile
    • http://www.groogy.se
    • Email
Transformable initial state not identity
« on: January 27, 2013, 02:20:52 pm »
Was experimenting around a little and while doing my BDD-based tests I noticed a funny thing. It isn't really a bug but it could be quite unexpected if you don't look in sf::Transformable's implementation.

A sf::Transformable that has been newly created with no changes, I would expect it's transform to be identity. It sort of is but because of an implementation detail in C++ and floats this will fail:

entity.transform.should == Transform::IDENTITY

Looking at the matrix inside the transform I get:
[ 1.0,  0.0,  0.0, 0.0,
 -0.0,  1.0,  0.0, 0.0,  
  0.0,  0.0,  1.0, 0.0,
  0.0,  0.0,  0.0, 1.0]

That negative zero comes from when the transform is generated by the sf::Transformable::getTransform function. The value that is causing this is the sys variable.

float sys    = m_scale.y * sine;

The result itself isn't wrong but I just noticed this when doing my behavior specifications tests and I wanted to guarantee that an unmodified entity has a transformation equal to Identity. And no don't come ruining the thread now with "floating point comparison is dangerous". Yes it is but this is for identity which is a constant value and should always be the same. If you fail to compare against identity then something is wrong.

So yeah, posted this here instead of on Github because i don't really find it a bug. But maybe you Laurent are still interested in solving it? Maybe provide a isIdentity() query function or something?
Developer and Maker of rbSFML and Programmer at Paradox Development Studio

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Transformable initial state not identity
« Reply #1 on: January 27, 2013, 02:34:53 pm »
Quote
And no don't come ruining the thread now with "floating point comparison is dangerous". Yes it is but this is for identity which is a constant value and should always be the same.
The identity transform is a constant value, but your entity's transform is not. We could discuss whether the transform should be forced to Transform::Identity until something changes, but then how could I ensure that Transform::Identity is also returned after you call, for example, entity.setPosition(0, 0)? I can't detect that all the transformation components are reset to their initial value, and thus force Transform::Identity. Unless I use fuzzy comparisons for floating point values. But that would cancel your whole argument, and thus this thread ;)

But maybe you had something else in mind? What would you suggest?
Laurent Gomila - SFML developer

Groogy

  • Hero Member
  • *****
  • Posts: 1469
    • MSN Messenger - groogy@groogy.se
    • View Profile
    • http://www.groogy.se
    • Email
Re: Transformable initial state not identity
« Reply #2 on: January 27, 2013, 02:50:41 pm »
Well like I said the current computation is not wrong. And like how it works right now isn't wrong either. And there are never a runtime example of when you want to compare two transformations. I was just thinking to use it for verification that the entity transforms as expected by comparing against constant matrices after I have performed an operation on it to verify the behavior stays the same. But of course not sure of that as well but I'll have to see what makes the specifications look the best. But I thought it was still worth putting this up here if there were any desire to actually fix it since the result you would expect is Identity.

I saw some time ago a matrix implementation that had a isIdentity() function. I thought it was XNA's Matrix implementation but I was wrong and might have been some opengl based math library. But that's like finding a needle in a haystack.

I think also I've seen some old legacy code at work where we kept track of if it was identity or not. But I think that was for optimization purposes and not for solving something like this.

Another possible solution would be to compensate for C++'s float having two different 0's. But like you mentioned this would probably entail comparisons in the getTransform() function for sf::Transformable.
Developer and Maker of rbSFML and Programmer at Paradox Development Studio