// Bento Avatar Gelenk-Tester
// Steuerung über Chat-Befehle
// Liste der wichtigsten Bento-Gelenke
list BENTO_JOINTS = [
"mPelvis", "mTorso", "mChest", "mNeck", "mHead",
"mHipLeft", "mHipRight", "mKneeLeft", "mKneeRight",
"mAnkleLeft", "mAnkleRight", "mFootLeft", "mFootRight",
"mToeLeft", "mToeRight",
"mCollarLeft", "mCollarRight", "mShoulderLeft", "mShoulderRight",
"mElbowLeft", "mElbowRight", "mWristLeft", "mWristRight",
"mHandLeft", "mHandRight",
// Finger links
"mThumbLeft", "mThumbLeft01", "mThumbLeft02",
"mIndexLeft", "mIndexLeft01", "mIndexLeft02",
"mMiddleLeft", "mMiddleLeft01", "mMiddleLeft02",
"mRingLeft", "mRingLeft01", "mRingLeft02",
"mPinkyLeft", "mPinkyLeft01", "mPinkyLeft02",
// Finger rechts
"mThumbRight", "mThumbRight01", "mThumbRight02",
"mIndexRight", "mIndexRight01", "mIndexRight02",
"mMiddleRight", "mMiddleRight01", "mMiddleRight02",
"mRingRight", "mRingRight01", "mRingRight02",
"mPinkyRight", "mPinkyRight01", "mPinkyRight02",
// Zusätzliche Bento-Gelenke
"mEyeLeft", "mEyeRight", "mJaw",
"mTail01", "mTail02", "mTail03",
"mEarLeft", "mEarRight",
"mWingLeft", "mWingRight"
];
// Aktuelle Einstellungen
integer current_joint_index = 0;
rotation current_rotation = ZERO_ROTATION;
vector current_position = <0,0,0>;
key avatar_id = NULL_KEY;
// Hilfsfunktion zum Anwenden der Animation
update_animation()
{
if(avatar_id == NULL_KEY) return;
string joint = llList2String(BENTO_JOINTS, current_joint_index);
// Setze Rotation und Position für das aktuelle Prim (Root oder Link)
llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_ROT_LOCAL, current_rotation, PRIM_POSITION, current_position]);
llSetText("Joint: " + joint + "\nRot: " + (string)llRound(llRot2Angle(current_rotation) * RAD_TO_DEG) + "°\nPos: " + (string)current_position, <1,1,1>, 1.0);
llSetText("Joint: " + joint + "\nRot: " + (string)llRound(llRot2Angle(current_rotation) * RAD_TO_DEG) + "°\nPos: " + (string)current_position, <1,1,1>, 1.0);
}
default
{
state_entry()
{
llOwnerSay("Bento Avatar Tester gestartet");
llOwnerSay("Befehle:");
llOwnerSay("/1 [jointname] - Wähle Gelenk (z.B. '/1 mHead')");
llOwnerSay("/1 next - Nächstes Gelenk");
llOwnerSay("/1 prev - Vorheriges Gelenk");
llOwnerSay("/1 list - Zeige alle Gelenke");
llOwnerSay("/1 rot X Y Z - Rotation in Grad (z.B. '/1 rot 0 90 0')");
llOwnerSay("/1 pos X Y Z - Position in Metern");
llOwnerSay("/1 reset - Setze Gelenk zurück");
llOwnerSay("/1 clear - Lösche alle Overrides");
llListen(1, "", llGetOwner(), "");
// Setze Text
llSetText("Bento Tester\nWarte auf Avatar...", <1,1,0>, 1.0);
}
on_rez(integer param)
{
llResetScript();
}
touch_start(integer total_number)
{
avatar_id = llDetectedKey(0);
llOwnerSay("Avatar erkannt: " + llKey2Name(avatar_id));
update_animation();
}
listen(integer channel, string name, key id, string message)
{
list parts = llParseString2List(message, [" "], []);
string cmd = llList2String(parts, 0);
if(cmd == "next")
{
current_joint_index = (current_joint_index + 1) % llGetListLength(BENTO_JOINTS);
current_rotation = ZERO_ROTATION;
current_position = ZERO_VECTOR;
update_animation();
llOwnerSay("Aktuelles Gelenk: " + llList2String(BENTO_JOINTS, current_joint_index));
}
else if(cmd == "prev")
{
current_joint_index = (current_joint_index - 1 + llGetListLength(BENTO_JOINTS)) % llGetListLength(BENTO_JOINTS);
current_rotation = ZERO_ROTATION;
current_position = ZERO_VECTOR;
update_animation();
llOwnerSay("Aktuelles Gelenk: " + llList2String(BENTO_JOINTS, current_joint_index));
}
else if(cmd == "list")
{
llOwnerSay("Verfügbare Gelenke:");
integer i;
for(i = 0; i < llGetListLength(BENTO_JOINTS); i++)
{
llOwnerSay(" " + (string)i + ": " + llList2String(BENTO_JOINTS, i));
}
}
else if(cmd == "rot")
{
if(llGetListLength(parts) >= 4)
{
float x = (float)llList2String(parts, 1) * DEG_TO_RAD;
float y = (float)llList2String(parts, 2) * DEG_TO_RAD;
float z = (float)llList2String(parts, 3) * DEG_TO_RAD;
// Konvertiere zu Quaternion (Reihenfolge: Z, Y, X für Euler)
current_rotation = llEuler2Rot(<x, y, z>);
update_animation();
llOwnerSay("Rotation gesetzt auf: " + llList2String(parts, 1) + "° " +
llList2String(parts, 2) + "° " + llList2String(parts, 3) + "°");
}
}
else if(cmd == "pos")
{
if(llGetListLength(parts) >= 4)
{
float x = (float)llList2String(parts, 1);
float y = (float)llList2String(parts, 2);
float z = (float)llList2String(parts, 3);
current_position = <x, y, z>;
update_animation();
llOwnerSay("Position gesetzt auf: " + (string)current_position);
}
}
else if(cmd == "reset")
{
current_rotation = ZERO_ROTATION;
current_position = ZERO_VECTOR;
update_animation();
llOwnerSay("Gelenk zurückgesetzt");
}
else if(cmd == "clear")
{
// Setze Rotation und Position zurück
current_rotation = ZERO_ROTATION;
current_position = ZERO_VECTOR;
update_animation();
llOwnerSay("Alle Gelenk-Positionen zurückgesetzt");
}
else if(cmd == "help")
{
llOwnerSay("Befehle:");
llOwnerSay("/1 [jointname] - Wähle Gelenk (z.B. '/1 mHead')");
llOwnerSay("/1 next - Nächstes Gelenk");
llOwnerSay("/1 prev - Vorheriges Gelenk");
llOwnerSay("/1 list - Zeige alle Gelenke");
llOwnerSay("/1 rot X Y Z - Rotation in Grad");
llOwnerSay("/1 pos X Y Z - Position in Metern");
llOwnerSay("/1 reset - Setze Gelenk zurück");
llOwnerSay("/1 clear - Lösche alle Overrides");
}
else
{
// Versuche Gelenkname direkt zu setzen
integer index = llListFindList(BENTO_JOINTS, [cmd]);
if(index != -1)
{
current_joint_index = index;
current_rotation = ZERO_ROTATION;
current_position = ZERO_VECTOR;
update_animation();
llOwnerSay("Gelenk ausgewählt: " + cmd);
}
else
{
llOwnerSay("Unbekannter Befehl. Tippe '/1 help' für Hilfe.");
}
}
}
}