読者です 読者をやめる 読者になる 読者になる

なんとなく

誰得感満載な記事が多いかも。Mono関係とLinuxのサーバ関係、レビューとか。

libopenmetaverseを使ってteleport機能を実装してみる

はじめに

そういえば、Androidではまだテレポート機能を実装していなかったなぁと思ったので、現状7~8割の出来ですが実装してみました。テレポート機能を実装すると移動したくなるので、AutoPilot機能も欲しくなりますが、とりあえずテレポート機能のみです。

概要は

  • SIM名を検索して、ヒットするものをリストに表示
  • 対象のSIM名をクリックすると、SIMのMinimapを表示
  • 表示されているSIMのMinimapを長押しするとテレポートの可否を確認する。
  • OKならテレポートする

な感じ。

イメージは、
f:id:takeshich:20131223221428p:plain
の簡易版みたいなの。

今回はlibopenmetaverseの使い方のみの紹介です。Xamarin.Android側での実装でいろいろと取り組んだのですが、完成していないのでそちらは後日ということで。。

SIMの検索と取得した結果でリストを作成

libopenmetaverseでSIMを検索する方法

まずは、SIM名を検索するというところですが、libopenmetaverseを使用して、任意のSIMを検索するには、ログインした状態で

Client.Grid.RequestMapRegion(任意の文字列, GridLayerType.Objects);

メソッドを使用します。

Client.Grid.GridRegion

イベントハンドラで結果を取得できます。

詳しくは、
OpenMetaverse_GridManager_GridRegion
を参照してください。

このイベントハンドラで検索結果を取得し、リストを作成します。(赤枠で囲んだ部分)
f:id:takeshich:20131223222257p:plain

今回はデバッグ用にSIMの名前だけではなく、MinimapのUUIDも表示しています。

MinimapとそのSIMにいるアバターの描画

libopenmetaverseでMinimapを取得し、描画する方法

リストの値をクリックしたら、Minimapが表示されるようにします。デフォルトで表示されるのは自アバターがいるSIMにしておきます。

Akibaにログインしている状態(デフォルト状態)
f:id:takeshich:20131223222508p:plain

リストのAkibareをクリックするとAkibareのSIMのMinimapを表示する。
f:id:takeshich:20131223222517p:plain

libopenmetaverseを使ってMinimapを取得し、描画する方法は、
LibOpenMetaverseとCSJ2KでSIMのMinimap画像を表示してみる - なんとなく
で触れましたので、そちらを参照ください。

また、libopenmetaverseを使って現在自身がいるSIMのアバターの位置情報について取得する方法は
LibOpenMetaverseを利用してSIMのアバターリストと位置を得る - なんとなく
で触れましたので、そちらを参照ください。

任意のSIMのアバターの位置情報については

Client.Grid.RequestMapItems (siminfo.RegionHandle, GridItemType.AgentLocations, GridLayerType.Objects);

メソッドを使用します。
第一引数には、RegionHandle(SIMの一意性を示すもの)が必要なのですが、SIMを検索した時に取得できる(Client.Grid.GridRegionのイベントで取得可能)のでリストを選択した際にデータが渡るようにしておきます。
また、このメソッドではアバターの位置情報だけでなく、以下に示すものが取得を依頼できます。

  • Telehub
  • PG rated event
  • Mature rated event
  • Popular location
  • Locations of avatar groups in a region(今回はこれだけ)
  • Land for sale
  • Classified ad
  • Adult rated event
  • Adult land for sale

値については

Client.Grid.GridItems

イベントハンドラで取得できます。
MapItemの型で帰ってくるのですが、MapAgentLocationに変換し、X座標、Y座標を取り出します。

リストで選択したSIMが現在自身がいるSIMがでない場合、Minimap上に取得したX座標、Y座標を使って
LibOpenMetaverseを利用してSIMのアバターリストと位置を得る - なんとなく
と同様にして描画できます。

Xamarin.AndroidでNativeライブラリ(libopenmetaverseの中のlibopenjpeg-dotnet)を使ってみた - なんとなく
において、3~4倍高速化できるCSJ2Kを使わない方法が確立できたのですが、libopenmetaverseへの移植がまだできていないので、今回は使っていませんw

テレポート

libopenmetaverseでテレポートする方法

リストでSIMを選択し、そのMinimap上を長押してテレポートしたい座標を指定します。libopenmetaverseでは、sim名と座標を指定することでテレポートできます。

Client.Self.Teleport(String, Vector3)

メソッドを使用します。
sim名ではなく、RegionHandleにも対応していますし、テレポート後のlookatにも対応しているようです。
詳しくは、
OpenMetaverse_AgentManager_Teleport
を参照してください。

Client.Self.TeleportProgress

イベントハンドラでステータスを取得します。

f:id:takeshich:20131223231006p:plain

Xamarin.Android

まだ、きちんとできていないので、Xamarin.Androidでの実装の説明はまだできないのですが、使用しているものについて触れたいと思います。

  • ActionBarSherlockで検索条件を入力しています。(javaのbindingのコンポーネントです)
  • CustomListをlistfragmentに指定しています。
  • dialogfragmentを使用しています。
  • listfragmentからViewにカスタムクラスの値を渡しています。

まとめ

テレポートする際にViewer側で処理している内容について触れたつもりです。Simを検索するときはこういう処理が行われているんだということを感じていただけたらと思います。
個人的にはAndroidのUIやFragmentに大ハマリして、実はまだ横表示のしか実装できていなかったりします。スマホなどで縦表示するときの実装は時間がなくてできませんでした。
Androidでは、Fragmentによっていろいろな表示表現ができるようにはなってきたのですが、実装するのはかなり面倒くさい。。。よいのですが、面倒くさい。
もう少し、進めてXamarin.Android側での説明もできればなぁと思っています。