jueves, 7 de junio de 2007

Rotaciones locales y posicion relativa (Capitulo 1)

En muchas ocasiones nos podemos encontrar con el tremendo dolor de cabeza que supone obtener las coordenadas locales de destino en función de las coordenadas del prim principal de un objeto y de su correspondiente rotación.

Una cosa es clara, cuando esas coordenadas van a aplicarse a un prim que pertenece al mismo linkset la solucion es bien sencilla y sin necesidad de andar con calculos y reconversiones, como por ejemplo la apertura de una puerta en una casa, dicha puerta pertenece al mismo linkset de toda la casa, así que la forma sencilla y sin complicaciones es crear un script en el propio prim de la puerta y q sea algo así

default{
    touch(integer param){
        llOwnerSay("rot = " + (string)llGetLocalRot());
        llOwnerSay("pos = " + (string)llGetLocalPos());
    }
}











Explicacion
default{todos los scripts deben contener esta declaración de estado, es obligatoria
touch(integer param){lo contenido dentro de este evento se disparará cada vez que un avatar pulse sobre el objeto
llOwnerSayorden que interpreta el script para enviar un mensaje que solo el dueño del objeto pueda leer, este mensaje saldrá por defecto de color verde en el chat general
"rot = " y "pos = "cadena literal, el llOwnerSay lo dirá tal cual aparezca
(string)función de reconversión de formatos, llOwnerSay, llSay, llShout, ll Whisper y llInstantMessage sólo aceptan mensajes con formato String (cadena de caracteres) por tanto cuando se desee mostrar una variable cuyo tipo no sea "string" habrá q realizar dicha reconversión
+concatenación o suma, si se "suman" sctring, realmente se concatenan( "a" + "b" = "ab") si se suman valores numericos (integer, float...), realizará la consabida suma
llGetLocalRotfuncion que obtiene la rotación del prim hijo respecto a la rotacion el prim principal de un objeto, es decir, la rotación del prim hijo siempre será la misma independientemente de la rotación del todo el conjunto del objeto, esta función solo es válida si el objeto no tiene las propiedades físicas activadas
llGetLocalPosfuncion que cumple semejante cometido a llGetLocalRot, pero en esta ocasion, para averiguar las coordenadas de posicion


Una vez guardado este script, basta con ubicar la puerta y pulsar sobre ella, nos llegarán dos mensajes uno con la posicion y otro con la rotacion relativas segun el prim principal del objeto... volvemos a ubicar y girar la puerta y volvermos a pulsar, y obtenemos de nuevo sendos datos con ligeras variaciones, una vez se tengan, pues ya se aplica el script que convenga como por ejemplo


// coordenadas y rotaciones de ejemplo, poner los valores correctos
rotation rotacionpuertacerrada = <1,0,0,1>;
rotation rotacionpuertaabierta = <0,1,0,1>;
vector posicionpuertacerrada = <1,1,1>;
vector posicionpuertaabierta = <2,2,2>;
integer abierto = FALSE;
default{
    touch(integer param){
        if (abierto){
            llSetLocalRot( rotacionpuertacerrada );
            llSetPos( posicionpuertacerrada );
            abierto = FALSE;
        }else{
            llSetLocalRot( rotacionpuertaabierta );
            llSetPos( posicionpuertaabierta );
            abierto = TRUE;
        }
    }
}









Explicacion
rotation rotacionpuertacerrada = <1,0,0,1>;declaración de variable de tipo rotation, nombre de variable y su valor, las rotaciones son parecidas a los vectores, pero tienen un valor más, al asignar un valor a una variable rotation hay q asegurarse que no se trate de una string
vector posicionpuertacerrada = <1,1,1>;declaración de variable de tipo vector
integer abierto = FALSE;declaración de una variable de tipo integer, y asignando el valor FALSE, las variables de tipo integer también admiten los valores TRUE y FALSE, que no dejan de ser los valores 1 y 0 respectivamente, en muchas ocasiones se utiliza TRUE y FALSE para que se pueda entender mejor el script
if (abierto){esto es un if, una condicion, dado que se está usando los valores TRUE y FALSE, no es necesario comparar el entero con nada, pues si su valor es TRUE (verdadero) entrará dentro de la condicion, si es falso, pasará al "else" en cayo que lo haya
llSetLocalRot( rotacionpuertacerrada );esta función es semejante a llGetLocalRot, pero en este caso, en vez de devolver un valor "rotation" realmente aplica al prim la rotación que se le diga, esta rotación es relativa a la rotación del prim principal.
llSetPos( posicionpuertacerrada );IMPORTANTE, hasta el momento NO existe la funcion llSetLocalPos... realmente la funcion llSetPos aplica la posicion que se le pase a un prim, si este es el prim principal, la posicion será en función a las coordenadas de la region (sim), si el prim es un prim hijo de un objeto, dicha posicion será el sumatorio respecto a las coordenadas del prim principal


Explicación detallada de llSetPos:
si la orden llSetPos está en un script dentro de un prim principal (u objeto de un solo prim) entonces las coordenadas de destino serán respecto a la region entera, eso está claro, pero si dicha orden está contenida en el script de un prim hijo, el destino de dicho prim hijo será el resultado de la suma de las coordenadas del prim principal más las coordenadas q se le pasen, y teniendo siempre en cuenta que al tratarse de un prim hijo, la orientacion de todo el objeto tb influye en el destino

por ejemplo, estamos trabajando en un objeto y queremos q una puerta deslizante (como las que hay en los supermercados) se mueva 1,5 metros respecto al eje LOCAL y, pues entonces la función será llSetPos(<0,1.5,0>) siempre y cuando esa puerta forme parte del mismo linkset y no sea un objeto independiente esa puerta funcionará correctamente aunque el "supermercado" cambie de orientación, pues para la puerta, su eje y siempre será el mismo independientemente el eje y de la region... en caso q la puerta sea un objeto independiente pues ya se aplicaría las coordenadas de la region como por ejemplo llSetPos(<195,230,45>) y siempre teniendo en cuenta los ejes de desplazamiento x y z de la region.

No hay comentarios: