ソラマメブログ

2008年07月30日

Puppeteer もどき 作ってみよう(その13)

とりあえず言っていたものを作ってみた
-----
コントローラから 2つのスクリプトを起動する(一方の script_id を 2 にし 同じ本体スクリプトを 2つ入れておく)
-----
ついでに というかこっちの方が手間ではあったんだけど 圧縮するとき位置のデータ 8 ビットで取ってたが それを 10 ビットに変更した
-----
これだと 1m ぐらいずらしても 1mm 単位で大丈夫そう
-----
というわけでリストも上げておきます < ざっと作ってみただけなので 制御方法はもう少し考えてみる必要あり(script_id が 1 の場合のみコマンドを受け入れるようにし タッチでの start/stop はコントローラを起動することにし コントローラもタイマーで制御すべきだろう... ということで この後 もう 1回は要改造 ^^)
-----
まずはコントローラから
//
// File: Animator_Controller.lsl
// Date Author number of nodes
// 2008/7/30 walkinglint 25
//
float delay;
integer num_of_script = 2;
integer script_id = 1;
integer num_of_notecard;
string notecard_name;
integer LOAD_PLAY1 = 5;
integer LOAD_PLAY2 = 6;
default {
state_entry() {
while (TRUE) {
delay = 60.0 + llFrand(60);
num_of_notecard = llGetInventoryNumber(INVENTORY_NOTECARD);
notecard_name = llGetInventoryName(INVENTORY_NOTECARD, llFloor(llFrand(num_of_notecard)));
if (script_id == 1) {
llMessageLinked(LINK_THIS, LOAD_PLAY1, notecard_name, "");
llOwnerSay("load playing script 1 with " + notecard_name);
script_id = 2;
} else {
llMessageLinked(LINK_THIS, LOAD_PLAY2, notecard_name, "");
llOwnerSay("load playing script 2 with " + notecard_name);
script_id = 1;
}
llSleep(delay);
}
}
on_rez(integer param) {
llResetScript();
}
}
次に本体
//
// File: Animator3.lsl
// Date Author number of nodes
// 2008/7/30 walkinglint 298
// 2008/7/29 walkinglint 277
// 2008/7/29 walkinglint 239 (Animator2->Animator3)
// 2008/7/29 walkinglint 239
// 2008/7/28 walkinglint 232
// 2008/7/27 walkinglint 202
// 2008/7/26 walkinglint 199
// 2008/7/26 walkinglint 179 (Animator->Animator2)
// 2008/7/26 walkinglint 179
// 2008/7/25 walkinglint 377
// 2008/7/21 walkinglint 374
// 2008/7/19 walkinglint 374
//
integer script_id = 1;
float delay_to_stop_recording = 0.5;
integer GET_POSE = 1;
integer SET_POSE = 2;
integer DO_POSE = 3;
integer LOAD_PLAY1 = 5;
integer LOAD_PLAY2 = 6;
integer STOP1 = 7;
integer STOP2 = 8;
integer size_of_record = 4; // duration, link_num, rot, pos
list seq0 = [];
integer num_of_seq;
list cur_seq;
integer cur_seq_num;
float cur_duration;
integer cur_link_num;
integer cur_rotation;
integer cur_position;
string preset_notecard_name = "anim seq";
string notecard_name;
integer read_line;
key query_id;
integer is_animating = FALSE;
integer i;
integer num_of_prim;
integer pose_num;
integer handle;
integer is_recording = FALSE;
integer play_once = FALSE;
integer output_load_message = FALSE;
integer from_load_play = FALSE;
get_record() {
cur_link_num = llList2Integer(cur_seq, 1);
cur_rotation = llList2Integer(cur_seq, 2);
cur_position = llList2Integer(cur_seq, 3);
}
float update_cur_seq_and_get_duration() {
cur_seq = llList2List(seq0, cur_seq_num * size_of_record, (cur_seq_num + 1) * size_of_record - 1);
if (++cur_seq_num > num_of_seq) {
cur_seq_num = 0;
}
return llList2Float(cur_seq, 0);
}
dump() {
llSay(0, "Dump Animation");
dump_body();
}
dump_body() {
string line = "";
integer l = llGetListLength(seq0);
integer line_per_chat = 10;
integer cnt = 0;
for (i = 0; i < l; i += size_of_record) {
integer link = llList2Integer(seq0, i + 1);
string comment = " // " + llGetLinkName(link);
cnt++;
if (cnt >= line_per_chat) {
line += (string)llList2Float(seq0, i) + ":" + (string)link + ":"
+ (string)llList2Integer(seq0, i + 2) + ":" + (string)llList2Integer(seq0, i + 3) + comment;
llSay(0, line);
cnt = 0;
line = "";
} else {
line += (string)llList2Float(seq0, i) + ":" + (string)link + ":"
+ (string)llList2Integer(seq0, i + 2) + ":" + (string)llList2Integer(seq0, i + 3) + comment
+ "\n";
}
}
if (llStringLength(line) != 0) {
llSay(0, line);
}
}
first() {
llSay(0, "First Animation");
num_of_seq = llGetListLength(seq0) / size_of_record;
cur_seq_num = 0;
llSetTimerEvent(1.0);
play_once = TRUE;
}
load() {
output_load_message = TRUE;
load_body(preset_notecard_name);
}
load_body(string note) {
seq0 = [];
notecard_name = note;
read_line = 0;
pose_num = 1;
if (output_load_message) {
llSay(0, "Loading " + notecard_name + " ...");
llOwnerSay("free memory = " + (string)llGetFreeMemory());
}
query_id = llGetNotecardLine(notecard_name, read_line);
}
next() {
llSay(0, "Next Animation");
num_of_seq = llGetListLength(seq0) / size_of_record;
llSetTimerEvent(1.0);
play_once = TRUE;
}
play() {
llSay(0, "Starting Animation");
num_of_seq = llGetListLength(seq0) / size_of_record;
play_body();
if (!play_once) {
is_animating = TRUE;
}
}
play_body() {
cur_seq_num = 0;
llSetTimerEvent(1.0);
}
publish() {
llSay(0, "Publish Animation");
dump_body();
llListenRemove(handle);
}
record() {
stop_body();
is_recording = TRUE;
llMessageLinked(LINK_ALL_CHILDREN, GET_POSE, "", NULL_KEY);
}
reset() {
llSay(0, "Reset Animation");
seq0 = [];
pose_num = 1;
}
stop() {
llSay(0, "Stop Animation");
stop_body();
}
stop_body() {
llSetTimerEvent(0.0);
is_animating = FALSE;
}
default {
state_entry() {
llSetTimerEvent(0.0);
handle = llListen(32, "", "", "");
pose_num = 1;
}
touch_start(integer total_number) {
is_animating = !is_animating;
if (is_animating) {
play();
} else {
stop();
}
}
listen(integer channel, string name, key id, string message) {
if ((message == "dump") || (message == "print")) {
dump();
} else if (message == "first") {
first();
} else if ((message == "load") || (message == "load")) {
load();
} else if (message == "next") {
next();
} else if ((message == "play") || (message == "replay") || (message == "start")) {
play();
} else if (message == "publish") {
publish();
} else if (message == "record") {
record();
} else if ((message == "reset") || (message == "clear")) {
reset();
} else if (message == "stop") {
stop();
}
}
timer() {
if (is_recording) {
llSay(0, "Recorded snapshot: " + (string)pose_num);
pose_num++;
llSetTimerEvent(0.0);
is_recording = FALSE;
integer l = llGetListLength(seq0);
seq0 = llListReplaceList((seq0 = []) + seq0, [1.0], l - size_of_record, l - size_of_record);
} else {
integer max_count = 0;
while ((cur_duration = update_cur_seq_and_get_duration()) == 0.0) {
get_record();
if (llGetAttached()) {
llMessageLinked(cur_link_num, SET_POSE, (string)cur_rotation + ":"
+ (string)cur_position + ":" + (string)llGetLocalRot(), NULL_KEY);
} else {
llMessageLinked(cur_link_num, SET_POSE, (string)cur_rotation + ":"
+ (string)cur_position, NULL_KEY);
}
if (++max_count > num_of_seq) {
llSetTimerEvent(0.0);
return ;
}
}
get_record();
if (llGetAttached()) {
llMessageLinked(cur_link_num, SET_POSE, (string)cur_rotation + ":"
+ (string)cur_position + ":" + (string)llGetLocalRot(), NULL_KEY);
} else {
llMessageLinked(cur_link_num, SET_POSE, (string)cur_rotation + ":"
+ (string)cur_position, NULL_KEY);
}
llMessageLinked(LINK_ALL_CHILDREN, DO_POSE, "", NULL_KEY);
if (play_once) {
llSetTimerEvent(0.0);
play_once = FALSE;
} else {
llSetTimerEvent(cur_duration);
}
}
}
dataserver(key queryid, string data) {
if (queryid == query_id) {
if (data != EOF) {
// process data
integer l = llSubStringIndex(data, "//");
if (l == 0) {
data = "";
} else if (l != -1) {
data = llGetSubString(data, 0, l - 1);
}
if (llStringLength(data) != 0) {
integer l = llSubStringIndex(data, ":");
float delay = (float)llGetSubString(data, 0, l - 1);
seq0 = (seq0 = []) + seq0 + delay;
if (delay != 0.0) {
pose_num++;
}
data = llGetSubString(data, l + 1, llStringLength(data) - 1);
l = llSubStringIndex(data, ":");
seq0 = (seq0 = []) + seq0 + (integer)llGetSubString(data, 0, l - 1);
data = llGetSubString(data, l + 1, llStringLength(data) - 1);
l = llSubStringIndex(data, ":");
seq0 = (seq0 = []) + seq0 + (integer)llGetSubString(data, 0, l - 1);
data = llGetSubString(data, l + 1, llStringLength(data) - 1);
seq0 = (seq0 = []) + seq0 + (integer)data;
}
read_line++;
query_id = llGetNotecardLine(notecard_name, read_line);
} else {
num_of_seq = llGetListLength(seq0) / size_of_record;
cur_seq_num = 0;
if (output_load_message) {
llSay(0, "Loading " + notecard_name + "(" + (string)(pose_num - 1) + " snapshot) complete.");
llOwnerSay("free memory = " + (string)llGetFreeMemory());
output_load_message = FALSE;
}
if (from_load_play) {
if (script_id == 1) {
llMessageLinked(LINK_THIS, STOP2, "", "");
} else {
llMessageLinked(LINK_THIS, STOP1, "", "");
}
play_body();
}
}
}
}
link_message(integer sender_num, integer num, string str, key id) {
if (num == GET_POSE) {
llSetTimerEvent(0.0);
float delay = 0.0;
integer l = llSubStringIndex(str, ":");
string rot_str = llGetSubString(str, 0, l - 1);
string pos_str = llGetSubString(str, l + 1, llStringLength(str) - 1);
seq0 = (seq0 = []) + seq0 + [delay, sender_num, (integer)rot_str, (integer)pos_str];
llSetTimerEvent(delay_to_stop_recording);
} else if (((num == LOAD_PLAY1) && (script_id == 1)) || ((num == LOAD_PLAY2) && (script_id == 2))) {
output_load_message = FALSE;
from_load_play = TRUE;
load_body(str);
} else if (((num == STOP1) && (script_id == 1)) || ((num == STOP2) && (script_id == 2))) {
if (script_id == num) {
stop_body();
}
}
}
}
最後に子プリムに入れるもの
//
// File: Animator_Probe3.lsl
// Date Author number of nodes
// 2008/7/30
//
integer GET_POSE = 1;
integer SET_POSE = 2;
integer DO_POSE = 3;
rotation rot;
string tmp_str;
rotation root_rot;
vector pos;
integer rot2int(rotation rot) {
integer x = (integer)llFloor(rot.x * 100.0);
integer y = (integer)llFloor(rot.y * 100.0);
integer z = (integer)llFloor(rot.z * 100.0);
integer s = (integer)llFloor(rot.s * 100.0);
return (integer)(((x & 0xff) << 24) | ((y & 0xff) << 16) | ((z & 0xff) << 8) | (s & 0xff));
}
rotation int2rot(integer i) {
rotation rot;
rot.x = (float)((i & 0xff000000) >> 24) / 100.0;
rot.y = (float)(((i & 0xff0000) << 8) >> 24) / 100.0;
rot.z = (float)(((i & 0xff00) << 16) >> 24) / 100.0;
rot.s = (float)(((i & 0xff) << 24) >> 24) / 100.0;
return rot;
}
integer vec2int(vector vec) {
integer x = (integer)llFloor(vec.x * 1000.0);
integer y = (integer)llFloor(vec.y * 1000.0);
integer z = (integer)llFloor(vec.z * 1000.0);
return (integer)(((x & 0x3ff) << 20) | ((y & 0x3ff) << 10) | (z & 0x3ff));
}
vector int2vec(integer i) {
vector vec;
vec.x = (float)(((i & 0x3ff00000) << 2) >> 22) / 1000.0;
vec.y = (float)(((i & 0xffc00) << 12) >> 22) / 1000.0;
vec.z = (float)(((i & 0x3ff) << 22) >> 22) / 1000.0;
return vec;
}
default {
link_message(integer sender_num, integer num, string str, key id) {
if (num == GET_POSE) {
integer int_rot = rot2int(llGetLocalRot());
integer int_pos = vec2int(llGetLocalPos());
llMessageLinked(1, GET_POSE, (string)int_rot + ":" + (string)int_pos, NULL_KEY);
} else if (num == SET_POSE) {
integer l = llSubStringIndex(str, ":");
rot = int2rot((integer)llGetSubString(str, 0, l - 1));
if (llGetAttached() == 0) {
pos = int2vec((integer)llGetSubString(str, l + 1, llStringLength(str) - 1));
rot = rot / llGetRootRotation();
} else {
tmp_str = llGetSubString(str, l + 1, llStringLength(str) - 1);
l = llSubStringIndex(tmp_str, ":");
pos = int2vec((integer)(llGetSubString(tmp_str, 0, l)));
root_rot = (rotation)llGetSubString(tmp_str, l + 1, llStringLength(tmp_str) - 1);
rot = rot / root_rot;
}
} else if (num == DO_POSE) {
llSetPrimitiveParams([PRIM_POSITION, pos, PRIM_ROTATION, rot]);
}
}
}

同じカテゴリー(walking のスクリプティング講座)の記事
 プロフィール写真の表示に問題 (2009-11-30 20:55)
 ミニ太陽系 (2009-03-21 06:03)
 関数から文字列を返したら何か問題になる? (2009-03-18 18:02)
 llListFindList って型って関係ないんだったっけ (2009-03-18 14:02)
 夏時間(PDT)の実験 (2009-03-08 22:04)
 15パズルの作り方(その3) (2009-03-08 06:03)
上の画像に書かれている文字を入力して下さい
 
<ご注意>
書き込まれた内容は公開され、ブログの持ち主だけが削除できます。