内容に「Pro」を含む
1〜10件目 / 32件
1 2 3 4 次へ

 SwitchのコントローラでMIDIを再生するツールを作った / magicien 

JoyConSwiftの開発を進める中で、コントローラ振動機能をテストする必要があったので、ついでにMIDIを読み込む機能も追加してツール化しました。
ダウンロード:JoyfulPlayerのReleasesからJoyfulPlayer-vX.X.X.dmgのような名前をダウンロードしてください。

Proコンで UNDERTALE の Megalovania を再生した動画↓


技術的な解説

動画にも書いた通り、コントローラの振動は、リニア振動モーターなるものが使われており、Joy-Conには1つ、Proコンには2つ、このモーターが入っています。

学研さんと「HD振動」のヒミツについて調べてみました。 | トピックス | Nintendo

このモーターは、上下方向と左右方向でそれぞれ別の周波数で振動させることができるため、一つのモーターで同時に2つの音を発生させることができます。例えば、上下方向に 262Hz、左右方向に 440Hz で振動させると、ドとラの和音が鳴るわけです。Proコンには、モーターが2つ入っているので、最大で4和音まで再生できることになります。
実は2軸で指定できる周波数の範囲に差があり、1つは 40.88〜626.29Hz、もう1つは 81.75〜1252.57Hz が指定できるようです。音階にすると、E1〜D#5、E2〜D#6くらい。

Rumble data table

音楽の世界では、一般的に1オクターブを12分割していますが、このモーターで指定できる周波数は1オクターブにつき16段階なので、正確な音階は表現できません。今回作ったツールでは、一番近い周波数を選ぶことでそれっぽい音を鳴らすようにしています。絶対音感がある人には、とても気持ち悪いかもしれませんが、正直なところ自分には音がずれているのかどうか、よくわかりませんでした。(そもそもコントローラは楽器ではない)
課題として、特定の周波数の範囲でコントローラ全体が共鳴してしまい、うるさい、という問題があります。おそらくコントローラによって共鳴する周波数が違うので、真面目に音量調整しようとするとかなり苦労しそうです。上の動画では音声編集ツールを使ってある程度音量差を抑えていますが、それでも特定の音がかなりうるさく感じるでしょう。

MIDIファイルの解析には、MidiParserを使わせていただきました。このシンプルかつ強力なライブラリのおかげで、MIDIファイルの解析で特に困ったことはありませんでした。

自分の中で新たなチャレンジとして取り組んだのは、SwiftUIによるインタフェースの作成でした。VueやReactを使ったことがある人は割ととっつきやすいと思います。JavaScriptより型が厳密である分、SwiftUIの方が安心感があります。まだ発展途上の段階で、APIの追加・変更が多いので、もう少し落ち着くまで待つのも手だと思います。

2020/08/19(Wed) 02:16:39

 Mac の Unreal Engine 4.25.1 でMMDモデル・モーションを一発で読み込む / magicien 

MMDモデル・モーションを読み込むUE4用プラグイン「IM4U」をMacに対応させた。
プラグインのダウンロードはここから。詳細は続きに。

(モデル:ロボ子さん(© 2019 cover corp.)、モーション:あざとかわいいターン

オリジナルのIM4Uは既に開発停止してしまっているが、UE4.24向けにアップデートした方がいたので(tekifuta/IM4U)、これをMac UE4.25.1でビルドできるように修正した。(Mac UE 4.24 以前では動かないと思う)

インストール方法

今のところバイナリは配布していないので、プロジェクト毎にインストールする必要がある。

1. UE4.25.1のプロジェクトを作成する。
2. 作成したプロジェクトのパスに Plugins ディレクトリを作成する。(自分の環境だと、/Users/ユーザ名/Documents/Unreal Projects/プロジェクト名/Plugins)
3. Plugins ディレクトリの下に IM4U のGithubリポジトリを丸ごとダウンロードする。
("git clone https://github.com/magicien/IM4U.git" コマンドか、Githubのページの "Clone or download" > "Download ZIP" でダウンロードしたZIPを展開する)
4. UEのプロジェクトを開き直すと、IM4Uをビルドするか聞かれるので、ビルドする。
5. あとは他のモデル・モーションファイルと同様にpmd/pmx/vmdファイルが読み込める。


以下はまだ対応できていないもの。後で対応するかもしれない。
・ルートボーンが無い(複数ある)PMDモデル対応
・モーション読み込み時にIKを適用する(UEにもIKの機能があるが、モーション自体にIK計算後のボーン位置を焼き込んだ方が良いだろう)
・物理演算対応(剛体だけだっけ?)
・英語対応(UI、コード中のコメント)
・リファクタリング

英語対応だけしておけば、残りは誰かが勝手にやってくれるかもしれない。

2020/06/15(Mon) 00:25:57

 Epic Online Services のAccount IDからProduct User IDを取得する / magicien 

Epic Online Services のSDKでフレンドのプレゼンスを取得・監視する」の続き。

EOSでP2P通信するために、自分と相手のProduct User IDを指定する必要がある。ログイン・フレンド検索で使うIDは、Epic Account IDなので、Epic Account IDに紐づくProduct User IDを別途取得しないといけない。

よくよく調べると、このアカウント周りの処理は、やれることが多い分、処理内容もかなり複雑で、まだ理解しきれていない部分が多い。ライブラリ側でもう少し複雑さを隠蔽してくれてもいいのに。

今回は、一番簡単であろう、外部アカウントIDとして Epic Games を使った場合の流れについて。


まず、Epic Account ID と、Product User ID の関係を図にすると、次のようになる、はず。

フレンドはEpic Account IDで管理されているが、P2P通信はゲームに紐づいたProduct User IDを指定する。そのため、フレンドとP2P通信をするには、Epic Account ID から Product User ID を取得しなければならない。

Epic Account ID

EpicのアカウントのIDは、Epic Gamesでユーザ登録すれば発行される。Epic Account IDは、ユーザに紐づくので、基本的に一人一つだけ割り当てられることになる。

Epic Account IDとExternal IDの関係

実は、Epic Gamesでユーザ登録しなくても、他のアカウント管理システムに紐づいて Epic Account ID の発行ができる。Apple、Nintendo、PSN、...で認証されたユーザのIDに紐付けて、Epic Account IDが発行される。外部アカウントのユーザID一つに紐づけられるEpic Account IDは一つだけ。逆に、一つの Epic Account ID を、複数の外部アカウントに紐付ける事はできる。

Organization User ID?

ドキュメントによると、Organization User IDなるものがあるらしい。が、SDK上にはそれらしいものが見当たらない。謎。
実際は、External IDからProduct User IDに紐づいているように思える。

External IDとProduct User IDの関係

Product User IDは、ゲーム毎に発行されるユーザID。External ID一つにつき、Product User IDが一つ紐づく。複数のExternal IDで一つのProduct User IDが共有できる。

※PSのIDとゲームA用のProduct User ID(Product User A1)が既に紐づいている場合は、同じゲーム内で別のProduct User ID(Product User A2)に紐づけることはできない。

ユーザ、フレンドのEpic Account IDからProduct User IDを取得する


プレイヤー(Local User)のEpic Account IDは、ログイン時に取得できる。
さらに、Account IDからアクセストークンを取得、EOS_Connect_Loginにアクセストークンと外部アカウント(今回はEpic Games)を指定することで、プレイヤーのProduct User IDが取得できる。

フレンドのEpic Account IDは、EOS_Friends_QueryFriends のフレンド検索結果から得られる。この Epic Account ID を、外部アカウントのIDとして使う。EOS_Connect_QueryExternalAccountMappings に フレンドの Epic Account ID と、ユーザの Product User ID を渡して、フレンドの Product ID を取得する。
EOS_Connect_QueryExternalAccountMappings には、複数のフレンドの外部アカウントIDを渡せるので、一回のクエリでProduct User IDをまとめて取得できる。


文章にしようとすると、かなり複雑になってしまう。本当は、プレイヤーのProduct User IDが無い場合に、EOS_Connect_CreateUser でIDを作らないといけなかったり、既存のProduct User IDに外部アカウントを関連づけるために EOS_Connect_LinkAccount を呼んだりする場合があって、より複雑になる。(公式ドキュメント参照)

今回はここまで。

2020/06/06(Sat) 17:37:38

 Epic Online Services のSDKでフレンドのプレゼンスを取得・監視する(Swift) / magicien 

「Epic Online Services のSDKでログインしたユーザの情報を取得する」の続き。
フレンドのプレゼンス(オンライン・オフラインの状態、「〜をプレイ中」みたいなテキスト)を取得・監視する。


大まかな流れ

1. フレンド一覧を取得するクエリを発行する。
2. 取得したフレンドID一覧を基にさらに情報取得する(今回はプレゼンスを取得するクエリを発行する)。また、プレゼンスの変更を監視する。
3. プレゼンス取得結果を確認する。
4. プレゼンスに変更があった場合にこの関数が呼ばれる。

プレゼンスの監視対象が自分だけなのか、フレンドも含まれるかが未確認。(確認後に記事を更新予定)

上記コードには処理を書いていないが、不要になった監視は、EOS_Presence_RemoveNotifyOnPresenceChanged で止める必要がある。

追記1(5/31):現状、同じOrganizationに登録されているユーザしかフレンドとして認識されないようだ。アプリの審査が通れば、他のユーザもフレンドとして認識されるのかもしれない。
追記2(6/5):ドキュメントにアプリの審査が通るまで同じOrganizationのユーザとしかやりとりできない旨が書いてあった。("Initially, you will only be able to interact with other users within your organization. After your application has passed review, it can be distributed to any users within the Epic ecosystem.")
今回はここまで。

続き:Epic Online Services のAccount IDからProduct User IDを取得する

2020/05/31(Sun) 02:43:29

 Epic Online Services のSDKでログインするまでの流れ(Swift) / magicien 

Epic Online Services のSDKをSwiftから使うの続き。

C++のサンプルをそのまま書き換えれば動くけれど、GUIに関わる部分を排除してログインに必要な処理のみをSwiftに書き換えると次のようになる。

大まかな流れ

1. アプリの初期化(EOS_Initialize)
2. ログ用コールバックの設定(EOS_Logging_SetCallback)
3. プラットフォームの初期化(EOS_Platform_Create)
4. Tick用コールバックの設定(CVDisplayLinkStart -> EOS_Platform_Tick)
5. ログイン処理(EOS_Auth_Login)

EOSの内部処理は EOS_Platform_Tick をトリガとして処理が進んでいくので、定期的に(毎フレーム)EOS_Platform_Tick を呼ぶ必要があることに注意。
3. で必要なIDがどこに書いてあるかは、 「Epic Online Services のサンプルをMacでコンパイルして動かす」の「6.4. Product情報を集める」を参照。

文字列の型を変換する

APIで文字列を渡す部分はC言語用に直さないといけないので、
let productName = "Test".cString(using: .ascii)
productName?.withUnsafeBufferPointer {
    initOptions.ProductName = $0.baseAddress
}
こんな感じで String から UnsafePointer に変換して渡す。

今回はここまで。

続き:Epic Online Services のSDKでログインしたユーザの情報を取得する(Swift)

2020/05/24(Sun) 22:03:35

 Epic Online Services のSDKをSwiftから使う / magicien 

Epic Online Services のサンプルをMacでコンパイルして動かすの続き。

Epic Online Services のMac向けSDKは、dylib(動的ライブラリ)の形で配布されており、Swiftから直接使うことができない。Swiftから、このライブラリを使うための手順は次の通り。


普通のdylibなら、module.mapとXcodeのパス設定追加でSwiftから使えるようになる。

1. ライブラリ用ファイル構成

Xcodeで作ったプロジェクトの中にライブラリ用ディレクトリを作る。
プロジェクトルート/
 ┗ Frameworks/
   ┗ EOSSDK-Mac-Shipping/
     ┣ libEOSSDK-Mac-Shipping.dylib (ダウンロードしたSDKの SDK/Bin/libEOSSDK-Mac-Shipping.dylib をコピー)
     ┣ module.map (後で作る)
     ┗ Headers/ (ダウンロードしたSDKの SDK/Include をディレクトリごとコピー)
       ┣ eos_achievements.h
       ┣ ...

2. libEOSSDK-umbrella.h を作る

インポートするヘッダをまとめたファイルを一つ作る。
基本的に全てのヘッダファイルを記載するのだけれど、後述 (6.) のエラー対応のために "eos_ui_keys.h" と "eos_result.h" を除外する。

3. module.mapを作る

これは基本的にテンプレート通り。"EOSSDK" がSwiftからimportするときの名前になる。

4. libEOSSDK-Mac-Shipping.dylib をプロジェクトに登録する

libEOSSDK-Mac-Shipping.dylib をXcodeにドラッグ&ドロップする。


TARGET の Frameworks, Libraries, and Embedded Content に libEOSSDK-Mac-Shipping.dylib が登録されていることを確認(無ければドラッグで追加)し、Embed & Sign (または Embed Without Signing)に設定する。


5. パス設定追加

プロジェクトのパス設定を追加する。

・Search Paths > Library Search Paths
"$(PROJECT_DIR)/Frameworks/EOSSDK-Mac-Shipping" を追加

・Swift Compiler - Search Paths > Import Paths
"$(PROJECT_DIR)/Frameworks/EOSSDK-Mac-Shipping" を追加

6. EOSのヘッダファイルを修正

本来ならこの段階で使えるようになるが、clangのプリプロセッサの問題なのか、一部ヘッダでエラーが出るので修正する。
規約に引っかかりそうなので、修正後のファイルを載せないが、次のように修正する。

・eos_ui_types.h
eos_ui_keys.h の中身を丸ごとコピーして 101行目の 「#include "eos_ui_keys.h"」 の部分にペースト

・eos_common.h
eos_result.h の中身を丸ごとコピーして 15行目の 「#include "eos_result.h"」の部分にペースト

・eos_ui_keys.h を削除
・eos_result.h を削除

7. 使う

module.map に設定した名前でインポートする。
import EOSSDK

今回はここまで。

続き:Epic Online Services のSDKでログインするまでの流れ(Swift)

2020/05/24(Sun) 20:35:54

 JoyKeyMapper: SwitchのJoy-ConとProコントローラをMacで使うツールを作った / magicien 

タイトルの通り、SwitchのJoy-ConとProコントローラをMacで使うツールを作りました。
JoyKeyMapper(App Store)

JoyKeyMapper screenshot
オープンソースなので、Githubでソースコードを公開しています。
詳しい使い方もGithubの方に書いたので、そちらをご覧ください。

2020/05/21(Thu) 20:20:39

 Epic Online Services のサンプルをMacでコンパイルして動かす / magicien 

ご無沙汰しております。まさか5月にもなって2020年初、どころか令和初投稿です。
先日、Epic Games から Unreal Engine 5 の映像が公開されて話題になりましたが、個人的には、ユーザアカウント管理が無料でできる Epic Online Services の方が気になったので、Macでサンプルを動かしてみました。
以下、Macでサンプルを動かすまでの手順を書いておきます。


大まかな手順は Quick Start Guide を参照。

1. Developer Portal のユーザ登録

ユーザ登録がまだの人はまず登録から。Epic Games のユーザと共通。
ログインページ

2. SDK&サンプルのダウンロード

Developer Portal からSDKをダウンロードする。

ダウンロードしたSDKの中にサンプルコードも入っている。

3. 必要なライブラリ等のインストール

・Xcode(とコマンドラインツール):App Storeからインストール
・Homebrew:Homebrewのサイトにあるコマンドをコピペして実行
・SDL2:Homebrewでインストール。
brew install sdl2

・SDL2_ttf:Homebrewでインストール。
brew install sdl2_ttf

・GLEW:Homebrewでインストール。
brew install glew

・cmake:Homebrewでインストール。
brew install cmake


4. サンプルの一部修正(いらないかも)

自分の環境だと cmake で GLEW の読み込みがうまくいかない(GLEW_LIBRARIES 等の変数が設定されない。cmakeの仕様、というかバグだと思う)ので、サンプル内のCMakeLists.txt の内容を一部修正する。(cmake自体を直してしまってもいいかもしれない)
find_package(GLEW)
を次のようなコードに置き換える。(例えば、Samples/SimpleFramework/CMakeLists.txt の場合は76行目)
find_path(GLEW_INCLUDE_DIR GL/glew.h
    /usr/local/include
    /System/Library/Frameworks/GLEW.framework/Versions/A/Headers
    ${OPENGL_LIBRARY_DIR}
)
find_library(GLEW_LIBRARIES GLEW
    /usr/local/lib
    /usr/openwin/lib
    /usr/X11R6/lib
    /usr/local/Cellar/glew/2.1.0_1/lib
)
if (DEFINED GLEW_LIBRARIES)
    message(STATUS "GLEW found")
    set(GLEW_FOUND TRUE)
endif()
修正後のCMakeLists.txtの例。glewのパス "/usr/local/Cellar/glew/2.1.0_1/lib" のバージョンは各自の環境に合わせて変更してください。バージョン番号を埋め込んでいるのであくまで応急処理。

5. サンプルのビルド

chmod 755 ./Build.sh
でビルド用シェルに実行権限を付与。
./Build.sh
でビルド。エラーが出ずにビルドが完了すればOK。

6. アプリの設定

ここで一旦 Developer Portal に戻ってアプリの設定をする。
詳しい手順は Getting Started with Epic Account Servicesを参照。

6.1. Productの作成

アカウント作成時に「My Product xxxxx」というProductがデフォルトで出来ているようなので、それを使っても良い。新しく作る場合は、「Create Product」から。後で気づいたけど、現状、作成したProductを消す術が無いようなので無闇に作らない方が良いかもしれない。


6.2. Clientの作成

Product Settings > Client Credentials > NEW CLIENT でクライアントを作成。FEATURESはとりあえず全部付けておく。


6.3. Epic Account Servicesの設定

作ったProductのEpic Account Servicesの設定をする。

・Brand Settings:Privacy Policy URL が必須。テスト用で公開するつもりがないなら、適当に自分の持っているURLか何かで埋めれば良いと思う。自分は App Privacy Policy Generatorで自動生成したものをGistに貼り付けた。実物はここ

「SUBMIT FOR REVIEW」ボタンがあるけど、アプリの審査はまだないっぽい。

・PERMISSIONS:全部試したいので全部REQUIREDにする


・CLIENTS:6.2. で作成したClientを選ぶ


3つとも CONFIGURED になればOK。

6.4. Product情報を集める

"Product Settings" のページからサンプルの実行に必要な情報を集める。

・Product ID


・Sandbox ID


・Deployment ID:Sandboxesの DEPLOYMENTS から


・Client ID



・Client Secret:三点リーダーのメニュー内のClient Detailsから。"Copy secret key" でキーをコピーする。



7. サンプル実行用シェルの修正

・Run.sh を編集して実行時の引数を追加する。6.4. で集めたIDを引数として渡す。


chmod 755 Run.sh
で実行権限を付与。

8. サンプル実行

./Run.sh
で実行。

・ファイルの信頼性のエラーが出た場合
うろ覚えだけど、実行時に SDK/Bin/libEOSSDK-Mac-Shipping.dylib の信頼性でエラーが出た気がする(App Store以外からダウンロードしたファイルを実行しようとしたときに出るあれ)。その場合は、ライブラリを右クリック(Ctrl + クリック)して Open を選択して一度ファイルを開けばエラーが出なくなる。


・アプリ起動後、Account Portal > LOG IN を選ぶとブラウザが開いてログインページに飛ぶ。


・審査前なので、Unverified Application の警告が出るが、気にせず CONTINUE TO APP を選ぶ


・ALLOW を選ぶ


・サンプルのログインが完了し、ユーザ名が表示される。


今回はここまで。

続き:Epic Online Services のSDKをSwiftから使う

2020/05/20(Wed) 03:02:10

 GitHubから取得したファイルをindexedDBに保存する / magicien 

ブラウザ(JavaScript)からGitHubのリポジトリのアーカイブを取得・展開するの続き。
展開したファイルをIndexedDBに保存する。


DBのオープンやデータの更新を要求すると、戻り値として IDBRequest のオブジェクトが返ってくる。このオブジェクトの onsuccess と onerror に関数を設定すると、処理が終わった時に呼び出される。ソースはこんな感じ。例によって検証していないので、typoとかバグとかあるかも。

リクエストを発行してからでないとコールバック関数が設定できないのは設計がおかしいんじゃなかろうか。
とりあえず、getResult関数でonsuccess、onerrorをPromiseでラップしておく。transactionの場合は、イベント名がちょっと違って、oncomplete、onerror、onabort になる。ディスクの空き容量が足りないと、QuotaExceededError が起きて onabort が呼び出される。手元のMacBook Airだとこのエラーが頻繁に起きる。
IndexedDBで使える容量はブラウザや状況(ディスクの空き容量)によって変わるようで、ひどい時はChromeで容量上限が10KBだった。おまえ、キャッシュとかswapとかで軽く数GB食いつぶすくせにIndexedDBには厳しすぎない?まぁ無いものは無いのでエラーを出して終了するしかない。Chromeを終了してディスクを解放してから再起動すると上限が1GBに増えていたりする。

2017/10/08(Sun) 07:46:30

 新iPhone! / magicien 

既に色々と情報がリークしていましたが、ようやく新iPhoneが発表されましたね。

iPhone9が欠番になっちゃいましたが、8sの代わりに9が出たりするのかなぁ。Xも出ちゃったので以降のネーミングはmacOSみたいな感じになりそうですね。

個人的にはAnimojiが一番気になりました。顔認証技術をそうやって使うのかと。
そのうちMacBookにも同じ機能が付くのかなぁ。MMDの表情モーションを自分で演じて作るというのも面白いかもですね。
Dot Projectorというパーツが増えていたので、Kinectと同じようなことをしているんでしょう。Microsoftと何らかのやり取りがあったんでしょうか。ここら辺の技術はどこが持っているのか。
(追記:2013年にAppleがイスラエルのPrimeSenseという会社を買収していたようですね。Kinectのセンサーを作っていた会社らしいです。4年前からFaceIDの開発が進められていたってことですかね。対してKinectは生産終了...うーむ。iPhoneのDot Projectorで姿勢検知までできるようになると良いですね。)

もう一つ気になったのは、Apple TVとiPhoneのHDR対応。ディスプレイ側がHDRに対応するとなると、シェーダはどうやって書けば良いんでしょう。HDR対応有無でシェーダ書き分けるのとか面倒そう...

そういえば、Touch IDで他人がロックを解除できる確率は1/50,000とか言っていたけれど、結構確率高くないですか。まぁiPhoneに限らず、指紋認証機能を使っていると、自分の指なのになかなか認証が通らなかったり、他の人の指で解除できてしまったりということが多々あったので、あんまり信用できないか、精度を上げようとするとお金がかかる技術なのかなぁという印象があったのですが。
Face IDは、人工マスクでもロック解除できないことをテストしました、ということでしたが、サーモグラフィでも見ているんですかね。そのうち例によって顔認証をハックしちゃう人たちが現れるでしょう。

2017/09/13(Wed) 05:21:53