2016年6月12日日曜日

AutoValue ライブラリを試してみた

https://github.com/google/auto/blob/master/value/userguide/index.md

immutable value class を生成してくれるライブラリ。abstract クラスを用意して @AutoValue をつけると、equals() や hashCode() などの boilerplate なコードを実装したクラスを用意してくれる。

設定

dependencies { compile 'com.google.auto.value:auto-value:1.2' apt 'com.google.auto.value:auto-value:1.2' }

使い方

例えば @AutoValue abstract class Animal { abstract String name(); abstract int numberOfLegs(); } のようなクラスを定義すると、AutoValue_Animalというクラスが生成される。 final class AutoValue_Animal extends Animal { private final String name; private final int numberOfLegs; AutoValue_Animal( String name, int numberOfLegs) { if (name == null) { throw new NullPointerException("Null name"); } this.name = name; this.numberOfLegs = numberOfLegs; } @Override String name() { return name; } @Override int numberOfLegs() { return numberOfLegs; } @Override public String toString() { return "Animal{" + "name=" + name + ", " + "numberOfLegs=" + numberOfLegs + "}"; } @Override public boolean equals(Object o) { if (o == this) { return true; } if (o instanceof Animal) { Animal that = (Animal) o; return (this.name.equals(that.name())) && (this.numberOfLegs == that.numberOfLegs()); } return false; } @Override public int hashCode() { int h = 1; h *= 1000003; h ^= this.name.hashCode(); h *= 1000003; h ^= this.numberOfLegs; return h; } } コンスタクタでは name と numberOfLegs を引数に取り、equals() や hasCode() ではこれらを使った実装になっている。 immutable value class なのでコンスタクタで受け取った引数は final として保持される。

abstract クラスに static な生成メソッドを用意して利用する。 @AutoValue abstract class Animal { static Animal create(String name, int numberOfLegs) { return new AutoValue_Animal(name, numberOfLegs); } abstract String name(); abstract int numberOfLegs(); } コンスタクタの引数は null チェックされる。これを止めたいときは abstract メソッドの戻り値に @Nullable をつける。 @AutoValue abstract class Animal { @Nullable abstract String name(); abstract int numberOfLegs(); } final class AutoValue_Animal extends Animal { private final String name; private final int numberOfLegs; AutoValue_Animal( @Nullable String name, int numberOfLegs) { this.name = name; this.numberOfLegs = numberOfLegs; } ... } Builder を用意することも可能。@AutoValue をつけるクラスにインナークラスとして abstract static な Builder クラスを定義し、@AutoValue.Builder をつける。 @AutoValue abstract class Animal { abstract String name(); abstract int numberOfLegs(); static Builder builder() { return new AutoValue_Animal.Builder(); } @AutoValue.Builder abstract static class Builder { abstract Builder name(String value); abstract Builder numberOfLegs(int value); abstract Animal build(); } } final class AutoValue_Animal extends Animal { ... static final class Builder extends Animal.Builder { private String name; private Integer numberOfLegs; Builder() { } Builder(Animal source) { this.name = source.name(); this.numberOfLegs = source.numberOfLegs(); } @Override public Animal.Builder name(String name) { this.name = name; return this; } @Override public Animal.Builder numberOfLegs(int numberOfLegs) { this.numberOfLegs = numberOfLegs; return this; } @Override public Animal build() { String missing = ""; if (name == null) { missing += " name"; } if (numberOfLegs == null) { missing += " numberOfLegs"; } if (!missing.isEmpty()) { throw new IllegalStateException("Missing required properties:" + missing); } return new AutoValue_Animal( this.name, this.numberOfLegs); } } }

2016年5月23日月曜日

Project Tango - Google I/O 2016

What's New with Project Tango

デモとビデオがたくさんあり、Tango の Keynote っぽいセッション。恐竜のアプリ楽しそう。
  • Standard Android development and publishing
  • C/C++, Java, Unity, Unreal
  • Detect if Tango features are available on device
Googel Store で $512.00 で新しい Project Tango タブレット開発キットが買えるようになった
https://store.google.com/product/project_tango_tablet_development_kit
(*日本では買えません)

追記:わざわざセッションで言及してたので new かと勘違いしてしまいました。new じゃなかった。残念...

Consumer 向けの Tango Phone を Lenovo と開発中。2016年の後半に出る予定。詳しくは 2016年6月9日の Lenovo Tech World で発表される。
http://www.lenovo.com/registerfortechworld/
http://www.lenovo.com/projecttango/


Introducing Project Tango Area Learning



Project Tango の主な3技術として Motion Tracking と Depth Perception と Area Learning がある。 Motion Tracking によってデバイスが最初のいちからどれだけ動いたかがわかる。 Tango 用の Tablet と Phone には特別な3Dカメラがついており、Tango はこのカメラを使って実世界の 3D geometry を検出できる。

Area Learning は Tango デバイスに記憶を与える。 Tango には広域カメラが付いていて、実世界の特徴のあるものをランドマークとして覚える。ランドマークの位置がカメラ内で移動したらデバイスが移動したとして Motion Tracking している。 目を閉じて見た目の全然異なる所に移動すると前にいた場所がわからなくなるのと同じように、これまで Tango には記憶がなかったので Motion Tracking を開始するたびに同じ状況になっていた。 Area Learning ではランドマークがどこに見えたかと、ランドマークの見た目についての mathmatical description の2つを記憶する。

AR でバーチャル椅子をダイニングに配置するとする。Motion Tracking だけだと、椅子の位置が徐々にずれてきてしまう。Area Learning を使うとこの drift がなくなる。椅子の位置を記憶するので Motion Tracking の drift を補正して正しい場所に表示できる。

複数人VRゲームでは、ゲームしている場所を記憶してその記憶をすべてのデバイスで共有することで、それぞれの位置が正しく補正されゲーム体験を改善できる。

Tango は
- 片付いているときと散らかっているときの部屋
- 異なる時間帯(朝・夜)の部屋
- 異なるライティング
- 観客がいるときといないときのスタジアム
- ランドマークの少ない部屋(全部白くてものが何もない部屋とか)
- 異なる季節(木に葉がある/ないなど)
などで同じ場所だと認識するのが難しい。

解決するキーは時間。 実世界には時間をかけてゆっくり変わるものと、短い時間で変わるものがある。地下鉄の駅では人や広告が入れ替わるので、記憶したものは短い間だけ正しくなる。 そこで、短い期間の記憶に頼るようにアプリをつくるのが良い戦略になる。

AR drift correction // Configure drift-free motion tracking mConfig = new TangoConfig(); mConfig = mTango.getConfig(TangoConfig.CONFIG_TYPE_CURRENT); mConfig.putBoolean(TangoConfig.KEY_BOOLEAN_ENABLE_DRIFT_CORRECTION, true); // ← // Query drift-free motion tracking TangoCoordinateFramePair frame_pair; frame_pair.base = TANGO_COORDINATE_FRAME_AREA_DESCRIPTION; // ← frame_pair.target = TANGO_COORDINATE_FRAME_DEVICE; TangoService_getPoseAtTime(timestamp, frame_pair, &area_description_T_device); Multiplayer game

Create Memory → Share Memory → Multi Player

Create Memory // Learning an area description mConfig = new TangoConfig(); mConfig = mTango.getConfig(TangoConfig.CONFIG_TYPE_CURRENT); mConfig.putBoolean(TangoConfig.KEY_BOOLEAN_LEARNINGMODE, true); // ← // Saving an area description mMemory = new String(); mMemory = mTango.saveAreaDescription(); // ← Share Memory between devices // Export an area description Intent mExportIntent = new Intent(); mExportIntent.setClassName("com.projecttango.tango" "com.google.atap.tango.RequestImportExportActivity"); mExportIntent.putExtra(EXTRA_KEY_SOURCEUUID, mMemory); mExportIntent.putExtra(EXTRA_KEY_DESTINATIONFILE, "/sdcard/area_description"); mActivity.startActivityForResult(mExportIntent, Tango.TANGO_INTENT_ACTIVITYCODE); Multi Player // Loading an area description mConfig = new TangoConfig(); mConfig = mTango.getConfig(TangoConfig.CONFIG_TYPE_CURRENT); mConfig.putBoolean(TangoConfig.KEY_STRING_AREADESCRIPTION, mMemory); // ← // Query device pose in are description TangoCoordinateFramePair frame_pair; frame_pair.base = TANGO_COORDINATE_FRAME_AREA_DESCRIPTION; // ← frame_pair.target = TANGO_COORDINATE_FRAME_DEVICE; TangoService_getPoseAtTime(timestamp, frame_pair, &area_description_T_device);


6 Degrees of Freedom Gaming in Android with Project Tango

Tango の3つの technology (Motion Tracking と Depth Perception と Area Learning)を一通り解説。

ARで何ができるか何ができないのかを見せるために猫のアプリを作ることにしたそうだ。virtual cat を実世界に。
このページをチェックすると楽しいらしい。
https://en.wikipedia.org/wiki/Cats_and_the_Internet

フレーム変換 TangoErrorType TangoService_getPoseAtTime( double timestamp, TangoCoordinateFramePair frame, TangoPoseData* pose); TangoCoordinateFramePair frame_pair; frame_pair.base = TANGO_COORDINATE_FRAME_START_OF_SERVICE; frame_pair.target = TANGO_COORDINATE_FRAME_DEVICE; TangoPoseData start_device_T_device; TangoService_getPoseAtTime(timestamp, frame_pair, &start_service_T_device); 猫を実世界の geometry に合わせないと、猫が宙に浮いたりしてしまう。 Tango ならこれを解決できる。 TangoPoseData pose_color_camera_t0_T_depth_camera_t1; TangoSupport_calculateRelativePose( last_color_time_, TANGO_COORDINATE_FRAME_CAMERA_COLOR, last_cloud_->timestamp, TANGO_COORDINATE_FRAME_CAMERA_DEPTH, &pose_color_camera_t0_T_depth_camera_t1); TangoSupport_fitPlaneModelNearClick( last_cloud_, &color_camera_intrinsics_, &pose_color_camera_t0_T_depth_camera_t1, glm::value_ptr(uv), glm::value_ptr(double_depth_position); glm::value_ptr(double_depth_plane_equation)); 猫アプリのデモ必見。

猫が家具の後ろにいったときに透けて見えてしまうのは現実っぽくない。 Tango は実世界の 3D データを作ることができる。ここからメッシュを作ると、実世界の家具の向こうにいった virtual の猫を非表示にしたり半透明にできる。 これのための処理はSDKで抽象化されていて、利用できる messing library もある。

あれこれやってデバイスのパワーを使いすぎると、デバイスがすごく熱くなったりする。Tango チームは速く効率的になるようにコードを最適化している。


Project Tango Developer Panel

3rd party の Tango アプリ開発者による Panel Session


2016年5月22日日曜日

Image compression for Android developers - Google I/O 2016

(テンション高いし、聞き取りやすい英語なのでオススメです)

Before we start

その他便利ツールなど

Four formats you care about

  • PNG
  • VectorDrawable
  • JPG
  • WebP

PNG

144x144 の単色の I/O アイコンが github では 6k だがストアの apk では 2k。でもまだ 144x144 にしてはでかい。8 color indexed image にすれば 932bytes になる。
  • palette や indexed にできるように調整する
  • 透明なピクセルのRGBチャネルを処理する
  • preprocess するなら gradle で cruncherEnabled = false
詳しくは Smaller PNGs : goo.gl/1yp3Bj

VectorDrawable

  • VectorDrawable使おう
  • 特に単色のピクトグラムに最適
  • POTrace (goo.gl/TG5z) は画像から vector に変換するツール

JPEG

  • qualityには何を指定すればいいの?
  • ImgMin project (goo.gl/OSvkMS) が参考になる
  • Butteraugli (goo.gl/1ehQOi) も参考になる

JPG Optimizer

  • JPEGMini (Lossy)
  • MozJPEG (Lossy)
  • cJPEG (Lossless)
  • packJPG (Lossless, Custom format)
  • Web solutions
どれ使ってもいいからやろう

image format 選択フロー

VectorDrawable にできる - yes -> VectorDrawable
 |
 no
↓
WebP をサポートしてる? - yes -> WebP
 |
 no
↓
透明が必要? - yes -> PNG
 |
 no
↓
simple or complex ? - simple -> PNG
 |
 complex
↓
JPG

PNG -> Use a tool, Resuce Colors, Hand Optimize
JPG -> Use a tool, Correct Quality, Hand Optimize


PROFILE YOUR CODE!!