MRが楽しい

MRやVRについて学習したことを書き残す

HoloToolKitのSharingメッセージを拡張する

本日は hololens の技術調査枠です。
以下の記事を参考に、Sharing で共有する情報を追加します。
bril-tech.blogspot.jp

以下の Sharing 環境の構築を行ったプロジェクトを前提とします。
bluebirdofoz.hatenablog.com

初めに CustomMessages.cs に新しい MessageID を追加します。
f:id:bluebirdofoz:20170920001323j:plain

今回は3つのTransform情報と2つのモード情報を転送します。
・CustomMessages.cs

public enum TestMessageID : byte
{
    HeadTransform = MessageID.UserMessageIDStart,
    MainTransform,       // MainオブジェクトのTransform情報
    SimulationTransform, // SimulationオブジェクトのTransform情報
    PanelTransform,      // PanelオブジェクトのTransform情報
    PanelMode,   // PanelオブジェクトのMode情報
    TapMode,     // Tap操作のMode情報
    Max
}

次に、追加したIDに対応する SendMessage 関数を作成します。
一例としてMainTransform情報の送信関数は以下のようなメソッドを追加します。
・CustomMessages.cs

public void SendMainTransform(Vector3 position, Quaternion rotation, Vector3 scale)
{
    // If we are connected to a session, broadcast our head info
    if (serverConnection != null && serverConnection.IsConnected())
    {
        // Create an outgoing network message to contain all the info we want to send
        NetworkOutMessage msg = CreateMessage((byte)TestMessageID.MainTransform);

        AppendTransformScale(msg, position, rotation, scale);

        // Send the message as a broadcast, which will cause the server to forward it to all other users in the session.
        serverConnection.Broadcast(
    msg,
    MessagePriority.Immediate,
    MessageReliability.UnreliableSequenced,
    MessageChannel.Avatar);
    }
}

private void AppendTransformScale(NetworkOutMessage msg, Vector3 position, Quaternion rotation, Vector3 scale)
{
    AppendVector3(msg, position);
    AppendQuaternion(msg, rotation);
    AppendVector3(msg, scale);
}


またMode情報の送信関数は以下のようなメソッドを追加します。
・CustomMessages.cs

public void SendPanelMode(byte val)
{
    // If we are connected to a session, broadcast our head info
    if (serverConnection != null && serverConnection.IsConnected())
    {
        // Create an outgoing network message to contain all the info we want to send
        NetworkOutMessage msg = CreateMessage((byte)TestMessageID.PanelMode);

        msg.Write(val);

        // Send the message as a broadcast, which will cause the server to forward it to all other users in the session.
        serverConnection.Broadcast(
    msg,
    MessagePriority.Immediate,
    MessageReliability.UnreliableSequenced,
    MessageChannel.Avatar);
    }
}

後は作成した関数を送信したいタイミングで実行します。
・GameManager.cs

public void SetTapObjectMode(ETapObjectMode a_ETapObjectMode)
{
    if (p_ETapObjectMode != ETapObjectMode.Locked)
    {
        p_ETapObjectMode = a_ETapObjectMode;
        HoloToolkit.Sharing.Tests.CustomMessages.Instance.SendTapMode((byte)p_ETapObjectMode);
    }
}

・EGameManager.cs

public enum ETapObjectMode : byte
{
    Neutral = 0,
    Nothing = 1,
    Locked = 2,
    MainObject = 3
}

送信側の実装はこれで完了です。

次に受信側の設定を行います。
追加した MessageID 毎にコールバックの設定を追加します。
・GameManager.cs

private void Start()
{
    // Sharingコールバックの設定
    CustomMessages.Instance.MessageHandlers[CustomMessages.TestMessageID.MainTransform] = SharingMainTransform;
    CustomMessages.Instance.MessageHandlers[CustomMessages.TestMessageID.SimulationTransform] = SharingSimulationTransform;
    CustomMessages.Instance.MessageHandlers[CustomMessages.TestMessageID.PanelTransform] = SharingPanelTransform;
    CustomMessages.Instance.MessageHandlers[CustomMessages.TestMessageID.PanelMode] = SharingPanelMode;
    CustomMessages.Instance.MessageHandlers[CustomMessages.TestMessageID.TapMode] = SharingTapMode;
}

MainTransform情報の受信関数は以下のようなメソッドを指定します。
・GameManager.cs

/// <summary>
/// MainオブジェクトのTransformコールバック関数
/// </summary>
/// <param name="msg">受信メッセージ</param>
private void SharingMainTransform(NetworkInMessage msg)
{
    // Parse the message
    long userID = msg.ReadInt64();
    Vector3 transformPosition = CustomMessages.Instance.ReadVector3(msg);
    Quaternion transformRotation = CustomMessages.Instance.ReadQuaternion(msg);
    Vector3 transformScale = CustomMessages.Instance.ReadVector3(msg);

    // set Transform
    Transform transformObject = p_ViewerMainObject.transform;
    transformObject.position = transformPosition;
    transformObject.rotation = transformRotation;
    transformObject.localScale = transformScale;
}

PanelMode情報の受信関数は以下のようなメソッドを指定します。
・GameManager.cs

/// <summary>
/// PanelオブジェクトのModeコールバック関数
/// </summary>
/// <param name="msg">受信メッセージ</param>
private void SharingPanelMode(NetworkInMessage msg)
{
    // Parse the message
    long userID = msg.ReadInt64();
    int modeByteVal = msg.ReadByte();
    EShowPanelMode panelMode = (EShowPanelMode)System.Enum.ToObject(typeof(EShowPanelMode), modeByteVal);

    // set Mode
    p_EShowPanelMode = panelMode;
    // 状態を反映する
    p_ActiveManager.SetActiveEShowPanelMode(p_EShowPanelMode);
}

以上で Sharing 情報の追加は完了です。