本日はUnity枠です。
現在BlenderからUnity製アプリケーションに向けてネットワーク経由でメッシュ情報を双方向に通信するパッケージを開発しています。
MixedRealityModelingToolsという仮称で開発していますが今回は昨日に引き続きBlender側のコア機能を紹介します。
〇MessagePackとは?
今回はデータのシリアル化、デシリアライズにMessagePackを使用しています。
これはC#、Pythonなど多くのプラットフォームで使用することができるバイナリデータの交換用フォーマットで、Json形式のデータとしてバイナリを格納することで非常にデータをコンパクトにすることができます。
筆者の開発中のツールでは高速な通信を実現するためにMessagePackを使用しています。
〇メッシュをUnityに送信する関数
先述の通りUnity側とBlender側ではMessagePackでシリアライズ化したデータを送信して受け取ります。
これを実現する関数が以下になります。
import msgpack
・・・
def send_mesh_data_to_unity(mesh_data):
vertices, triangles, normals = mesh_data
# Convert numpy arrays to list
vertices_list = np.array(vertices, dtype='<f4').flatten().tolist()
triangles_list = np.array(triangles, dtype='<i4').flatten().tolist()
normals_list = np.array(normals, dtype='<f4').flatten().tolist()
# データを辞書として構築
data_dict = {
'vertices': vertices_list,
'triangles': triangles_list,
'normals': normals_list
}
# MessagePackでシリアライズ
serialized_mesh_data = msgpack.packb(data_dict)
#print(f"Serialized data (bytes): {serialized_mesh_data.hex()}")
verification_mesh_data(serialized_mesh_data)
# ここでデシリアライズの確認を行う
try:
deserialized_data = msgpack.unpackb(serialized_mesh_data)
print("Deserialization success!")
#print(deserialized_data) # もし必要ならば、デシリアライズされたデータを出力する
except Exception as e:
print(f"Deserialization error: {e}")
return # エラーが発生した場合、関数をここで終了する
for client in server_thread.clients:
try:
client.sendall(serialized_mesh_data)
#print(serialized_mesh_data)
except Exception as e:
print(f"Error while sending mesh data to client: {e}")
import msgpackにてmsgpackを使用しています。このためにはBelnder側にMessagePackを導入する必要があります。この点は別途説明します。
MessagePackは前述のとおりJson形式(正式にはJsonのような)でデータを格納しバイナリ化します。
これを定義しているのが以下です。
data_dict = {
'vertices': vertices_list,
'triangles': triangles_list,
'normals': normals_list
}
ここでは頂点、メッシュのインデックス、法線の3つのデータを格納しています。
ここで辞書として追加したデータをMessagePackでシリアライズ化します。
serialized_mesh_data = msgpack.packb(data_dict)
送信する前のデータ(=実際のデータ)は次のようになっています。
'vertices': [1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0], 'triangles': [4, 2, 0, 2, 7, 3, 6, 5, 7, 1, 7, 5, 0, 3, 1, 4, 1, 5, 4, 6, 2, 2, 6, 7, 6, 4, 5, 1, 3, 7, 0, 2, 3, 4, 0, 1], 'normals': [0.5773503184318542, 0.5773503184318542, 0.5773503184318542, 0.5773503184318542, 0.5773503184318542, -0.5773503184318542, 0.5773503184318542, -0.5773503184318542, 0.5773503184318542, 0.5773503184318542, -0.5773503184318542, -0.5773503184318542, -0.5773503184318542, 0.5773503184318542, 0.5773503184318542, -0.5773503184318542, 0.5773503184318542, -0.5773503184318542, -0.5773503184318542, -0.5773503184318542, 0.5773503184318542, -0.5773503184318542, -0.5773503184318542, -0.5773503184318542]
これをバイナリデータとして次のようになります。
\x83\xa8vertices\xdc\x00\x18\xcb?\xf0\x00\x00\x00\x00\x00\x00\xcb?\xf0\x00\x00\x00\x00\x00\x00\xcb?\xf0\x00\x00\x00\x00\x00\x00\xcb?\xf0\x00\x00\x00\x00\x00\x00\xcb?\xf0\x00\x00\x00\x00\x00\x00\xcb\xbf\xf0\x00\x00\x00\x00\x00\x00\xcb?\xf0\x00\x00\x00\x00\x00\x00\xcb\xbf\xf0\x00\x00\x00\x00\x00\x00\xcb?\xf0\x00\x00\x00\x00\x00\x00\xcb?\xf0\x00\x00\x00\x00\x00\x00\xcb\xbf\xf0\x00\x00\x00\x00\x00\x00\xcb\xbf\xf0\x00\x00\x00\x00\x00\x00\xcb\xbf\xf0\x00\x00\x00\x00\x00\x00\xcb?\xf0\x00\x00\x00\x00\x00\x00\xcb?\xf0\x00\x00\x00\x00\x00\x00\xcb\xbf\xf0\x00\x00\x00\x00\x00\x00\xcb?\xf0\x00\x00\x00\x00\x00\x00\xcb\xbf\xf0\x00\x00\x00\x00\x00\x00\xcb\xbf\xf0\x00\x00\x00\x00\x00\x00\xcb\xbf\xf0\x00\x00\x00\x00\x00\x00\xcb?\xf0\x00\x00\x00\x00\x00\x00\xcb\xbf\xf0\x00\x00\x00\x00\x00\x00\xcb\xbf\xf0\x00\x00\x00\x00\x00\x00\xcb\xbf\xf0\x00\x00\x00\x00\x00\x00\xa9triangles\xdc\x00$\x04\x02\x00\x02\x07\x03\x06\x05\x07\x01\x07\x05\x00\x03\x01\x04\x01\x05\x04\x06\x02\x02\x06\x07\x06\x04\x05\x01\x03\x07\x00\x02\x03\x04\x00\x01\xa7normals\xdc\x00\x18\xcb?\xe2y\xa7`\x00\x00\x00\xcb?\xe2y\xa7`\x00\x00\x00\xcb?\xe2y\xa7`\x00\x00\x00\xcb?\xe2y\xa7`\x00\x00\x00\xcb?\xe2y\xa7`\x00\x00\x00\xcb\xbf\xe2y\xa7`\x00\x00\x00\xcb?\xe2y\xa7`\x00\x00\x00\xcb\xbf\xe2y\xa7`\x00\x00\x00\xcb?\xe2y\xa7`\x00\x00\x00\xcb?\xe2y\xa7`\x00\x00\x00\xcb\xbf\xe2y\xa7`\x00\x00\x00\xcb\xbf\xe2y\xa7`\x00\x00\x00\xcb\xbf\xe2y\xa7`\x00\x00\x00\xcb?\xe2y\xa7`\x00\x00\x00\xcb?\xe2y\xa7`\x00\x00\x00\xcb\xbf\xe2y\xa7`\x00\x00\x00\xcb?\xe2y\xa7`\x00\x00\x00\xcb\xbf\xe2y\xa7`\x00\x00\x00\xcb\xbf\xe2y\xa7`\x00\x00\x00\xcb\xbf\xe2y\xa7`\x00\x00\x00\xcb?\xe2y\xa7`\x00\x00\x00\xcb\xbf\xe2y\xa7`\x00\x00\x00\xcb\xbf\xe2y\xa7`\x00\x00\x00\xcb\xbf\xe2y\xa7`\x00\x00\x00
\x○○という形式でデータが格納されており、○○部が16進数に変換したデータは以下になります。
131168220024203240000000203240000000203240000000203240000000203240000000203191240000000203240000000203191240000000203240000000203240000000203191240000000203191240000000203191240000000203240000000203240000000203191240000000203240000000203191240000000203191240000000203191240000000203240000000203191240000000203191240000000203191240000000169220042027365717503141546226764513702340116722002420322616700020322616700020322616700020322616700020322616700020319122616700020322616700020319122616700020322616700020322616700020319122616700020319122616700020319122616700020322616700020322616700020319122616700020322616700020319122616700020319122616700020319122616700020322616700020319122616700020319122616700020319122616700
このようにしてシリアライズしたデータを次のようにclient.sendall()でクライアントに送信します。
client.sendall(serialized_mesh_data)
以上でBlenderからUnityにデータを渡す処理になります。
次回はUnity側について紹介します。