This problem has been driving me crazy for over a week now, so perhaps someone here can lend me a few brain cells.
I am trying to set the rotation of a texture on the face of a prim using llSetLinkPrimitiveParamsFast while maintaining its aspect ratio.
When the rotation is 0°, the long side of the prim face should have a texture repeat of 1, and the short side of the prim face should have a repeat short/long. As the the texture is rotated I would like it maintain its aspect ratio. This requires that I change the horizontal and vertical repeats to account for the texture rotation.
I have a partial solution that works for the cardinal directions (0, 90, 180, 270). But the texture becomes distorted as it rotates between these points. How do I maintain the aspect ratio of the texture as it is rotated?
Here are some images that demonstrate what I'm seeing.
The texture rotation at 0 and 90 degrees.
Texture rotation at 45 and 22.5 degrees.
And here is my code so far
fixTexture()
{
list params = llGetLinkPrimitiveParams(LINK_THIS, [
PRIM_TEXTURE, 0
]);
string texture = "90cd268c-d657-0b36-238c-5e39ed7929c4"; //llList2String(params, 0);
vector repeats = <1, 1, 0>; // actual repeats calculated below.
vector offsets = llList2Vector(params, 2);
float zrot = llList2Float(params, 3);
rotation texture_rot = llEuler2Rot(<0, 0, zrot>);
vector dims = llGetScale(); // we want the X/Y of the prim
dims.z = 0; // we don't care about z.
// The larger dim determines our actual number of repeats.
// I want 1 repeat across the larger of X or Y, the other
// is some fraction of 1.
if (dims.x > dims.y)
repeats.y = dims.y / dims.x;
else if (dims.y > dims.x)
repeats.x = dims.x / dims.y;
// this is what's missing *something*
// It works at the cardinal points (0, 90, 180, 270), but
// stretches in between. Wost distortion at 22.5
repeats = repeats * texture_rot;
repeats.x = llFabs(repeats.x);
repeats.y = llFabs(repeats.y);
//llOwnerSay("repeats now: " + (string)repeats);
llSetLinkPrimitiveParamsFast(LINK_THIS, [
PRIM_TEXTURE, 0, texture, repeats, offsets, zrot
]);
integer degrees = (integer)(zrot * RAD_TO_DEG);
llSetText((string)degrees + "°\n" +
(string)repeats, <1,1,1>, 1);
}
integer STARTED = FALSE;
default
{
state_entry()
{
STARTED = TRUE;
llSetTimerEvent(0.1);
}
touch_start(integer total_number)
{
fixTexture();
STARTED = !STARTED;
if (STARTED)
llSetTimerEvent(0.1);
else
llSetTimerEvent(0);
}
timer()
{
fixTexture();
}
}