So! PBR is great so far. However, I'd love to be able to do a particular thing with it that I'm not sure how to do mathematically.
See, with legacy textures, textures rotate and scale around the center of the texture ...
... however, with PBR, textures rotate and scale around the upper left corner of the texture ...
The offsets also do the same thing: moving along the X-axis moves them in the same direction, but the Y-axis moves the texture up in glTF, and down in legacy!
... and, in PBR but not Legacy, when you set one (but not both) of the Scale values to a negative number, the rotation changes direction!
So, if you want use LSL to set the texture in both glTF and Blinn-Phong (or, I mean, manually either), I have to convert between the two coordinate systems.
When rotation is 0, I have it down pat:
list glTF2LegacyAndBack (vector repeats, vector offsets, float rot, integer isLegacy2glTF)
{
if (repeats.x < 0 == repeats.y < 0)
rot = -rot;
if (rot < 0) rot += TWO_PI;
offsets.x = -offsets.x;
offsets.z = repeats.z = 0;
vector otherOffset;
// Half the difference between "expanded repeat" and "no repeat".
otherOffset.x = (llFabs(repeats.x) - 1) / 2;
otherOffset.y = (llFabs(repeats.y) - 1) / 2;
// Make sure it stays within the range of [0..1)
otherOffset.x = otherOffset.x - (integer)otherOffset.x;
otherOffset.y = otherOffset.y - (integer)otherOffset.y;
if (otherOffset.x < 0) otherOffset.x += 1;
if (otherOffset.y < 0) otherOffset.y += 1;
// Apply the offsets!
// I wrote it as a single function because interestingly enough, it seems that the only difference
// between the two processes (at least when rot == 0) is this exact place: you want to negate
// otherOffset.x when repeats.x is zero when converting from legacy to PBR, and when repeats.x is
// *non*negative when converting PBR to legacy.
if (repeats.x < 0 == isLegacy2glTF)
otherOffset.x = -otherOffset.x;
if (repeats.y < 0)
otherOffset.y = -otherOffset.y;
// ... Okay, what do I do with rot now????
//Constrain it to [0..1) again.
offsets.x = offsets.x - (integer)offsets.x;
if (offsets.x < 0) offsets.x += 1;
offsets.y = offsets.y - (integer)offsets.y;
if (offsets.y < 0) offsets.y += 1;
return [ repeats, offsets, rot ];
}
However, I'm completely at a loss for what to do when rotation is nonzero. I tried simply rotating otherOffset around the Z-axis (in either direction, and both before and after applying the modified offsets), but that didn't work at all; it kept ending up in the wrong spot no matter what I did. Help?