I wanna pick the color

Friday, December 7, 2007

In taking the kart color concept a bit further, we spent some time last night working on a color picker GUI. You can see the results of our work in this video.

ZeroGear color picker from marshmonkey on Vimeo

Now here is why this is cool. We did this using Navi + Lua. The C++ framework only needed slight modifications. I feel this was done extremely quick and has a nice, clean result. Here is how we did it.

We got the color picker html + javascript code from here.

And here is the part that I added to the color picker javascript:

function HSVupdate(v)
  var tempColor = HSV=v?v:slideHSV;
  v = hsv2hex(tempColor);


  $ND('HandleEvent', {LUAFUNC: 'SetKartColor', Color: v}).send();


This function is called whenever the user changes the color in the GUI. The line that starts with "$ND" is the message from the Navi GUI to Lua. "$ND" is the javascript code included with Navi that sends the message. "HandleEvent" is the function that Navi calls in C++ and LUAFUNC is the Lua function that "HandleEvent" will call when this event happens. "SetKartColor" is the name of the Lua function and it is passed the new color as a parameter.

Here is that Lua function:

function SetKartColor(guiArgs)

  local colorValue = GetNaviMultiValue(guiArgs, "Color")
  local color = colorValue:str()
  local colorNum = hex.to_dec("0x" .. color)

  local red = bit.brshift(colorNum, 16) / 255
  local green = bit.brshift(colorNum, 8)
  green = bit.band(green, 255) / 255
  local blue = bit.band(colorNum, 255) / 255
  local alpha = 1
  kart:SetColor(red, green, blue, alpha)


It is basically just a conversion function. The javascript code gives the color as a hex value in this format "4499FF". So I do some conversion with this lua bit library to get the color as red, green, and blue float values to pass to the C++ code.

And here is the SetColor C++ code that changes the color of the kart:

void OGREPlayerKart::SetColor(float red, float green, float blue, float alpha)
  Ogre::Entity * testEnt = kart->GetEntity();
  for (unsigned int i = 0; i <>getNumSubEntities(); i++)
    Ogre::SubEntity * testSubEnt = testEnt->getSubEntity(i);
    Ogre::MaterialPtr testMatPtr = testSubEnt->getMaterial();
    Ogre::Technique * testTech = testMatPtr->getBestTechnique();
    Ogre::Pass * testPass = testTech->getPass("ColorTweak");
    Ogre::TextureUnitState * testTUS = testPass->getTextureUnitState("ColorTweak");
    testTUS->setColourOperationEx(Ogre::LBX_BLEND_TEXTURE_ALPHA, Ogre::LBS_MANUAL, Ogre::LBS_CURRENT,     Ogre::ColourValue(red, green, blue, alpha), Ogre::ColourValue(1, 1, 1, 1), 0);

This C++ function is where I want to improve. I want to support changing colors on different parts of the player and karts (shirt, skin, paint, windshield, whatever). Also, different karts will have different parts that you can change the color of.

As you can see, this was all done in only a few lines of code. I bet you can see how easy something like a color picker is when you are using HTML/JS/CSS and Lua for your GUI.


Sargent Lovemuffin said...

tidy and neat- I love how fluid this is and the nearly infinite shades within shades- easy to understand (the program that is- I don't know WHAT's going on with that codes stuff- it's all geek to me).