セカンドライフでタッチしたプリムの情報を取得する

はじめに

セカンドライフでプリムをクリックしたときにどこの位置を触ったのか、
といった情報をずらーっと出してみるサンプルです。

サンプル

とにかくいろいろ情報を取得してみます。
全部表示すると訳が分からなくなるのでちょっと表示しています。
ちなみに、テクスチャのUUIDに関しては権限を持っていないと取得できません。

integer	detected_link		= 0;
integer	detected_face		= 0;
vector	detected_touch_pos	= ZERO_VECTOR;
vector	detected_touch_uv	= ZERO_VECTOR;

integer	selected_link		= 0;
integer	selected_face		= 0;
vector	selected_touch_pos	= ZERO_VECTOR;
vector	selected_touch_uv	= ZERO_VECTOR;
string	selected_name;
string	selected_description;
vector	selected_position;
rotation selected_rotation;
vector	selected_size;
string	selected_texture_name;
vector	selected_texture_repeats;
vector	selected_texture_offsets;
float	selected_texture_rotation_in_radians;
vector	selected_color;
float	selected_alpha;
integer	selected_isfullbright;
float	selected_intensity;
string	selected_normal_name;
vector	selected_normal_repeats;
vector	selected_normal_offsets;
float	selected_normal_rotation_in_radians;
string	selected_specular_name;
vector	selected_specular_repeats;
vector	selected_specular_offsets;
float	selected_specular_rotation_in_radians;
vector	selected_specular_color;
integer	selected_specular_glossiness;
integer	selected_specular_environment;
integer	selected_alpha_mode;
integer	selected_mask_cutoff;

setSelected(integer target_link, integer target_face, vector target_touch_pos, vector target_touch_uv) {
	integer num = 0;
	list x = llGetLinkPrimitiveParams(target_link,
		[
			PRIM_NAME,						// string name
			PRIM_DESC,						// string description
			PRIM_POS_LOCAL,					// vector position
			PRIM_ROT_LOCAL,					// rotation rot
			PRIM_SIZE,						// vector size
			PRIM_TEXTURE, target_face,		// string texture, vector repeats, vector offsets, float rotation_in_radians
			PRIM_COLOR, target_face,		// vector color, float alpha
			PRIM_FULLBRIGHT, target_face,	// integer boolean
			PRIM_GLOW, target_face,			// float intensity
			PRIM_NORMAL, target_face,		// string texture, vector repeats, vector offsets, float rotation_in_radians
			PRIM_SPECULAR, target_face,		// string texture, vector repeats, vector offsets, float rotation_in_radians, vector color, integer glossiness integer environment
			PRIM_ALPHA_MODE, target_face	// integer alpha_mode, integer mask_cutoff 
		]
	);
	selected_link			= target_link;
	selected_face			= target_face;
	selected_touch_pos		= target_touch_pos;
	selected_touch_uv		= target_touch_uv;
	selected_name			= llList2String(x, num++);
	selected_description	= llList2String(x, num++);
	selected_position		= llList2Vector(x, num++);
	selected_rotation		= llList2Rot(x, num++);
	selected_size			= llList2Vector(x, num++);
	selected_texture_name					= llList2String(x, num++);
	selected_texture_repeats				= llList2Vector(x, num++);
	selected_texture_offsets				= llList2Vector(x, num++);
	selected_texture_rotation_in_radians	= llList2Float(x, num++);
	selected_color							= llList2Vector(x, num++);
	selected_alpha							= llList2Float(x, num++);
	selected_isfullbright					= llList2Integer(x, num++);
	selected_intensity						= llList2Float(x, num++);
	selected_normal_name					= llList2String(x, num++);
	selected_normal_repeats					= llList2Vector(x, num++);
	selected_normal_offsets					= llList2Vector(x, num++);
	selected_normal_rotation_in_radians		= llList2Float(x, num++);
	selected_specular_name					= llList2String(x, num++);
	selected_specular_repeats				= llList2Vector(x, num++);
	selected_specular_offsets				= llList2Vector(x, num++);
	selected_specular_rotation_in_radians	= llList2Float(x, num++);
	selected_specular_color					= llList2Vector(x, num++);
	selected_specular_glossiness			= llList2Integer(x, num++);
	selected_specular_environment			= llList2Integer(x, num++);
	selected_alpha_mode						= llList2Integer(x, num++);
	selected_mask_cutoff					= llList2Integer(x, num++);
}

showSelectedData() {
	llOwnerSay(
		"linknum: "		+ (string)selected_link + ", " + 
		"facenum: "		+ (string)selected_face + "\n" +
		"linkpos: "		+ (string)selected_position + "\n" +
		"linksize: "	+ (string)selected_size + "\n" +
		"color: "		+ (string)selected_color + "\n" +
		"alpha: "		+ (string)selected_alpha + "\n" +
		"texture: "		+ (string)selected_texture_name + "\n" +
		"normal: "		+ (string)selected_normal_name + "\n" +
		"specular: "	+ (string)selected_specular_name + "\n" + 
		"touchuv: "		+ (string)selected_touch_uv + "\n" +
		"touchpos: "	+ (string)selected_touch_pos + "\n" +
		""
	);
}

touchStart() {
	// 押した場所を確認
	setSelected(detected_link, detected_face, detected_touch_pos, detected_touch_uv);
	showSelectedData();
}

default {
	
	touch_start(integer num_detected){
		detected_link		= llDetectedLinkNumber(0);
		detected_face		= llDetectedTouchFace(0);
		detected_touch_pos	= llDetectedTouchPos(0);
		detected_touch_uv	= llDetectedTouchUV(0);
		touchStart();
	}
	
}

 

セカンドライフでタッチしている時間によって動作を変える

はじめに

セカンドライフでタッチしている時間によって動作をかえます。

タイマーを測って動作を切り替える

フラグとllResetTimeとllGetTimeを組み合わせるサンプルです。
作り方によっては、細かく時間を区切ることができます。

なお、ユーザーが一人の場合を想定しています。
複数の場合は、作りを変えた方がいいかもしれません。

integer	is_touching			= FALSE;

touchStart() {
	llOwnerSay("touchStart");
}

shortTouchEnd() {
	llOwnerSay("shortTouchEnd");
}

longTouchEnd() {
	llOwnerSay("longTouchEnd");
}

longlongTouch() {
	llOwnerSay("longlongTouch");
}

default {
	
	touch_start(integer num_detected){
		is_touching		= TRUE;
		touchStart();
		llResetTime();
	}
	
	// 押し続け
	touch(integer num_detected) {
		float timeSec = llGetTime();
		// 1秒以上の押し続け
		if(is_touching && (timeSec >= 3.0)) {
			longlongTouch();
			is_touching = FALSE;
		}
	}
	 
	touch_end(integer num_detected){
		// 1秒未満の押し終わり
		if(is_touching) {
			float timeSec = llGetTime();
			if(timeSec < 1.0) {
				shortTouchEnd();
			}
			else if(timeSec < 3.0) {
				longTouchEnd();
			}
			is_touching = FALSE;
		}
	}
}

タイマーイベントで押した時間を測る

細かいことはできませんが、タイマーイベントを使用しても作ることができます。

ちなみに、これもまた複数ユーザーのことは考えていません・・・

touchStart() {
	llOwnerSay("touchStart");
}

longlongTouch() {
	llOwnerSay("longlongTouch");
}

default {
	
	touch_start(integer num_detected){
		touchStart();
		llSetTimerEvent(0);
		llSetTimerEvent(3);
	}
	
	// 3秒以上押し続けた場合
	timer() {
		llSetTimerEvent(0);
		longlongTouch();
	}
	
	touch_end(integer num_detected){
		llSetTimerEvent(0);
	}
}

複数ユーザーの対応方法

まずどんな場合でも初期状態に戻す初期化関数を作っておきましょう。

クリックされると引数に値が入ってきます。
1つであれば1人かクリックした場合です。
1人がクリックした場合にllDetectedKeyでユーザーのUUIDを内部メモリに保存しましょう。
2人以上がもしクリックした場合は初期化関数を呼びましょう。

クリックが始まったらtouch_startのイベントを締め切りましょう(誰かがクリックするの防止)
あとは、touch関数の引数は1人のときのみのUUIDを確認して、
最初に保存したUUIDと一致するか調べて処理を行います。

タッチが終了したら、内部メモリのUUIDを解放しましょう。

なお、タイミングにより内部メモリにUUIDが残り続ける場合があるので、
タイムアウトできれいにするようにしておくとよいでしょう。

2枚目のクレジットカードは楽天かAmazonか

はじめに

一応私クレジットカード1枚持っていまして、
三菱東京UFJ銀行の「ICクレジットカード 三菱UFJ-VISA」というもの。
※1か月に1回でも使えば、コンビニATM手数料が優遇されるがシルバーステージ以上なら関係なし

年会費はもちろん無料でして、ETCカードの年会費も無料。
学生時代に銀行を開設したときについでに作ったものです。
ポイントとかはしょぼいもので、1%未満であってないようなものだったのですが、
たくさんクレジットカードを持つのが嫌いで、1枚を維持していました。

ただ昨年、財布を落としたときがありまして
(当日見つかりました。拾って交番に届けて頂いた方はありがとうございます……!)
その時クレジットカードの失効手続きをとりました。
まあ、すぐに新しいクレジットカードが届くのですが、
その間はクレジットカードがなくて、自動引き落としとかに困りました。

それでその時からもう1枚あったほうがいいなーと思いつつ。
少し調べてみることに!

比較

まあ、2枚目ということで、調べる時間もあり、
どれがよいか考えてみました。

それで、ポイント還元率が高く、
年会費がかからないクレジットカードである
楽天クレジットカード
Amazonクレジットカード
でしぼって私なりの視点で比較してみました。

Amazon Mastercardクラシック楽天カード
年会費1度以上使えば無料
入会費は1,350円
無料
たまるポイントAmazon ポイント楽天ポイント
ポイント付与
(換金率)
Amazon買い物 2%(プライム会員)
Amazon買い物 1.5%(通常会員)
それ以外で買い物 1%
楽天市場買い物 3%, xx%(キャンペーン)
楽天市場以外の楽天の場合は、1%のもあり
それ以外で買い物 1%
カードデザインダンボール!シンプル!
ブランドMastercardVISA / Mastercard /JCB から選択
Apple PayiD のみ対応QUICPay
※Mastercard /JCB / VISA どれでも利用可能
Suicaチャージ可能だがポイント付与無し可能だがポイント付与無し

こんな感じです。

Apple Payに関して

ともに、iDとQUICPayのどちらか一方ずつとなります。
一応、もし1枚のクレジットカードで両方とも対応させたい場合は、
Orico Card THE POINT」というのもあるらしいですが、
まあ、あんまり私としては聞いたことがないカードなので今回はやめます。

それで、iDとQUICPayのどちらがいいかということなんですが、
コンビニでの利用だけに限っていえば、どちらも制限はありません。

コンビニ以外では、通常のクレジットカードとして利用することを考えれば
あんまりここで迷う必要はないかと思います。

ポイント付与について

ここが、大きな違いとなります。
もちろん、両方のクレジットカートとも自分のサイトで買い物をすれば、
より多くポイント付与ができる形になります。

楽天については、サービスによって3%ついたり、
キャンペーンに応募することで10%以上つくことがあります。
しかし、3%つかないサービスもあります。
例えば、私がよく使う楽天トラベルなどでは、基本的には1%しかつきません。

一方、アマゾンの方はアマゾンで買えば必ず2%固定というのがよいです。
※プライム会員でない場合は、1.5%となります。

ブランドについて

基本的に選ぶのであればVISAというのがあります。
これが使える店舗が最も多いためです。

しかし、今回1枚目がすでにVISAを持っているので、
あえてVISAを選ぶ必要はありません。

そのため、Mastercard か JCB となるのですが、
JCBは使えない店舗があるので、Mastercard がよいかと思います。

なお、選択したブランドによってApple Payが使用できないこともあるようです。
楽天カードも以前はVISAを選んでしまうと、QUICPayが使えないというがありましたが
2018/05/14からは使えるようになっています。

結論

クレジットカードの2枚目についてですが、
結論としましては、
楽天よりAmazonをより使うのであればAmazonクレジットカード
楽天の方がより使うのであれば楽天クレジットカードです。
どちらも同じぐらいなのであれば楽天市場が3倍ポイントの楽天がよいかも。

Mastercardしか選べないのですが、今回2枚目ということもあり、
VISAは持っているので問題ありません。JCBは使えない店舗がありますしね。

Apple Payに関しては、コンビニだけに限っていえば、
Amazonか楽天かどちらでもよいです。

私は現状Amazonのほうが使っているので、
とりあえず、Amazonカードを作ってみたいと思います!

ちなみに、楽天カードをもし作る場合は、
持っている友人などから紹介という形をとるといいらしいです。

Amazonクレジットカードポイントとは?

補足としまして、Amazonクレジットカードポイントというのもあります。
本家のサイトからリンクは張っていないため、古い情報となっています。
例えば、2014年のキャンペーンのサイトでは、

Amazon.co.jpでのご利用はもちろん、いつものお買い物でAmazonクレジットカードポイントが貯まる。

貯まったポイントは1,000ポイント毎にAmazonギフト券100円分へ自動交換。

Amazonクレジットカードポイントは25,000ポイント貯まると、2,500円分のAmazonギフト券に毎月10日頃自動的に交換されます。25,000ポイント貯まっていない場合は翌月以降に繰り越されます。

「Amazonクレジットカードポイント」と「Amazonポイント」、「パートナーポイントプログラム」は、それぞれ異なるポイントプログラムです。

このように、買い物をすると、「Amazonクレジットカードポイント」がたまり、
「Amazonクレジットカードポイント」からAmazonギフト券に変換できるという記載があります。
1000ポイント毎にギフト券100円に自動変換、25000ポイントでギフト券2500円に自動変換など、
どっちなんだという支離滅裂な情報もありますが、現在の2018年のサイトにはこのような情報はありません。

カスタマーレビューにて、

2015年8月よりAmazon MasterCardのポイントプログラムが改定され、
Amazon MasterCardを使用してお買い物をすると、
ご利用に応じてアカウントにAmazonポイントが加算されるようになりました。

とあるため、現在は、Amazonクレジットカードポイントではなく、
Amazonポイントがおそらく直接たまるようになったかと思われます。

なお、2015年のキャンペーンサイトも残っています。
2015年なので、まだAmazonクレジットカードポイントです。
紛らわしいので、注意文を掲載するか、
キャンペーン記事を削除すればいいんですけどねー。

3DCG用テクスチャ作成ツールのPixPlantがすごい

以前からテクスチャ用のツールが欲しいなーと思っていたのですが、
先日 Bitmap2Material が Steam でセール中(¥ 10,300 → ¥ 6,798)になったので、
これを機会に買おうかなと少し調査しました。

もともと PixPlant か Bitmap2Material で迷っていたのですが、
PixPlant がかなり良さそうなので、
PixPlant の機能について少し紹介したいと思います。
2018/7/2の時点での情報となります。

PixPlantの公式サイト


PixPlantとは?

一言でいうと写真から3DCG用のテクスチャを作れるツールです。
上下左右が自然につながったテクスチャを簡単に作れます。

ライセンス

WindowsとMacで動作します。
有料のライセンスは2種類あります。

通常バージョン

$129 = 約 14800 円(税抜き)
通常バージョンとなります。
会社で買う場合は下記のフリーランスではないので、こちらかと思います。
4つ以上から割引価格になるようです。

フリーランスバージョン

$49 = 約 5600 円(税抜き)
フリーランス用(1人の会社用)となります。
上のライセンスと機能の違いはありません。
このライセンスは、所有者のパソコンでのみ使用できます。

デモバージョン

サイトからライセンスキーなしでダウンロードできるバージョンです。
名前をつけて保存でテクスチャを保存すると透かしが入ります。

購入方法

ここで購入が可能です。
購入する際は、使用許諾などの同意のチェックボックスが非常に小さいので注意
(タブキーとスペースキーを駆使してチェックをいれました!)

購入すると、メールでライセンスキーとダウンロードページが案内されます。
そこでライセンスキーを入力すればフルバージョンをダウンロードできます。

使い方

簡単な使い方を紹介いたします。
全ての機能を紹介はできませんが、イメージはつかめると思います。
とっても簡単なのでDEMOバージョンで是非試してみましょう!

1. テクスチャのサイズ設定
まず起動したらサイズを設定します。

上記はデフォルトの設定です。
「Both」だと上下左右がシームレスに接続されます。

2. 画面の右側の部分に画像をドラッグ&ドロップします。

3. 画像が読み込まれます。

4. 「Seed Wizard」を押すとパースペクティブ補正が行えます。

写真のひずみを消します。不要な部分はバッサリと消して、上下左右が平行になるようにしておきましょう。

5. 「Next」を押すと、1ブロックの設定が行えます。

ここは、最初から自動で認識しているようで楽々です。

6. あとは「<< Generate」を押せば完成!

すごく簡単!

もちろん非幾何学なテクスチャも自然に作れます。

↑写真1枚右側において、特に設定せず「Generate」押しただけですが、かなり自然です。

他にも複数の写真を元にして、1つのテクスチャを作成することも可能です。

さらに書ききれませんが、他に以下のようなことが可能です。

左側のテクスチャの画面で、ドラッグで範囲指定した後に、「<< Generate」を押すと、
範囲指定した中で、改めてテクスチャを自動で生成できるので、不自然な個所を直すことができる!

右側のシードとなるテクスチャでドラッグの範囲指定すると、
部分的に自動生成用のシードとして、使用しないようにマスクさせることができる!

3DCG上での見た目表示機能や、
ノーマルマップ用テクスチャや、AOの焼きこみなど色々できます!


最後は駆け足になりましたが、
上記で興味がわいた方は、Demoバージョンをぜひ試してみるとよいと思います!
あと、Youtubeでも操作している動画があるので見るとよいかも。

shで文字列の判定がうまくいかない

by なたで 0 Comments

つい先日、shで文字列判定がうまくいかないときがありました。

問題のスクリプト

スクリプトを書いていて、どうも処理が期待通りにならずに、
コードを少しずつ狭めていき、原因を調査していたんです。

そしたら、下記のコードに問題があることが分かりました、

#!/bin/sh

readonly string="OK"

if [ ${string} = "OK" ]; then
	echo "OK"
fi

if [ ${string} = "NG" ]; then
	echo "NG"
fi

これを実行すると、

./test.sh
OK
NG

!?

なぜ、NGまで出るんだ・・・

調査

みんなに聞いてまわり、

  • 文字列の判定なら「=」ではなく「==」ではないか。
  • 変数名が間違っているのでは?
  • if文の書き方それであってるの?
  • 気合が足らない

といろいろアドバイスをもらったのですが、

結局、解決できず、もやもやしていました。

原因判明

いろいろいじってたら次のような現象がおきました。

#!/bin/sh

readonly string="OK"

if [ ${string} = "NG" ]; then
	echo "NG1"
fi

if [ ${string} = "NG" ]; then
	echo "NG2"
fi

これを実行すると、

./test.sh
NG1

うーん。

なぜか2回目のif文の判定はうまくいくようだ・・・

ん・・・

!?

「=」の前が全角スペースになっているではないか!?

原因は全角スペースの混入

いやー。そんなポカミスしてるとは思っていませんでした。

というか全角スペースが入っている時点でエラーが出ると思ったのですが、
出ないんですねー。(処理系に依存しますが)

今回、半角スペースの制御文字に色を付ける設定もしていなかったので、
全角スペースと半角スペースがエディタ上から見わけがつかずに
かなり混乱していました。

灯台下暗し

%d人のブロガーが「いいね」をつけました。