[fixed]toSColor() not accurate

You discovered a bug in the engine, and you are sure that it is not a problem of your code? Just post it in here. Please read the bug posting guidelines first.
Post Reply
Virion
Competition winner
Posts: 2148
Joined: Mon Dec 18, 2006 5:04 am

[fixed]toSColor() not accurate

Post by Virion »

I realize currently Irrlicht's SColorf to SColor conversion isn't very accurate

example:

I set an SColor's RGB values to 1, 2, 3 (small value to test out accuracy) and it saves 3 of these values into f32 when saving scene, resulting 0.003922, 0.007843, 0.011765

When I load back the scene using loadScene(), I get 1, 1, 3 instead of 1, 2, 3... I have to grab those RGB values to fill in the GUI form for my level editor and I want it to be precise. I realized that if I use Irrlicht's built-in toSColor() function it doesn't round off the decimals.

I've tested it by manually *255 for each of the f32 value
0.003922*255 = 1.00011
0.007843*255 = 1.999965
0.011765*255 = 3.000075

should be 1, 2, 3 but it gives me 1, 1, 3...
Lonesome Ducky
Competition winner
Posts: 1123
Joined: Sun Jun 10, 2007 11:14 pm

Post by Lonesome Ducky »

It's a precision error I believe, irrlicht can't be more accurate than the floating point that holds the values. EDIT: Oh are you talking about the rounding down instead of up?
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Post by CuteAlien »

Thanks, nice catch. I suppose using core::round_ instead might be the better option (a little slower...). Maybe the same in getInterpolated and in SColorHSL::toRGB1. Although I'm not sure if it's worth the speed-hit in getInterpolated (then again getInterpolated also seems to waste some time on clamping a value). Also not sure right now if we should fix this for 1.7.2 or 1.8 (is this is a bug or does that count as changing behavior?).

Anyway - I think we should change it, but I'm waiting a day or two in case anyone else has some feedback.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Halifax
Posts: 1424
Joined: Sun Apr 29, 2007 10:40 pm
Location: $9D95

Post by Halifax »

The speed increase would be minimal, but I don't think that core::round_ should be used. The behavior of a cast from a positive floating-point value to an unsigned integer is truncation i.e. floor. So I think an explicit addition of 0.5 should be added. core::round_ adds 0.5 to value, casts it to a 64-bit unsigned integer, performs a floor on the value, and then finally casts it to a 32-bit floating-point value.
TheQuestion = 2B || !2B
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

The proper call would probably be round32. Using library calls is always better than doing it manually in the code.
Virion
Competition winner
Posts: 2148
Joined: Mon Dec 18, 2006 5:04 am

Post by Virion »

for now i can do it manually for the values that I get from getShadowColor(), getAmbientLight() etc. but I realize that getFog only returns u32 values and no f32 so I couldn't convert it. maybe i'll just wait for the update.
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Post by CuteAlien »

Ok, I have used round32 and changed it in the 1.7 svn branch.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Post Reply