ラベル tips の投稿を表示しています。 すべての投稿を表示
ラベル tips の投稿を表示しています。 すべての投稿を表示

2019年4月27日土曜日

LSLバックステージがネット上から消えたので 要約掲載 高速化編

のでまぁテクニックのところだけでも抜粋して
何回かに分けて乗っけとくこととする

でまぁ更に適当に抜粋に抜粋して要約する

3.1高速化手法

3.1.1定数演算は演算結果を書く

なんかLSLコンパイラで計算結果が変わらない定数演算も
そのままアセンブラコードにしちゃうらしいので
定数計算はコメントアウトして計算結果だけ代入しとけとのこと

ただこれも過剰にやると可読性が死ぬので
秒単位で演算時間が変わるような長大ループとか

ミリ秒単位で処理時間圧縮したい場合に有用

ワイの場合メモリに余裕あれば初期化処理してグローバル変数にぶっこむかな

変数間移動とハードコーディング数値の代入では前者が早い

3.1.2ループ中で計算結果の変わらない異処理はループの外に出す

for文とかで比較対象の固定数値をいちいちllList2とか使うと
なんかループの回数分list2が実行されちゃうらしく

先に変数に代入しとけということのようだ

これはllList2系命令の処理の食われ方からしても妥当やな


まぁこれもうちょい短縮方法ある

Listに対して固定でなんかするループ処理の場合
リスト長の変数自体をインクリメントなりデクリメントなりして
whileでぶん回すと結構な短縮になる

llist length = llGetListLength(Holge);

do{
    (何らかの処理)
    --length;
}while(hoge>-1);

これまぁリンクセットダンプとかでも使える


3.1.3 短い処理は インライン展開

なんでもかんでも関数定義して投げるなって話っぽい

概ね10演算子辺りがボーダーらしいので

複数箇所から呼び出すことがわかってる処理以外は
可能な限りユーザー関数使うなみたいな感じだな

これも秒オーダーで処理時間変わるループや
ミリ秒オーダーでイベント終わらせる必要がある場合以外は
割と無視していいが 最後の詰めに使えるな


3.1.4 インクリメント・デクリメント

i++;
より
++i;
の方がアセンブラコードになったときに2命令文圧縮できるとのこと
これは普段使いではくせにしちゃっていいと思う

で更に

ビット反転した後に符号反転すると+1したことになるとかで

a=-(~a); // ++a と等価

符号反転してからビット反転すると-1したことになるとかで

b=~(-b); // --b と等価


という記述方法が紹介されているけど
これも山ほど動かしたり
ミリ秒オーダーじゃないかぎりそこまでは不要かなぁ


3.1.5 ローカル変数は宣言時に初期化する

これはまぁちょっとわかりにくいな

ゼロやNULLで宣言しておく分には関係ない話
特定の数値代入して初期化する際に
宣言と代入と分けずに 宣言即代入したほうが早い

integer i;
i=5;

とするより

integer i =5;

こっちのほうが2命令文早いとのこと

これもミ(ry

3.1.6 同じ値を複数の変数に代入

同じ数値なら=でチェーン記述したほうがええということらしい

a = 0;
b = 0;

よりも

a = b = 0;

のほうが効率的とのこと

3.1.7 ローカル変数VSグローバル変数

ローカル変数の方が確保と開放の処理分ちょい重いとのこと

これは体感としてスタックヒープコリジョンの対策でちょい有効
ループカウンタの変数とか文字列入れる一時変数とか
その辺をグローバル定義するとメモリ圧縮になることもなる


3.1.8 リストへの値の追加

リストへ値を一つ追加する場合は []で囲わなくても
そのまま+=でいけるとのこと

これもリスト初期化処理とかで便利かなぁというところだけど
可読性とのトレードオフがあるから使い所は選ぶね

3.1.9 文字列定数、リスト定数のグローバル変数宣言

これもあれだな グローバル変数定義だと
ローカル変数定義時みたいに確保と削除が無い分

ポインタ参照的な挙動になって高速化するというやつだな

1.0.10 ビット演算を用いた、条件判定の高速化

ちょっとこれ要約するの無理だなぁ
integer値が32までならビット演算で複数の範囲判定が同時に行えるという話

3.1.11 list の長さの非0 判定

listの長さがゼロで無い判定
(lst!=[])
listの長さがゼロの判定
(lst==[])

3.1.12 llGetListLength() [互換性に注意]

ちょっとこれ衝撃だなぁ

integer len = llGetListLength(a);
これは
integer len = (a != []);

こう置き換え可能で listの!=演算が単純なブーリアン値ではなく
リストの長さの差分を計算するプログラムになってるんだってさ

で更に空リストをグローバル変数定義すれば高速化するとのこと

list null_list = []; // グローバル変数として宣言しておく
integer len = (a!=null_list);

ただしこの処理自体を関数化すると相殺されるらしいので
使い所ってことだと結構微妙かなぁ

でまぁこれこれちょっと今使えるかどうかわかんないなぁ


//-------------------------------------------------------------------------------

高速化の章の話はこれで終わり

常用するのはインクリメント・デクリメントと
あと代入処理のチェーンくらいかなぁ

計算結果定数の記述はまぁ詰めでやるくらいでいいかねと


以上

2016年12月19日月曜日

メモ ワイヤリングでIKを使う場合の話

まぁあdaeでエクスポートするときは結局マージしないといけないけどね


バージョンは2.77

参考サイト

インバースキネマティクス(IK) その1【Blenderの便利な機能を超簡単に紹介】


IKのやり方について

まずそれっぽい形状にベースのワイヤーを作る

アーマチュア(ボーン)を作って ワイヤー→ボーン の順番に選択して親子付する

ウェイトはとりあえず自動でもいけるみたいだけど
挙動的にウェイトペイントはやり直したほうがよさげ

ウェイトペイント手順は
アーマチュアをポーズモードでボーン選択
その後オブジェクトを選択してウェイトペイントモードにすると

あとは選択したボーンのウェイトが出て来るのでペイントで修正する
ペイントのブラシは左側に切り替えボタンがあるはずだ


単純に位置だけ調整でなんとかなるワイヤリングならIKのみでいけるが
そうでないなら"たわみ"の挙動が自動だとあんまよくないので

ボーンの回転ある程度手付けせんとだめくさい


IKのチェーン長に関しては
デフォルト設定のままいじるとゼッテー崩壊するので
ある程度設定は見といたほうがいい




dae出力する前段階のマージする話 最終的な手修正が必要な場合も同上


とりあえず ワイヤ→アーマチュア の順番で選択して移動コピーする

ワイヤ側についてる モディファイアのアーマチュアを適用してしまう

そのあとプロパティのオブジェクトタブで ワイヤの親子関係を削除
(ここの手順で結構ハマってしまう場合がある)

親子関係カットしたアーマチュアは邪魔なので削除してしまう




作業中にハマりそうな罠

モディファイア適用のチェック入れて出力すると何故かポリゴンメッシュが二重化するので
出力オプションに頼らずに複製して適用して出力すること



大体この辺だな

以上

2016年12月10日土曜日

割と旧世代の書かれ方したスクリプトを現代の技術で軽量化する場合のお話

具体的には1プリム複数スクリプト状態を是正するための話

・リサイズスクリプトはllScaleByFactor使っとけ

 これで回避出来ないissueはMOD可にして対応しろ 時間と手間の無駄になる
 スクリプトでリサイズしつつ平面マップ貼り付けした面をどうにかしたいとかだと
 とりあえず面番号と貼ってあるテクスチャのUUIDは現状どうやったって必須なので
 そっち方面の専門家(最低でもダンプが取れること)に依頼して
 専用ロジックを組んでもらう以外の方法は無い

 可能ならルートプリムのXYZどれかを1Mとかにすると
 いきなりリセットかかったりした際の管理が楽だ

あととりあえず避けないといけない部分として

・物理ヴィークルで特定のプリムのみでコリジョンを拾いたい場合は
 そのプリムにスクリプトを入れてLSL2でコンパイルする

これだけはもうSLのSIM自体のバグによるものなのでここだけはどうにもならん
ヴィークル系で完全シングルスクリプトのは無理だ 諦めろ

あとはレスポンスアップとか作動のスムースさの話

・llSetLinkPrimitiveParamsFast は可能な限り最小の回数で済ます

大昔だと大量のパーツを同時稼働するためだけに
全部の稼働プリムにこれだけが入ってるやつとかあったっぽいな

 PRIM_LINK_TARGET これを多用すること
 逆にこれを使えない構造になっているロジックはレートコントロールとか考えたほうがいい

・SetTextとTargetOmegaはllSetLinkPrimitiveParamsにある

大昔のスクリプトだとボタン類とかホイール類で
この辺やるためだけにスクリプト分割するのが常道だったんだけど
現在ならPRIM_LINK_TARGETと併用することでスクリプトを使わなくて済む

・テクスチャアニメとパーティクル再生は一枚のスクリプトに全部ぶちこむ


これでカバー出来ないレベルで大量のパーティクルやテクスチャアニメの同期制御があるなら
コンセプト自体に何らかの間違いがあるから再検討すること

・モデリング段階でのピボットオフセットは場合によっては危険だが有用

 当たり判定を考えなくて良くて関節が一個でスイングさせたいだけならかなり有用
 ただし自動車のドアみたいな複数の関節制御や
 ある程度形状通りのまともなコリジョンが必要な場合はスクリプトでやったほうがええ

2015年10月22日木曜日

LSL外部エディタとして秀丸を使うお話 (Gitは現状では無理ぽ)

ドーモ秀丸原理主義者です

世の中にはvim原理主義過激派みたいなめんどくさいのが居るらしいですが

こちとらもう10年以上秀丸使ってるっちゅうねん



LSL外部エディタの設定って
まぁ初期はほんとまともに使い物にならんかったわけよ

今もデバッグセッティングから設定必須だったりして微妙だけどw



んでまぁ
今回の最終目標は
秀丸でのスクリプトエディットの実用化と
Gitでのバージョン管理だったわけなんだけど

gitはかなり大掛かりなビューワー改造しないと
そもそもスタートラインにすら立てない感じ


スクリプトファイルの名称がSL_script_(UUID).lslなので
複数ウィンドウ開くとタスクバーで判別がつかんし

生成先がOSの一時フォルダに階層無しでぶちこまれてるので
既存のツールで最低限で済ます 的な運用では割とどうにもならん



・外部エディタの設定方法

デバッグセッティングの該当箇所にエディタのフルパスを指定
多分マルチバイトOSだとダブルコーテーションが要る

http://wiki.secondlife.com/wiki/Debug_Settings

ちなみに項目名は"ExternalEditor"これな


ちなみにこれで外部エディタ開くと

user\xxxx\appdata\local\temp

辺りにUUIDのファイル名で生成されたのが開かれる

firesotrm系なら別フォルダに書き出して修正とかも出来るんだけど
書き出したファイルを修正してビューワーでロードしてコンパイルしてなんて悠長なことは

リアルタイムでテストしながらデバッグしてる環境だとぶっちゃけ使い物にならんので

(あーでもgit利用するだけならファイル書き出しでもいけるか 考えとこう)

基本的に外部エディタに同時に投げられるのは3つくらいまでと思っといていい



・外部エディタを使う際の注意点

Loadingで外部エディタ開いたらファイルがぶっ壊れて死ぬ 解決策一切なし アキラメロン

ノーマル系のビューワーならeditボタンがそもそもloadingでアクティブにならないんだけど

firestormだとメニューバーについちゃってるので誤操作が危険過ぎる




・秀丸でLSLをエディットするお話

まー世の中にはものすごい便利なものがあってだなぁ

秀丸 LSL でググるとこいつが出てくる

LSL用強調表示定義 Ver.2

ぶっちゃけこれ導入するだけでものすげー便利になる
こいつの機能

1.関数や定数の強調表示
2.ユーザー関数やスクリプトステートへの一発ジャンプが可能なツリー表示

このふたつが使えるようになる

あと適当にジャンプ用のインデックスもツリーに登録しとけば
機能ごとのコードにダイレクトジャンプできるのでチョー便利
新関数とか対応大丈夫なのかよとか色々と危惧してたんだけど

その辺は秀丸の強調表示判定がものすごい優秀なので問題なかった

実際のエディット画面はこんな感じ


実際に使うとフォントサイズとかも可変だし標準エディタみたいなカーソル崩壊も無いので
作業快適性がものすげー高くなる

あと適当につまづいたところを抜粋

1.カーソル行の強調表示がウザイのでデザインのとっからカーソル行のチェックをOFF

2.標準だとダブルスラッシュのコメントアウト対応してないので
   複数行コメントんところの言語設定を自動判定から言語指定で"C言語/Java"を指定

3.タブの文字数が8になってるので4に

4.アウトラインの解析んところに適当に行ジャンプ用のタグを指定すると便利

5.SSに使われてるのはメイリオの等倍化フォント(やり方はぐぐってくれい)




だいたいこの辺かな

以上

2015年8月10日月曜日

blender 2.7 とPrimstar2 の組み合わせで出力データがぶっ壊れる場合の対処法について

どうもなんかファイル形式によるものっぽいんだよなぁってのが確定して解決したので記録

ファイルがぶっ壊れる現象について

・2.7で普通にrender sculpt maps すると2.6同様の形状でアルファマスクされた画像が生成される

・このファイルをtga raw もしくはtgaでそのまま保存するとぶっ壊れる

・pngで保存してもぶっ壊れる

・ぶっ壊れる現象としては
 tgaの場合アルファ部分が黒つぶれを起こす
 pngの場合アルファ部が白飛びを起こす



んで解決策

保存方式にRGBAを指定して
tgaもしくはpngで保存

こんだけ

ってかこの現象のせいで一年近く2.65a使うはめになってたのが解決した

これで複数のバージョンのblenderを管理する必要がなくなったので
多少作業効率とかが改善するかねぇ


以上

2015年4月1日水曜日

とりまL$引き出しに関して適当に

買う方はぶっちゃけクレカ登録すりゃいいだけなんだけど

L$売って引き出すには結構周到に前準備しないとダメっす



準備するもの

・クレカとして支払情報が行えるカード(一部VISAデビッド可)

・Lindex公式でのL$購入実績(とりあえず10ドル分くらい)

・郵便認証を済ませたpaypalアカウント(本名登録 プレミアム推奨)

・必要に応じて免許証等のスキャン

・ちゃんとしたアカウント情報(でたらめな情報が入っている捨て垢は不可)

 ただしL$引き出し用に新しいアカウント作ってそこに大量送金すると
 アカウントホールドされる場合があるので事前にチケット切るとか推奨


大体この辺

通常の引き出しで大体通しで10日かかります

事前準備を怠ると三ヶ月前後かかる場合があります

手数料諸々考慮すると引き出しは550ドル(14万L$程度)以上がオススメ

最小は100ドル前後くらいでもいける


手順

前提条件としてpaypalアカウントの郵便認証は済んでいるものとする


①まず支払情報にpaypalとクレカを登録します

②どっちでもいいので10ドル分程度のL$を買います

③支払いが通ってL$がチャージされてから即時もしくは数日でL$売りリミットが開放されます

④リミット開放されたら適当にL$を売ります
   急ぐなら32000L$単位くらいを 248L$/1US$ くらいがええかと 数時間から数日で終わります
   L$売れた段階で手数料引かれます この手数料が リンデンの主要収入源の一つです

⑤アカウントにUS$がチャージされるので確認する
  上記のレートで売ると120ドル前後になるはず

  ちなみにチャージされているUS$はプレ垢や土地代の支払いに使えます
  売上だけでSIM維持してる云々の話は大体この辺

⑥資金の処理を行います
 paypalアカウントへの送金は大体一週間前後かかります
 ここで手数料が1ドル前後取られるのである程度まとまった額推奨

⑦paypalアカウントに送金されます
 paypalは日本円でのアカウントチャージが出来ない仕様なので
 アカウントにはUS$でチャージされます

⑧銀行口座への引き出し
  500ドル以下だと250円の手数料がかかります 大体一晩かかります

⑨銀行口座に入金されて(゚д゚)ウマー

大体こんな流れ

ストレートで大体10日かかります


完全にゼロベースで開始する場合一番手数が少なくて済むのは
ジャパンネットバンクか楽天銀行のVISAデビッドカードっす

楽天銀行のVISAデビッドは手数料かかる糞仕様になっちゃったので
今から取得するならジャパンネットバンクかねぇ



イレギュラーな事態について

現状知られている限りでイレギュラーな事態



・リンデンへの書類の提出が必要になる場合
 所謂身分証明とかその辺のお話
 これは運転免許証かパスポートのスキャンが必要です
 スキャンがあれば手続き自体はペーパーレスなので割とすぐ終わります


・paypal認証にネットバンク以外の口座が必要になる場合

 実店舗持ちの銀行口座の情報が必要になる場合があります
 大体地方銀行の口座でおk ゆうちょは不明


・paypalの認証をせずに送金してしまった場合

 これはなーんのアクションも無しで静かなエラーになります
 一回これになっちゃうと事務手続き等で三ヶ月覚悟すること


 まぁなので最初は100ドル前後を送金して流れとかを把握するのも手




ってな辺りかな
以上

2015年3月12日木曜日

llSetForceのお話

簡単に解説すると

llSetForce(<1,0,0>*llGetMass(),TRUE);

これでローカルX軸方向にオブジェクトを1m/sec^2で加速します

簡単でしょ?

んでまぁSLには空気抵抗が無いので
llSetBuoyancy(1.0);とかで
空中浮遊させたオブジェクトだと無限に加速しちゃいます

方向転換とかしたいときは減速する必要があり

force切っただけだとダメです

llApplyImpulse(-llGetVel()*llGetMass(),FALSE);

これ実行すりゃ空中でならほぼ100%止まる


ヴィークルのハック系で
一定重量以上のオブジェクトでは浮力が効かなくなるバグってのが
一部の業界では有名です

そういうときは

llSetForce(<0,0,9.8>*llGetMass(),FALSE);

これで浮力の代用とすることが可能と知られています


大体この辺かな

以上

2015年2月2日月曜日

LSLのちょっとしたif文圧縮テクニック

まぁほぼ使うことはないと思う

たとえばこういう状況

integer A=TRUE;
integer B=3;
integer C;


if(A && B==3)C=TRUE;else C=FALSE;


こういう場合 if文の結果は Boolean値 (TRUE or FALSE)なので

C=(A && B == 3 );

こう出来る

たったこれだけなんだけど

まぁたとえばこれが4箇所くらいに分散してて
メモリがどうしてもカッツカツだった場合

これに置き換えることで
スタックメモリの消費を512バイトほど減らすことが可能な場合があります

まぁ負荷ではなくあくまでVM内メモリの話なので
パフォーマンス重視なら全く必要ない上に
メモリが足りてるなら ソースの可読性が下がってしまうデメリットのほうが
デカイテクニックではあるんだけど

知ってると最後の一手みたいな状況でちょっと役に立つかもね的な

以上

2014年12月10日水曜日

オフセット回転スクリプトのお話

現物はここから(タダじゃないよw)


面倒なのでソース全文 適当なオブジェクトにコピペで入れても多分動かん

//とりあえず相対座標での回転演算をかなり簡略化して記述したやつ
//変な角度のヒンジでスムーズに回さないといけないってだけならこいつだけでいける

rotation axis;
vector offset_pos;
offset_rot(vector offset,rotation rot){
    // プリムナンバー,基準からの相対位置,プリムのベース回転 と記述する
    //グローバル変数でもいいんだけどプリムナンバーに変数使いたいかもしれないので関数内に記述
    list parts=[2,<0.025,0.00,-0.25>,llEuler2Rot(<0,0,0>),//黄色い円柱 
                3,<0.525,0.00,-0.25>,llEuler2Rot(<0,0,0>)];//青い板
    integer list_length=llGetListLength(parts)/3;
    list params;
    integer i;
    vector parts_pos;
    rotation parts_rot;
    for(i=0;i<list_length;++i){
        parts_pos=llList2Vector(parts,i*3+1);
        parts_rot=llList2Rot(parts,i*3+2);
        //一括で回転させるためにリストにぶっこむ 記述的には
        //プリムナンバー 回転軸基準座標+(基準からの相対位置*指定回転)  プリムのベース回転*指定回転
        params+=[PRIM_LINK_TARGET,llList2Integer(parts,i*3),PRIM_POSITION,offset+(parts_pos*rot),PRIM_ROT_LOCAL,parts_rot*rot];
    }
    llSetLinkPrimitiveParamsFast(0,params);
    
}

default
{
    state_entry()
    {
        offset_pos=<0,0,1.0>;//回転軸基準座標 必要なら関数内にぶっこんでもおk
        axis=llEuler2Rot(<PI/4,PI_BY_TWO/4,0>);//ベースの回転軸rot axisangle2rotで使うだけならvectorで指定しても変わらないんだけど実験ならこっちのほうが調整しやすいので
        llSetLinkPrimitiveParams(4,[PRIM_POSITION,offset_pos,PRIM_ROT_LOCAL,axis]);//視覚的に見せるために赤いプリムを仮想回転軸として配置
        
        
//offset_rot命令でコメントアウトしてある方は 座標系をルートプリムでなく回転軸の座標系にするやつ 多分実際に見たほうが速い

//        offset_rot(offset_pos,axis*llAxisAngle2Rot(<0,0,1>*axis,0.0));//デバッグのために一応ゼロ回転へ全部戻す
        offset_rot(offset_pos,llAxisAngle2Rot(<0,0,1>*axis,0.0));//デバッグのために一応ゼロ回転へ全部戻す
    }

    touch_start(integer total_number)
    {
        integer j;
        //開閉処理 フレーム数とかを変数にしてもいいけどサンプルなのでベタ書き 
        //15fpsで21フレーム 可動域90度
        for(j=0;j<=20;++j){//オープン
//            offset_rot(offset_pos,axis*llAxisAngle2Rot(<0,0,1>*axis,j*PI_BY_TWO/20));
            offset_rot(offset_pos,llAxisAngle2Rot(<0,0,1>*axis,j*PI_BY_TWO/20));
            llSleep(0.066);//ウェイト
        }
        for(j=0;j<=20;++j){//クローズ
//            offset_rot(offset_pos,axis*llAxisAngle2Rot(<0,0,1>*axis,PI_BY_TWO-(j*PI_BY_TWO/20)) );
            offset_rot(offset_pos,llAxisAngle2Rot(<0,0,1>*axis,PI_BY_TWO-(j*PI_BY_TWO/20)) );
            llSleep(0.066);//ウェイト
        }
    }
}

大体この辺かね
以上

2014年11月6日木曜日

rotationからオイラー角(ピッチ ロール ヨー)を取り出す方法

基本的な考え方として

大抵のエディターの場合 回転が DEG値で<x,y,z>となっている場合

これをオイラー角とか呼称します
んでなんでこれが3dプログラミングだとまずいかってーと
"ジンバルロック"
っチュー現象がどうやったっておきます

大雑把に説明すると基準平面に対して自分の現在の向きから
行える方向転換が限定される現象のことです


んでまぁ タイトルにあるような演算が必要な用途として

例えば飛行機ゲーム あとはFPS

ここ最近の航空機のグラスコックピットの場合
このオイラー角を直感的にわかるようにした計器がついてます

んで X軸を正面 Y軸を側面 Z軸を上面とした場合に

x軸:ロール
y軸:ピッチ
z軸:ヨー

って感じで記述することが可能

ゲームでの航法や射撃ならピッチとヨーだけわかってりゃ
とりあえず自分が向きたい方向を表現できる
けど基準平面が無い空間だったり姿勢まで見るならロールも欲しい ッて感じだな


んで大抵の3Dプログラミングだと
回転値はクオータニオンっちゅー4値あるデータを使います
理由は
"ジンバルロック"の対策ね

んでまぁ大抵のSDKの場合 クオータニオンとオイラー角は
相互変換のライブラリーが揃ってます

ただこの相互変換関数
望む結果が出ることはほぼありません

何故か

変換時にZYXの順番で処理するから

(直感的に回しやすいのは大抵XYZの順番なので)
じゃぁ使い物にならねーじゃねーかってなるわけですが

そこはライブラリーというか使い方があります

オイラー角のXYZを個別のクオータニオンとして生成して合成すればいい


逆もしかり

具体的な計算式は

オイラー角からクオータニオンへの変換

目的の回転rot=(X回転のeuler2rot)*(Y回転のeuler2rot)*(Z回転のeuler2rot)

クオータニオンからオイラー角への変換は
回転z=クオータニオンのローカルX軸のvectorのyとxでAtan2
回転y=クオータニオンのローカルX軸のvectorのzとxy合成した長さでAtan2

回転y=クオータニオンからzy回転を引いたローカルy軸のvectorのzとyでAtan2


面倒なのでLSL表記すると
vector rot2angle(rotation rot){

    vector vec=<1,0,0>*rot;
    vector angle;

    angle.z=llAtan2(vec.y,vec.x);
    angle.y=-llAtan2(vec.z,llVecMag(<vec.x,vec.y,0>));//yだけatan2と逆回りになる
    rot= rot /llEuler2Rot(<0,0,angle.z>)/llEuler2Rot(<0,angle.y,0>);

    vec=<0,1,0>*rot;
    angle.x=llAtan2(vec.z,vec.y);

    return angle;
}
rotation angle2rot(vector angle){
    rotation rot=llEuler2Rot(<angle.x,0,0>)*llEuler2Rot(<0,angle.y,0>)*llEuler2Rot(<0,0,angle.z>);
    return rot;
}
default
{
    touch_start(integer total_number)
    {
        llSay(0, (string)(rot2angle(llGetRot())*RAD_TO_DEG));
        llSay(0, (string)(angle2rot(rot2angle(llGetRot())))+","+(string)llGetRot());
    }
}
大体こんな感じ
出力(サンプル)

[11:36] Object: <44.99883, -45.00175, -44.99999>
[11:36] Object: <0.19133, -0.46195, -0.19134, 0.84462>,<0.19133, -0.46195, -0.19134, 0.84462>


ってなところかね

以上

2014年11月5日水曜日

チャットが聞こえる範囲と邪魔なメッセージをスマートに絞る方法

ヴィークルとかで乗ってるアバターにだけ聞こえる状態にしたいけど
○○のささやき とか出るのはダサいとか
ラップタイマーとかでログを整理したいときに
○○の叫び とか出るのはちょいと面倒だとか

その辺をスマートに解決する方法

やりかた自体はちょー簡単で
Stringの先頭に "/me :"
これを追加するだけ

以下がサンプル

default
{
    touch_start(integer total_number)
    {
        llSay(0, "/me :Say.");
        llWhisper(0, "/me :Whisper.");
        llShout(0, "/me :Shout.");
    }
}

ってなところかね

以上

2014年4月1日火曜日

SLにおけるグリーフィング(通称テロ)と武器のお話

まず前提条件として武器について

随分前のエントリにも書いたとおり

・武器の形をしているものは攻撃能力が無くても全部武器

・攻撃能力があればどんだけしょぼい見た目でも全部武器

んでこれの後者の方

"攻撃能力"

SLではこれに対するボーダーってのが文化的側面
(11年も同じサービスやってりゃ文化的なタブーもあるさ)もあり
実害的な部分もある

で、どういうものが攻撃能力として見なされるかというと

・爆発物 ミサイル 核兵器 銃弾 砲弾 レーザー ビーム類
 (人やものに向かって発射する場合は空砲やエフェクトのみのダミーをも含む)

・花火等のでかい音とパーティクルが出るものを人に向かって発射

・なにかを射出してアバターや他人のオブジェクトに当てる仕組み全般
 (スイカ砲とかpopgunとか鰤とかも含む)

・push(llPushObjectだけではなくオブジェクトのめり込みを使用するものも含む)



直接的な攻撃能力が無くても文化的な側面で攻撃とみなされる行為
迷惑行為 嫌がらせ とか言われるようなやつ

・アバターや他人のオブジェクトに不用意に銃口を向ける行為
 (これは銃口管理っちゅーてコンバットやる人間なら必須の概念)

・非許可エリアで他人に危害を与えるようなものを正当な理由無くむき出しで所持する行為
  (警棒 スタンガン 銃 手錠 でかいタイラップ 刃物類)

・画面が埋まるレベルのパーティクルを出すオブジェクト
 (GTX TITANですらFPS低下が起きる場合がある)

・無限増殖系のオブジェクト(一般的にテロと言われてるものはこれがメジャー)
 これの定義が結構曖昧というか面倒な部分で
 たとえば タマが確実に消える処理が入ってない銃弾とかでも含まれます
 (メインランドで土地境界に大量に刺さってるグローオブジェクトとかがそれ)

・存在し動作するだけでSIMのパフォーマンスを著しく下げるオブジェクト
 これも完全に私有でパブリック・アクセスではないのSIM以外では
 (たとえそのSIMのオーナーが許可したとしても)嫌がらせと見なされます
 (完全封鎖SIMでも同じマシン上にあるSIMに迷惑がかかるが)



んで

このへんの行為に対する明確で確実な対処法

"無言でAR書いてTPHOMEしてオブジェクト全リターンかけてエステートBAN"
ヘタに武器つかって反撃したり交渉で抑えこもうとしないこと
というかそういうのするのは大抵かまってちゃんなので
こっちが会話しようとした時点でこちらの負けだ


メインランドじゃ無力じゃねーかってツッコミが入るだろうけど
メインランドはリンデン管轄で土地オーナー権限がかなり強いので
ARちゃんと書くだけでも効果あります 的な


以上

2014年2月25日火曜日

銃関係のお話

SLでの銃に関して
まず禁止事項としましてはこんなもんがあります

・許可されていない一般エリアでの(ホルスター状態も含む)装着および発砲の禁止
・人に向かって撃つことの禁止
・ケージガン、push弾及び核兵器の全面禁止

よくお馬鹿なnoob君がBANされる原因としまして

そのフィールドなりSIMのルールも碌に読まずに
セイフティーエリアでもお構いなく
適当に入手した無料の銃で人を撃って
しかもスタッフやオーナーの警告も”英語わかりません”って無視して

それで数回TPHOMEにあったり返り討ちにあったりして
勝てないからってぶちきれて
無限増殖系のテロアイテムや核兵器を使う

とまーここまでテンプレ

んでまぁこういうお馬鹿なnoob君が凸してる時に
たまたま善良なnoob君が居合わせてケージガン食らったり爆発物の巻き添え食らって
わけも分からずホームに戻って二度と行かなくなる 的なことも
割とよくあります

ちゅわけでSLで銃を持ったり
銃を扱う場所へ行くときの心構えというかそんな感じのもの

・マニュアルをちゃんと読む
 米国内の実銃には大抵”マニュアルを読め”の刻印が有ります
 そのくらいマニュアルは大切なモノです ちゃんと読みませう

・Homeは銃を持ってても大丈夫な場所にする
 SLで死ぬとホームに戻されます
 戻された先が銃禁止のエリアだった場合
 BANされる可能性が大変高いので
 そういう危険の無い場所をホームにしませう

・自分に銃口を向けられない限りは銃が好きな人にあんまり悪い人は居ません
 基本的な使い方とかおすすめの銃とか教えてくれたりします

・銃は基本的に買うものです
 出処不明な無料の銃はトラップ入りだったりまともに撃てなかったりと
 大抵の場合ろくな事になりません
 しょぼい見た目の銃はテロリストと疑われるリスクもありますので気をつけませう

 価格帯としては
 ライフルだと1000L$~2500L$
 ハンドガンでは500L$~1200L$
 くらいのが一番ハズレが少ないです

 同じメーカーの銃で見た目で安い銃があって VICEとかMCEとか書いてあるやつは
 専用CS(勝敗判定装置)のフィールドでしか使えない銃です

・おもちゃの銃 なんてもんはこの世界にはありません
 銃の形をしていればとりあえず全て銃です
 逆にどう見ても銃の形をしていなくてもタマが出るなら銃です
 ガンアレルギーの人口はむしろSLの方が多いくらいかもしれませぬ

・違法な銃に気をつける
 具体的な実在メーカー名や市販銃をそのままの名前で売ってる奴は全部アウト
 第二次大戦以前のものや
 軍用銃を軍の制式名で出してる奴は大体大丈夫ですが
 極端な安値や高値がついてる場合アウト品の場合があります
 よくわかんない時は銃が好きな人に聞きましょう


てなところかねぇ
以上

新型リサイズ命令関係のお話

実装されたものの時代はmeshに移行してる上に


リサイズの所謂"強制執行"が出来ないっチューことで
いまいち不人気の新型リサイズ命令ですが

平面マップも対応してないっちゅーやる気の無さっぷりなわけですよ


まぁそれだけ書くのもアレなので
誰得なソースを適当に置いときます

//どのプリムが縮小出来ない原因なのかを教えてくれるだけのスクリプト
default
{
    state_entry()
    {
        llSetLinkPrimitiveParamsFast(LINK_SET,[PRIM_TEXT,"",<1,1,1>,1.0]);
        integer nop=llGetNumberOfPrims();
        vector scale;
        do{
            scale=llList2Vector(llGetLinkPrimitiveParams(nop,[PRIM_SIZE]),0);
            if(scale.x<0.015||scale.y<0.015||scale.z<0.015){
                llOwnerSay((string)nop+","+(string)scale+","+llGetLinkName(nop));
                llSetLinkPrimitiveParamsFast(nop,[PRIM_TEXT,"FOUND\n",<1,1,1>,1>]);
//                llSetLinkPrimitiveParamsFast(nop,[PRIM_TEXT,"FOUND\n",<1,1,1>,1.0,PRIM_SIZE,<0.015,0.015,0.015>]);
            }
            --nop;
        }while(nop>0);
        llRemoveInventory(llGetScriptName());
    }
}
//[EOF}

コメントアウトしてる行を入れ替えると
縮小限界をちょい上げる程度にリサイズします






あとは各命令に関する適当な解説

Functioninteger llScaleByFactorfloat scaling_factor );
こいつがメインとなるリサイズ命令

記述の仕方が現在のスケールからの相対なので
従来型の基準スケールから〇〇%プラスて感じのを
そのまま入れ替えるとかはちょい無理っすな



Functionfloat llGetMinScaleFactor( );
Functionfloat llGetMaxScaleFactor( );

この2つがリサイズの限界を見るための命令
こいつの戻り値も現在スケールからの相対値なので
一気に限界までリサイズかけたいって場合を除き
あんまり使い道がありませぬ

llScaleByFactor(llGetMinScaleFactor( ));

petitteさんとかだと割とこいつ多用する感じになるんじゃないかのぉ
ただこれ使ってもサイズ合わないなら
従来型の強制執行が可能なリサイザーになりますな


ってなところかねー
以上

2014年2月20日木曜日

タイピングAOのスクリプト

//適当にコメント付きソースを貼っつけとく
//まぁやってることは単純明快です
//コピペすりゃ動くようにしてあるけどインデントとかは各自なんとかしてください

//タイピングアニメーションスクリプト mod v1.0 20140219 by UEPONYA

//******基本的な使い方****************
//スクリプトとアニメを一緒にいれればおk
//スクリプトが先ならアニメが入った時点でリロードがかかりますし
//アニメが先ならスクリプトの初期化時にロードされます
//複数アニメ対応とかは面倒なので無し

//---------以下解説とソース------------------

//*****装着物スクリプトの基本*******
//装着物は基本的に 装着をon_rez 取り外しをattachイベントで検出します
//タイマーはよっぽどの用途でも無い限りは0.2秒レートがええです
//AO系でタイマーを起動する場合 パーミッション取得出来た時のみにしたほうがうけがよろしいです

//*****負荷コントロール周り*********
//あとLSLの基本としてスクリプト外への出力は最低限のレートに留めるべきとされています
//データ取得に関しては関数一個で完結するものはいくらやってもok
//内部での変数書き換えはリスト以外なら気にせずじゃんじゃんやっちまっていい


key     owner_key;
string  anim_name;

integer Cur_status;
integer Lst_status;

default
{
    state_entry()
    {
         owner_key  = llGetOwner();
         anim_name  = llGetInventoryName(INVENTORY_ANIMATION,0);//アニメーション取得は一回でおk
         llRequestPermissions(llGetOwner(),PERMISSION_TRIGGER_ANIMATION);
    }
    run_time_permissions(integer perm){
        //ホントはちゃんと取得されたパーミッションフラグを確認せんとあかんのだけど
       //こんくらいのスクリプトなら無くても割と問題なく動くのでやらない

        llSetTimerEvent(0.2);//ハイレートすぎると重いのでこの程度にしておく
    }
    timer()
    {
        Cur_status = llGetAgentInfo(owner_key) & AGENT_TYPING;
        // 同じ情報の参照が二箇所以上ある場合はグローバル変数にぶっこむ方がトータルでは軽い

        if(Cur_status!=Lst_status){//切り替わった時だけアニメ再生を制御するほうが軽い
            if (Cur_status){//このへんのif elseの書き方は全体の書かれ方とかを見て決める
                //タイピング開始時の処理
                llStartAnimation(anim_name);
            }else{
                //タイピング終了時の処理
                llStopAnimation(anim_name);
            }            

            Lst_status=Cur_status;
        }
    }
    changed(integer change){
        if(change&CHANGED_INVENTORY)llResetScript();//プリムの中身変わったらスクリプトリセットしてしまう
        //これだけでよっぽどのバグが無い限り回復するのでメンテナンスフリーになる
    }
    attach(key id)
    {
        if(id==NULL_KEY){//デタッチ時はアニメーションのパーミッションを取得してる前提で止めちゃう
            llSetTimerEvent(0.0);//別にタイマー止める必要は全くないんだがテンプレみたいなもんなので
            llStopAnimation(anim_name);
        }
    }
    on_rez(integer t){
        llResetScript();//装着時はアタッチよりonrezが先にくるのでここでリセットしてしまう
    }
}

2013年11月25日月曜日

mesh関係のお話



3Dデータについて基本的なことがわかってる前提で

文書化されてなかったり解説が分散してたりするお話のまとめ



現状わかってる範囲でやるなって言われてる感じのこと


・llSetAlpha系命令によるオブジェクトアニメーション


 これはllSetTextureAnimとは別の話ね



 同じ場所に大量の面を重ねてアルファ切り替えで
 アニメーションしているように見せる処理のことらしい


・ものすごいハイポリゴンのオブジェクトを
 計算上低LIに見せかけるテクニック

 (ある程度方法がテンプレ化してんだけどそれはここで書かない そのうちどうせ潰される)

・ダミー面使ってセンターをずらしたObjectのアップロード
 当たり判定の処理的にかなりまずいらしく
 どうしてもセンターオフセット回転やりたいなら
 パペッター系のスクリプトでやれとのこと

・convex hullの多用
 物理シェイプ的には正四面体をアップロード時に指定が最軽量らしいとのこと





スクリプト連動周りのお話



・アニメーションではなく見た目切り替えの処理でなら

 (車だとエアロパーツとかホイールとかの辺り)

 setalphaで不可視状態にして最小化 が最善とのこと
 (レンダリング負荷周りのお話っぽい)

・これは推奨ってわけではなくそういう手もあるって話ですが

 furryさんとかでnフレームの口パクさせたい場合
 左端1/nのエリアを通常の絵
 残りを透明にしたテクスチャを用意して
てくすちゃあにめ でワンフレームづつずらしたものを指定して
 動いてるように見せかけるって手が使えます

 (ローカル動作なので40fpsとかでもSIMラグはほぼ無し)
 マテリアルでアルファマスクをワンビットアルファにしてやれば
 アルファ面が前後するバグも考えなくておkです




んでその他のFAQみたいなもの


・スカルプもアニメーションさせるのにUUIDフリップがあるじゃないか


  あれも本来は多用するなって方針ですよ


・出来るようにしてあるならそれはやっていいってことだろ?


  [お前がそう思うんならそうなんだろう お前ん中ではな]

  (テンプレらしいので使ってるだけですよ)


・ソースを出せ


  ソースが出せるんだったらURL羅列して終わってんだよ



・つまりどういうことだってばよ?


  meshはどうやったって重いんだから無駄にトラフィック圧迫するようなことすんなってことです









ってなところかね


以上

2013年6月7日金曜日

スカルプテッドプリムについて

webを適当に見た感じ日本語でまともな解説やってるサイトがほぼ無いです
あっても情報が2008年代とかで
大規模な仕様変更が2009年以降におきてるんだけど
その後のまとめ解説が見つけられなかったですよ


というわけで軽く解説



どういうものかってのを3Dやってる人ならこれでわかるって表現だと

UV座標上のピクセルにオブジェクトの位置座標を
RGBで対応させたものがスカルプです




んじゃ実際のスカルプについて適当に

まずはデータ形式から

SLの画像データは32bitのbitmap(RGBA)なので
そこから頂点精度は8bitとなります

んで昔のドキュメントだと頂点数は32*32って解説されてたと思うんですが
実際の形状データは32*32"面"ですので
頂点は33*33です

これは最初のスカルプの仕様が球体のみで
全部のポリゴン終端が収束されてる前提での仕様でした



その後ご存知の通り仕様変更がおきました


データ上33*33ですがプリムパラメータにより

球体         32*33
シリンダー 32*33
トータス     32*32
平面        33*33

とデータ解釈が行われます

其の関係でUVマップは格子状で数量固定にせざるをえないので

昔言われてた"スカルプは頂点の切り貼り厳禁"って話になるわけですな
仕様さえ理解してりゃ制限があるにはあるけど
実際にはいくらでも出来るんですけどね


昔のチュートリアル自由形状UV展開して配置して
アップロードしたものの見た目がいまいちよろしくないってのがあったと思いますが
あれはピクセルデータリード解釈についてきちんとした情報がなかった時代に
試行錯誤到達したですので
最初から仕様通りのUV頂点配置のオブジェクト作ってしまえば
綺麗なデータが作れるというお話です



次はビューワー上の実装でのお話

スカルプマップの画像は最低64*64でないと正常にリードされません
これは前記のとおり頂点解釈が33*33であるためです

んでリードされるピクセルですが
33ってことは基本一個おきリードですが片方の終端は連続リードされます
んで連続リードされる頂点ですが
SLビューワのデータリードは左下原点です

なので上端と右端が2ピクセル分連続リードされます

ってなところですな


次アス比スカルプ

現在ガチ勢が使ってるのは大抵アス比スカルプですな
LOD安定性ってことだと正方形アス比のスカルプはいまいち使いにくいので
アス比スカルプ使う場合がどうしても多くなります

アス比スカルプといっても奇数は配列に出来ないです
あとは四角面総数が1024にならないとあかんです

面数配置のリストはこんな感じ

4*256
8*128
16*64
32*32
64*16
8*128
256*4


んでもってLODについて

LODってのは要は遠距離オブジェクトのポリゴン省略して
レンダリング負荷を減らすための仕組みです

LODはちょいめんどくさい話になるんですが
アス比の場合長い方からLODがかかります

んでもって(シリンダーにした場合の)断面方向は
4頂点以下には絶対にならないようになってます
(テロとかで右クリック選択出来ないオブジェクトを使われないようにするため)
なので角材を組み合わせたオブジェクトとかは
極端なアス比スカルプのほうがいいってことになります




実際にモデリングする際のtips

テクスチャ解像度のコントロールのために
UVを調整するってのが"ほぼ"出来ません
(気合と根性で出来るっちゃ出来るけどツールと腕に依存する)
なので頂点配置数で解像度コントロールすることになります

あとはLODが弱い頂点は形状のアウトラインとしては使いものにならないので
実際に形状として使える頂点数は全体の50%から25%になります
それ以外の頂点は曲線表現の中間調点とかそんくらいの用途です

ってなところかな

あと細かい部分の質問はコメントにでも書いてもらえれば
わかる範囲で返答するかもしれません

以上

2013年3月31日日曜日

近況メモ

詳細書くとまずい部分適当にはぼかすので察してください


・3つの動作規格に合わせて 最終的に
 メインモジュールの定数だけ差し替えれば移植完了するスクリプト

・法線コントロールのために
 平面マップのリボンを組み上げてエッジを出すモデリング方式

・アニメヘッド+ヘア+furry系のボディー耳とアパレル規格について
  (mod名称から勝手に命名 rikugou neko)
 
これのヘッドパーツ
 ヘッドパーツ用のヘア
 
 これのボディーとヘッドパーツの耳を使用
  (タンクトップとショーツはmodで使うので捨てずに保持)
 ボディーと耳用のテクスチャキット(複数種有り パーツにテクスチャはりつけ)
   (一応ヘアのカラーと合わせたほうがいいけどめんどいならどーでもおk)


 カーゴパンツはマケプレに無いので本店ベンダーから購入
 ジャケットもあるけどはえり周りがでかすぎるので
 調整しきれない前提で買うかどうか検討のこと

 全部そろえてmodをちょい追加で買うと3000l$前後かな

 ブルーギャラクシーのボディーキットと服は
 規格品で全ての服に差し替え用のテクスチャ(通称mod)があるので
 服のスタイル自体は変えられないが
 ベースの服さえ買ってしまえばバリエーションはそれなりにある

 デフォのブルーギャラクシー用シェイプだと
 furryのヘッドサイズに合わせてて明らかにごついので
 体格とヘッドのバランスは各自好みに合わせて調整のこと
 うちで調整した感じだと180センチ以下にしないと等身バランスがおかしい
 それ以上の慎重で等身のバランス取ろうとすると
 ヒーローショーの敵役みたいなゴツさになるので注意

 ちゃんと調整すりゃバイクとかもひととおり乗れる




ってなところかね
以上 

2013年3月15日金曜日

スクリプト関係のビューワー改造メモ

現在V3系はスクリプトエディタの文字数制限がかかってます(65536文字)


で、
この制限って場合によってはかなり厄介で

コメント等をメンテナンス性向上のため満載していたり
インデントきっちりつけてる1系ビューワー時代のソースだと
文字数がオーバしてる場合が多いです

そういうソースをV3系ビューワーで開くと
まぁ下のほうが途切れて表示されるわけですが




絶対にその状態で

 編集したり

 外部エディターで開いたり

 外部エディターで開いても途切れてるのを確認した後にエディターを閉じたり

してはいけません

途切れた後のデータ消えます

これでロストして泣いた人知ってます

まぁこれ知らない人結構居るというか
そういう長さのソース書く人間って少ないからねー





んで
これの解決策なんですが2つあります

・coolVL Phoenix Inprudence等の1系ビューワを使う
 この方法昔なら推奨してたんですが
 2系ビューワーが標準になってからSLはじめた人も結構いますので
 現状でわざわざ低機能な1系使わせるのはある意味拷問です

・Skinsのpanel_script_ed.xmlを改変してリミットを解除する
 多少リスクがありますが現状だとこの方法が一番確実ですな


後者のやり方を説明

XMLが開けるテキストエディタが入ってる前提で話を進めます
(メモ帳でもおk)

\ビューワーインストルフォルダ\skins\default\xui\en\ panel_script_ed.xml


これをデスクトップにコピーしてテキストエディタで開きます
で、

  max_length="65536"

この行を探してください
これを

  max_length="1048576"


これに変更します
これで文字数制限が16倍になります(4倍くらいでもいいですけど一応余裕を見ます)
んでこれをさっきのフォルダに上書きすればおk

これで途切れずに表示可能になるはずです

ね?簡単でしょ?


以上