ちら帳

喉元を過ぎると熱さを忘れる自分の為の、ちら裏メモ帳ブログです。

React VRで頭の動きに追従するカーソルを表示する

VR初心者のちらです。

今回はVRでよくある、頭の動きに追従するカーソルの表示方法についてのお話です。

まずReact VRのカーソルシステムについてのドキュメントはこちら。

facebook.github.io

カーソルの実装

カーソルはRayCasterを利用して実装します。

学生時代のおぼろげな記憶で説明をするのも良くないので、レイキャストについての詳細は割愛しますが、ちゃんと調べたい人はレイキャストとかレイキャスティングで検索をかけるといいと思います。

RayCasterで実装が必要なメソッドは以下の3つになります。

  • getType - raycasterを一意に特定できるような文字列を指定します。
  • getRayOrigin - カメラを基準にしたときの光線の原点を3次元座標で指定します。
  • getRayDirection - カメラの向きをもとに光線の方向を3次元ベクトルで指定します。

さらにオプションで2つのメソッドが用意されています。

  • frame - アプリケーションのフレーム毎に呼び出されるメソッドです。
  • drawCursor - 目に見えるカーソルを描画するかどうか決定するメソッドです。

カーソル用に各メソッドを実装するのであれば、  

  • getType : 任意の文字列
  • getRayOrigin : [0, 0, 0] カメラの原点
  • getRayDirection : [0, 0, -1] カメラの正面方向
  • frame : 実装しない
  • drawCursor : true

とするのがいいと思います。

カーソルの可視性の制御

カーソルの可視性はcursorVisibilityというオプションで制御できます。
このオプションはclient.jsやindex.htmlでの初期化の際に設定することができます。

設定できる値は以下の3つです。

  • hidden - カーソルを常に非表示にします。デフォルトではhiddenになっています。
  • visible - カーソルを常に表示します。
  • auto - 入力イベントハンドラを持つコンポーネント(など)に視線がぶつかっているときにカーソルを表示します。

autoを設定する場合も、デバッグ中はvisibleにしておくのがよさそうです。

実装

今回はアプリケーション全体でカーソルを可視化する体でclient.jsに可視化処理を実装しました。
初期化時のオプションのraycastersにカーソル用のRayCasterを実装し、同じくオプションのcursorVisibilityをvisibleにします。

// Auto-generated content.
// This file contains the boilerplate to set up your React app.
// If you want to modify your application, start in "index.vr.js"

// Auto-generated content.
import {VRInstance} from 'react-vr-web';

function init(bundle, parent, options) {

  const vr = new VRInstance(bundle, 'ReactVrSample', parent, {
     // Pass in the custom font as an initialization property
     raycasters: [
          {
            getType: () => "mycursor",
            getRayOrigin: () => [0, 0, 0],
            getRayDirection: () => [0, 0, -1],
            drawsCursor: () => true
          } 
     ],
     cursorVisibility: 'visible',
     ...options,
  });

  vr.render = function() {
  // Any custom behavior you want to perform on each frame goes here
  };
  // Begin the animation loop
  vr.start();
  return vr;
};

window.ReactVR = {init};

せっかくなのでカーソルの当たり判定も確認できるようにします。
index.vr.jsに画面上にピンクの文字列を表示して、文字列にカーソルが当たっているときには色を赤に変える処理を書きます。

import React from 'react';
import { AppRegistry, asset, Pano, Text, View } from 'react-vr';


export default class ReactVrSample extends React.Component {
 constructor() {
    super();

    this.state = {textColor: 'pink'};
  }

  render() {
    return (
        <View>
        <Pano source={asset('chess-world.jpg')}/>
      <Text
        style={{color: this.state.textColor, 
            fontSize: 0.3,
            fontWeight: '400',
            layoutOrigin: [0.5, 0.5],
            paddingLeft: 0.2,
            paddingRight: 0.2,
            textAlign: 'center',
            textAlignVertical: 'center',
            transform: [{translate: [0, 0, -3]}],
          }}
        onEnter={() => this.setState({textColor: 'red'})}
        onExit={() => this.setState({textColor: 'pink'})}>
        This text will turn red when you look at it.
      </Text>
      </View>
    );
  }  
};

AppRegistry.registerComponent('ReactVrSample', () => ReactVrSample);

確認

白い丸がカーソルです。GIFはありませんが、VRモードにして頭を動かすとちゃんと追従します。

f:id:chira_pym:20170528234908p:plain

文字の方を見ると、カーソルが文字に当たって文字の色が変わります。 f:id:chira_pym:20170528234940p:plain

ひとこと

A-Frameのtracked controllersのサンプルみたいにコントローラーの位置をトラッキングして手を表示したいのですが、公式サンプルはまだですか。

ReactVRで日本語フォントを扱う

ご無沙汰しております。ちらです。

以前からやるやる詐欺をしていたReact VRにとうとう手を出し始めました。
とは言っても、まだまだ、サンプルコード動いたー!やったー!って喜んでる段階ですが。

f:id:chira_pym:20170527131852p:plain

で、本題です。試しにサンプルコードのhello部分をはろーわーるどにしてみたのですが、こんな感じに文字化けしてしまいました。

f:id:chira_pym:20170527132352p:plain

日本語フォントをインストールしたら直ったので、備忘録として手順を残しておきます。

手順はこのドキュメントを参考にしました。
react-vr/Fonts.md at master · facebook/react-vr · GitHub

日本語フォントのダウンロード

ドキュメントを見ると、ovruiパッケージ内のfontsディレクトリに日本語フォント用のファイルが含まれているので、これを使えばいいよ的なことが書いてある気がします。

そこでまずプロジェクト直下のstatic_assetsにfontsディレクトリを作って、そこに必要なファイルをダウンロードしてきます。

必要なファイル: https://github.com/facebook/react-vr/raw/master/OVRUI/fonts/japanese.png https://github.com/facebook/react-vr/raw/master/OVRUI/fonts/japanese.fnt

client.jsを書き換える

次にドキュメントの真似をしながらvrディレクトリ内のclient.jsを書き換えます。こんな感じであってるかな?

// Auto-generated content.
// This file contains the boilerplate to set up your React app.
// If you want to modify your application, start in "index.vr.js"

// Auto-generated content.
import {VRInstance} from 'react-vr-web';
import * as OVRUI from 'ovrui';

var fallbackFonts = {
  '../static_assets/fonts/japanese.fnt': '../static_assets/fonts/japanese.png'
};

// use the embedded defaultFont and and fallbacks
var font = OVRUI.loadFont();
var count = 0;

function init(bundle, parent, options) {
  function addFallback(fallbackFont) {
    OVRUI.addFontFallback(font, fallbackFont);
    count--;
    if (count === 0) {
      // all fallbacks are loaded start the VRInstance
      // 'font' contains everything React VR needs to render <Text> elements with
      // your custom font.

      // Pass it to the boilerplate init code
      const vr = new VRInstance(bundle, 'ReactVrSample', parent, {
        // Pass in the custom font as an initialization property
        font: font,
        ...options,
      });

      vr.render = function() {
      // Any custom behavior you want to perform on each frame goes here
      };
      // Begin the animation loop
      vr.start();
      return vr;
    }
  }
  
  for (var key in fallbackFonts) {
    // allow each font to asynchronously load in parallel and start VR instance when all complete
    count++;
    OVRUI.loadFont(key, fallbackFonts[key]).then((fallbackFont) => {
      addFallback(fallbackFont);
    });
  }
}

window.ReactVR = {init};

確認

画面をリロードするとこんな感じで日本語が表示されます。やったーヾ( ・ω・)ノ

f:id:chira_pym:20170527131919p:plain

おわりに

React VRが1.1.0からバージョンが上がった際には、コードをコピペしても動かなくなる可能性があるので、その際は公式ドキュメントをご覧ください。
以上です。

esaの運用ルールについて少しだけ考えてみた( ⁰⊖⁰)

esaを使い始めた #トノコト

Boostnoteをうまく使いこなせない系エンジニアのちらです。

最近一人でesa.ioを使い始めました。

全体的にUIが使いやすく、見た目もかわいいので結構気に入っています。

あとWIPという概念がとても良いですね。

ブログとかチケットとかの文章はなんとなく綺麗に書かないといけないという強迫観念に縛られて生きているので、 アウトプットが遅くなりがちなのですが、そのあたりの心理的障壁が下がって、個人的にはすごく刺さるものがありました。

また、Chrome拡張のtsuibamiを利用すると、メモ速度が爆速になります=͟͟͞͞ (\( ⁰⊖⁰)/)
ChromeVivaldiを使っている方におすすめです。

社内のナレッジ共有にも使いたい #トノコト

社内のナレッジ共有が滞りがちなので、会社でもesaを使えたらいいなあと思っています。
でも組織で使う場合は、運用ルールが整備されていないと、せっかくのツールの良さも活かされなかったりするんですよね…

ということで、esa歴3日の素人ながら、社内でのesaの運用ルールやテンプレートについて少し考えてみました。

前提

今回運用を考える上での前提やら想定やらです。

  • 社内全体で使用する(規模は中小レベルを想定)
  • 個人の知識の共有をメインとするが、他にも社内で共有したいことがあれば、基本的に自由に投稿して良い
  • 社外秘・社内秘の情報だけは書かない
    • プロジェクト内のルールや特有の設定などに関しては、プロジェクト管理ツール(Redmineなど)に書く
    • その他、外に出せない情報は社内専用の情報共有場所(社内wikiなど)に書く
  • WebhookはEmailのみ使用

WebhookにEmailしか使わないのは、単に私が職場でチャットサービスを使ってなくて、SlackやHipChatに詳しくないからです。

カテゴリ

何をカテゴリにして、何をタグにするかを悩みましたが、とりあえずこんな感じになりました。

※PCから見たときに縦に長くなるので、技術情報の第三階層はリストにするのをやめました。

カテゴリの説明

esa Tips:
esaのTips集です。 公式のProTipカテゴリみたいなものです。

経営:
エンジニアも経営のことを知っていた方が良いとよく話を聞くので、経営カテゴリを用意しました。

不勉強なのでこれ以上階層を切れませんでしたが、きっと経理、組織論、法務あたりの情報を共有するのだと思います。

マーケティング:
Webマーケティングの情報に関するカテゴリです。
営業の人が使う想定で用意しました。

このカテゴリも詳しくないので、これ以上の階層を切っていません。
Webエンジニア的にはSEOアクセス解析についての情報が共有されるとうれしいです。

技術情報:
技術に関する備忘録、はまったこと、発見したことなどを共有するカテゴリです。
一部、カテゴリを言語で切るか、フレームワークで切るか悩みましたが、なるべく言語で切ることにしました。

他のカテゴリとの関係を考えて、言語、フレームワークは必ずタグで記述する決まりにします。
この時、タグに言語やフレームワークのバージョン番号は書かない方針にします。

面倒がって書かない人がいるでしょうし、バージョンが関係する情報はその旨がドキュメント内に書かかれるはずなのでそれで良いかなという判断です。

QAコーナー:
QAコーナーはStack Overflow的なカテゴリです。
ここに記事が投稿されたらメーリスに通知するようにしておきます。

内容が解決したら、アーカイブするか、技術情報のカテゴリへ移します。

社内チャットなど、すでにナレッジコミュニティが他にあるなら、このカテゴリは無くてもいいと思います。

イベント:
技術展や勉強会といったイベントに関する情報を共有するカテゴリです。

イベントを主催するときのお知らせや参加レポを共有します。 開催情報のカテゴリに記事が投稿されたらメーリスに通知するようにしておきます。

書籍:
最近読んだ技術書やビジネス書などの情報を共有するカテゴリです。 本の概要や内容に関するメモ、所感を書いて共有します。

ドキュメントを書こうと思った本のドキュメントが既出の場合は、コメントにメモや感想を追記します。

これ以上、下の階層を増やすどうか悩みましたが、とりあえずタグを使った運用にして、ドキュメントが増えてきたらカテゴリを増やせばいいと思います。

ポエム:
ここでいうポエムとは以下のような文章を指します。

ビジネス文章としての整合性や第三者からの検証性を必ずしも重視せず,書き手自身の理想であったり熱意だったり危機感だったり,そういう何らかの感情の発露を自分の中で反芻してとりまとめた表現した文章や図面の事。規模は数行から数十行であることが多い。
第1回 事業会社における開発とポエム:会社で「ポエム」を綴ろう! ~ポエム駆動で理想を語ると社内の風が変わる!~|gihyo.jp … 技術評論社 

ポエム駆動型開発を取り入れないにしても、こういうのを吸い上げられる場所って大事だと思うんですよね、というポエム。

雑記:
これまで紹介したどのカテゴリにも属さないドキュメントを共有するカテゴリです。

どのカテゴリに置いてよいかわからないドキュメントは、ひとまずここに書いておいて、 あとで新しくカテゴリを増やすなり、既存のカテゴリに移すなりするといった運用もできます。

テンプレート

ドキュメントをさくっと書けるように、必要事項を埋めるだけで良いようなテンプレートを用意してみました。

インストール手順テンプレート

f:id:chira_pym:20170320014119p:plain

#:raised_hand: 前提

### :dvd: インストールするソフトウェアとバージョン  
piyo 1.0

###  :computer: OS  
Windows 10

### :cd: 事前にインストールが必要なソフトウェア
なし

# :memo: 手順
1. hoge
2. fuga

#:warning: 注意点

イベント案内テンプレート

f:id:chira_pym:20170320041825p:plain

# :information_source: 基本情報

:calendar:  日時 : 
 
:office:  会場 : 

:black_nib:  テーマ:

# :scroll: 概要

URL: http://google.com

イベント参加レポテンプレート

f:id:chira_pym:20170320040939p:plain

# :information_source:  基本情報

:calendar:  日時 :
 
:office:  会場 :

:black_nib:  テーマ:

# :scroll: 概要

# :thumbsup: 良かった発表・勉強になったことなど  

# :books: 資料
<!--
このようにSlide Shareのスクリプトを埋め込むことができます。
<script async class="speakerdeck-embed" data-id="5633a9b0599d01326f2b4e55f5ecb48c" data-ratio="1.41436464088398" src="//speakerdeck.com/assets/embed.js"></script>
-->
# :coffee:   所感

書籍テンプレート

f:id:chira_pym:20170320133311p:plain

# :blue_book: タイトル

# :scroll: 概要

# :memo: メモ
<!--
読んだことに関して、何かメモしておきたいことがあれば記入してください。
-->

# :coffee:   所感

# :clipboard:  アンケート(任意)

**評価** : :star: × n

## 良かったこと
なし

## 良くなかったこと
なし

## どんな人におすすめか
なし

最後は管理者が頑張るしかない #トノコト

なるべく人が悩む要素はつぶしましたが、それでも、この構成でAWSやDocker関連のドキュメントはどこにどう書こうか、自分でも悩むので、まだまだわかりにくいカテゴリルールになっていると思います。

また、タグの付け方のルールをしっかり定義していないので、そのあたりに起因する問題も起きそうです。

ということで、実際に運用したわけではありませんが、運用時には以下のことが想定されます。

  • カテゴリやタグが乱立する
  • ドキュメントに期待するタグをつけてもらえない
  • ドキュメントが重複する

もともと情報が育ったら整理することを前提としたサービスなので、週1、あるいは月1でドキュメントを整理する時間を設けて、その時にこういったドキュメントの整理もした方が良さそうです。

その時に、それこそドキュメントの整理時のルールを共有するようにしたら良いのではないかと思います。

所感

遅筆なのでここまで書くのに体力と時間をかなり持っていかれました。
お昼寝して起きたら、もっとすごい人たちのちゃんとした記事が上がってるに違いないです。

それではおやすみなさい(:3[___]

MariaDBを削除したらPostfixも一緒に消えちゃった話

会社で休眠状態になってるサーバーを上手いこと活用すべく、色々なツールを入れていたところ、気付いたらそのサーバーからメールが飛ばなくなっていました。

maillogを見てみるとそもそもPostfixが動いていないようでした。 先週まで元気に動いてたはずなのにおかしいなと思いつつ、起動させようとしてみました。すると「postfix.serviceは存在しません」みたいなことを言われました。

…このサーバーを立ち上げる時にPostfixを入れて、四苦八苦しながら設定作業をしたのは私のはずですし、そもそも先週まではちゃんと動いていたはずなのですが、これは一体😓

念の為、こんな感じのコマンドでサービス一覧を出してみましたが、postfix.serviceは見当たりませんでした。

$ systemctl list-unit-files --type=service

結果は貼れませんが、Dovecotとかはちゃんといました。一体Postfixはどこへ… 嫌な汗をかきつつ、whichコマンドを打ちます。

$ which postfix
no postfix in ...

見つかりません。 間違いなくPostfixが入ってるはずなのに… 混乱した頭でyumのインストール済みのパッケージの一覧を出します。

$ yum list installed | grep postfix

何も返ってこない😨

半ば祈る気持ちでfindコマンドを打ちます🙏

$ find / -name postfix
/etc/postfix

…設定ファイルのディレクトリはありました。 実は全てが自分の気のせいで、そもそもPostfixなんて入ってなかったオチとかじゃなくて良かったです😅

ここで少し落ち着きを取り戻して「postfix 消えた」という、大変ざっくりしたキーワードでググり始めました。 こんな雑な検索でも、このような記事が引っかかってくれました。

[Postfix]そうだったのかキミはMySQLと関係を持っていたのか![Postfix]そうだったのかキミはMySQLと関係を持っていたのか!

こんにちは。パッケージの削除について考えらされたので記事にしました。こちらのエントリーで構築した環境でメールテストを行った際に発覚しました。[ローカル開発環境 ...

この記事だとMySQLを更新するのにremoveしたところ、Postfixも削除されてしまったそうなのですが、ずばり私もMariaDBのアップデートをするのに、それまで使ってたバージョンを削除していました。

つまりPostfixを削除した犯人は私だったのです…!

うん、そんな気はしてた。そんな気はしてたけど…!そんな…!!

こう、推理小説とかで、主人公が実は犯人だったみたいな展開って、はたから見るとすべってることも多いのですが、いざ体験してみると、ものすごくびっくりするんですね。今すごく読者との温度差を感じます。

気を取り直して、先ほどの記事にあるように、yum historyを確認します。

$ yum history list | grep Erase

Eraseになってる直近の履歴が出力されるので、あとはちまちまとyum infoで確認していきました。

$ yum history info 20

これも結果は貼れませんが、切り替えたパッケージの項目に「削除 postfix …」と書かれているものが見つかりました。

さらにスクリプトの出力の項目を見てみると /etc/postfix/main.cfや/etc/postfix/master.cf, /etc/postfix/virtualはバックアップが保存されている旨の警告が出ていました。 今回はよりにもよって物理サーバーでやらかしたので、ものすごくげんなりしていましたが、設定ファイルが無事となれば、すぐに元の状態に戻せそうです。

意気揚々とPostfixを再インストールしなおします。

$ yum install postfix

やらかしたばかりなので、yオプションはつけませんでした。でも明日辺りには、また軽率にオプションをつけていく生活に戻る気がします。

あとは警告で出ていた設定ファイルたちを元の場所に戻します。

$ rm -f /etc/main.cf
$ mv /etc/main.cf.rpmsave /etc/main.cf

/etc/postfix/virtualを設定しているので、postmapコマンドも打っておきます。

$ postmap /etc/postfix/virtual

これでなんとかメールサーバーを復旧させることができました🙌

はてなブログはじめました。

はじめまして、ちらです。

表題の通り、はてなブログを始めてみました。

ブログの一通りの設定をするだけで、かなり満足してしまいましたが、もう少し頑張って自己紹介的なものを書いていきたいと思います。

 

👔 職業

まだまだ🔰なWebエンジニアです。

オライリー本を机に置いておけば、仕事ができる人っぽく見えると信じています💻

🎮 趣味

友達と一緒に謎解きに行くのが好きです。

参加するイベントの大半はSCRAP主催のイベントで、いつもラス殺しに遭ってます👼

あと酔わなくて、怖くないVRコンテンツで遊ぶのも好きです。

🍀 ブログを始めようと思った理由

Twitterを備忘録的に使う事に難しさを感じて、ブログを始めることにしました。

基本的に自分向けのものなので、非公開設定でも良かったのですが、拙い内容でも、もしかしたら誰かの役に立つこともあるのかなと思い、公開設定にしています🔓

そんなこんなで会社の人に見つかっても怒られないような事を書いていきたい所存です。

そんなこんなで、よろしくお願いします🐣🐣