Rang: Ehrenmitglied
Mitglied seit: 05.09.2014(UTC) Beiträge: 84  Wohnort: Tulln und Rostock Dankte: 1 mal(e)
|
Mit diesem Skript kann ein sitzender Avatar (indem er mit einem Klick ein Menü aufruft) seine Position und Rotation mit den Pfeiltasten ändern. Code:
integer iMODE_ADJUST_POS = 1; //Mode: adjust position.
integer iMODE_ADJUST_ROT = 2; //Mode: adjust rotation.
integer iMODE_ADJUST_NONE = 0; //Mode: exited all adjust-modes.
integer iMODE_ADJUST = iMODE_ADJUST_NONE; //Global storage of adjust-mode.
key kAVATAR = NULL_KEY; //Global storage of avatar-key.
string sDialogText = "Please choose an option (use page-up/page-down and up/down-keys to adjust the position):";
string sButton_Adjustpos = "Adjust pos"; //Dialog-text.
string sButton_Adjustrot = "Adjust rot";
string sButton_Exit = "Exit edit";
integer iChannel = -240897; //Dialog-channel.
vector vROTATION = ZERO_VECTOR; //Global pos/rot. !!Initial sittarget-values here!
vector vPOS = ZERO_VECTOR;
float fOffsetPos = 0.1; //Offset for adjustment (1 single step). Meters.
float fOffsetRot = 5; //Offset for adjustment (1 single step). Degrees.
UpdateSitTarget(vector pos, rotation rot)
{//Using this while the object is moving may give unpredictable results.
llSitTarget(pos, rot);//Set the sit target
//We need to make the position and rotation local to the current prim
rotation localrot = ZERO_ROTATION;
vector localpos = ZERO_VECTOR;
if(llGetLinkNumber() > 1)//only need the local rot if it's not the root.
{
localrot = llGetLocalRot();
localpos = llGetLocalPos();
}
vector size = llGetAgentSize(llAvatarOnSitTarget());
//<0.008906, -0.049831, 0.088967> are the coefficients for a parabolic curve that best fits real avatars. It is not a perfect fit.
float fAdjust = ((((0.008906 * size.z) + -0.049831) * size.z) + 0.088967) * size.z;
llSetLinkPrimitiveParamsFast(llGetNumberOfPrims(),
[PRIM_POS_LOCAL, (pos + <0.0, 0.0, 0.4> - (llRot2Up(rot) * fAdjust)) * localrot + localpos,
PRIM_ROT_LOCAL, rot * localrot]);
}
makeDialog()
{ //Display a dialog with adjust/exit-options.
list lBUTTONS;
if (iMODE_ADJUST != iMODE_ADJUST_NONE)
{ //Currently adjusting, add 'exit'-button.
lBUTTONS = [sButton_Exit];
}
lBUTTONS += [sButton_Adjustrot, sButton_Adjustpos];
llDialog(kAVATAR, sDialogText, lBUTTONS, iChannel);
}
adjust(integer imode)
{ //Adjust pos/rot.
vector vr = vROTATION;
vector vp = vPOS;
if (iMODE_ADJUST == iMODE_ADJUST_NONE)
{ //Not adjusting. Return.
return;
}
if (imode == CONTROL_FWD)
{
vr = vr + <0.0, fOffsetRot, 0.0>;
vp = vp + <fOffsetPos, 0.0, 0.0>;
}
if (imode == CONTROL_BACK)
{
vr = vr + <0.0, -fOffsetRot, 0.0>;
vp = vp + <-fOffsetPos, 0.0, 0.0>;
}
if (imode == CONTROL_ROT_LEFT)
{
vr = vr + <-fOffsetRot, 0.0, 0.0>;
vp = vp + <0.0, fOffsetPos, 0.0>;
}
if (imode == CONTROL_ROT_RIGHT)
{
vr = vr + <fOffsetRot, 0.0, 0.0>;
vp = vp + <0.0, -fOffsetPos, 0.0>;
}
if (imode == CONTROL_UP)
{
vp = vp + <0.0, 0.0, fOffsetPos>;
}
if (imode == CONTROL_DOWN)
{
vp = vp + <0.0, 0.0, -fOffsetPos>;
}
if (iMODE_ADJUST == iMODE_ADJUST_POS)
{ //Change onnly pos.
vr = vROTATION; //Reset local value.
vPOS = vp; //Update global.
}
else
{ //Change only rot.
vp = vPOS; //Reset local value.
vROTATION = vr; //Update global.
}
UpdateSitTarget(vp, llEuler2Rot(vr*DEG_TO_RAD)); //Update
}
default
{
state_entry()
{
UpdateSitTarget(vPOS, llEuler2Rot(vROTATION * DEG_TO_RAD)); //Set initial sittarget-values.
llListen(iChannel, "", "", "");
}
listen(integer channel, string name, key id, string message)
{
if (id == kAVATAR)
{
if (message == sButton_Adjustpos)
{
iMODE_ADJUST = iMODE_ADJUST_POS;
}
else if (message == sButton_Adjustrot)
{
iMODE_ADJUST = iMODE_ADJUST_ROT;
}
else if (message == sButton_Exit)
{
iMODE_ADJUST = iMODE_ADJUST_NONE;
}
}
}
touch_start(integer num_detected)
{
if (llDetectedKey(0) == kAVATAR)
{
makeDialog(); //Show dialog.
}
}
changed(integer change)
{
if (change & CHANGED_LINK)
{
if(llGetObjectPrimCount(llGetKey()) < llGetNumberOfPrims())
{ //Avatar sitting.
kAVATAR = llGetLinkKey(llGetNumberOfPrims()); //Store key.
UpdateSitTarget(vPOS, llEuler2Rot(vROTATION * DEG_TO_RAD)); //Set initial sittarget-values.
llRequestPermissions(kAVATAR, PERMISSION_TAKE_CONTROLS);
}
else
{ //Avatar unsat.
llReleaseControls();
iMODE_ADJUST = iMODE_ADJUST_NONE; //Reset mode.
kAVATAR = NULL_KEY;
}
}
}
control(key id, integer level, integer edge)
{
if (level & edge)
{ //Key press
if ((level & CONTROL_FWD) || (edge & CONTROL_FWD))
{
adjust(CONTROL_FWD);
}
if ((level & CONTROL_BACK) || (edge & CONTROL_BACK))
{
adjust(CONTROL_BACK);
}
if ((level & CONTROL_ROT_LEFT) || (edge & CONTROL_ROT_LEFT))
{
adjust(CONTROL_ROT_LEFT);
}
if ((level & CONTROL_ROT_RIGHT) || (edge & CONTROL_ROT_RIGHT))
{
adjust(CONTROL_ROT_RIGHT);
}
if ((level & CONTROL_UP) || (edge & CONTROL_UP))
{
adjust(CONTROL_UP);
}
if ((level & CONTROL_DOWN) || (edge & CONTROL_DOWN))
{
adjust(CONTROL_DOWN);
}
}
}
run_time_permissions(integer perm)
{
if (perm & PERMISSION_TAKE_CONTROLS)
{
llTakeControls(CONTROL_FWD | CONTROL_BACK | CONTROL_ROT_LEFT | CONTROL_ROT_RIGHT | CONTROL_UP | CONTROL_DOWN, TRUE, FALSE);
}
}
}
|
It is the mark of an educated mind to be able to entertain a thought without accepting it. |