Here is a screenshot of my mockup environment.
The positions would be numbered 0-63. The starting location would be 0. Touch the green button and the piece would move to the next position.
The first problem is to find the size of the board. Since it is the root object it's pretty easy to find. To note, if it's not the root prim you are screwed and it is very difficult, and I'll talk about that in the next post. The size (PRIM_SIZE) is the actual size of the object in meters. When calculating the location on that prim with local coordinates, the origin is at the center of the prim.
list params = llGetPrimitiveParams([PRIM_SIZE]);
vector sz = llList2Vector(params,0);
Next is to calculate the x and y row and column. This is also very simple given there are 8 rows and 8 columns.
integer px = curPos / 8;
integer py = curPos % 8;
I then calculate the size of each square and save it.
float sqr_x_size = sz.x / 8;
float sqr_y_size = sz.y / 8;
Once you have all that it is fairly straight forward to calculate the location of that square, but look at all the comments and see how many tests I went through to get it right. Tons of experimentation here.
//llOwnerSay(" sqr_x_size="+(string)sqr_x_size+" sqr_y_size="+(string)sqr_y_size);
vector p = < (sqr_x_size * px) - (sz.x/2) + (sqr_x_size/2),
(sqr_y_size * py) - (sz.y/2) + (sqr_y_size/2),
0.051 >;
//vector p = < (sqr_x_size * px) - (sz.x/2),
// (sqr_y_size * py) - (sz.y/2),
// 0.1 >; // the position without centering on the square
//vector p = < sz.x/2, sz.y/2, 0.1 >; // the origin
//vector p = < -sz.x/2, -sz.y/2, 0.1 >; // the negative origin - this didn't work
//vector p = <0,0,0.1>; // the 0,0 location which is the center of the board
//vector p = <(sqr_x_size/2),(sqr_y_size/2),0.1>; // just a futile experiement to offset from the origin some amount
//llOwnerSay(" new pos = "+(string)p); // the debug message seen over and over and over again
Given all that, the actual calculation that I used can be summed up like this.
For x: The location given the x location minus the offset because the origin is the center + the offset of half a square to center on the square.
For y: Same as x
For z: Just a number which I twiddled to get right.
The last step is to set the actual location. This is pretty simple given that you know the link num for the piece you want to move. This number was retrieved on initialization. After that, change curPos and wait for the next touch.
llSetLinkPrimitiveParams(pieceLinkNum,[PRIM_POSITION,p]);
curPos++;
And yes, this was more work, but as I expected it will be a lot more efficient and easier to work with in the long run.