ソラマメブログ
QRコード
QRCODE
※カテゴリー別のRSSです
アクセスカウンタ
読者登録
メールアドレスを入力して登録する事で、このブログの新着エントリーをメールでお届けいたします。解除は→こちら
現在の読者数 1人
プロフィール
Hitomi Magne
Hitomi Magne
ヌーディスト件ダンサーです。Susukinoによく出没します
オーナーへメッセージ

  

Posted by at

2009年03月31日

サーバのバグっぽい

llRezObjectについての問題
https://jira.secondlife.com/browse/SVC-3145

1.グループ所有の土地の設定でグループでもRez不可にしている。
2.グループの役割でRez可の人がいる。
まあ、お店などでコアスタッフだけがRez可とか、よくある形態だと思いますが、この条件が揃ったとき、

3.llRezObject()関数が、オブジェクトのオーナー(Rez権限あり)がINしていないと失敗する

ということになっています。
私がママやってるDanceBar CCでは、お客様にドリンクをお渡しするときに失敗して床にめりこんだりすることを防ぐために、グループRez不可にしていたのですが、ステージの特殊装置でダンサーが踊っているときにその足元からパーティクルを出す装置が、クリエイターのnaonao2ちゃんがINしていないと動作しないという不思議な事態に陥っていまして。いろいろ調べていてこの情報を見つけました。このパーティクル発生器はダンサーの位置からパーティクルを出すために、透明プリムをRezしていたのですが、それが上記の理由で失敗していたわけです。

しょうがないので土地の設定をグループRez可にしました。失敗した飲み物はまめにリターンするしかないですねー。

jiraに上がっていること、わりと最近このような動作になったという事から、バグと考えられますので、いずれ直るかもしれません。
  


Posted by Hitomi Magne at 19:53Comments(1)LSL

2009年01月20日

追跡型チップジャーは重いか

最近仕事を始めたSusukinoの DanceBar CCでは、スタッフの頭上に浮かぶ追跡型チップジャーを使っています。しかし一秒間隔で特定スタッフの位置を判定し、その頭上に移動するというスクリプトなので、これがSIMに負荷をかけるのではないかと心配になりました。実際夜になると結構重いし。
LSL Portalでも
・短く、頻繁にtimerをかける。(5秒以内)
というスクリプトは劣悪なものとされています。
重さに影響するのは短い間隔のタイマーとアバターの位置特定、オブジェクトの移動というあたりと仮定して、簡単なテストをしてみました。
まず、あらかじめ表示→統計情報を出しておきます。

default
{
state_entry()
{
llSetTimerEvent(1);
}

touch_start(integer total_number)
{
llSay(0, "Touched.");
}
timer()
{
list l = llGetObjectDetails(llGetOwner(),[OBJECT_POS]);
vector apos = llList2Vector(l,0);
apos.z = apos.z+1.5;
llSetPos(apos);

}
}

このスクリプトをファントムの箱に入れて、箱をどんどんコピーします。25個くらい作りましたが、全部頭上に重なってるので一個にみえます(笑)。
この前後で統計情報のTime Dilationや Sim FPSを注視してみましたが、ほとんど変化がありませんでした。

木の箱二十数個を引き連れて歩く私ww

もちろん、これだけでOKとはいえませんが、1秒間隔のタイマーを動かしているオブジェクトが20個やそこら同時に動いていたからといって、ただちに高負荷となるわけではなさそうです。  


Posted by Hitomi Magne at 18:03Comments(2)LSL

2008年11月25日

UNICODE表示プリム高速版


以前のバージョンだと1024 x 1024サイズのテクスチャに1024文字ずつ収納していましたが、あれだとテクスチャの読み込みに時間がかかって、電光掲示板のような用途では読み込まれる前に流れてしまったりしてしまいました。
一つの解決策はテクスチャを縦横半分に縮小してしまうことですが、これをすると文字が圧縮されて読みづらくなってしまうんですね。16x16ドットあればよさそうなものですが、テクスチャとして使用するとアンチエイリアスがかかってぼやけるため、カクカクしたままぼけるということになってしまいます。
というわけで、もう一つの解決策、512 x 512のテクスチャに縦横16文字ずつ、計256文字を収録するという方をやってみます。いままでこれをためらっていたのは、テクスチャの枚数が4倍になってしまうからです。合計163枚、アップロード料金実に1630L$を支払い(間違ったテクスチャを「大量アップロード」してしまい、途中であわててビューアを終了させたりしたので、実際はもっとかかっています><)えいやっと実行。
ついに完成しました。テクスチャ選択関数の行数が163行以上になってしまうので、これを手でUUIDのコピー、ペースト、数値の書き換えなんてやってたらいつまでかかるか分からないし、ちょっとした書き間違いを発見できなくなってしまうので、半自動でここを行うことにしました。

適当なプリムに、アップロードしたテクスチャを全部入れます。テクスチャの名前は
0000-00ff
0100-01ff
という具合に、開始コードポイント、終了コードポイントを16進で書いて、間を"-"でつなげたものです。そして以下のスクリプトを入れます。

string hexc="0123456789ABCDEF";
list textures;
string int2hex(integer x)
{
integer x0 = x & 0xF;
string res = llGetSubString(hexc, x0, x0);
x = (x >> 4) & 0x0FFFFFFF; //otherwise we get infinite loop on negatives.
while( x != 0 )
{
x0 = x & 0xF;
res = llGetSubString(hexc, x0, x0) + res;
x = x >> 4;
}
return "0x"+ res;

}
default
{

touch_start(integer total_number)
{
integer num=llGetInventoryNumber(INVENTORY_TEXTURE);
integer i;
string s;
key k;
string ks;
string st;
string ed;
list tmp;
string output;
textures=[];
llSay(0,"------"+(string)num+"-----");
for (i=0; i<num; i++){
s = llGetInventoryName(INVENTORY_TEXTURE, i);
k= llGetInventoryKey(s);
ks = (string)k;
tmp= llParseString2List(s, ["-"],[]);
st = llList2String(tmp,0);
ed = llList2String(tmp,1);
textures+=[(integer)("0x"+st)];
textures+=[ks];
}
textures=llListSort(textures, 2 ,TRUE);
integer start;
for (i=0; i<num*2; i+=2){
start=llList2Integer(textures,i);
st = int2hex(start);
ed = int2hex(start+255);
ks = llList2String(textures,i+1);
llSay(0,"if (code >= "+ st +" && code <= " + ed +" ) return [ " + st + ",\""+ks+"\" ];");

}
}
}


このプリムをタッチすれば、中に入れたテクスチャを調べてUUIDを抽出し、コードの形で喋ってくれます。チャットウィンドウでこれをコピーして、チャット行の頭の時刻とオブジェクト名をエディタで消してしまえばOK。というわけで、以下、改造版文字表示プリムのスクリプトです。  続きを読む


Posted by Hitomi Magne at 14:46Comments(1)LSL

2008年11月21日

文字コードを取得する方法。

LSLでは、文字コードを得る関数は用意されていないのですが、llStringToBase64()でBase64にエンコードし、llBase64ToInteger()で数値に変換することができます。ところが、llBase64ToInteger()には問題があって、4Byteの数値になる長さ(エンコード状態で6Byte)のBase64文字列以外では正しい結果を返しません。ひらがなの"あ"をエンコードすると"44GC"となり、日本語文字列はうまく6Byteにすることはできません。実際にどういう結果になるか見てみると。
"あ"→"E3818200"
"a"→"6100F612"
といった感じの結果になります。他の文字についても調べてみると、どうやら左詰めで正しい変換結果が入り、余ったバイトには無意味な数値が入っているようです。ということは、余ったバイトは無視して左から必要なバイト数だけ取り出せば問題ないはずです。

SLでの文字コードはUTF-8で、左から順に検査すれば文字コードの長さは求まりますのでこの方法でUTF-8をUCS-2に変換して返す関数を作りました。この関数は一度に一文字しか受け付けませんので、呼び出し元で文字列を一文字ずつ取り出して使用する必要があります。



integer toUnicode(string c) //Accept one unicode character only.
{
string s= llStringToBase64(c);
integer n= llBase64ToInteger(s);
//
// n contains UTF-8 character code with 'Left to Right order'.
// We accept only 2 byte unicode m so it was only 1 to 3 byte UTF-8.
//
if ((n & 0x80000000) == 0) return ((n & 0x7f000000) >>24);
if ((n & 0xe0000000) == 0xc0000000) return ((n & 0x1f000000) >>18) | ((n & 0x003f0000)>>16);
if ((n & 0xf0000000) == 0xe0000000) return ((n & 0x0f000000) >>12) | ((n & 0x003f0000) >>10) | ((n & 0x00003f00) >>8);
return 32; // else return space code.
}



UTF-8では一文字4byteまで使う可能性があるのですが、この場合3byteまでの変換のみを行っています。4byteUTF-8に対応する場合、もう一行増やす必要があります。現在はUTF-8 3byteを越えるものは32(空白)を返すようになっています。UTF-8 3byteの範囲で、基本的な文字(16bitであらわせる範囲)は含まれていますので、実用上はこれでなんとかなるはずです。JIS第三、第四水準の文字をすべて扱いたいという場合は4byte UTF-8に対応する必要があります。  


Posted by Hitomi Magne at 15:25Comments(0)LSL

2008年11月20日

電光掲示板とかホワイトボードとか


上はJ-CASTニュースを拾ってきて右から左に表示する電光掲示板、下は各国語対応のホワイトボードです。

電光掲示板のニュース取得方法は外部サーバに置いたPHPスクリプトを使用していますので、SL内で完結したものにはできていません。もう、ほんとllHTTPRequestの使えなさって><…

ところで、電光掲示板は右から左に文字が流れていくのですが、当初のスクリプトではあちこちの文字がバラバラと切り替わるのが表示されて、結果的に非常に読みにくいものになっていました。実質読めないといってもいい感じ。下のホワイトボードみたいに静的なものならそれでもいいんですけど、動かしちゃうと、一部の文字が先に左に行き、一部は少し遅れってのがあちこち重なると、まじで読めません。表示部分の抜本的な対策が必要でした。   続きを読む


Posted by Hitomi Magne at 23:47Comments(0)LSL

2008年11月17日

UNOCODEなんでも表示プリム

黒板の作者さんが、MITライセンスで配布したのかどうか、LSLコンベンションが終わってしまった今では分からないのですが、とりあえず探しても見つからなかったので…
やってみたらできちゃったface03

日本語

韓国語

中国語
私偉い。天才かもwww  続きを読む


Posted by Hitomi Magne at 19:10Comments(0)LSL

2008年11月16日

黒板のスクリプトって…

すっかりおなじみになった黒板ですが、あれって、どうやってるのか考えると眠れなくなります。

XyzzyTextをもとにして日本語対応してるらしいけど、どうやって??
XyzzyTextの基本を少し。
一つの立方体プリムをぐにぐに変形させて、正面に立方体の6面のうち5面を並べます。この段階で「ぎゃー」っていいたくなるけど、これは序の口。
文字列を分解して頭から一文字ずつ表示するわけだけど、ここに文字を表示するためには、文字のテクスチャが必要です。一文字ずつテクスチャにしてたら、英数記号だけでもアップロード料金が100L$くらいかかっちゃうので、一枚のテクスチャに文字を並べたものを作ってるわけですね。テクスチャの表示位置や倍率を調整して、目的の文字だけを目的の面に表示するわけです。

1プリムに10文字表示可能なバージョンはまたえらいことをしていて、ありうる二文字の組み合わせを全部並べたテクスチャを作っているのですが、それはまた別の話。

英数字だけなら、そこそこ高解像度にしてもテクスチャ一枚とかでいけちゃうんです。実際はテクスチャの効率も考えて、あまり大きくないテクスチャ数枚に分けているようですが。

で、日本語を出すとなると、数千文字は必要なわけです。
SLで使えるテクスチャの最大サイズは1024×1024。
一文字のサイズを32×32ドットにすれば、1024文字一つのテクスチャに入ります。
JIS第一水準は約3000文字ですから、三枚のテクスチャでほぼカバーできます。
これくらいなら許容範囲ですけど、問題はLSLの文字コードがユニコードだってことなんですね。ユニコードって、日本と中国と韓国の漢字を全部並べていて、JIS漢字コードとは全然互換性ないんです。日本で分類されたJIS第一水準とかは適当に統合漢字の中にちらばっています。だからユニコードのままでテクスチャ作ろうとしたら漢字だけで約二万字、テクスチャ20枚位作ってアップロードする必要があります。

じゃあ、JISコードの配列のテクスチャ作ってユニコードからJISコードに変換すればいいんじゃないかと思うでしょうが、ユニコードからJISコードへの変換テーブルのサイズがでっかくなっちゃいます。Integerのリストを作ったとして、32ビットの数字を2万個入れるリストが必要なので、8万バイト、ってことは約72kb必要なわけです。Monoになって拡張されたといえ、スクリプト一個の使えるメモリは最大64kbですから、これじゃ足りません。

いったいどうやってるんだろう…  


Posted by Hitomi Magne at 14:35Comments(0)LSL

2008年11月03日

ラジオ:曲名の日本語表示


成功!!
こちらのPHPコードをほぼそのままパクって、文字コード変換を仕込みました。


<?php

if ( isset ($_GET['url']) ) {
$url=$_GET['url'];
$port=$_GET['port'];
} else {
return;
}



$fp = @fsockopen ($url, $port, $errno, $errstr,1);
header ("Content-type: text/html; charset=utf-8");

if (!$fp)
{
echo "Connection refused"; // Diaplays when sever is offline
}
else
{
fputs($fp, "GET /7.html HTTP/1.0\r\nUser-Agent: Mozilla\r\n\r\n");
while ( !feof($fp) )
{
$info = fgets($fp);
}
$info = str_replace ( '</body></html>' , "" , $info );
$split = explode ( ',' , $info);
if ( empty ( $split [6] ) )
{
echo "The current song is not available"; // Displays when sever is online but no song title
}
else
{
$title = str_replace ( '\'' , '`' , $split[6] );
$title = str_replace ( ',' , ' ' , $title );
$title = mb_convert_encoding( $title , "UTF-8" , "auto" );
echo "$title"; // Diaplays song
}
}
?>



こんな感じ。プレイリストから抽出したshoutcastのストリーミングサーバのURLから、"http://"を削除したものを?url=で投げてやれば曲名を返します。port番号は別個に指定しなくても、urlに含まれる形(xxx.xxx.xxx.xxx:yyyy)とかでいいみたい。
header("Content-type: text/html; charset=utf-8");
でUTF-8で出力する事を明示して、
$title = mb_convert_encoding($title, "UTF-8", "auto");
で変換しただけ。単機能のCGIなので、出力はHTMLとかXMLとかじゃなくていいやと、ベタテキストで出力しています。これをLSLから呼んで、llSetTextで表示しちゃえばOK。
ただ、bodyをそのまま表示すると改行コードだかEOFだか変なゴミが出ちゃうので
llStringTrim(body,STRING_TRIM)でホワイトスペースを削除しています。

しかし、なんだこの曲ww
誰だこのラジオ流してるの。  


Posted by Hitomi Magne at 07:27Comments(0)LSL

2008年11月03日

ラジオ作りにハマる


SHOUTcastっていうネットラジオがあります。個人が手軽にサーバを立ててラジオを流せるらしいですが、これをSLで使えればお手軽ラジオができるなーと思っていろいろやってみたのですが、難しい…
。  続きを読む


Posted by Hitomi Magne at 05:16Comments(0)LSL