ソラマメブログ

  

Posted by at

2007年12月12日

コーヒーメーカー

仕掛け入りのコーヒーカップで、関係者用サイトが更新されるとコーヒーが注がれて湯気が出る。店においても違和感ないし知らない人は気がつかない。関係者だけに通知するにはいい仕掛けだ。  


Posted by march at 21:35Comments(0)

2007年12月12日

libsecondlifeサンプル - オブジェクト情報取得


オブジェクトがRezされたり更新されたり削除されたりした場合に、
そのオブジェクトの情報を取得することが出来ます。

オブジェクトの情報には、以下の情報が含まれています。
右クリックしてパイメニューの「Edit」で得られる情報はほぼ取得できそうです。
・基本的な情報(LLObjectクラス)、
 UUIDや置かれている位置やテクスチャUUIDなど
・プロパティ情報(ObjectPropertiesFamily構造体、ObjectProperties構造体)、
 名前や販売種別や販売価格など
・プリム情報(Primitiveクラス)、
 テーパ角度、物理属性か否かなど


オブジェクトの情報の取得は以下の流れです。
(他にもっとスマートなやり方がありそうですが…)
前にこのBLOGでも少し書いた、0L$以上で販売しているオブジェクトの情報の取得は
このやり方です。

1.取得したいオブジェクトのある場所にログイン/テレポートする
2.OnNewPrimイベントでオブジェクトのUUIDを得る
3.RequestObjectPropertiesFamilyで上記のUUIDのオブジェクトのプロパティを要求する
4.OnObjectPropertiesFamilyイベントでプロパティを得る

・この方法では、近くにあるはずのオブジェクトの情報が取得できていない
 場合があります。
 公式クライアントで見たときのように、アバターの体の向きを変えたり
 歩き回ったりすればいいのかも知れませんが、未調査です。
・OnNewPrimは名前のとおり新しいプリムを発見したときに発生するイベントなので、
 既にログイン/テレポートしてから時間がたった後で
 自分の周囲にあるオブジェクトのUUIDを得ようとする場合には使えません。
・OnNewPrimイベントは1オブジェクトごとに発生するので、
 数分で数千回~数万回程度呼ばれる場合が多いため、いったん配列などに入れて
 イベントハンドラ外で非同期に処理したほうがいいかもしれません。
・プロパティ情報を要求してもOnObjectPropertiesFamilyイベントが発生せず
 情報が得られない場合があります。
・スレッドプールが不足した旨のエラーで落ちる場合があります。
 0.3.1リリースノートにあるようにlibsecondlife側の問題です。
 http://www.libsecondlife.org/wiki/libsecondlife:Release_Notes/0.3.1


以下はサンプルコードです。

#libsecondlifeのロード
import clr
clr.AddReferenceToFile("libsecondlife.dll")
import libsecondlife
import time

#ログイン情報の設定
firstName = 'abcd' #苗字
lastName = 'efgh' #名前
passWord = 'ijkl' #パスワード

#各オブジェクトの情報
primSummary = {} #オブジェクトの基本的な情報
sims = {} #オブジェクトの置いてあるSIM
primProperties = {} #オブジェクトのプロパティ情報

#イベント待ち合わせ用クラスの定義
class EventTracker:
def __init__(self):
self.data=False
def Clear(self):
self.data=False
def Set(self):
self.data=True
def Wait(self):
while not self.data:
time.sleep(0.1)
def WaitTimeout(self, s):
t = time.time()
while not self.data:
time.sleep(0.1)
if(t < time.time() - s):
print 'event timeout',
break
else:
#print 'wait,..', t, s, time.time(),
pass

#新規オブジェクト検出イベント処理用のハンドラの定義
def NewPrimHandler(sim, prim, regionHandle, timeDilation):
#オブジェクトの情報を辞書に格納
global sims, primSummary
if(primSummary.has_key(prim.ID)):
return
sims[prim.ID] = sim
primSummary[prim.ID] = prim
#プリムの基本情報の取得
#print client.Objects.RequestObject(sim, prim.LocalID)
#プリムのプロパティ情報の取得
client.Objects.RequestObjectPropertiesFamily(client.Network.CurrentSim, prim.ID)

#オブジェクト情報取得イベント処理用のハンドラの定義
def ObjectPropertiesFamilyHandler(sim, properties):
global primSummary, primProperties #, gItemPointer
if(primProperties.has_key(properties.ObjectID)):
return
primProperties[properties.ObjectID] = properties

#初期設定
event = EventTracker()
client = libsecondlife.SecondLife()
client.Objects.OnNewPrim += libsecondlife.ObjectManager.NewPrimCallback(NewPrimHandler)
client.Objects.OnObjectPropertiesFamily += libsecondlife.ObjectManager.ObjectPropertiesFamilyCallback(ObjectPropertiesFamilyHandler)

#接続
client.Network.Login(firstName, lastName, passWord, '', '')
time.sleep(10)

#実際の処理(10秒まって、周囲のオブジェクトの情報を出力)
client.Objects.OnNewPrim -= libsecondlife.ObjectManager.NewPrimCallback(NewPrimHandler)
time.sleep(10)
for i in primSummary.keys():
#オブジェクトの基本的な情報の出力
print 'sim =', sims[i]
print 'prim.Position =', primSummary[i].Position
print 'prim =', primSummary[i]
#オブジェクトのプロパティ情報の出力
if primProperties.has_key(i):
p = primProperties[i]
print 'Name =', p.Name
print 'Description =', p.Description
print 'SaleType =', p.SaleType
print 'SalePrice =', p.SalePrice #@see ObjectManager.cs #Not / Original / Copy / Contents
print 'Category =', p.Category
print 'GroupID =', p.GroupID
print 'LastOwnerID =', p.LastOwnerID
print 'ObjectID =', p.ObjectID
print 'OwnerID =', p.OwnerID
print 'OwnershipCost =', p.OwnershipCost #0.3.0
print 'Permissions =', p.Permissions #0.3.0
else:
print 'no propertiesFamilly'
print '---'

#切断
client.Network.Logout()


以下のページも参考になります。
http://www.cs.unc.edu/~rgayle/Comp790-058/lectures/Comp790-BotsAndPlanning.ppt
  


Posted by march at 12:25Comments(0)libsecondlife