Mantis Bug Tracker

View Issue Details Jump to Notes ] Issue History ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0007814opensim[REGION] Script Functionspublic2016-01-15 22:582016-01-16 09:34
Reportermewtwo0641 
Assigned To 
PrioritynormalSeverityminorReproducibilitysometimes
StatusnewResolutionopen 
PlatformOSOS Version
Product Versionmaster (dev code) 
Target VersionFixed in Version 
Summary0007814: Setting a prim's color via script is sometimes slightly off
DescriptionWhen setting a prim's color via llSetColor or llSetPrimitiveParams (or its *Link* variants) the resulting color is sometimes very slightly off compared to the vector input of the function and as well as on SL.
Steps To ReproduceScript:

default
{
    state_entry()
    {
        llSetColor(<0.243137, 0.031373, 0.443137>, ALL_SIDES);
        
        llSay(0, "\n \nllGetColor(): " + (string)llGetColor(ALL_SIDES) + "\nllGetLinkPrimitiveParams(): " + llList2String(llGetLinkPrimitiveParams(LINK_THIS, [PRIM_COLOR,

ALL_SIDES]), 0));
    }
}

1. Run this script in a new prim on both SL and OpenSim (I used latest master for this test) and compare the results

My testing resulted in the following:

SL Results:

Results in an RGB value in the color picker of 62, 8, 113

llGetColor(): <0.24314, 0.03137, 0.44314>
llGetLinkPrimitiveParams(): <0.243137, 0.031373, 0.443137>


OS 0.9.0 Dev Results:

Results in an RGB value in the color picker of 61, 8, 112

llGetColor(): <0.239216, 0.031373, 0.439216>
llGetLinkPrimitiveParams(): <0.239216, 0.031373, 0.439216>
Additional InformationI've also tested on a release version of OpenSim with the same results.
TagsNo tags attached.
Git Revision or version numberMaster
Run ModeStandalone (1 Region) , Standalone (Multiple Regions)
Physics EngineODE, BulletSim
Script Engine
Environment.NET / Windows64
Mono VersionNone
ViewerN/A
Attached Files

- Relationships

-  Notes
(0029971)
melanie (administrator)
2016-01-15 23:03

The issue is caused by the float to int conversion used in SL vs. the one used in OpenSim. I have known about it for a while because it affected the development of the CCS combat system, but never considered it significant.

However, it does exist. Any math wizards may now step forward ;)
(0029973)
mewtwo0641 (reporter)
2016-01-15 23:23

It's a very minor issue admittedly; It came up in the development of a color HUD I was making for someone. I had been scratching my head wondering why the results were slightly different on OS vs. SL. It uses presets that can be read from a notecard in either hex, rgb, or sl format and the hud will convert accordingly to SL color format.

At first I had thought maybe there was an error the the conversion code I wrote and chalked it up to that but then thought it peculiar that SL got the color right on the dot whereas OS would not. So I set out to do some much simpler tests-- My initial tests revealed that setting the color by hand and then using one of the Get functions to output the color would match up fine and that lead me to the realization that the "slightly offness" occurred when setting the color through script functions.

I might take a look at the OS source code and see if I can find anything but I'm definitely no math wizard :)
(0029976)
Mata Hari (reporter)
2016-01-16 04:22

It looks very much as though SL uses round(value*255) whereas Opensim uses (integer)(value*255) which is equivalent to floor(value*255)

Example: the x component in the above script is 0.243137 which, when multiplied by 255 results in 61.999935. SL rounds this to 62, Opensim drops the decimal element.

I don't know where in the code to find it, but that's my guess as to why it's happening. The SL method is correct.
(0029977)
mewtwo0641 (reporter)
2016-01-16 05:32

@Mata - That was a good suggestion, I tried playing around with Math.Round() in the SetColor() method (Located in LSL_Api.cs) in the OS source code

i.e.

texcolor.R = Util.Clip((float)Math.Round(color.x), 0.0f, 1.0f);
...
...
etc.

in order to round the number before casting it to float; but didn't have a whole lot of luck-- The values still came out slightly off.

A quick look at Utils.Clip() tells me that it is returning Math.Min(Math.Max(x, min), max);

So if I read that right I'm getting what ever is the result of Math.Min(Math.Max((float)Math.Round(color.x), 0.0f), 1.0f); ?
(0029978)
Mata Hari (reporter)
2016-01-16 07:43

I'm not a coder, so I can't help you with how it needs to be handled in C#. What happens in LSL (and presumably natively in C#?) is when you cast a float value to an integer it simply drops all decimals and returns the integer part of the value.

ie. if you did any of the following....
(integer)1.01
(integer) 1.5
(integer) 1.99999999999
...the value being returned will always be 1.

When converting a float range of 0.0 to 1.0 to an integer range of 0-255 you would use the LSL code:

vector colourAsFloat;
integer R=llRound(255.0*colourAsFloat.x);
integer G=llRound(255.0*colourAsFloat.y);
integer B=llRound(255.0*colourAsFloat.z);

What appears to be happening based on the values you're reporting is the LSL equivalent of doing

integer wrongR=(integer)(255.0*colourAsFloat.x);
integer wrongG=(integer)(255.0*colourAsFloat.y);
integer wrongB=(integer)(255.0*colourAsFloat.z);

That second method will always return a value that is less representative of the "actual" colour when the 255*value has a decimal component >=0.5.

I don't know what the distinctions/methods are in C# but that would appear to be the issue.
(0029981)
Seth Nygard (reporter)
2016-01-16 09:34

Although not perfect, one simple way to achieve a reasonable 4/5 rounding is to add 0.5 to any float value that is being cast or converted to an integer. The truncated value will then be what is generally expected from 4/5 rounding rules. Anything less than 0.5 remains the original whole number value, while anything over is the whole number decimal value +1.

If we take the above example and add 0.5 to each number then the result is closer to what we expect to see ...
(integer)(1.01+0.5) will be 1
(integer)(1.5+0.5) will be 2
(integer)(1.99999999999+0.5) will be 2
(integer)(1.45+0.5) will be 1

- Issue History
Date Modified Username Field Change
2016-01-15 22:58 mewtwo0641 New Issue
2016-01-15 23:03 melanie Note Added: 0029971
2016-01-15 23:23 mewtwo0641 Note Added: 0029973
2016-01-16 04:22 Mata Hari Note Added: 0029976
2016-01-16 05:32 mewtwo0641 Note Added: 0029977
2016-01-16 07:43 Mata Hari Note Added: 0029978
2016-01-16 09:34 Seth Nygard Note Added: 0029981


Copyright © 2000 - 2012 MantisBT Group
Powered by Mantis Bugtracker